diff --git a/.gitignore b/.gitignore index 0af7cb4e..a26a7311 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.tmproj .dotest /.emacs-project +/.redcar config/database.yml config/site.yml config/deploy.rb @@ -20,3 +21,4 @@ public/javascripts/tracks-cached.js public/stylesheets/tracks-cached.css .idea .rvmrc +.yardoc diff --git a/.yardopts b/.yardopts new file mode 100644 index 00000000..88651e3e --- /dev/null +++ b/.yardopts @@ -0,0 +1,3 @@ +--title "Tracks Documentation" +--charset utf-8 +--markup="textile" diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..5163e0eb --- /dev/null +++ b/Gemfile @@ -0,0 +1,56 @@ +source :gemcutter +source "http://gems.github.com/" + +gem "rake", "~>0.8.7" +gem "rails", "~>2.3.12" +gem "highline", "~>1.5.0" +gem "RedCloth", "4.2.8" +gem "sanitize", "~>1.2.1" +gem "rack", "1.1.0" +gem "will_paginate", "~> 2.3.15" +gem "has_many_polymorphs", "~> 2.13" +gem "acts_as_list", "~>0.1.4" +gem "aasm", "~>2.2.0" +gem "rubyjedi-actionwebservice", :require => "actionwebservice" +gem "rubycas-client", "~>2.2.1" +gem "ruby-openid", :require => "openid" +gem "sqlite3" +gem 'bcrypt-ruby', '~> 2.1.4' +gem 'htmlentities', '~> 4.3.0' +gem "mail" + +if RUBY_VERSION.to_f >= 1.9 + gem "soap4r-ruby1.9" +else + gem "soap4r", "~>1.5.8" +end + +gem "webrat", ">=0.7.0", :groups => [:cucumber, :test] +gem "database_cleaner", ">=0.5.0", :groups => [:cucumber, :selenium] +gem "cucumber-rails", "~>0.3.0", :groups => :cucumber + +group :development do + if RUBY_VERSION.to_f >= 1.9 + gem "ruby-debug19" + gem "mongrel", "1.2.0.pre2" + else + gem "ruby-debug" + gem "mongrel" + end + gem "yard" +end + +group :test do + gem "test-unit", "1.2.3" + gem "flexmock" + gem "ZenTest", ">=4.0.0" + gem "hpricot" + gem "hoe" + gem "rspec-rails", "~>1.3.3" + gem "thoughtbot-factory_girl" + gem 'memory_test_fix', '~>0.1.3' +end + +group :selenium do + gem "selenium-client" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..bf2fd94f --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,148 @@ +GEM + remote: http://rubygems.org/ + remote: http://gems.github.com/ + specs: + RedCloth (4.2.8) + ZenTest (4.6.1) + aasm (2.2.0) + actionmailer (2.3.14) + actionpack (= 2.3.14) + actionpack (2.3.14) + activesupport (= 2.3.14) + rack (~> 1.1.0) + activerecord (2.3.14) + activesupport (= 2.3.14) + activeresource (2.3.14) + activesupport (= 2.3.14) + activesupport (2.3.14) + acts_as_list (0.1.4) + bcrypt-ruby (2.1.4) + builder (3.0.0) + cgi_multipart_eof_fix (2.5.0) + columnize (0.3.4) + cucumber (1.0.2) + builder (>= 2.1.2) + diff-lcs (>= 1.1.2) + gherkin (~> 2.4.5) + json (>= 1.4.6) + term-ansicolor (>= 1.0.5) + cucumber-rails (0.3.2) + cucumber (>= 0.8.0) + daemons (1.1.4) + database_cleaner (0.6.7) + diff-lcs (1.1.2) + fastthread (1.0.7) + flexmock (0.9.0) + gem_plugin (0.2.3) + gherkin (2.4.11) + json (>= 1.4.6) + has_many_polymorphs (2.13) + activerecord + highline (1.5.2) + hoe (2.12.0) + rake (~> 0.8) + hpricot (0.8.4) + htmlentities (4.3.0) + httpclient (2.2.1) + i18n (0.6.0) + json (1.5.3) + linecache (0.46) + rbx-require-relative (> 0.0.4) + mail (2.3.0) + i18n (>= 0.4.0) + mime-types (~> 1.16) + treetop (~> 1.4.8) + memory_test_fix (0.1.3) + mime-types (1.16) + mongrel (1.1.5) + cgi_multipart_eof_fix (>= 2.4) + daemons (>= 1.0.3) + fastthread (>= 1.0.1) + gem_plugin (>= 0.2.3) + nokogiri (1.4.7) + polyglot (0.3.2) + rack (1.1.0) + rack-test (0.6.1) + rack (>= 1.0) + rails (2.3.14) + actionmailer (= 2.3.14) + actionpack (= 2.3.14) + activerecord (= 2.3.14) + activeresource (= 2.3.14) + activesupport (= 2.3.14) + rake (>= 0.8.3) + rake (0.8.7) + rbx-require-relative (0.0.5) + rspec (1.3.2) + rspec-rails (1.3.4) + rack (>= 1.0.0) + rspec (~> 1.3.1) + ruby-debug (0.10.4) + columnize (>= 0.1) + ruby-debug-base (~> 0.10.4.0) + ruby-debug-base (0.10.4) + linecache (>= 0.3) + ruby-openid (2.1.8) + rubycas-client (2.2.1) + activesupport + rubyjedi-actionwebservice (2.3.5.20100714122544) + actionpack (~> 2.3.0) + activerecord (~> 2.3.0) + activesupport (~> 2.3.0) + sanitize (1.2.1) + nokogiri (~> 1.4.1) + selenium-client (1.2.18) + soap4r (1.5.8) + httpclient (>= 2.1.1) + sqlite3 (1.3.4) + term-ansicolor (1.0.6) + test-unit (1.2.3) + hoe (>= 1.5.1) + thoughtbot-factory_girl (1.2.2) + treetop (1.4.10) + polyglot + polyglot (>= 0.3.1) + webrat (0.7.3) + nokogiri (>= 1.2.0) + rack (>= 1.0) + rack-test (>= 0.5.3) + will_paginate (2.3.16) + yard (0.7.3) + +PLATFORMS + ruby + +DEPENDENCIES + RedCloth (= 4.2.8) + ZenTest (>= 4.0.0) + aasm (~> 2.2.0) + acts_as_list (~> 0.1.4) + bcrypt-ruby (~> 2.1.4) + cucumber-rails (~> 0.3.0) + database_cleaner (>= 0.5.0) + flexmock + has_many_polymorphs (~> 2.13) + highline (~> 1.5.0) + hoe + hpricot + htmlentities (~> 4.3.0) + mail + memory_test_fix (~> 0.1.3) + mongrel + rack (= 1.1.0) + rails (~> 2.3.12) + rake (~> 0.8.7) + rspec-rails (~> 1.3.3) + ruby-debug + ruby-openid + rubycas-client (~> 2.2.1) + rubyjedi-actionwebservice + sanitize (~> 1.2.1) + selenium-client + soap4r (~> 1.5.8) + sqlite3 + test-unit (= 1.2.3) + thoughtbot-factory_girl + webrat (>= 0.7.0) + will_paginate (~> 2.3.15) + yard diff --git a/README b/README index d2c82d58..3ba3299b 100644 --- a/README +++ b/README @@ -1,24 +1,31 @@ # Tracks: a GTD(TM) web application, built with Ruby on Rails +**IMPORTANT: Tracks is moving to a GitHub Organization to make it easier to continue administering the project. Development will soon cease at bsag/tracks and move to TracksApp/tracks. If you are currently pulling from bsag/tracks, please pull from TracksApp instead.** + +`git clone git://github.com/TracksApp/tracks.git` + +**The new home for Tracks is https://github.com/TracksApp/tracks** + * Project homepage: http://getontracks.org/ -* Manual: http://bsag.github.com/tracks/ -* Source at GitHub: http://github.com/bsag/tracks/ +* Manual: http://TracksApp.github.com/tracks/ +* Source at GitHub: http://github.com/TracksApp/tracks/ * Assembla space (for bug reports and feature requests): http://www.assembla.com/spaces/tracks-tickets/tickets -* Wiki (community contributed information): http://getontracks.org/wiki/ +* Wiki (community contributed information): https://github.com/TracksApp/tracks/wiki * Forum: http://getontracks.org/forums/ * Mailing list: http://lists.rousette.org.uk/mailman/listinfo/tracks-discuss * Original developer: bsag (http://www.rousette.org.uk/) -* Contributors: http://getontracks.org/wiki/Contributors -* Version: 2.0devel -* Copyright: (cc) 2004-2010 rousette.org.uk. +* Contributors: https://github.com/TracksApp/tracks/wiki/Contributors +* Version: 2.1devel +* Copyright: (cc) 2004-2011 rousette.org.uk. * License: GNU GPL All the documentation for Tracks can be found within the /doc directory and at http://bsag.github.com/tracks/ The latter includes full instructions for both new installations and upgrades from older installations of Tracks. The instructions might appear long and intimidatingly complex, but that is mostly because of the number of different platforms supported, and the different configurations which can be used (e.g. running Tracks on your local computer or on a remote server). If you choose the appropriate section for your situation (installation vs. upgrade), and use the easiest (recommended) method, you should find the instructions easy to follow. If you encounter problems, try searching the wiki, forum or mailing list (URLs above), and ask a question if you cannot find a solution to your problem. +The wiki has a lot of user contributed installation HOWTOs for various webhosts, specific OS's and more. -If you are thinking about contributing towards the development of Tracks, please read /doc/README_DEVELOPERS for general information, or /doc/tracks_api_wrapper.rb for information on Tracks' API. +If you are thinking about contributing towards the development of Tracks, please read /doc/README_DEVELOPERS for general information, or /doc/tracks_api_wrapper.rb for information on Tracks' API. Also you can find some information on development on the wiki. While fully usable for everyday use, Tracks is still a work in progress. Make sure that you take sensible precautions and back up all your data frequently, taking particular care when you are upgrading. -Enjoy being productive! \ No newline at end of file +Enjoy being productive! diff --git a/Rakefile b/Rakefile index 494c7b6f..2704572a 100644 --- a/Rakefile +++ b/Rakefile @@ -13,4 +13,4 @@ begin require 'test/rails/rake_tasks' rescue LoadError => e #It's ok if you don't have ZenTest installed if you're not a developer -end \ No newline at end of file +end diff --git a/app/apis/todo_api.rb b/app/apis/todo_api.rb index bae240b8..5f980a64 100644 --- a/app/apis/todo_api.rb +++ b/app/apis/todo_api.rb @@ -15,8 +15,8 @@ class TodoApi < ActionWebService::API::Base :expects => [{:username => :string}, {:token => :string}], :returns => [[Context]] - api_method :list_projects, - :expects => [{:username => :string}, {:token => :string}], - :returns => [[Project]] + api_method :list_projects, + :expects => [{:username => :string}, {:token => :string}], + :returns => [[Project]] end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 32d0a869..6f75ea61 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -15,7 +15,8 @@ class ApplicationController < ActionController::Base layout proc{ |controller| controller.mobile? ? "mobile" : "standard" } exempt_from_layout /\.js\.erb$/ - + + before_filter :check_for_deprecated_password_hash before_filter :set_session_expiration before_filter :set_time_zone before_filter :set_zindex_counter @@ -23,12 +24,12 @@ class ApplicationController < ActionController::Base prepend_before_filter :login_required prepend_before_filter :enable_mobile_content_negotiation after_filter :set_charset - + # By default, sets the charset to UTF-8 if it isn't already set def set_charset - headers["Content-Type"] ||= "text/html; charset=UTF-8" + headers["Content-Type"] ||= "text/html; charset=UTF-8" end - + def set_locale locale = params[:locale] # specifying a locale in the request takes precedence locale = locale || prefs.locale unless current_user.nil? # otherwise, the locale of the currently logged in user takes over @@ -36,7 +37,7 @@ class ApplicationController < ActionController::Base I18n.locale = locale.nil? ? I18n.default_locale : (I18n::available_locales.include?(locale.to_sym) ? locale : I18n.default_locale) logger.debug("Selected '#{I18n.locale}' as locale") end - + def set_session_expiration # http://wiki.rubyonrails.com/rails/show/HowtoChangeSessionOptions unless session == nil @@ -58,11 +59,20 @@ class ApplicationController < ActionController::Base end end end - + + # Redirects to change_password_user_path if the current user uses a + # deprecated password hashing algorithm. + def check_for_deprecated_password_hash + if current_user and current_user.uses_deprecated_password? + notify :warning, t('users.you_have_to_reset_your_password') + redirect_to change_password_user_path current_user + end + end + def render_failure message, status = 404 render :text => message, :status => status end - + # def rescue_action(exception) # log_error(exception) if logger # respond_to do |format| @@ -74,21 +84,24 @@ class ApplicationController < ActionController::Base # format.xml { render :text => 'An error occurred on the server.' + $! } # end # end - + # Returns a count of next actions in the given context or project The result # is count and a string descriptor, correctly pluralised if there are no # actions or multiple actions # def count_undone_todos_phrase(todos_parent, string="actions") count = count_undone_todos(todos_parent) - if count == 1 - word = string.singularize + deferred_count = count_deferred_todos(todos_parent) + if count == 0 && deferred_count > 0 + word = deferred_count == 1 ? string.singularize : string.pluralize + word = "deferred " + word + deferred_count.to_s + " " + word else - word = string.pluralize + word = count == 1 ? string.singularize : string.pluralize + count.to_s + " " + word end - return count.to_s + " " + word end - + def count_undone_todos(todos_parent) if todos_parent.nil? count = 0 @@ -100,6 +113,14 @@ class ApplicationController < ActionController::Base count || 0 end + def count_deferred_todos(todos_parent) + if todos_parent.nil? + count = 0 + else + count = todos_parent.todos.deferred.count + end + end + # Convert a date object to the format specified in the user's preferences in # config/settings.yml # @@ -156,11 +177,11 @@ class ApplicationController < ActionController::Base def create_todo_from_recurring_todo(rt, date=nil) # create todo and initialize with data from recurring_todo rt todo = current_user.todos.build( { :description => rt.description, :notes => rt.notes, :project_id => rt.project_id, :context_id => rt.context_id}) - + # set dates todo.recurring_todo_id = rt.id todo.due = rt.get_due_date(date) - + show_from_date = rt.get_show_from_date(date) if show_from_date.nil? todo.show_from=nil @@ -168,20 +189,20 @@ class ApplicationController < ActionController::Base # make sure that show_from is not in the past todo.show_from = show_from_date < Time.zone.now ? nil : show_from_date end - + saved = todo.save if saved todo.tag_with(rt.tag_list) - todo.tags.reload + todo.tags.reload end # increate number of occurences created from recurring todo rt.inc_occurences - + # mark recurring todo complete if there are no next actions left checkdate = todo.due.nil? ? todo.show_from : todo.due rt.toggle_completion! unless rt.has_next_todo(checkdate) - + return saved ? todo : nil end @@ -192,21 +213,21 @@ class ApplicationController < ActionController::Base end protected - + def admin_login_required unless User.find_by_id_and_is_admin(session['user_id'], true) render :text => t('errors.user_unauthorized'), :status => 401 return false end end - + def redirect_back_or_home respond_to do |format| format.html { redirect_back_or_default home_url } format.m { redirect_back_or_default mobile_url } end end - + def boolean_param(param_name) return false if param_name.blank? s = params[param_name] @@ -214,11 +235,11 @@ class ApplicationController < ActionController::Base return true if s == true || s =~ /^true$/i raise ArgumentError.new("invalid value for Boolean: \"#{s}\"") end - + def self.openid_enabled? Tracks::Config.openid_enabled? end - + def openid_enabled? self.class.openid_enabled? end @@ -239,12 +260,30 @@ class ApplicationController < ActionController::Base self.class.prefered_auth? end + def get_done_today(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + start_of_this_day = Time.zone.now.beginning_of_day + completed_todos.completed_after(start_of_this_day).all(includes) + end + + def get_done_this_week(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + start_of_this_week = Time.zone.now.beginning_of_week + start_of_this_day = Time.zone.now.beginning_of_day + completed_todos.completed_after(start_of_this_week).completed_before(start_of_this_day).all(includes) + end + + def get_done_this_month(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + start_of_this_month = Time.zone.now.beginning_of_month + start_of_this_week = Time.zone.now.beginning_of_week + completed_todos.completed_after(start_of_this_month).completed_before(start_of_this_week).all(includes) + end + + private - + def parse_date_per_user_prefs( s ) prefs.parse_date(s) end - + def init_data_for_sidebar @completed_projects = current_user.projects.completed @hidden_projects = current_user.projects.hidden @@ -258,19 +297,19 @@ class ApplicationController < ActionController::Base init_project_hidden_todo_counts(['project']) end end - + def init_not_done_counts(parents = ['project','context']) parents.each do |parent| eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || current_user.todos.active.count(:group => :#{parent}_id)") end end - + def init_project_hidden_todo_counts(parents = ['project','context']) parents.each do |parent| eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || current_user.todos.count(:conditions => ['state = ? or state = ?', 'project_hidden', 'active'], :group => :#{parent}_id)") end - end - + end + # Set the contents of the flash message from a controller Usage: notify # :warning, "This is the message" Sets the flash of type 'warning' to "This is # the message" @@ -278,7 +317,7 @@ class ApplicationController < ActionController::Base flash[type] = message logger.error("ERROR: #{message}") if type == :error end - + def set_time_zone Time.zone = current_user.prefs.time_zone if logged_in? end @@ -287,5 +326,5 @@ class ApplicationController < ActionController::Base # this counter can be used to handle the IE z-index bug @z_index_counter = 500 end - + end diff --git a/app/controllers/backend_controller.rb b/app/controllers/backend_controller.rb index 5fceed53..0f84c649 100644 --- a/app/controllers/backend_controller.rb +++ b/app/controllers/backend_controller.rb @@ -1,6 +1,7 @@ class CannotAccessContext < RuntimeError; end class BackendController < ApplicationController + acts_as_web_service wsdl_service_name 'Backend' web_service_api TodoApi web_service_scaffold :invoke diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb index 6e6cd265..7d8a14ea 100644 --- a/app/controllers/contexts_controller.rb +++ b/app/controllers/contexts_controller.rb @@ -11,7 +11,7 @@ class ContextsController < ApplicationController def index # #true is passed here to force an immediate load so that size and empty? # checks later don't result in separate SQL queries - @active_contexts = current_user.contexts.active(true) + @active_contexts = current_user.contexts.active(true) @hidden_contexts = current_user.contexts.hidden(true) @new_context = current_user.contexts.build @@ -19,8 +19,8 @@ class ContextsController < ApplicationController @all_contexts = @active_contexts + @hidden_contexts @count = @all_contexts.size - init_not_done_counts(['context']) + respond_to do |format| format.html &render_contexts_html format.m &render_contexts_mobile @@ -34,10 +34,10 @@ class ContextsController < ApplicationController format.autocomplete { render :text => for_autocomplete(@active_contexts + @hidden_contexts, params[:term])} end end - + def show @contexts = current_user.contexts(true) - if (@context.nil?) + if @context.nil? respond_to do |format| format.html { render :text => 'Context not found', :status => 404 } format.xml { render :xml => 'Context not found', :status => 404 } @@ -51,7 +51,7 @@ class ContextsController < ApplicationController end end end - + # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: # application/xml' # -u username:password @@ -86,14 +86,14 @@ class ContextsController < ApplicationController end end end - + # Edit the details of the context # def update params['context'] ||= {} success_text = if params['field'] == 'name' && params['value'] - params['context']['id'] = params['id'] - params['context']['name'] = params['value'] + params['context']['id'] = params['id'] + params['context']['name'] = params['value'] end @original_context_hidden = @context.hidden? @@ -110,7 +110,7 @@ class ContextsController < ApplicationController end # TODO is this param ever used? is this dead code? - + elsif boolean_param('update_context_name') @contexts = current_user.projects render :template => 'contexts/update_context_name.js.rjs' @@ -121,6 +121,13 @@ class ContextsController < ApplicationController else respond_to do |format| format.js + format.xml { + if @saved + render :xml => @context.to_xml( :except => :user_id ) + else + render :text => "Error on update: #{@context.errors.full_messages.inject("") {|v, e| v + e + " " }}", :status => 409 + end + } end end end @@ -138,7 +145,7 @@ class ContextsController < ApplicationController def destroy # make sure the deleted recurring patterns are removed from associated todos @context.recurring_todos.each { |rt| rt.clear_todos_association } unless @context.recurring_todos.nil? - + @context.destroy respond_to do |format| format.js do @@ -159,7 +166,32 @@ class ContextsController < ApplicationController notify :error, $! redirect_to :action => 'index' end - + + def done_todos + @source_view = 'context' + @context = current_user.contexts.find(params[:id]) + @page_title = t('contexts.completed_tasks_title', :context_name => @context.name) + + completed_todos = @context.todos.completed + + @done_today = get_done_today(completed_todos) + @done_this_week = get_done_this_week(completed_todos) + @done_this_month = get_done_this_month(completed_todos) + @count = @done_today.size + @done_this_week.size + @done_this_month.size + + render :template => 'todos/done' + end + + def all_done_todos + @source_view = 'context' + @context = current_user.contexts.find(params[:id]) + @page_title = t('contexts.all_completed_tasks_title', :context_name => @context.name) + + @done = @context.todos.completed.paginate :page => params[:page], :per_page => 20, :order => 'completed_at DESC', :include => Todo::DEFAULT_INCLUDES + @count = @done.size + render :template => 'todos/all_done' + end + protected def update_state_counts @@ -179,23 +211,23 @@ class ContextsController < ApplicationController render end end - + def render_contexts_mobile lambda do @page_title = "TRACKS::List Contexts" @active_contexts = current_user.contexts.active @hidden_contexts = current_user.contexts.hidden - @down_count = @active_contexts.size + @hidden_contexts.size + @down_count = @active_contexts.size + @hidden_contexts.size cookies[:mobile_url]= {:value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} render :action => 'index_mobile' end end - + def render_context_mobile lambda do @page_title = "TRACKS::List actions in "+@context.name - @not_done = @not_done_todos.select {|t| t.context_id == @context.id } - @down_count = @not_done.size + @not_done = @not_done_todos.select {|t| t.context_id == @context.id } + @down_count = @not_done.size cookies[:mobile_url]= {:value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} @mobile_from_context = @context.id render :action => 'mobile_show_context' @@ -205,18 +237,18 @@ class ContextsController < ApplicationController def render_contexts_rss_feed lambda do render_rss_feed_for current_user.contexts.all, :feed => feed_options, - :item => { :description => lambda { |c| c.summary(count_undone_todos_phrase(c)) } } + :item => { :description => lambda { |c| @template.summary(c, count_undone_todos_phrase(c)) } } end end def render_contexts_atom_feed lambda do render_atom_feed_for current_user.contexts.all, :feed => feed_options, - :item => { :description => lambda { |c| c.summary(count_undone_todos_phrase(c)) }, + :item => { :description => lambda { |c| @template.summary(c, count_undone_todos_phrase(c)) }, :author => lambda { |c| nil } } end end - + def feed_options Context.feed_options(current_user) end @@ -226,7 +258,7 @@ class ContextsController < ApplicationController rescue @context = nil end - + def init @source_view = params['_source_view'] || 'context' init_data_for_sidebar @@ -235,21 +267,19 @@ class ContextsController < ApplicationController def init_todos set_context_from_params unless @context.nil? - @context.todos.send :with_scope, :find => { :include => [:project, :tags] } do + @context.todos.send :with_scope, :find => { :include => Todo::DEFAULT_INCLUDES } do @done = @context.done_todos end @max_completed = current_user.prefs.show_number_completed - + # @not_done_todos = @context.not_done_todos TODO: Temporarily doing this # search manually until I can work out a way to do the same thing using # not_done_todos acts_as_todo_container method Hides actions in hidden # projects from context. - @not_done_todos = @context.todos.find( - :all, - :conditions => ['todos.state = ? AND (todos.project_id IS ? OR projects.state = ?)', 'active', nil, 'active'], - :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", - :include => [:project, :tags]) + @not_done_todos = @context.todos.active( + :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", + :include => Todo::DEFAULT_INCLUDES) @projects = current_user.projects diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb index 93989c71..70c93b17 100644 --- a/app/controllers/integrations_controller.rb +++ b/app/controllers/integrations_controller.rb @@ -1,6 +1,7 @@ class IntegrationsController < ApplicationController - - skip_before_filter :login_required, :only => [:search_plugin, :google_gadget] + require 'mail' + + skip_before_filter :login_required, :only => [:cloudmailin, :search_plugin, :google_gadget] def index @page_title = 'TRACKS::Integrations' @@ -26,14 +27,59 @@ class IntegrationsController < ApplicationController end def search_plugin - @icon_data = [File.open(RAILS_ROOT + '/public/images/done.png').read]. - pack('m').gsub(/\n/, '') - - render :layout => false + @icon_data = [File.open(RAILS_ROOT + '/public/images/done.png').read]. + pack('m').gsub(/\n/, '') + + render :layout => false end def google_gadget render :layout => false, :content_type => Mime::XML end + + def cloudmailin + # verify cloudmailin signature + provided = request.request_parameters.delete(:signature) + signature = Digest::MD5.hexdigest(request.request_parameters.sort{|a,b| a[0].to_s <=> b[0].to_s}.map{|k,v| v}.join + SITE_CONFIG['cloudmailin']) + # if signature does not match, return 403 + if provided != signature + render :text => "Message signature verification failed.", :status => 403 + return false + end + + # parse message + message = Mail.new(params[:message]) + + # find user + user = User.find(:first, :include => [:preference], :conditions => ["preferences.sms_email = ?", message.from]) + if user.nil? + render :text => "No user found", :status => 404 + return false + end + + # load user settings + context = user.prefs.sms_context + + # prepare body + if message.body.multipart? + body = message.body.preamble + else + body = message.body.to_s + end + + # parse mail + if message.subject.to_s.empty? + description = body + notes = nil + else + description = message.subject.to_s + notes = body + end + + # create todo + todo = Todo.from_rich_message(user, context.id, description, notes) + todo.save! + render :text => 'success', :status => 200 + end end diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index 119f79c3..52716b6f 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -84,6 +84,12 @@ class LoginController < ApplicationController def expire_session # this is a hack to enable cucumber to expire a session by calling this # method. The method will be unavailable for production environment + + @user.forget_me if logged_in? + cookies.delete :auth_token + session['user_id'] = nil + reset_session + unless Rails.env.production? session['expiry_time'] = Time.now respond_to do |format| diff --git a/app/controllers/preferences_controller.rb b/app/controllers/preferences_controller.rb index db27434b..e1c8638c 100644 --- a/app/controllers/preferences_controller.rb +++ b/app/controllers/preferences_controller.rb @@ -1,23 +1,31 @@ class PreferencesController < ApplicationController - + def index @page_title = t('preferences.page_title') @prefs = current_user.prefs + @user = current_user end - def edit - @page_title = t('preferences.page_title_edit') - @prefs = current_user.prefs - end - def update + @prefs = current_user.prefs + @user = current_user user_updated = current_user.update_attributes(params['user']) prefs_updated = current_user.preference.update_attributes(params['prefs']) - if user_updated && prefs_updated + if (user_updated && prefs_updated) + notify :notice, "Preferences updated" redirect_to :action => 'index' else - render :action => 'edit' + msg = "Preferences could not be updated: " + msg += "User model errors; " unless user_updated + msg += "Prefs model errors; " unless prefs_updated + notify :warning, msg + render 'index' end end - + + def render_date_format + format = params[:date_format] + render :text => l(Date.today, :format => format) + end + end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index a1f8f6ba..07f42df1 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -2,7 +2,7 @@ class ProjectsController < ApplicationController helper :application, :todos, :notes before_filter :set_source_view - before_filter :set_project_from_params, :only => [:update, :destroy, :show, :edit] + before_filter :set_project_from_params, :only => [:update, :destroy, :show, :edit, :set_reviewed] before_filter :default_context_filter, :only => [:create, :update] skip_before_filter :login_required, :only => [:index] prepend_before_filter :login_or_feed_token_required, :only => [:index] @@ -12,15 +12,15 @@ class ProjectsController < ApplicationController @new_project = current_user.projects.build if params[:projects_and_actions] projects_and_actions - else + else @contexts = current_user.contexts.all init_not_done_counts(['project']) + init_project_hidden_todo_counts(['project']) if params[:only_active_with_no_next_actions] - @projects = current_user.projects.active.select { |p| count_undone_todos(p) == 0 } + @projects = current_user.projects.active.select { |p| count_undone_todos(p) == 0 } else @projects = current_user.projects.all end - init_project_hidden_todo_counts(['project']) respond_to do |format| format.html &render_projects_html format.m &render_projects_mobile @@ -33,10 +33,53 @@ class ProjectsController < ApplicationController end end + def review + @page_title = t('projects.list_reviews') + @projects = current_user.projects.all + @contexts = current_user.contexts.all + @projects_to_review = current_user.projects.select {|p| p.needs_review?(current_user)} + @stalled_projects = current_user.projects.select {|p| p.stalled?} + @blocked_projects = current_user.projects.select {|p| p.blocked?} + @current_projects = current_user.projects.uncompleted.select {|p| not(p.needs_review?(current_user))} + + init_not_done_counts(['project']) + init_project_hidden_todo_counts(['project']) + current_user.projects.cache_note_counts + + @page_title = t('projects.list_reviews') + @count = @projects_to_review.count + @blocked_projects.count + @stalled_projects.count + @current_projects.count + + @no_projects = current_user.projects.empty? + @new_project = current_user.projects.build + end + + def done + @source_view = params['_source_view'] || 'project_list' + @page_title = t('projects.list_completed_projects') + + page = params[:page] || 1 + projects_per_page = 20 + @projects = current_user.projects.completed.paginate :page => page, :per_page => projects_per_page + @count = @projects.count + @total = current_user.projects.completed.count + @no_projects = @projects.empty? + + @range_low = (page.to_i-1) * projects_per_page + 1 + @range_high = @range_low + @projects.size - 1 + + init_not_done_counts(['project']) + end + + def set_reviewed + @project.last_reviewed = Time.zone.now + @project.save + redirect_to :action => 'show' + end + def projects_and_actions @projects = current_user.projects.active respond_to do |format| - format.text { + format.text { render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime::TEXT } end @@ -46,12 +89,12 @@ class ProjectsController < ApplicationController @max_completed = current_user.prefs.show_number_completed init_data_for_sidebar unless mobile? @page_title = t('projects.page_title', :project => @project.name) - - @not_done = @project.todos.active_or_hidden(:include => [:tags, :context, :predecessors]) - @deferred = @project.deferred_todos(:include => [:tags, :context, :predecessors]) - @pending = @project.pending_todos(:include => [:tags, :context, :predecessors]) + + @not_done = @project.todos.active_or_hidden(:include => Todo::DEFAULT_INCLUDES) + @deferred = @project.todos.deferred(:include => Todo::DEFAULT_INCLUDES) + @pending = @project.todos.pending(:include => Todo::DEFAULT_INCLUDES) @done = @project.todos.find_in_state(:all, :completed, - :order => "todos.completed_at DESC", :limit => current_user.prefs.show_number_completed, :include => [:context, :tags, :predecessors]) + :order => "todos.completed_at DESC", :limit => current_user.prefs.show_number_completed, :include => Todo::DEFAULT_INCLUDES) @count = @not_done.size @down_count = @count + @deferred.size + @pending.size @@ -64,10 +107,17 @@ class ProjectsController < ApplicationController respond_to do |format| format.html format.m &render_project_mobile - format.xml { render :xml => @project.to_xml( :except => :user_id ) } + format.xml { + render :xml => @project.to_xml(:except => :user_id) { |xml| + xml.not_done { @not_done.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } } + xml.deferred { @deferred.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } } + xml.pending { @pending.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } } + xml.done { @done.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } } + } + } end end - + # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: # application/xml' # -u username:password @@ -111,6 +161,8 @@ class ProjectsController < ApplicationController # Edit the details of the project # def update + template = "" + params['project'] ||= {} if params['project']['state'] @new_state = params['project']['state'] @@ -118,8 +170,8 @@ class ProjectsController < ApplicationController params['project'].delete('state') end success_text = if params['field'] == 'name' && params['value'] - params['project']['id'] = params['id'] - params['project']['name'] = params['value'] + params['project']['id'] = params['id'] + params['project']['name'] = params['value'] end @project.attributes = params['project'] @@ -137,43 +189,50 @@ class ProjectsController < ApplicationController @contexts = current_user.contexts update_state_counts init_data_for_sidebar - render :template => 'projects/update.js.erb' - return + + template = 'projects/update.js.erb' # TODO: are these params ever set? or is this dead code? elsif boolean_param('update_status') - render :template => 'projects/update_status.js.rjs' - return + template = 'projects/update_status.js.rjs' elsif boolean_param('update_default_context') - @initial_context_name = @project.default_context.name - render :template => 'projects/update_default_context.js.rjs' - return + @initial_context_name = @project.default_context.name + template = 'projects/update_default_context.js.rjs' elsif boolean_param('update_default_tags') - render :template => 'projects/update_default_tags.js.rjs' - return + template = 'projects/update_default_tags.js.rjs' elsif boolean_param('update_project_name') @projects = current_user.projects - render :template => 'projects/update_project_name.js.rjs' - return + template = 'projects/update_project_name.js.rjs' else render :text => success_text || 'Success' return end else init_data_for_sidebar - render :template => 'projects/update.js.erb' - return + template = 'projects/update.js.erb' end - render :template => 'projects/update.js.erb' + + respond_to do |format| + format.js { render :template => template } + format.html { redirect_to :action => 'index'} + format.xml { + if @saved + render :xml => @project.to_xml( :except => :user_id ) + else + render :text => "Error on update: #{@project.errors.full_messages.inject("") {|v, e| v + e + " " }}", :status => 409 + end + } + end + end - + def edit respond_to do |format| format.js end end - + def destroy @project.recurring_todos.each {|rt| rt.remove_from_project!} @project.destroy @@ -186,7 +245,7 @@ class ProjectsController < ApplicationController format.xml { render :text => "Deleted project #{@project.name}" } end end - + def order project_ids = params["container_project"] @projects = current_user.projects.update_positions( project_ids ) @@ -195,23 +254,46 @@ class ProjectsController < ApplicationController notify :error, $! redirect_to :action => 'index' end - + def alphabetize @state = params['state'] @projects = current_user.projects.alphabetize(:state => @state) if @state @contexts = current_user.contexts init_not_done_counts(['project']) - init_project_hidden_todo_counts(['project']) if @state == 'hidden' end - + def actionize @state = params['state'] - @projects = current_user.projects.actionize(current_user.id, :state => @state) if @state + @projects = current_user.projects.actionize(:state => @state) if @state @contexts = current_user.contexts init_not_done_counts(['project']) - init_project_hidden_todo_counts(['project']) if @state == 'hidden' end - + + def done_todos + @source_view = 'project' + @project = current_user.projects.find(params[:id]) + @page_title = t('projects.completed_tasks_title', :project_name => @project.name) + + completed_todos = @project.todos.completed + + @done_today = get_done_today(completed_todos) + @done_this_week = get_done_this_week(completed_todos) + @done_this_month = get_done_this_month(completed_todos) + @count = @done_today.size + @done_this_week.size + @done_this_month.size + + render :template => 'todos/done' + end + + def all_done_todos + @source_view = 'project' + @project = current_user.projects.find(params[:id]) + @page_title = t('projects.all_completed_tasks_title', :project_name => @project.name) + + @done = @project.todos.completed.paginate :page => params[:page], :per_page => 20, :order => 'completed_at DESC', :include => Todo::DEFAULT_INCLUDES + @count = @done.size + render :template => 'todos/all_done' + end + protected def update_state_counts @@ -229,7 +311,8 @@ class ProjectsController < ApplicationController @count = current_user.projects.count @active_projects = current_user.projects.active @hidden_projects = current_user.projects.hidden - @completed_projects = current_user.projects.completed + @completed_projects = current_user.projects.completed.find(:all, :limit => 10) + @completed_count = current_user.projects.completed.count @no_projects = current_user.projects.empty? current_user.projects.cache_note_counts @new_project = current_user.projects.build @@ -242,12 +325,12 @@ class ProjectsController < ApplicationController @active_projects = current_user.projects.active @hidden_projects = current_user.projects.hidden @completed_projects = current_user.projects.completed - @down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size + @down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size cookies[:mobile_url]= {:value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} render :action => 'index_mobile' end end - + def render_project_mobile lambda do if @project.default_context.nil? @@ -265,38 +348,37 @@ class ProjectsController < ApplicationController lambda do render_rss_feed_for @projects, :feed => feed_options, :title => :name, - :item => { :description => lambda { |p| summary(p) } } + :item => { :description => lambda { |p| @template.summary(p) } } end end def render_atom_feed lambda do render_atom_feed_for @projects, :feed => feed_options, - :item => { :description => lambda { |p| summary(p) }, + :item => { :description => lambda { |p| @template.summary(p) }, :title => :name, :author => lambda { |p| nil } } end end - + def feed_options Project.feed_options(current_user) end def render_text_feed lambda do - init_project_hidden_todo_counts(['project']) render :action => 'index', :layout => false, :content_type => Mime::TEXT end end - + def set_project_from_params @project = current_user.projects.find_by_params(params) end - + def set_source_view @source_view = params['_source_view'] || 'project' end - + def default_context_filter p = params['project'] p = params['request']['project'] if p.nil? && params['request'] @@ -310,13 +392,4 @@ class ProjectsController < ApplicationController end end - def summary(project) - project_description = '' - project_description += sanitize(markdown( project.description )) unless project.description.blank? - project_description += "

#{count_undone_todos_phrase(p)}. " - project_description += t('projects.project_state', :state => project.state) - project_description += "

" - project_description - end - end diff --git a/app/controllers/recurring_todos_controller.rb b/app/controllers/recurring_todos_controller.rb index 126e7c4b..dd34bb1b 100644 --- a/app/controllers/recurring_todos_controller.rb +++ b/app/controllers/recurring_todos_controller.rb @@ -7,10 +7,10 @@ class RecurringTodosController < ApplicationController def index @page_title = t('todos.recurring_actions_title') - + @source_view = params['_source_view'] || 'recurring_todo' find_and_inactivate @recurring_todos = current_user.recurring_todos.active - @completed_recurring_todos = current_user.recurring_todos.completed + @completed_recurring_todos = current_user.recurring_todos.completed.find(:all, :limit => 10) @no_recurring_todos = @recurring_todos.size == 0 @no_completed_recurring_todos = @completed_recurring_todos.size == 0 @@ -24,6 +24,17 @@ class RecurringTodosController < ApplicationController def show end + + def done + @page_title = t('todos.completed_recurring_actions_title') + @source_view = params['_source_view'] || 'recurring_todo' + items_per_page = 20 + page = params[:page] || 1 + @completed_recurring_todos = current_user.recurring_todos.completed.paginate :page => params[:page], :per_page => items_per_page + @total = @count = current_user.recurring_todos.completed.count + @range_low = (page.to_i-1) * items_per_page + 1 + @range_high = @range_low + @completed_recurring_todos.size - 1 + end def edit respond_to do |format| @@ -131,7 +142,6 @@ class RecurringTodosController < ApplicationController end def destroy - # remove all references to this recurring todo @todos = @recurring_todo.todos @number_of_todos = @todos.size @@ -176,7 +186,6 @@ class RecurringTodosController < ApplicationController @completed_remaining = current_user.recurring_todos.completed.count # from completed back to active -> check if there is an active todo - # current_user.todos.count(:all, {:conditions => ["state = ? AND recurring_todo_id = ?", 'active',params[:id]]}) @active_todos = @recurring_todo.todos.active.count # create todo if there is no active todo belonging to the activated # recurring_todo diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 872b4fdd..44fa0d3f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,12 +1,22 @@ class SearchController < ApplicationController - helper :todos, :application, :notes, :projects - + helper :todos, :application, :notes, :projects + def results @source_view = params['_source_view'] || 'search' @page_title = "TRACKS::Search Results for #{params[:search]}" terms = '%' + params[:search] + '%' - @found_todos = current_user.todos.find(:all, :conditions => ["todos.description LIKE ? OR todos.notes LIKE ?", terms, terms], :include => [:tags, :project, :context]) + + @found_not_complete_todos = current_user.todos.find(:all, + :conditions => ["(todos.description LIKE ? OR todos.notes LIKE ?) AND todos.completed_at IS NULL", terms, terms], + :include => Todo::DEFAULT_INCLUDES, + :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC") + @found_complete_todos = current_user.todos.find(:all, + :conditions => ["(todos.description LIKE ? OR todos.notes LIKE ?) AND NOT (todos.completed_at IS NULL)", terms, terms], + :include => Todo::DEFAULT_INCLUDES, + :order => "todos.completed_at DESC") + @found_todos = @found_not_complete_todos + @found_complete_todos + @found_projects = current_user.projects.find(:all, :conditions => ["name LIKE ? OR description LIKE ?", terms, terms]) @found_notes = current_user.notes.find(:all, :conditions => ["body LIKE ?", terms]) @found_contexts = current_user.contexts.find(:all, :conditions => ["name LIKE ?", terms]) @@ -18,17 +28,17 @@ class SearchController < ApplicationController "LEFT JOIN todos ON taggings.taggable_id = todos.id "+ "WHERE todos.user_id=? "+ "AND tags.name LIKE ? ", current_user.id, terms]) - + @count = @found_todos.size + @found_projects.size + @found_notes.size + @found_contexts.size + @found_tags.size - + init_not_done_counts init_project_hidden_todo_counts end def index - @page_title = "TRACKS::Search" + @page_title = "TRACKS::Search" end - + def init @source_view = params['_source_view'] || 'search' end diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index c87ce450..fac58ec2 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -1,6 +1,6 @@ class StatsController < ApplicationController - helper :todos + helper :todos, :projects, :recurring_todos append_before_filter :init, :exclude => [] @@ -643,6 +643,18 @@ class StatsController < ApplicationController end end + def done + @source_view = 'done' + + init_not_done_counts + + @done_recently = current_user.todos.completed.all(:limit => 10, :order => 'completed_at DESC', :include => Todo::DEFAULT_INCLUDES) + @last_completed_projects = current_user.projects.completed.all(:limit => 10, :order => 'completed_at DESC', :include => [:todos, :notes]) + @last_completed_contexts = [] + @last_completed_recurring_todos = current_user.recurring_todos.completed.all(:limit => 10, :order => 'completed_at DESC', :include => [:tags, :taggings]) + #TODO: @last_completed_contexts = current_user.contexts.completed.all(:limit => 10, :order => 'completed_at DESC') + end + private def get_unique_tags_of_user diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index d0a558b1..b626653f 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -7,9 +7,9 @@ class TodosController < ApplicationController append_before_filter :find_and_activate_ready, :only => [:index, :list_deferred] # TODO: replace :except with :only - append_before_filter :init, :except => [ :tag, :tags, :destroy, :completed, - :completed_archive, :check_deferred, :toggle_check, :toggle_star, - :edit, :update, :defer, :create, :calendar, :auto_complete_for_predecessor, :remove_predecessor, :add_predecessor] + append_before_filter :init, :except => [ :tag, :tags, :destroy, :done, + :check_deferred, :toggle_check, :toggle_star, :edit, :update, :defer, :create, + :calendar, :auto_complete_for_predecessor, :remove_predecessor, :add_predecessor] protect_from_forgery :except => :check_deferred @@ -22,18 +22,18 @@ class TodosController < ApplicationController @contexts = current_user.contexts.find(:all) @contexts_to_show = current_user.contexts.active - + respond_to do |format| format.html &render_todos_html format.m &render_todos_mobile - format.xml { render :xml => @todos.to_xml( :except => :user_id ) } + format.xml { render :xml => @todos.to_xml( *to_xml_params ) } format.rss &render_rss_feed format.atom &render_atom_feed format.text &render_text_feed format.ics &render_ical_feed end end - + def new @projects = current_user.projects.active @contexts = current_user.contexts.find(:all) @@ -47,16 +47,16 @@ class TodosController < ApplicationController # we have a project but not a context -> use the default context @mobile_from_context = @mobile_from_project.default_context end - render :action => "new" + render :action => "new" } end end - + def create @source_view = params['_source_view'] || 'todo' @default_context = current_user.contexts.find_by_name(params['default_context_name']) @default_project = current_user.projects.find_by_name(params['default_project_name']) unless params['default_project_name'].blank? - + @tag_name = params['_tag_name'] is_multiple = params[:todo] && params[:todo][:multiple_todos] && !params[:todo][:multiple_todos].nil? @@ -67,32 +67,41 @@ class TodosController < ApplicationController p.parse_dates() unless mobile? tag_list = p.tag_list predecessor_list = p.predecessor_list - + @todo = current_user.todos.build(p.attributes) if p.project_specified_by_name? project = current_user.projects.find_or_create_by_name(p.project_name) @new_project_created = project.new_record_before_save? @todo.project_id = project.id + elsif !(p.project_id.nil? || p.project_id.blank?) + project = current_user.projects.find_by_id(p.project_id) + @todo.errors.add(:project, "unknown") if project.nil? end - + if p.context_specified_by_name? context = current_user.contexts.find_or_create_by_name(p.context_name) @new_context_created = context.new_record_before_save? @not_done_todos = [@todo] if @new_context_created @todo.context_id = context.id + elsif !(p.context_id.nil? || p.context_id.blank?) + context = current_user.contexts.find_by_id(p.context_id) + @todo.errors.add(:context, "unknown") if context.nil? end - @todo.add_predecessor_list(predecessor_list) + if @todo.errors.empty? + @todo.starred= (params[:new_todo_starred]||"").include? "true" - # Fix for #977 because AASM overrides @state on creation - specified_state = @todo.state - @saved = @todo.save + @todo.add_predecessor_list(predecessor_list) - # Fix for #977 because AASM overrides @state on creation - @todo.update_attribute('state', specified_state) unless specified_state == "immediate" - @saved = @todo.save - @todo.update_state_from_project if @saved + # Fix for #977 because AASM overrides @state on creation + specified_state = @todo.state + @saved = @todo.save + + @todo.update_state_from_project if @saved + else + @saved = false + end unless (@saved == false) || tag_list.blank? @todo.tag_with(tag_list) @@ -128,7 +137,7 @@ class TodosController < ApplicationController @projects = current_user.projects.find(:all) if @new_project_created @initial_context_name = params['default_context_name'] @initial_project_name = params['default_project_name'] - @default_tags = @todo.project.default_tags unless @todo.project.nil? + @initial_tags = params['initial_tag_list'] @status_message = t('todos.added_new_next_action') @status_message += ' ' + t('todos.to_tickler') if @todo.deferred? @status_message += ' ' + t('todos.in_pending_state') if @todo.pending? @@ -165,7 +174,10 @@ class TodosController < ApplicationController tag_list = params[:tag_list] + @sequential = !params[:todos_sequential].blank? && params[:todos_sequential]=='true' + @todos = [] + @predecessor = nil params[:todo][:multiple_todos].split("\n").map do |line| unless line.blank? @todo = current_user.todos.build( @@ -173,12 +185,20 @@ class TodosController < ApplicationController @todo.project_id = @project_id @todo.context_id = @context_id @saved = @todo.save + + if @predecessor && @saved && @sequential + @todo.add_predecessor(@predecessor) + @todo.block! + end + unless (@saved == false) || tag_list.blank? @todo.tag_with(tag_list) @todo.tags.reload end + @todos << @todo @not_done_todos << @todo if @new_context_created + @predecessor = @todo end end @@ -190,6 +210,7 @@ class TodosController < ApplicationController @projects = current_user.projects.find(:all) if @new_project_created @initial_context_name = params['default_context_name'] @initial_project_name = params['default_project_name'] + @initial_tags = params['initial_tag_list'] if @todos.size > 0 @default_tags = @todos[0].project.default_tags unless @todos[0].project.nil? else @@ -213,39 +234,40 @@ class TodosController < ApplicationController end end end - + def edit - @todo = current_user.todos.find(params['id'], :include => [:project, :context, :tags, :taggings, :predecessors]) + @todo = current_user.todos.find(params['id'], :include => Todo::DEFAULT_INCLUDES) @source_view = params['_source_view'] || 'todo' @tag_name = params['_tag_name'] respond_to do |format| format.js - end - end - - def show - @todo = current_user.todos.find(params['id']) - respond_to do |format| - format.m do + format.m { @projects = current_user.projects.active @contexts = current_user.contexts.find(:all) @edit_mobile = true @return_path=cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path - render :action => 'show' - end - format.xml { render :xml => @todo.to_xml( :root => 'todo', :except => :user_id ) } + render :template => "/todos/edit_mobile.html.erb" + } end end - + + def show + @todo = current_user.todos.find(params['id']) + respond_to do |format| + format.m { render :action => 'show' } + format.xml { render :xml => @todo.to_xml( *to_xml_params ) } + end + end + def add_predecessor @source_view = params['_source_view'] || 'todo' @predecessor = current_user.todos.find(params['predecessor']) - @todo = current_user.todos.find(params['successor']) + @predecessors = @predecessor.predecessors + @todo = current_user.todos.find(params['successor'], :include => Todo::DEFAULT_INCLUDES) @original_state = @todo.state unless @predecessor.completed? - # Add predecessor @todo.add_predecessor(@predecessor) - @todo.state = 'pending' + @todo.block! @saved = @todo.save @status_message = t('todos.added_dependency', :dependency => @predecessor.description) @@ -254,15 +276,15 @@ class TodosController < ApplicationController @saved = false end respond_to do |format| - format.js + format.js end end def remove_predecessor - puts "@@@ start remove_predecessor" @source_view = params['_source_view'] || 'todo' - @todo = current_user.todos.find(params['id']) + @todo = current_user.todos.find(params['id'], :include => Todo::DEFAULT_INCLUDES) @predecessor = current_user.todos.find(params['predecessor']) + @predecessors = @predecessor.predecessors @successor = @todo @removed = @successor.remove_predecessor(@predecessor) determine_remaining_in_context_count @@ -278,26 +300,27 @@ class TodosController < ApplicationController @source_view = params['_source_view'] || 'todo' @original_item_due = @todo.due @original_item_was_deferred = @todo.deferred? + @original_item_was_pending = @todo.pending? @original_item_was_hidden = @todo.hidden? @original_item_context_id = @todo.context_id @original_item_project_id = @todo.project_id + @todo_was_completed_from_deferred_or_blocked_state = @original_item_was_deferred || @original_item_was_pending @saved = @todo.toggle_completion! - + + @todo_was_blocked_from_completed_state = @todo.pending? # since we toggled_completion the previous state was completed + # check if this todo has a related recurring_todo. If so, create next todo @new_recurring_todo = check_for_next_todo(@todo) if @saved - - if @todo.completed? - @pending_to_activate = @todo.pending_to_activate - @pending_to_activate.each do |t| - t.activate! - end - else - @active_to_block = @todo.active_to_block - @active_to_block.each do |t| - t.block! + + @predecessors = @todo.uncompleted_predecessors + if @saved + if @todo.completed? + @pending_to_activate = @todo.activate_pending_todos + else + @active_to_block = @todo.block_successors end end - + respond_to do |format| format.js do if @saved @@ -313,7 +336,7 @@ class TodosController < ApplicationController end render end - format.xml { render :xml => @todo.to_xml( :except => :user_id ) } + format.xml { render :xml => @todo.to_xml( *to_xml_params ) } format.html do if @saved # TODO: I think this will work, but can't figure out how to test it @@ -324,17 +347,39 @@ class TodosController < ApplicationController redirect_to :action => "index" end end + format.m { + if cookies[:mobile_url] + old_path = cookies[:mobile_url] + cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']} + notify(:notice, t("todos.action_marked_complete", :description => @todo.description, :completed => @todo.completed? ? 'complete' : 'incomplete')) + redirect_to old_path + else + notify(:notice, t("todos.action_marked_complete", :description => @todo.description, :completed => @todo.completed? ? 'complete' : 'incomplete')) + redirect_to todos_path(:format => 'm') + end + } end end - + def toggle_star - @todo = current_user.todos.find(params['id'], :include => [:taggings, :tags]) + @todo = current_user.todos.find(params['id']) @todo.toggle_star! @saved = true # cannot determine error respond_to do |format| format.js - format.xml { render :xml => @todo.to_xml( :except => :user_id ) } + format.xml { render :xml => @todo.to_xml( *to_xml_params ) } format.html { redirect_to request.referrer} + format.m { + if cookies[:mobile_url] + old_path = cookies[:mobile_url] + cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']} + notify(:notice, "Star toggled") + redirect_to old_path + else + notify(:notice, "Star toggled") + redirect_to todos_path(:format => 'm') + end + } end end @@ -352,8 +397,8 @@ class TodosController < ApplicationController determine_remaining_in_context_count(@original_item_context_id) respond_to do |format| - format.js {render :action => :update } - format.xml { render :xml => @todo.to_xml( :except => :user_id ) } + format.js { render :action => :update } + format.xml { render :xml => @todo.to_xml( *to_xml_params ) } end end @@ -365,18 +410,18 @@ class TodosController < ApplicationController cache_attributes_from_before_update update_tags - update_project - update_context + update_project + update_context update_due_and_show_from_dates update_completed_state update_dependencies update_attributes_of_todo - + @saved = @todo.save # this is set after save and cleared after reload, so save it here @removed_predecessors = @todo.removed_predecessors - + @todo.reload # refresh context and project object too (not only their id's) update_dependency_state @@ -393,7 +438,7 @@ class TodosController < ApplicationController @status_message = t('todos.added_new_project') + ' / ' + @status_message if @new_project_created @status_message = t('todos.added_new_context') + ' / ' + @status_message if @new_context_created } - format.xml { render :xml => @todo.to_xml( :except => :user_id ) } + format.xml { render :xml => @todo.to_xml( *to_xml_params ) } format.m do if @saved if cookies[:mobile_url] @@ -409,14 +454,21 @@ class TodosController < ApplicationController end end end - + def destroy @source_view = params['_source_view'] || 'todo' - @todo = current_user.todos.find(params['id'], :include => [:pending_successors, :uncompleted_predecessors, :taggings, :tags, :project, :context]) + @todo = current_user.todos.find(params['id']) @original_item_due = @todo.due @context_id = @todo.context_id @project_id = @todo.project_id @todo_was_destroyed_from_deferred_state = @todo.deferred? + @todo_was_destroyed_from_pending_state = @todo.pending? + @todo_was_destroyed_from_deferred_or_pending_state = @todo_was_destroyed_from_deferred_state || @todo_was_destroyed_from_pending_state + + @uncompleted_predecessors = [] + @todo.uncompleted_predecessors.each do |predecessor| + @uncompleted_predecessors << predecessor + end # activate successors if they only depend on this todo activated_successor_count = 0 @@ -434,9 +486,9 @@ class TodosController < ApplicationController # check if this todo has a related recurring_todo. If so, create next todo @new_recurring_todo = check_for_next_todo(@todo) if @saved - + respond_to do |format| - + format.html do if @saved message = t('todos.action_deleted_success') @@ -450,7 +502,7 @@ class TodosController < ApplicationController redirect_to :action => 'index' end end - + format.js do if @saved determine_down_count @@ -463,43 +515,55 @@ class TodosController < ApplicationController end render end - + format.xml { render :text => '200 OK. Action deleted.', :status => 200 } - + end end - def completed + def done + @source_view = 'done' @page_title = t('todos.completed_tasks_title') - @done = current_user.completed_todos - @done_today = @done.completed_within Time.zone.now - 1.day - @done_this_week = @done.completed_within Time.zone.now - 1.week - @done_this_month = @done.completed_within Time.zone.now - 4.week + + completed_todos = current_user.todos.completed + + @done_today = get_done_today(completed_todos) + @done_this_week = get_done_this_week(completed_todos) + @done_this_month = get_done_this_month(completed_todos) @count = @done_today.size + @done_this_week.size + @done_this_month.size + + respond_to do |format| + format.html + format.xml { render :xml => completed_todos.to_xml( *to_xml_params ) } + end end - def completed_archive - @page_title = t('todos.archived_tasks_title') - @done = current_user.completed_todos + def all_done + @source_view = 'done' + @page_title = t('todos.completed_tasks_title') + + @done = current_user.todos.completed.paginate :page => params[:page], :per_page => 20, :order => 'completed_at DESC', :include => Todo::DEFAULT_INCLUDES @count = @done.size - @done_archive = @done.completed_more_than Time.zone.now - 28.days end - + def list_deferred @source_view = 'deferred' @page_title = t('todos.deferred_tasks_title') - + @contexts_to_show = @contexts = current_user.contexts.find(:all) - - @not_done_todos = current_user.deferred_todos(:include => [:tags, :taggings, :projects]) + current_user.pending_todos(:include => [:tags, :taggings, :projects]) + + includes = params[:format]=='xml' ? [:context, :project] : Todo::DEFAULT_INCLUDES + + @not_done_todos = current_user.todos.deferred(:include => includes) + current_user.todos.pending(:include => includes) @down_count = @count = @not_done_todos.size - + respond_to do |format| format.html format.m { render :action => 'mobile_list_deferred' } + format.xml { render :xml => @not_done_todos.to_xml( *to_xml_params ) } end end - + # Check for any due tickler items, activate them Called by # periodically_call_remote def check_deferred @@ -509,57 +573,58 @@ class TodosController < ApplicationController format.js end end - + def filter_to_context context = current_user.contexts.find(params['context']['id']) redirect_to context_todos_path(context, :format => 'm') end - + def filter_to_project project = current_user.projects.find(params['project']['id']) redirect_to project_todos_path(project, :format => 'm') end - + # /todos/tag/[tag_name] shows all the actions tagged with tag_name def tag init_data_for_sidebar unless mobile? @source_view = params['_source_view'] || 'tag' @tag_name = sanitize(params[:name]) # sanitize to prevent XSS vunerability! @page_title = t('todos.tagged_page_title', :tag_name => @tag_name) - + # mobile tags are routed with :name ending on .m. So we need to chomp it @tag_name = @tag_name.chomp('.m') if mobile? - + @tag = Tag.find_by_name(@tag_name) @tag = Tag.new(:name => @tag_name) if @tag.nil? - + @not_done_todos = current_user.todos.with_tag(@tag).active.not_hidden.find(:all, - :order => 'todos.due IS NULL, todos.due ASC, todos.created_at ASC', :include => [:context]) + :order => 'todos.due IS NULL, todos.due ASC, todos.created_at ASC', :include => Todo::DEFAULT_INCLUDES) @hidden_todos = current_user.todos.with_tag(@tag).hidden.find(:all, - :include => [:taggings, :tags, :context], + :include => Todo::DEFAULT_INCLUDES, :order => 'todos.completed_at DESC, todos.created_at DESC') @deferred = current_user.todos.with_tag(@tag).deferred.find(:all, - :order => 'show_from ASC, todos.created_at DESC', :include => [:context]) + :order => 'show_from ASC, todos.created_at DESC', :include => Todo::DEFAULT_INCLUDES) @pending = current_user.todos.with_tag(@tag).blocked.find(:all, - :order => 'show_from ASC, todos.created_at DESC', :include => [:context]) - + :order => 'show_from ASC, todos.created_at DESC', :include => Todo::DEFAULT_INCLUDES) + # If you've set no_completed to zero, the completed items box isn't shown on # the tag page max_completed = current_user.prefs.show_number_completed @done = current_user.todos.with_tag(@tag).completed.find(:all, :limit => max_completed, - :order => 'todos.completed_at DESC') + :order => 'todos.completed_at DESC', + :include => Todo::DEFAULT_INCLUDES) @projects = current_user.projects @contexts = current_user.contexts @contexts_to_show = @contexts.reject {|x| x.hide? } # Set defaults for new_action - @initial_tag_name = @tag_name + @initial_tags = @tag_name unless @not_done_todos.empty? @context = current_user.contexts.find_by_id(@not_done_todos[0].context_id) end - + # Set count badge to number of items with this tag @not_done_todos.empty? ? @count = 0 : @count = @not_done_todos.size @down_count = @count @@ -573,18 +638,47 @@ class TodosController < ApplicationController end end + def done_tag + @source_view = params['_source_view'] || 'tag' + @tag_name = sanitize(params[:name]) # sanitize to prevent XSS vunerability! + @page_title = t('todos.completed_tagged_page_title', :tag_name => @tag_name) + @tag = Tag.find_by_name(@tag_name) + @tag = Tag.new(:name => @tag_name) if @tag.nil? + + completed_todos = current_user.todos.completed.with_tag(@tag) + + @done_today = get_done_today(completed_todos) + @done_this_week = get_done_this_week(completed_todos) + @done_this_month = get_done_this_month(completed_todos) + @count = @done_today.size + @done_this_week.size + @done_this_month.size + + render :template => 'todos/done' + end + + def all_done_tag + @source_view = params['_source_view'] || 'tag' + @tag_name = sanitize(params[:name]) # sanitize to prevent XSS vunerability! + @page_title = t('todos.all_completed_tagged_page_title', :tag_name => @tag_name) + @tag = Tag.find_by_name(@tag_name) + @tag = Tag.new(:name => @tag_name) if @tag.nil? + + @done = current_user.todos.completed.with_tag(@tag).paginate :page => params[:page], :per_page => 20, :order => 'completed_at DESC', :include => Todo::DEFAULT_INCLUDES + @count = @done.size + render :template => 'todos/all_done' + end + def tags @tags = Tag.find(:all, :conditions =>['name like ?', '%'+params[:term]+'%']) respond_to do |format| format.autocomplete { render :text => for_autocomplete(@tags, params[:term]) } end end - + def defer @source_view = params['_source_view'] || 'todo' numdays = params['days'].to_i - @todo = current_user.todos.find(params[:id], :include => [:taggings, :tags, :uncompleted_predecessors, :pending_successors]) + @todo = current_user.todos.find(params[:id]) @original_item_context_id = @todo.context_id @todo_deferred_state_changed = true @new_context_created = false @@ -612,6 +706,16 @@ class TodosController < ApplicationController respond_to do |format| format.html { redirect_to :back } format.js {render :action => 'update'} + format.m { + notify(:notice, t("todos.action_deferred", :description => @todo.description)) + if cookies[:mobile_url] + old_path = cookies[:mobile_url] + cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']} + redirect_to old_path + else + redirect_to todos_path(:format => 'm') + end + } end end @@ -620,30 +724,31 @@ class TodosController < ApplicationController @page_title = t('todos.calendar_page_title') @projects = current_user.projects.find(:all) - + due_today_date = Time.zone.now due_this_week_date = Time.zone.now.end_of_week due_next_week_date = due_this_week_date + 7.days due_this_month_date = Time.zone.now.end_of_month - + included_tables = Todo::DEFAULT_INCLUDES + @due_today = current_user.todos.not_completed.find(:all, - :include => [:taggings, :tags], + :include => included_tables, :conditions => ['todos.due <= ?', due_today_date], :order => "due") @due_this_week = current_user.todos.not_completed.find(:all, - :include => [:taggings, :tags], + :include => included_tables, :conditions => ['todos.due > ? AND todos.due <= ?', due_today_date, due_this_week_date], :order => "due") @due_next_week = current_user.todos.not_completed.find(:all, - :include => [:taggings, :tags], + :include => included_tables, :conditions => ['todos.due > ? AND todos.due <= ?', due_this_week_date, due_next_week_date], :order => "due") @due_this_month = current_user.todos.not_completed.find(:all, - :include => [:taggings, :tags], + :include => included_tables, :conditions => ['todos.due > ? AND todos.due <= ?', due_next_week_date, due_this_month_date], :order => "due") @due_after_this_month = current_user.todos.not_completed.find(:all, - :include => [:taggings, :tags], + :include => included_tables, :conditions => ['todos.due > ?', due_this_month_date], :order => "due") @@ -655,9 +760,22 @@ class TodosController < ApplicationController @due_all = current_user.todos.not_completed.are_due.find(:all, :order => "due") render :action => 'calendar', :layout => false, :content_type => Mime::ICS } + format.xml { + @due_all = current_user.todos.not_completed.are_due.find(:all, :order => "due") + render :xml => @due_all.to_xml( *to_xml_params ) + } end end - + + def list_hidden + @hidden = current_user.todos.hidden + respond_to do |format| + format.xml { + render :xml => @hidden.to_xml( *to_xml_params ) + } + end + end + def auto_complete_for_predecessor unless params['id'].nil? get_todo_from_params @@ -721,13 +839,21 @@ class TodosController < ApplicationController end private - + + def to_xml_params + if params[:limit_fields] == 'index' + return [:only => [:id, :created_at, :updated_at, :completed_at] ] + else + return [:except => :user_id, :include => [:tags] ] + end + end + def get_todo_from_params # TODO: this was a :append_before but was removed to tune performance per # method. Reconsider re-enabling it @todo = current_user.todos.find(params['id']) end - + def find_and_activate_ready current_user.deferred_todos.find_and_activate_ready end @@ -772,7 +898,7 @@ class TodosController < ApplicationController @title << t('todos.next_actions_title_additions.completed') @description << t('todos.next_actions_description_additions.completed', :count => done_in_last.to_s) end - + if params.key?('tag') tag = Tag.find_by_name(params['tag']) if tag.nil? @@ -780,11 +906,11 @@ class TodosController < ApplicationController end condition_builder.add('taggings.tag_id = ?', tag.id) end - + Todo.send :with_scope, :find => {:conditions => condition_builder.to_conditions} do yield end - + end def with_parent_resource_scope(&block) @@ -828,47 +954,56 @@ class TodosController < ApplicationController with_feed_query_scope do with_parent_resource_scope do # @context or @project may get defined here with_limit_scope do - + if mobile? init_todos_for_mobile_view else - + # Note: these next two finds were previously using # current_users.todos.find but that broke with_scope for :limit # Exclude hidden projects from count on home page - @todos = current_user.todos.find(:all, :include => [ :project, :context, :tags, :pending_successors, :recurring_todo ]) + @todos = current_user.todos.find(:all, :include => Todo::DEFAULT_INCLUDES) # Exclude hidden projects from the home page @not_done_todos = current_user.todos.find(:all, :conditions => ['contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', false, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", - :include => [ :project, :context, :tags, :pending_successors, :recurring_todo ]) + :include => Todo::DEFAULT_INCLUDES) end end end end end - + def init_todos_for_mobile_view # Note: these next two finds were previously using current_users.todos.find # but that broke with_scope for :limit - + # Exclude hidden projects from the home page @not_done_todos = current_user.todos.find(:all, :conditions => ['todos.state = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', 'active', false, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context, :tags ]) end - + def determine_down_count source_view do |from| from.todo do @down_count = current_user.todos.active.not_hidden.count end from.context do - @down_count = current_user.contexts.find(@todo.context_id).todos.not_completed.count(:all) + context_id = @original_item_context_id || @todo.context_id + todos = current_user.contexts.find(context_id).todos.not_completed + + if @todo.context.hide? + # include hidden todos + @down_count = todos.count(:all) + else + # exclude hidden_todos + @down_count = todos.not_hidden.count(:all) + end end from.project do unless @todo.project_id == nil @@ -888,7 +1023,7 @@ class TodosController < ApplicationController end end end - + def determine_remaining_in_context_count(context_id = @todo.context_id) source_view do |from| from.deferred { @@ -901,6 +1036,7 @@ class TodosController < ApplicationController if tag.nil? tag = Tag.new(:name => params['tag']) end + @remaining_deferred_or_pending_count = current_user.todos.with_tag(tag).deferred_or_blocked.count @remaining_in_context = current_user.contexts.find(context_id).todos.active.not_hidden.with_tag(tag).count @target_context_count = current_user.contexts.find(@todo.context_id).todos.active.not_hidden.with_tag(tag).count @remaining_hidden_count = current_user.todos.hidden.with_tag(tag).count @@ -908,7 +1044,13 @@ class TodosController < ApplicationController from.project { project_id = @project_changed ? @original_item_project_id : @todo.project_id @remaining_deferred_or_pending_count = current_user.projects.find(project_id).todos.deferred_or_blocked.count - @remaining_in_context = current_user.projects.find(project_id).todos.active.count + + if @todo_was_completed_from_deferred_or_blocked_state + @remaining_in_context = @remaining_deferred_or_pending_count + else + @remaining_in_context = current_user.projects.find(project_id).todos.active.count + end + @target_context_count = current_user.projects.find(project_id).todos.active.count } from.calendar { @@ -929,7 +1071,7 @@ class TodosController < ApplicationController @remaining_in_context = current_user.contexts.find(context_id).todos(true).active.not_hidden.count if !@remaining_in_context @target_context_count = current_user.contexts.find(@todo.context_id).todos(true).active.not_hidden.count if !@target_context_count end - + def determine_completed_count source_view do |from| from.todo do @@ -966,11 +1108,11 @@ class TodosController < ApplicationController # If you've set no_completed to zero, the completed items box isn't shown # on the home page max_completed = current_user.prefs.show_number_completed - @done = current_user.completed_todos.find(:all, :limit => max_completed, :include => [ :context, :project, :tags ]) unless max_completed == 0 + @done = current_user.todos.completed.find(:all, :limit => max_completed, :include => Todo::DEFAULT_INCLUDES) unless max_completed == 0 # Set count badge to number of not-done, not hidden context items @count = current_user.todos.active.not_hidden.count(:all) - + render end end @@ -981,11 +1123,11 @@ class TodosController < ApplicationController @home = true cookies[:mobile_url]= { :value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} determine_down_count - + render :action => 'index' end end - + def render_rss_feed lambda do render_rss_feed_for @todos, :feed => todo_feed_options, @@ -997,7 +1139,7 @@ class TodosController < ApplicationController } end end - + def todo_feed_options options = Todo.feed_options(current_user) options[:title] = @feed_title @@ -1047,7 +1189,7 @@ class TodosController < ApplicationController def self.is_feed_request(req) ['rss','atom','txt','ics'].include?(req.parameters[:format]) end - + def check_for_next_todo(todo) # check if this todo has a related recurring_todo. If so, create next todo new_recurring_todo = nil @@ -1058,15 +1200,15 @@ class TodosController < ApplicationController # check if there are active todos belonging to this recurring todo. only # add new one if all active todos are completed if recurring_todo.todos.active.count == 0 - + # check for next todo either from the due date or the show_from date date_to_check = todo.due.nil? ? todo.show_from : todo.due - + # if both due and show_from are nil, check for a next todo from now date_to_check = Time.zone.now if date_to_check.nil? if recurring_todo.active? && recurring_todo.has_next_todo(date_to_check) - + # shift the reference date to yesterday if date_to_check is furher in # the past. This is to make sure we do not get older todos for overdue # todos. I.e. checking a daily todo that is overdue with 5 days will @@ -1082,7 +1224,7 @@ class TodosController < ApplicationController end return new_recurring_todo end - + def get_due_id_for_calendar(due) return "" if due.nil? due_today_date = Time.zone.now @@ -1102,7 +1244,7 @@ class TodosController < ApplicationController end return new_due_id end - + def is_old_due_empty(id) return 0 == count_old_due_empty(id) end @@ -1196,29 +1338,33 @@ class TodosController < ApplicationController def update_due_and_show_from_dates if params["todo"].has_key?("due") - params["todo"]["due"] = parse_date_per_user_prefs(params["todo"]["due"]) + begin + params["todo"]["due"] = parse_date_per_user_prefs(params["todo"]["due"]) + rescue + @todo.errors.add_to_base("Invalid due date") + end else params["todo"]["due"] = "" end if params['todo']['show_from'] - params['todo']['show_from'] = parse_date_per_user_prefs(params['todo']['show_from']) + begin + params['todo']['show_from'] = parse_date_per_user_prefs(params['todo']['show_from']) + rescue + @todo.errors.add_to_base("Invalid show from date") + end end end def update_completed_state if params['done'] == '1' && !@todo.completed? @todo.complete! - @todo.pending_to_activate.each do |t| - t.activate! - end + @todo.activate_pending_todos end # strange. if checkbox is not checked, there is no 'done' in params. # Therefore I've used the negation if !(params['done'] == '1') && @todo.completed? @todo.activate! - @todo.active_to_block.each do |t| - t.block! - end + @todo.block_successors end end @@ -1257,12 +1403,15 @@ class TodosController < ApplicationController source_view do |page| page.calendar do @old_due_empty = is_old_due_empty(@original_item_due_id) - @new_due_id = get_due_id_for_calendar(@todo.due) + @new_due_id = get_due_id_for_calendar(@todo.due) end page.tag do @tag_name = params['_tag_name'] @tag_was_removed = !@todo.has_tag?(@tag_name) end + page.context do + @todo_should_be_hidden = @todo_hidden_state_changed && @todo.hidden? + end end end @@ -1279,6 +1428,16 @@ class TodosController < ApplicationController true end + def determine_non_uniq_todo + # for calendar view. TODO: unused + all_list_uniq_ids = (@due_today.map(&:id) + @due_this_week.map(&:id) + + @due_next_week.map(&:id) + @due_this_month.map(&:id) + @due_after_this_month.map(&:id)).uniq + all_list_count = @due_today.count + @due_this_week.count + + @due_next_week.count + @due_this_month.count + @due_after_this_month.count + + return !( all_list_uniq_ids.length == all_list_count ) + end + class FindConditionBuilder def initialize @@ -1303,54 +1462,62 @@ class TodosController < ApplicationController @prefs = prefs @attributes = params['request'] && params['request']['todo'] || params['todo'] end - + def attributes @attributes end - + def show_from @attributes['show_from'] end - + def due @attributes['due'] end - + def project_name @params['project_name'].strip unless @params['project_name'].nil? end - + + def project_id + @attributes['project_id'] + end + def context_name @params['context_name'].strip unless @params['context_name'].nil? end - - def tag_list - @params['tag_list'] + + def context_id + @attributes['context_id'] end - + + def tag_list + @params['todo_tag_list'] + end + def predecessor_list @params['predecessor_list'] end - + def parse_dates() @attributes['show_from'] = @prefs.parse_date(show_from) @attributes['due'] = @prefs.parse_date(due) @attributes['due'] ||= '' end - + def project_specified_by_name? return false unless @attributes['project_id'].blank? return false if project_name.blank? return false if project_name == 'None' true end - + def context_specified_by_name? return false unless @attributes['context_id'].blank? return false if context_name.blank? true end - + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b4003c36..7b0eb8b7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,11 +1,12 @@ class UsersController < ApplicationController before_filter :admin_login_required, :only => [ :index, :show, :destroy ] skip_before_filter :login_required, :only => [ :new, :create ] + skip_before_filter :check_for_deprecated_password_hash, + :only => [ :change_password, :update_password ] prepend_before_filter :login_optional, :only => [ :new, :create ] - + # GET /users GET /users.xml def index - @users = User.find(:all, :order => 'login') respond_to do |format| format.html do @page_title = "TRACKS::Manage Users" @@ -15,10 +16,13 @@ class UsersController < ApplicationController # we get returned here when signup is successful store_location end - format.xml { render :xml => @users.to_xml(:except => [ :password ]) } + format.xml do + @users = User.find(:all, :order => 'login') + render :xml => @users.to_xml(:except => [ :password ]) + end end end - + # GET /users/id GET /users/id.xml def show @user = User.find_by_id(params[:id]) @@ -50,7 +54,7 @@ class UsersController < ApplicationController end render :layout => "login" end - + # Example usage: curl -H 'Accept: application/xml' -H 'Content-Type: # application/xml' # -u admin:up2n0g00d @@ -128,14 +132,14 @@ class UsersController < ApplicationController return end end - end - + end + # DELETE /users/id DELETE /users/id.xml def destroy @deleted_user = User.find_by_id(params[:id]) @saved = @deleted_user.destroy @total_users = User.find(:all).size - + respond_to do |format| format.html do if @saved @@ -149,14 +153,15 @@ class UsersController < ApplicationController format.xml { head :ok } end end - - + + def change_password @page_title = t('users.change_password_title') end - + def update_password - @user.change_password(params[:updateuser][:password], params[:updateuser][:password_confirmation]) + # is used for focing password change after sha->bcrypt upgrade + @user.change_password(params[:user][:password], params[:user][:password_confirmation]) notify :notice, t('users.password_updated') redirect_to preferences_path rescue Exception => error @@ -167,7 +172,7 @@ class UsersController < ApplicationController def change_auth_type @page_title = t('users.change_auth_type_title') end - + def update_auth_type if (params[:open_id_complete] || (params[:user][:auth_type] == 'open_id')) && openid_enabled? authenticate_with_open_id do |result, identity_url| @@ -199,16 +204,16 @@ class UsersController < ApplicationController redirect_to :action => 'change_auth_type' end end - + def refresh_token @user.generate_token @user.save! notify :notice, t('users.new_token_generated') redirect_to preferences_path end - + private - + def get_new_user if session['new_user'] user = session['new_user'] @@ -218,7 +223,7 @@ class UsersController < ApplicationController end user end - + def check_create_user_params return false unless params.has_key?(:request) return false unless params[:request].has_key?(:login) @@ -227,5 +232,5 @@ class UsersController < ApplicationController return false if params[:request][:password].empty? return true end - + end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0af710a0..fbf0a0cf 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -27,33 +27,42 @@ module ApplicationHelper # a 'traffic light' colour code # def due_date(due) - if due == nil - return "" - end + return "" if due.nil? days = days_from_today(due) - - case days - when 0 - "Due Today " - when 1 - "Due Tomorrow " - # due 2-7 days away - when 2..7 - if prefs.due_style == Preference.due_styles[:due_on] - "Due on #{due.strftime("%A")} " - else - "Due in #{pluralize(days, 'day')} " - end - else - # overdue or due very soon! sound the alarm! - if days < 0 - "Overdue by #{pluralize(days * -1, 'day')} " - else - # more than a week away - relax - "Due in #{pluralize(days, 'day')} " - end - end + + colors = ['amber','amber','orange','orange','orange','orange','orange','orange'] + color = :red if days < 0 + color = :green if days > 7 + color = colors[days] if color.nil? + + return content_tag(:a, {:title => format_date(due)}) { + content_tag(:span, {:class => color}) { + case days + when 0 + t('todos.next_actions_due_date.due_today') + when 1 + t('todos.next_actions_due_date.due_tomorrow') + when 2..7 + if prefs.due_style == Preference.due_styles[:due_on] + # TODO: internationalize strftime here + t('models.preference.due_on', :date => due.strftime("%A")) + else + t('models.preference.due_in', :days => days) + end + else + # overdue or due very soon! sound the alarm! + if days == -1 + t('todos.next_actions_due_date.overdue_by', :days => days * -1) + elsif days < -1 + t('todos.next_actions_due_date.overdue_by_plural', :days => days * -1) + else + # more than a week away - relax + t('models.preference.due_in', :days => days) + end + end + } + } end # Check due date in comparison to today's date Flag up date appropriately with @@ -152,12 +161,12 @@ module ApplicationHelper def recurrence_time_span(rt) case rt.ends_on when "no_end_date" - return rt.start_from.nil? ? "" : "from " + format_date(rt.start_from) + return rt.start_from.nil? ? "" : I18n.t("todos.recurrence.pattern.from") + " " + format_date(rt.start_from) when "ends_on_number_of_times" - return "for "+rt.number_of_occurences.to_s + " times" + return I18n.t("todos.recurrence.pattern.times", :number => rt.number_of_occurences) when "ends_on_end_date" - starts = rt.start_from.nil? ? "" : "from " + format_date(rt.start_from) - ends = rt.end_date.nil? ? "" : " until " + format_date(rt.end_date) + starts = rt.start_from.nil? ? "" : I18n.t("todos.recurrence.pattern.from") + " " + format_date(rt.start_from) + ends = rt.end_date.nil? ? "" : " " + I18n.t("todos.recurrence.pattern.until") + " " + format_date(rt.end_date) return starts+ends else raise Exception.new, "unknown recurrence time span selection (#{rt.ends_on})" @@ -252,7 +261,7 @@ module ApplicationHelper contexts.show_form contexts.show_form_title contexts.new_context_pre contexts.new_context_post common.cancel common.ok - common.ajaxError + common.ajaxError todos.unresolved_dependency }.each do |s| js << "i18n['#{s}'] = '#{ t(s).gsub(/'/, "\\\\'") }';\n" end @@ -266,5 +275,39 @@ module ApplicationHelper javascript_include_tag("i18n/jquery.ui.datepicker-#{locale}.js") end end + + def determine_done_path + case @controller.controller_name + when "contexts" + done_todos_context_path(@context) + when "projects" + done_todos_project_path(@project) + when "todos" + if source_view_is(:tag) + done_tag_path(@tag_name) + else + done_todos_path + end + else + done_todos_path + end + end + + def determine_all_done_path + case @controller.controller_name + when "contexts" + all_done_todos_context_path(@context) + when "projects" + all_done_todos_project_path(@project) + when "todos" + if source_view_is(:tag) + all_done_tag_path(@tag_name) + else + all_done_todos_path + end + else + all_done_todos_path + end + end end diff --git a/app/helpers/contexts_helper.rb b/app/helpers/contexts_helper.rb index 16058ff0..1b512689 100644 --- a/app/helpers/contexts_helper.rb +++ b/app/helpers/contexts_helper.rb @@ -1,25 +1,30 @@ module ContextsHelper - def get_listing_sortable_options - { - :tag => 'div', - :handle => 'handle', - :complete => visual_effect(:highlight, 'list-contexts'), - :url => order_contexts_path - } - end +def get_listing_sortable_options + { + :tag => 'div', + :handle => 'handle', + :complete => visual_effect(:highlight, 'list-contexts'), + :url => order_contexts_path + } +end + +def link_to_delete_context(context, descriptor = sanitize(context.name)) + link_to( + descriptor, + context_path(context, :format => 'js'), + { + :id => "delete_context_#{context.id}", + :class => "delete_context_button", + :x_confirm_message => t('contexts.delete_context_confirmation', :name => context.name), + :title => t('contexts.delete_context_title') + } + ) +end + +def summary(context, undone_todo_count) + content_tag(:p, "#{undone_todo_count}. Context is #{context.hidden? ? 'Hidden' : 'Active'}.") +end - def link_to_delete_context(context, descriptor = sanitize(context.name)) - link_to( - descriptor, - context_path(context, :format => 'js'), - { - :id => "delete_context_#{context.id}", - :class => "delete_context_button", - :x_confirm_message => t('contexts.delete_context_confirmation', :name => context.name), - :title => t('contexts.delete_context_title') - } - ) - end end diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index 8838ec68..4dd9330e 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -1,2 +1,18 @@ module PreferencesHelper + + def pref(model, pref_name, &block) + s = "
" + s << yield + s << "

" + s + end + + def pref_with_select_field(model, pref_name, collection = [ [t('preferences.is_true'),true], [t('preferences.is_false'), false] ]) + pref(model, pref_name) { select(model, pref_name, collection) } + end + + def pref_with_text_field(model, pref_name) + pref(model, pref_name) { text_field(model, pref_name) } + end + end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 587ea435..50ea79e9 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -8,7 +8,7 @@ module ProjectsHelper :url => order_projects_path } end - + def set_element_visible(id,test) if (test) page.show id @@ -30,7 +30,7 @@ module ProjectsHelper end html end - + def project_next_prev_mobile html = '' unless @previous_project.nil? @@ -57,5 +57,19 @@ module ProjectsHelper } ) end - + + def summary(project) + project_description = '' + project_description += sanitize(markdown( project.description )) unless project.description.blank? + project_description += content_tag(:p, + "#{count_undone_todos_phrase(p)}. " + t('projects.project_state', :state => project.state) + ) + project_description + end + + def needsreview_class(item) + raise "item must be a Project " unless item.kind_of? Project + return item.needs_review?(current_user) ? "needsreview" : "needsnoreview" + end + end diff --git a/app/helpers/recurring_todos_helper.rb b/app/helpers/recurring_todos_helper.rb index 9bc0d04f..7cea9601 100644 --- a/app/helpers/recurring_todos_helper.rb +++ b/app/helpers/recurring_todos_helper.rb @@ -3,9 +3,8 @@ module RecurringTodosHelper def recurring_todo_tag_list tags_except_starred = @recurring_todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} tag_list = tags_except_starred.collect{|t| "" + - # link_to(t.name, :controller => "todos", :action => "tag", :id => - # t.name) + TODO: tag view for recurring_todos (yet?) - t.name + + link_to(t.name, :controller => "todos", :action => "tag", :id => + t.name) + #TODO: tag view for recurring_todos (yet?) ""}.join('') "#{tag_list}" end diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index cd59eda1..2f3ef48e 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -18,7 +18,7 @@ module TodosHelper def remote_delete_menu_item(todo) return link_to( image_tag("delete_off.png", :mouseover => "delete_on.png", :alt => t('todos.delete'), :align => "absmiddle")+" "+t('todos.delete'), - {:controller => 'todos', :action => 'destroy', :id => todo.id}, + {:controller => 'todos', :action => 'destroy', :id => todo.id}, :class => "icon_delete_item", :id => "delete_#{dom_id(todo)}", :x_confirm_message => t('todos.confirm_delete', :description => todo.description), @@ -30,7 +30,7 @@ module TodosHelper :_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")} url[:_tag_name] = @tag_name if @source_view == 'tag' - options = {:x_defer_alert => false, :class => "icon_defer_item" } + options = {:x_defer_alert => false, :class => "icon_defer_item", :id => "defer_#{days}_#{dom_id(todo)}" } if todo.due futuredate = (todo.show_from || todo.user.date) + days.days if futuredate > todo.due @@ -55,18 +55,13 @@ module TodosHelper :_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")} url[:_tag_name] = @tag_name if @source_view == 'tag' - return link_to(image_tag("to_project_off.png", :align => "absmiddle")+" " + t('todos.convert_to_project'), url) + return link_to(image_tag("to_project_off.png", :align => "absmiddle")+" " + t('todos.convert_to_project'), url, {:id => "to_project_#{dom_id(todo)}"}) end def image_tag_for_defer(days) image_tag("defer_#{days}_off.png", :mouseover => "defer_#{days}.png", :alt => t('todos.defer_x_days', :count => days), :align => "absmiddle")+" "+t('todos.defer_x_days', :count => days) end - # waiting stuff can be deleted after migration of defer and dependencies - def successor_start_waiting_js(successor) - return "$('##{dom_id(successor, "successor")}').block({message: null})" - end - def collapsed_notes_image(todo) link = link_to(image_tag( 'blank.png', :width=>'16', :height=>'16', :border=>'0' ), "#", {:class => 'show_notes', :title => 'Show notes'}) notes = content_tag(:div, {:class => "todo_notes", :id => dom_id(todo, 'notes'), :style => "display:none"}) { format_note(todo.notes) } @@ -88,24 +83,25 @@ module TodosHelper {:controller => "recurring_todos", :action => "index"}, :class => "recurring_icon", :title => recurrence_pattern_as_text(todo.recurring_todo)) end - + def remote_toggle_checkbox(todo=@todo) check_box_tag("mark_complete_#{todo.id}", toggle_check_todo_path(todo), todo.completed?, :class => 'item-checkbox', :title => todo.pending? ? t('todos.blocked_by', :predecessors => todo.uncompleted_predecessors.map(&:description).join(', ')) : "", :readonly => todo.pending?) end - + def date_span(todo=@todo) if todo.completed? - "#{format_date( todo.completed_at )}" + content_tag(:span, {:class => :grey}) { format_date( todo.completed_at ) } elsif todo.pending? - "#{t('todos.pending')} " + title = t('todos.depends_on')+ ": " + todo.uncompleted_predecessors.map(&:description).join(', ') + content_tag(:a, {:title => title}) { content_tag(:span, {:class => :orange}) { t('todos.pending') } } elsif todo.deferred? show_date( todo.show_from ) else due_date( todo.due ) end end - + def successors_span(todo=@todo) unless todo.pending_successors.empty? pending_count = todo.pending_successors.length @@ -113,41 +109,41 @@ module TodosHelper image_tag( 'successor_off.png', :width=>'10', :height=>'16', :border=>'0', :title => title ) end end - + def grip_span(todo=@todo) unless todo.completed? - image_tag('grip.png', :width => '7', :height => '16', :border => '0', + image_tag('grip.png', :width => '7', :height => '16', :border => '0', :title => t('todos.drag_action_title'), :class => 'grip') end end - + def tag_list_text(todo=@todo) todo.tags.collect{|t| t.name}.join(', ') end - - def tag_list(todo=@todo) - tags_except_starred = todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} - tag_list = tags_except_starred.collect{|t| "" + link_to(t.name, :controller => "todos", :action => "tag", :id => t.name) + ""}.join('') - "#{tag_list}" + + def tag_span (tag, mobile=false) + content_tag(:span, :class => "tag #{tag.name.gsub(' ','-')}") { link_to(tag.name, (mobile ? mobile_tag_path(tag.name) : tag_path(tag.name))) } end - + + def tag_list(todo=@todo, mobile=false) + content_tag(:span, :class => 'tags') { todo.tags.all_except_starred.collect{|tag| tag_span(tag, mobile)}.join('') } + end + def tag_list_mobile(todo=@todo) - tags_except_starred = todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} - # removed the link. TODO: add link to mobile view of tagged actions - tag_list = tags_except_starred.collect{|t| - "" + - link_to(t.name, {:action => "tag", :controller => "todos", :id => t.name+".m"}) + - ""}.join('') - if tag_list.empty? then "" else "#{tag_list}" end + unless todo.tags.all_except_starred.empty? + return tag_list(todo, true) + else + return "" + end end - + def deferred_due_date(todo=@todo) if todo.deferred? && todo.due t('todos.action_due_on', :date => format_date(todo.due)) end end - + def project_and_context_links(todo, parent_container_type, opts = {}) str = '' if todo.completed? @@ -166,7 +162,7 @@ module TodosHelper end return str end - + # Uses the 'staleness_starts' value from settings.yml (in days) to colour the # background of the action appropriately according to the age of the creation # date: @@ -188,37 +184,41 @@ module TodosHelper end end + def show_date_tag(date, the_class, text) + content_tag(:a, :title => format_date(date)) do + content_tag(:span, :class => the_class) { text + " "} + end + end + # Check show_from date in comparison to today's date Flag up date # appropriately with a 'traffic light' colour code # def show_date(d) - if d == nil - return "" - end + return "" if d == nil days = days_from_today(d) - + case days # overdue or due very soon! sound the alarm! when -1000..-1 - "#{t('todos.scheduled_overdue', :days => (days * -1).to_s)} " + show_date_tag(d, :red, t('todos.scheduled_overdue', :days => (days * -1).to_s)) when 0 - "#{t('todos.show_today')} " + show_date_tag(d, :amber, t('todos.show_today')) when 1 - "#{t('todos.show_tomorrow')} " + show_date_tag(d, :amber, t('todos.show_tomorrow')) # due 2-7 days away when 2..7 if prefs.due_style == Preference.due_styles[:due_on] - "#{t('todos.show_on_date', :date => d.strftime("%A"))} " + show_date_tag(d, :orange, t('todos.show_on_date', :date => d.strftime("%A")) ) else - "#{t('todos.show_in_days', :days => days.to_s)} " + show_date_tag(d, :orange, t('todos.show_in_days', :days => days.to_s) ) end # more than a week away - relax else - "#{t('todos.show_in_days', :days => days.to_s)} " + show_date_tag(d, :green, t('todos.show_in_days', :days => days.to_s) ) end end - + def should_show_new_item source_view do |page| page.todo { return !@todo.hidden? } @@ -250,7 +250,7 @@ module TodosHelper def should_add_new_context return @new_context_created && !source_view_is(:project) end - + def parent_container_type return 'tickler' if source_view_is :deferred return 'project' if source_view_is :project @@ -258,18 +258,18 @@ module TodosHelper return 'tag' if source_view_is :tag return 'context' end - + def todo_container_is_empty default_container_empty = ( @down_count == 0 ) deferred_container_empty = ( @todo.deferred? && @remaining_deferred_count == 0) return default_container_empty || deferred_container_empty end - + def default_contexts_for_autocomplete projects = current_user.uncompleted.projects.find(:all, :include => [:context], :conditions => ['default_context_id is not null']) Hash[*projects.map{ |p| [escape_javascript(p.name), escape_javascript(p.default_context.name)] }.flatten].to_json end - + def default_tags_for_autocomplete projects = current_user.projects.uncompleted.find(:all, :conditions => ["default_tags != ''"]) Hash[*projects.map{ |p| [escape_javascript(p.name), p.default_tags] }.flatten].to_json @@ -282,7 +282,7 @@ module TodosHelper end joined_notes || "" end - + def formatted_pagination(total) s = will_paginate(@todos) (s.gsub(/(<\/[^<]+>)/, '\1 ')).chomp(' ') @@ -295,6 +295,7 @@ module TodosHelper def update_needs_to_hide_context return (@remaining_in_context == 0 && (@todo_hidden_state_changed && @todo.hidden?)) || (@remaining_in_context == 0 && @todo_was_deferred_from_active_state) || + (@remaining_in_context == 0 && @tag_was_removed) || (@remaining_in_context == 0 && @todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden)) if source_view_is(:tag) return false if source_view_is_one_of(:project, :calendar) @@ -304,13 +305,14 @@ module TodosHelper def update_needs_to_remove_todo_from_container source_view do |page| - page.context { return @context_changed || @todo.deferred? || @todo.pending? } + page.context { return @context_changed || @todo.deferred? || @todo.pending? || @todo_should_be_hidden } page.project { return @todo_deferred_state_changed || @todo_pending_state_changed || @project_changed} page.deferred { return @context_changed || !(@todo.deferred? || @todo.pending?) } page.calendar { return @due_date_changed || !@todo.due } page.stats { return @todo.completed? } page.tag { return (@context_changed && !@todo.hidden?) || @tag_was_removed || @todo_hidden_state_changed || @todo_deferred_state_changed } page.todo { return @context_changed || @todo.hidden? || @todo.deferred? || @todo.pending?} + page.search { return false } end return false end @@ -324,6 +326,7 @@ module TodosHelper page.stats { return !@todo.completed? } page.tag { return !update_needs_to_remove_todo_from_container && !@tag_was_removed } page.todo { return !update_needs_to_remove_todo_from_container } + page.search { return true } end return false end @@ -356,11 +359,21 @@ module TodosHelper source_view do |page| page.project { - return "tickler-empty-nd" if @todo_was_deferred_from_active_state || @todo_was_blocked_from_active_state || @todo_was_destroyed_from_deferred_state || @todo_was_created_deferred + return "tickler-empty-nd" if + @todo_was_deferred_from_active_state || + @todo_was_blocked_from_active_state || + @todo_was_destroyed_from_deferred_state || + @todo_was_created_deferred || + @todo_was_blocked_from_completed_state return "p#{todo.project_id}empty-nd" } page.tag { - return "tickler-empty-nd" if @todo_was_deferred_from_active_state || @todo_was_destroyed_from_deferred_state || @todo_was_created_deferred + return "tickler-empty-nd" if + @todo_was_deferred_from_active_state || + @todo_was_blocked_from_active_state || + @todo_was_destroyed_from_deferred_state || + @todo_was_created_deferred || + @todo_was_blocked_from_completed_state return "hidden-empty-nd" if @todo.hidden? return "c#{todo.context_id}empty-nd" } @@ -372,22 +385,27 @@ module TodosHelper return "c#{todo.context_id}empty-nd" end + def todo_was_removed_from_deferred_or_blocked_container + return @todo_was_activated_from_deferred_state || + @todo_was_activated_from_pending_state || + @todo_was_destroyed_from_deferred_or_pending_state || + @todo_was_completed_from_deferred_or_blocked_state + end + def show_empty_message_in_source_container container_id = "" source_view do |page| page.project { container_id = "p#{@original_item_project_id}empty-nd" if @remaining_in_context == 0 - container_id = "tickler-empty-nd" if ( - ( (@todo_was_activated_from_deferred_state || @todo_was_activated_from_pending_state) && @remaining_deferred_or_pending_count == 0) || - (@original_item_was_deferred && @remaining_deferred_or_pending_count == 0 && @todo.completed?) ) - container_id = "empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? + container_id = "tickler-empty-nd" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0 + container_id = "empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? } page.deferred { container_id = "c#{@original_item_context_id}empty-nd" if @remaining_in_context == 0 } page.calendar { container_id = "empty_#{@original_item_due_id}" if @old_due_empty } page.tag { container_id = "hidden-empty-nd" if (@remaining_hidden_count == 0 && !@todo.hidden? && @todo_hidden_state_changed) || (@remaining_hidden_count == 0 && @todo.completed? && @original_item_was_hidden) - container_id = "tickler-empty-nd" if (@todo_was_activated_from_deferred_state && @remaining_deferred_or_pending_count == 0) || + container_id = "tickler-empty-nd" if (todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0) || (@original_item_was_deferred && @remaining_deferred_or_pending_count == 0 && (@todo.completed? || @tag_was_removed)) container_id = "empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? } @@ -411,11 +429,22 @@ module TodosHelper return html + ";" end - private - - def image_tag_for_star(todo) - class_str = todo.starred? ? "starred_todo" : "unstarred_todo" - image_tag("blank.png", :title =>t('todos.star_action'), :class => class_str, :id => "star_img_"+todo.id.to_s) + def reset_tab_index + $tracks_tab_index = 0 end - + + def next_tab_index + # make sure it exists if reset was not called. Set to 20 to avoid clashes with existing form in sidebar + $tracks_tab_index ||= 20 + + $tracks_tab_index = $tracks_tab_index + 1 + return $tracks_tab_index + end + + private + + def image_tag_for_star(todo) + image_tag("blank.png", :title =>t('todos.star_action'), :class => "todo_star"+(todo.starred? ? " starred":""), :id => "star_img_"+todo.id.to_s) + end + end diff --git a/app/models/context.rb b/app/models/context.rb index a7d79f72..2a797397 100644 --- a/app/models/context.rb +++ b/app/models/context.rb @@ -1,13 +1,14 @@ class Context < ActiveRecord::Base - has_many :todos, :dependent => :delete_all, :include => :project, :order => "todos.completed_at DESC" + has_many :todos, :dependent => :delete_all, :include => :project, + :order => 'todos.due IS NULL, todos.due ASC, todos.created_at ASC' has_many :recurring_todos, :dependent => :delete_all belongs_to :user named_scope :active, :conditions => { :hide => false } named_scope :hidden, :conditions => { :hide => true } - acts_as_list :scope => :user + acts_as_list :scope => :user, :top_of_list => 0 extend NamePartFinder include Tracks::TodoList @@ -19,12 +20,13 @@ class Context < ActiveRecord::Base validates_does_not_contain :name, :string => ',', :message => "cannot contain the comma (',') character" def self.feed_options(user) + # TODO: move to view or helper { :title => 'Tracks Contexts', :description => "Lists all the contexts for #{user.display_name}" } end - + def self.null_object NullContext.new end @@ -32,36 +34,29 @@ class Context < ActiveRecord::Base def hidden? self.hide == true || self.hide == 1 end - + def title name end - - def summary(undone_todo_count) - s = "

#{undone_todo_count}. " - s += "Context is #{hidden? ? 'Hidden' : 'Active'}." - s += "

" - s - end - + def new_record_before_save? @new_record_before_save - end + end end class NullContext - + def nil? true end - + def id nil end - + def name '' end - + end \ No newline at end of file diff --git a/app/models/project.rb b/app/models/project.rb index 672bd777..f3f43d12 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,28 +1,5 @@ class Project < ActiveRecord::Base has_many :todos, :dependent => :delete_all - - # TODO: remove these scopes. Can be replaced by the named scopes on the todo relation - has_many :not_done_todos, - :include => [:context,:tags,:project], - :class_name => 'Todo', - :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", - :conditions => ["todos.state = ?", 'active'] - has_many :done_todos, - :include => [:context,:tags,:project], - :class_name => 'Todo', - :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", - :conditions => ["todos.state = ?", 'completed'] - has_many :deferred_todos, - :include => [:context,:tags,:project], - :class_name => 'Todo', - :conditions => ["todos.state = ? ", "deferred"], - :order => "show_from" - has_many :pending_todos, - :include => [:context,:tags,:project], - :class_name => 'Todo', - :conditions => ["todos.state = ? ", "pending"], - :order => "show_from" - has_many :notes, :dependent => :delete_all, :order => "created_at DESC" has_many :recurring_todos @@ -32,48 +9,51 @@ class Project < ActiveRecord::Base named_scope :active, :conditions => { :state => 'active' } named_scope :hidden, :conditions => { :state => 'hidden' } named_scope :completed, :conditions => { :state => 'completed'} - named_scope :uncompleted, :conditions => ["NOT state = ?", 'completed'] - + named_scope :uncompleted, :conditions => ["NOT(state = ?)", 'completed'] + validates_presence_of :name validates_length_of :name, :maximum => 255 validates_uniqueness_of :name, :scope => "user_id" - validates_does_not_contain :name, :string => ',' - acts_as_list :scope => 'user_id = #{user_id} AND state = \'#{state}\'' - acts_as_state_machine :initial => :active, :column => 'state' + acts_as_list :scope => 'user_id = #{user_id} AND state = \'#{state}\'', :top_of_list => 0 + + include AASM + aasm_column :state + aasm_initial_state :active + extend NamePartFinder #include Tracks::TodoList - - state :active - state :hidden, :enter => :hide_todos, :exit => :unhide_todos - state :completed, :enter => Proc.new { |p| p.completed_at = Time.zone.now }, :exit => Proc.new { |p| p.completed_at = nil } - event :activate do - transitions :to => :active, :from => [:hidden, :completed] + aasm_state :active + aasm_state :hidden, :enter => :hide_todos, :exit => :unhide_todos + aasm_state :completed, :enter => :set_completed_at_date, :exit => :clear_completed_at_date + + aasm_event :activate do + transitions :to => :active, :from => [:active, :hidden, :completed] end - - event :hide do + + aasm_event :hide do transitions :to => :hidden, :from => [:active, :completed] end - - event :complete do + + aasm_event :complete do transitions :to => :completed, :from => [:active, :hidden] end - + attr_protected :user attr_accessor :cached_note_count def self.null_object NullProject.new end - + def self.feed_options(user) { :title => I18n.t('models.project.feed_title'), :description => I18n.t('models.project.feed_description', :username => user.display_name) } end - + def hide_todos todos.each do |t| unless t.completed? || t.deferred? @@ -82,7 +62,7 @@ class Project < ActiveRecord::Base end end end - + def unhide_todos todos.each do |t| if t.project_hidden? @@ -91,22 +71,32 @@ class Project < ActiveRecord::Base end end end - + + def set_completed_at_date + self.completed_at = Time.zone.now + end + + def clear_completed_at_date + self.completed_at = nil + end + def note_count + # TODO: test this for eager and not eager loading!!! + return 0 if notes.size == 0 cached_note_count || notes.count end - + alias_method :original_default_context, :default_context def default_context original_default_context.nil? ? Context.null_object : original_default_context end - + # would prefer to call this method state=(), but that causes an endless loop # as a result of acts_as_state_machine calling state=() to update the attribute def transition_to(candidate_state) case candidate_state.to_sym - when current_state + when aasm_current_state return when :hidden hide! @@ -116,29 +106,48 @@ class Project < ActiveRecord::Base complete! end end - + + def needs_review?(current_user) + return active? && ( last_reviewed.nil? || + (last_reviewed < current_user.time - current_user.prefs.review_period.days)) + end + + def blocked? + ## mutually exclusive for stalled and blocked + # blocked is uncompleted project with deferred or pending todos, but no next actions + return false if self.completed? + return !self.todos.deferred_or_blocked.empty? && self.todos.not_deferred_or_blocked.empty? + end + + def stalled? + # stalled is active/hidden project with no active todos + return false if self.completed? + return self.todos.deferred_or_blocked.empty? && self.todos.not_deferred_or_blocked.empty? + end + + def name=(value) self[:name] = value.gsub(/\s{2,}/, " ").strip end - + def new_record_before_save? @new_record_before_save - end - + end + end class NullProject - + def hidden? false end - + def nil? true end - + def id nil end - + end diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb index dfd64985..e1ff6003 100644 --- a/app/models/recurring_todo.rb +++ b/app/models/recurring_todo.rb @@ -10,20 +10,19 @@ class RecurringTodo < ActiveRecord::Base named_scope :completed, :conditions => { :state => 'completed'} attr_protected :user - - acts_as_state_machine :initial => :active, :column => 'state' - state :active, :enter => Proc.new { |t| - t[:show_from], t.completed_at = nil, nil - t.occurences_count = 0 - } - state :completed, :enter => Proc.new { |t| t.completed_at = Time.zone.now }, :exit => Proc.new { |t| t.completed_at = nil } + include AASM + aasm_column :state + aasm_initial_state :active + + aasm_state :active, :enter => Proc.new { |t| t.occurences_count = 0 } + aasm_state :completed, :enter => Proc.new { |t| t.completed_at = Time.zone.now }, :exit => Proc.new { |t| t.completed_at = nil } - event :complete do + aasm_event :complete do transitions :to => :completed, :from => [:active] end - event :activate do + aasm_event :activate do transitions :to => :active, :from => [:completed] end @@ -41,8 +40,7 @@ class RecurringTodo < ActiveRecord::Base validate :set_recurrence_on_validations def period_specific_validations - periods = %W[daily weekly monthly yearly] - if periods.include?(recurring_period) + if %W[daily weekly monthly yearly].include?(recurring_period) self.send("validate_#{recurring_period}") else errors.add(:recurring_period, "is an unknown recurrence pattern: '#{self.recurring_period}'") @@ -94,7 +92,6 @@ class RecurringTodo < ActiveRecord::Base end end - def starts_and_ends_on_validations errors.add_to_base("The start date needs to be filled in") if start_from.nil? || start_from.blank? case self.ends_on @@ -388,9 +385,9 @@ class RecurringTodo < ActiveRecord::Base def recurring_target_as_text case self.target when 'due_date' - return "due" + return I18n.t("todos.recurrence.pattern.due") when 'show_from_date' - return "show" + return I18n.t("todos.recurrence.pattern.show") else raise Exception.new, "unexpected value of recurrence target '#{self.target}'" end @@ -403,38 +400,51 @@ class RecurringTodo < ActiveRecord::Base def recurring_show_always=(value) self.show_always=value end - + def recurrence_pattern return "invalid repeat pattern" if every_other1.nil? case recurring_period when 'daily' if only_work_days - return "on work days" + return I18n.t("todos.recurrence.pattern.on_work_days") else if every_other1 > 1 - return "every #{every_other1} days" + return I18n.t("todos.recurrence.pattern.every_n", :n => every_other1) + " " + I18n.t("common.days") else - return "every day" + return I18n.t("todos.recurrence.pattern.every_day") end end when 'weekly' if every_other1 > 1 - return "every #{every_other1} weeks" + return I18n.t("todos.recurrence.pattern.every_n", :n => every_other1) + " " + I18n.t("common.weeks") else - return 'weekly' + return I18n.t('todos.recurrence.pattern.weekly') end when 'monthly' return "invalid repeat pattern" if every_other2.nil? if self.recurrence_selector == 0 - return "every #{self.every_other2} month#{self.every_other2>1?'s':''} on day #{self.every_other1}" + on_day = " " + I18n.t('todos.recurrence.pattern.on_day_n', :n => self.every_other1) + if self.every_other2>1 + return I18n.t("todos.recurrence.pattern.every_n", :n => self.every_other2) + " " + I18n.t('common.months') + on_day + else + return I18n.t("todos.recurrence.pattern.every_month") + on_day + end else - return "every #{self.xth} #{self.day_of_week} of every #{self.every_other2} month#{self.every_other2>1?'s':''}" + if self.every_other2>1 + n_months = "#{self.every_other2} " + I18n.t('common.months') + else + n_months = I18n.t('common.month') + end + return I18n.t('todos.recurrence.pattern.every_xth_day_of_every_n_months', + :x => self.xth, :day => self.day_of_week, :n_months => n_months) end when 'yearly' if self.recurrence_selector == 0 - return "every year on #{self.month_of_year} #{self.every_other1}" + return I18n.t("todos.recurrence.pattern.every_year_on", + :date => I18n.l(DateTime.new(Time.zone.now.year, self.every_other2, self.every_other1), :format => :month_day)) else - return "every year on the #{self.xth} #{self.day_of_week} of #{self.month_of_year}" + return I18n.t("todos.recurrence.pattern.every_year_on", + :date => I18n.t("todos.recurrence.pattern.the_xth_day_of_month", :x => self.xth, :day => self.day_of_week, :month => self.month_of_year)) end else return 'unknown recurrence pattern: period unknown' @@ -442,18 +452,18 @@ class RecurringTodo < ActiveRecord::Base end def xth - xth_day = ['first','second','third','fourth','last'] + xth_day = [ + I18n.t('todos.recurrence.pattern.first'),I18n.t('todos.recurrence.pattern.second'),I18n.t('todos.recurrence.pattern.third'), + I18n.t('todos.recurrence.pattern.fourth'),I18n.t('todos.recurrence.pattern.last')] return self.every_other3.nil? ? '??' : xth_day[self.every_other3-1] end def day_of_week - days_of_week = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'] - return (self.every_count.nil? ? '??' : days_of_week[self.every_count]) + return (self.every_count.nil? ? '??' : I18n.t('todos.recurrence.pattern.day_names')[self.every_count]) end def month_of_year - months_of_year = ['January','Februari','March','April','May','June','July','August','September','October','November','December'] - return self.every_other2.nil? ? '??' : months_of_year[self.every_other2-1] + return self.every_other2.nil? ? '??' : I18n.t('todos.recurrence.pattern.month_names')[self.every_other2] end def starred? @@ -692,13 +702,7 @@ class RecurringTodo < ActiveRecord::Base end def toggle_completion! - saved = false - if completed? - saved = activate! - else - saved = complete! - end - return saved + return completed? ? activate! : complete! end def toggle_star! diff --git a/app/models/tag.rb b/app/models/tag.rb index 28f72662..0d6d24e5 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -11,38 +11,41 @@ class Tag < ActiveRecord::Base # rescue the ActiveRecord database constraint errors instead. validates_presence_of :name validates_uniqueness_of :name, :case_sensitive => false - + # Change this validation if you need more complex tag names. # validates_format_of :name, :with => /^[a-zA-Z0-9\_\-]+$/, :message => "can not contain special characters" - + # Set up the polymorphic relationship. - has_many_polymorphs :taggables, - :from => [:todos, :recurring_todos], - :through => :taggings, + has_many_polymorphs :taggables, + :from => [:todos, :recurring_todos], + :through => :taggings, :dependent => :destroy, - :skip_duplicates => false, + :skip_duplicates => false, :parent_extend => proc { # Defined on the taggable models, not on Tag itself. Return the tagnames # associated with this record as a string. def to_s self.map(&:name).sort.join(Tag::JOIN_DELIMITER) end + def all_except_starred + self.reject{|tag| tag.name == Todo::STARRED_TAG_NAME} + end } - + # Callback to strip extra spaces from the tagname before saving it. If you # allow tags to be renamed later, you might want to use the # before_save callback instead. - def before_create + def before_create self.name = name.downcase.strip.squeeze(" ") end def on(taggable, user) taggings.create :taggable => taggable, :user => user end - + # Tag::Error class. Raised by ActiveRecord::Base::TaggingExtensions if # something goes wrong. class Error < StandardError end - + end diff --git a/app/models/todo.rb b/app/models/todo.rb index 72ac6c0f..ea6e17c9 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -1,10 +1,13 @@ class Todo < ActiveRecord::Base + after_save :save_predecessors + + # relations belongs_to :context belongs_to :project belongs_to :user belongs_to :recurring_todo - + has_many :predecessor_dependencies, :foreign_key => 'predecessor_id', :class_name => 'Dependency', :dependent => :destroy has_many :successor_dependencies, :foreign_key => 'successor_id', :class_name => 'Dependency', :dependent => :destroy has_many :predecessors, :through => :successor_dependencies @@ -13,21 +16,18 @@ class Todo < ActiveRecord::Base :source => :predecessor, :conditions => ['NOT (todos.state = ?)', 'completed'] has_many :pending_successors, :through => :predecessor_dependencies, :source => :successor, :conditions => ['todos.state = ?', 'pending'] - - after_save :save_predecessors + # scopes for states of this todo named_scope :active, :conditions => { :state => 'active' } named_scope :active_or_hidden, :conditions => ["todos.state = ? OR todos.state = ?", 'active', 'project_hidden'] - named_scope :not_completed, :conditions => ['NOT (todos.state = ? )', 'completed'] - named_scope :completed, :conditions => ["NOT todos.completed_at IS NULL"] - named_scope :are_due, :conditions => ['NOT (todos.due IS NULL)'] - named_scope :deferred, :conditions => ["todos.completed_at IS NULL AND NOT todos.show_from IS NULL"] + named_scope :not_completed, :conditions => ['NOT (todos.state = ?)', 'completed'] + named_scope :completed, :conditions => ["NOT (todos.completed_at IS NULL)"] + named_scope :deferred, :conditions => ["todos.completed_at IS NULL AND NOT (todos.show_from IS NULL)"] named_scope :blocked, :conditions => ['todos.state = ?', 'pending'] - named_scope :deferred_or_blocked, :conditions => ["(todos.completed_at IS NULL AND NOT todos.show_from IS NULL) OR (todos.state = ?)", "pending"] - named_scope :not_deferred_or_blocked, :conditions => ["todos.completed_at IS NULL AND todos.show_from IS NULL AND NOT todos.state = ?", "pending"] - named_scope :with_tag, lambda { |tag| {:joins => :taggings, :conditions => ["taggings.tag_id = ? ", tag.id] } } - named_scope :of_user, lambda { |user_id| {:conditions => ["todos.user_id = ? ", user_id] } } - named_scope :hidden, + named_scope :pending, :conditions => ['todos.state = ?', 'pending'] + named_scope :deferred_or_blocked, :conditions => ["(todos.completed_at IS NULL AND NOT(todos.show_from IS NULL)) OR (todos.state = ?)", "pending"] + named_scope :not_deferred_or_blocked, :conditions => ["todos.completed_at IS NULL AND todos.show_from IS NULL AND NOT(todos.state = ?)", "pending"] + named_scope :hidden, :joins => :context, :conditions => ["todos.state = ? OR (contexts.hide = ? AND (todos.state = ? OR todos.state = ? OR todos.state = ?))", 'project_hidden', true, 'active', 'deferred', 'pending'] @@ -36,82 +36,100 @@ class Todo < ActiveRecord::Base :conditions => ['NOT(todos.state = ? OR (contexts.hide = ? AND (todos.state = ? OR todos.state = ? OR todos.state = ?)))', 'project_hidden', true, 'active', 'deferred', 'pending'] - STARRED_TAG_NAME = "starred" + # other scopes + named_scope :are_due, :conditions => ['NOT (todos.due IS NULL)'] + named_scope :with_tag, lambda { |tag| {:joins => :taggings, :conditions => ["taggings.tag_id = ? ", tag.id] } } + named_scope :of_user, lambda { |user_id| {:conditions => ["todos.user_id = ? ", user_id] } } + named_scope :completed_after, lambda { |date| {:conditions => ["todos.completed_at > ? ", date] } } + named_scope :completed_before, lambda { |date| {:conditions => ["todos.completed_at < ? ", date] } } - # regular expressions for dependencies + STARRED_TAG_NAME = "starred" + DEFAULT_INCLUDES = [ :project, :context, :tags, :taggings, :pending_successors, :uncompleted_predecessors, :recurring_todo ] + + # regular expressions for dependencies. TODO: are these still used? RE_TODO = /[^']+/ RE_CONTEXT = /[^']+/ RE_PROJECT = /[^']+/ RE_PARTS = /'(#{RE_TODO})'\s<'(#{RE_CONTEXT})';\s'(#{RE_PROJECT})'>/ # results in array RE_SPEC = /'#{RE_TODO}'\s<'#{RE_CONTEXT}';\s'#{RE_PROJECT}'>/ # results in string - - acts_as_state_machine :initial => :active, :column => 'state' - - # when entering active state, also remove completed_at date. Looks like :exit - # of state completed is not run, see #679 - state :active, :enter => Proc.new { |t| t[:show_from], t.completed_at = nil, nil } - state :project_hidden - state :completed, :enter => Proc.new { |t| t.completed_at = Time.zone.now }, :exit => Proc.new { |t| t.completed_at = nil } - state :deferred - state :pending - event :defer do + # state machine + include AASM + aasm_column :state + aasm_initial_state Proc.new { |t| (t.show_from && t.user && (t.show_from > t.user.date)) ? :deferred : :active} + + aasm_state :active + aasm_state :project_hidden + aasm_state :completed, :enter => Proc.new { |t| t.completed_at = Time.zone.now }, :exit => Proc.new { |t| t.completed_at = nil} + aasm_state :deferred, :exit => Proc.new { |t| t[:show_from] = nil } + aasm_state :pending + + aasm_event :defer do transitions :to => :deferred, :from => [:active] end - - event :complete do - transitions :to => :completed, :from => [:active, :project_hidden, :deferred] + + aasm_event :complete do + transitions :to => :completed, :from => [:active, :project_hidden, :deferred, :pending] end - - event :activate do - transitions :to => :active, :from => [:project_hidden, :completed, :deferred] - transitions :to => :active, :from => [:pending], :guard => :no_uncompleted_predecessors_or_deferral? + + aasm_event :activate do + transitions :to => :active, :from => [:project_hidden, :deferred] + transitions :to => :active, :from => [:completed], :guard => :no_uncompleted_predecessors? + transitions :to => :active, :from => [:pending], :guard => :no_uncompleted_predecessors_or_deferral? + transitions :to => :pending, :from => [:completed], :guard => :uncompleted_predecessors? transitions :to => :deferred, :from => [:pending], :guard => :no_uncompleted_predecessors? end - - event :hide do - transitions :to => :project_hidden, :from => [:active, :deferred] + + aasm_event :hide do + transitions :to => :project_hidden, :from => [:active, :deferred, :pending] end - - event :unhide do + + aasm_event :unhide do transitions :to => :deferred, :from => [:project_hidden], :guard => Proc.new{|t| !t.show_from.blank? } + transitions :to => :pending, :from => [:project_hidden], :guard => :uncompleted_predecessors? transitions :to => :active, :from => [:project_hidden] end - - event :block do + + aasm_event :block do transitions :to => :pending, :from => [:active, :deferred] end - + attr_protected :user # Description field can't be empty, and must be < 100 bytes Notes must be < # 60,000 bytes (65,000 actually, but I'm being cautious) validates_presence_of :description validates_length_of :description, :maximum => 100 - validates_length_of :notes, :maximum => 60000, :allow_nil => true + validates_length_of :notes, :maximum => 60000, :allow_nil => true validates_presence_of :show_from, :if => :deferred? validates_presence_of :context - + def initialize(*args) super(*args) @predecessor_array = nil # Used for deferred save of predecessors @removed_predecessors = nil end - + def no_uncompleted_predecessors_or_deferral? - return (show_from.blank? or Time.zone.now > show_from and uncompleted_predecessors.empty?) + no_deferral = show_from.blank? or Time.zone.now > show_from + no_uncompleted_predecessors = uncompleted_predecessors.all(true).empty? + return (no_deferral && no_uncompleted_predecessors) end - + def no_uncompleted_predecessors? - return uncompleted_predecessors.empty? + return uncompleted_predecessors.all(true).empty? end - + + def uncompleted_predecessors? + return !uncompleted_predecessors.all(true).empty? + end + # Returns a string with description def specification project_name = self.project.is_a?(NullProject) ? "(none)" : self.project.name return "\'#{self.description}\' <\'#{self.context.title}\'; \'#{project_name}\'>" end - + def validate if !show_from.blank? && show_from < user.date errors.add("show_from", I18n.t('models.todo.error_date_must_be_future')) @@ -123,7 +141,7 @@ class Todo < ActiveRecord::Base end end end - + def save_predecessors unless @predecessor_array.nil? # Only save predecessors if they changed current_array = self.predecessors @@ -145,21 +163,19 @@ class Todo < ActiveRecord::Base logger.error "Could not find #{todo.description}" # Unexpected since validation passed end end - end + end end def removed_predecessors return @removed_predecessors end - + def remove_predecessor(predecessor) - puts "@@@ before delete" # remove predecessor and activate myself self.predecessors.delete(predecessor) - puts "@@@ before activate" self.activate! end - + # Returns true if t is equal to self or a successor of self def is_successor?(todo) if self == todo @@ -176,6 +192,10 @@ class Todo < ActiveRecord::Base return false end + def has_pending_successors + return !pending_successors.empty? + end + def has_tag?(tag) return self.tags.select{|t| t.name==tag }.size > 0 end @@ -196,27 +216,26 @@ class Todo < ActiveRecord::Base end self.save! end - + def toggle_completion! - saved = false - if completed? - saved = activate! - else - saved = complete! - end - return saved + return completed? ? activate! : complete! end - + def show_from self[:show_from] end - + def show_from=(date) # parse Date objects into the proper timezone date = user.at_midnight(date) if (date.is_a? Date) + + # show_from needs to be set before state_change because of "bug" in aasm. + # If show_from is not set, the todo will not validate and thus aasm will not save + # (see http://stackoverflow.com/questions/682920/persisting-the-state-column-on-transition-using-rubyist-aasm-acts-as-state-machi) + self[:show_from] = date + activate! if deferred? && date.blank? defer! if active? && !date.blank? && date > user.date - self[:show_from] = date end alias_method :original_project, :project @@ -225,46 +244,28 @@ class Todo < ActiveRecord::Base original_project.nil? ? Project.null_object : original_project end - alias_method :original_set_initial_state, :set_initial_state - - def set_initial_state - if show_from && (show_from > user.date) - write_attribute self.class.state_column, 'deferred' - else - original_set_initial_state - end - end - - alias_method :original_run_initial_state_actions, :run_initial_state_actions - - def run_initial_state_actions - # only run the initial state actions if the standard initial state hasn't - # been changed - if self.class.initial_state.to_sym == current_state - original_run_initial_state_actions - end - end - def self.feed_options(user) { :title => 'Tracks Actions', :description => "Actions for #{user.display_name}" } end - + def starred? tags.any? {|tag| tag.name == STARRED_TAG_NAME} end - + def toggle_star! - if starred? - _remove_tags STARRED_TAG_NAME - tags.reload + self.starred= !starred? + end + + def starred=(starred) + if starred + _add_tags STARRED_TAG_NAME unless starred? else - _add_tags(STARRED_TAG_NAME) - tags.reload - end - starred? + _remove_tags STARRED_TAG_NAME + end + starred end def from_recurring_todo? @@ -284,20 +285,24 @@ class Todo < ActiveRecord::Base return @predecessor_array end - + def add_predecessor(t) @predecessor_array = predecessors @predecessor_array << t end - - # Return todos that should be activated if the current todo is completed - def pending_to_activate - return successors.find_all {|t| t.uncompleted_predecessors.empty?} + + # activate todos that should be activated if the current todo is completed + def activate_pending_todos + pending_todos = successors.find_all {|t| t.uncompleted_predecessors.empty?} + pending_todos.each {|t| t.activate! } + return pending_todos end - + # Return todos that should be blocked if the current todo is undone - def active_to_block - return successors.find_all {|t| t.active? or t.deferred?} + def block_successors + active_successors = successors.find_all {|t| t.active? or t.deferred?} + active_successors.each {|t| t.block!} + return active_successors end def raw_notes=(value) @@ -305,27 +310,27 @@ class Todo < ActiveRecord::Base end # Rich Todo API - + def self.from_rich_message(user, default_context_id, description, notes) fields = description.match(/([^>@]*)@?([^>]*)>?(.*)/) description = fields[1].strip context = fields[2].strip project = fields[3].strip - + context = nil if context == "" project = nil if project == "" context_id = default_context_id unless(context.nil?) - found_context = user.active_contexts.find_by_namepart(context) + found_context = user.contexts.active.find_by_namepart(context) found_context = user.contexts.find_by_namepart(context) if found_context.nil? context_id = found_context.id unless found_context.nil? end - + unless user.contexts.exists? context_id raise(CannotAccessContext, "Cannot access a context that does not belong to this user.") end - + project_id = nil unless(project.blank?) if(project[0..3].downcase == "new:") @@ -333,12 +338,12 @@ class Todo < ActiveRecord::Base found_project.name = project[4..255+4].strip found_project.save! else - found_project = user.active_projects.find_by_namepart(project) + found_project = user.projects.active.find_by_namepart(project) found_project = user.projects.find_by_namepart(project) if found_project.nil? end project_id = found_project.id unless found_project.nil? end - + todo = user.todos.build todo.description = description todo.raw_notes = notes @@ -346,4 +351,5 @@ class Todo < ActiveRecord::Base todo.project_id = project_id unless project_id.nil? return todo end + end diff --git a/app/models/user.rb b/app/models/user.rb index 5776d14d..26ebe9c7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,5 @@ require 'digest/sha1' +require 'bcrypt' class User < ActiveRecord::Base # Virtual attribute for the unencrypted password @@ -59,35 +60,23 @@ class User < ActiveRecord::Base self.update_positions(projects.map{ |p| p.id }) return projects end - def actionize(user_id, scope_conditions = {}) - @state = scope_conditions[:state] - query_state = "" - query_state = "AND project.state = '" + @state +"' "if @state - projects = Project.find_by_sql([ - "SELECT project.id, count(todo.id) as p_count " + - "FROM projects as project " + - "LEFT OUTER JOIN todos as todo ON todo.project_id = project.id "+ - "WHERE project.user_id = ? AND NOT (todo.state='completed') " + - query_state + - " GROUP BY project.id ORDER by p_count DESC",user_id]) - self.update_positions(projects.map{ |p| p.id }) - projects = find(:all, :conditions => scope_conditions) - return projects + def actionize(scope_conditions = {}) + todos_in_project = find(:all, :conditions => scope_conditions, :include => [:todos]) + todos_in_project.sort!{ |x, y| -(x.todos.active.count <=> y.todos.active.count) } + todos_in_project.reject{ |p| p.todos.active.count > 0 } + sorted_project_ids = todos_in_project.map {|p| p.id} + + all_project_ids = find(:all).map {|p| p.id} + other_project_ids = all_project_ids - sorted_project_ids + + update_positions(sorted_project_ids + other_project_ids) + + return find(:all, :conditions => scope_conditions) end end - has_many :active_projects, - :class_name => 'Project', - :order => 'projects.position ASC', - :conditions => [ 'state = ?', 'active' ] - has_many :active_contexts, - :class_name => 'Context', - :order => 'position ASC', - :conditions => [ 'hide = ?', false ] has_many :todos, :order => 'todos.completed_at DESC, todos.created_at DESC', :dependent => :delete_all - has_many :project_hidden_todos, - :conditions => ['(state = ? OR state = ?)', 'project_hidden', 'active'] has_many :recurring_todos, :order => 'recurring_todos.completed_at DESC, recurring_todos.created_at DESC', :dependent => :delete_all @@ -99,33 +88,16 @@ class User < ActiveRecord::Base find(:all, :conditions => ['show_from <= ?', Time.zone.now ]).collect { |t| t.activate! } end end - has_many :pending_todos, - :class_name => 'Todo', - :conditions => [ 'state = ?', 'pending' ], - :order => 'show_from ASC, todos.created_at DESC' - has_many :completed_todos, - :class_name => 'Todo', - :conditions => ['todos.state = ? AND NOT(todos.completed_at IS NULL)', 'completed'], - :order => 'todos.completed_at DESC', - :include => [ :project, :context ] do - def completed_within( date ) - reject { |x| x.completed_at < date } - end - - def completed_more_than( date ) - reject { |x| x.completed_at > date } - end - end has_many :notes, :order => "created_at DESC", :dependent => :delete_all has_one :preference, :dependent => :destroy - + attr_protected :is_admin validates_presence_of :login validates_presence_of :password, :if => :password_required? validates_length_of :password, :within => 5..40, :if => :password_required? validates_presence_of :password_confirmation, :if => :password_required? - validates_confirmation_of :password + validates_confirmation_of :password validates_length_of :login, :within => 3..80 validates_uniqueness_of :login, :on => :create validates_presence_of :open_id_url, :if => :using_openid? @@ -137,7 +109,7 @@ class User < ActiveRecord::Base #for will_paginate plugin cattr_accessor :per_page @@per_page = 5 - + def validate unless Tracks::Config.auth_schemes.include?(auth_type) errors.add("auth_type", "not a valid authentication type (#{auth_type})") @@ -152,43 +124,44 @@ class User < ActiveRecord::Base return nil if candidate.nil? if Tracks::Config.auth_schemes.include?('database') - return candidate if candidate.auth_type == 'database' && candidate.crypted_password == sha1(pass) + return candidate if candidate.auth_type == 'database' and + candidate.password_matches? pass end - + if Tracks::Config.auth_schemes.include?('ldap') return candidate if candidate.auth_type == 'ldap' && SimpleLdapAuthenticator.valid?(login, pass) end - + if Tracks::Config.auth_schemes.include?('cas') # because we can not auth them with out thier real password we have to settle for this return candidate if candidate.auth_type.eql?("cas") end - + if Tracks::Config.auth_schemes.include?('open_id') # hope the user enters the correct data return candidate if candidate.auth_type.eql?("open_id") end - + return nil end - + def self.find_by_open_id_url(raw_identity_url) normalized_open_id_url = OpenIdAuthentication.normalize_identifier(raw_identity_url) find(:first, :conditions => ['open_id_url = ?', normalized_open_id_url]) end - + def self.no_users_yet? count == 0 end - + def self.find_admin - find(:first, :conditions => [ "is_admin = ?", true ]) + find(:first, :conditions => [ "is_admin = ?", true ]) end - + def to_param login end - + def display_name if first_name.blank? && last_name.blank? return login @@ -199,13 +172,13 @@ class User < ActiveRecord::Base end "#{first_name} #{last_name}" end - + def change_password(pass,pass_confirm) self.password = pass self.password_confirmation = pass_confirm save! end - + def time Time.now.in_time_zone(prefs.time_zone) end @@ -213,23 +186,23 @@ class User < ActiveRecord::Base def date time.midnight end - + def at_midnight(date) return ActiveSupport::TimeZone[prefs.time_zone].local(date.year, date.month, date.day, 0, 0, 0) end - + def generate_token - self.token = Digest::SHA1.hexdigest "#{Time.now.to_i}#{rand}" + self.token = sha1 "#{Time.now.to_i}#{rand}" end - + def remember_token? - remember_token_expires_at && Time.now.utc < remember_token_expires_at + remember_token_expires_at && Time.now.utc < remember_token_expires_at end - + # These create and unset the fields required for remembering users between browser closes def remember_me self.remember_token_expires_at = 2.weeks.from_now.utc - self.remember_token ||= self.class.sha1("#{login}--#{remember_token_expires_at}") + self.remember_token ||= sha1("#{login}--#{remember_token_expires_at}") save(false) end @@ -239,38 +212,55 @@ class User < ActiveRecord::Base save(false) end + # Returns true if the user has a password hashed using SHA-1. + def uses_deprecated_password? + crypted_password =~ /^[a-f0-9]{40}$/i + end + + def password_matches?(pass) + if uses_deprecated_password? + crypted_password == sha1(pass) + else + BCrypt::Password.new(crypted_password) == pass + end + end + + def salted(s) + "#{Tracks::Config.salt}--#{s}--" + end + + def sha1(s) + Digest::SHA1.hexdigest salted s + end + + def hash(s) + BCrypt::Password.create s + end + protected - def self.sha1(s) - Digest::SHA1.hexdigest("#{Tracks::Config.salt}--#{s}--") - end - def crypt_password return if password.blank? - write_attribute("crypted_password", self.class.sha1(password)) if password == password_confirmation + write_attribute("crypted_password", hash(password)) if password == password_confirmation end - + def password_required? auth_type == 'database' && crypted_password.blank? || !password.blank? end - + def using_openid? auth_type == 'open_id' end - - def password_matches?(pass) - crypted_password == sha1(pass) - end - + def normalize_open_id_url return if open_id_url.nil? - + # fixup empty url value if open_id_url.empty? self.open_id_url = nil return end - + self.open_id_url = OpenIdAuthentication.normalize_identifier(open_id_url) end end diff --git a/app/views/contexts/_context_form.rhtml b/app/views/contexts/_context_form.rhtml index 952e8a44..92bd39aa 100644 --- a/app/views/contexts/_context_form.rhtml +++ b/app/views/contexts/_context_form.rhtml @@ -12,15 +12,15 @@
- <%= text_field('context', 'name', :class => 'context-name') %>
+ <%= text_field('context', 'name', :class => 'context-name', :tabindex => next_tab_index) %>
- <%= check_box('context', 'hide', :class => 'context-hide') %> + <%= check_box('context', 'hide', {:class => 'context-hide', :tabindex => next_tab_index}) %>
- diff --git a/app/views/contexts/_new_context_form.rhtml b/app/views/contexts/_new_context_form.rhtml index 26bde0ba..26d65348 100644 --- a/app/views/contexts/_new_context_form.rhtml +++ b/app/views/contexts/_new_context_form.rhtml @@ -1,3 +1,4 @@ +<%- reset_tab_index %>
-
\ No newline at end of file +
diff --git a/app/views/todos/add_predecessor.js.erb b/app/views/todos/add_predecessor.js.erb index 69af584b..608e3d9a 100644 --- a/app/views/todos/add_predecessor.js.erb +++ b/app/views/todos/add_predecessor.js.erb @@ -1,6 +1,6 @@ <% if !@saved if @predecessor.completed? -%> - TracksPages.page_notify('error', "<%= t('todos.cannot_add_dependency_to_completed_todo') %>", 8); + TracksPages.page_notify('error', "<%= t('todos.cannot_add_dependency_to_completed_todo') %>", 8); $('#<%=dom_id(@todo)%>').html(html_for_todo()); <% else -%> TracksPages.page_notify('error', "<%= t('todos.unable_to_add_dependency') %>", 8); @@ -29,7 +29,7 @@ function show_in_tickler_box() { function regenerate_predecessor_family() { <% - parents = @predecessor.predecessors + parents = @predecessors until parents.empty? parent = parents.pop parents += parent.predecessors -%> diff --git a/app/views/todos/all_done.html.erb b/app/views/todos/all_done.html.erb new file mode 100644 index 00000000..b758bb4f --- /dev/null +++ b/app/views/todos/all_done.html.erb @@ -0,0 +1,22 @@ +<% + paginate_options = { + :class => :add_note_link, + :previous_label => '« '+ t('common.previous'), + :next_label => t('common.next')+' »', + :inner_window => 2 + } +%> +
+
+ <%= will_paginate @done, paginate_options %> +

<%= t('todos.all_completed') %>

+ <% if @done.empty? -%> +

<%= t('todos.no_completed_actions') %>

+ <% else -%> + <%= render :partial => "todos/todo", :collection => @done, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> + <% end -%> +
+ + <%= will_paginate @done, paginate_options %> + +
diff --git a/app/views/todos/calendar.html.erb b/app/views/todos/calendar.html.erb index 987b7b56..a1d59aec 100644 --- a/app/views/todos/calendar.html.erb +++ b/app/views/todos/calendar.html.erb @@ -31,7 +31,7 @@
-

<%= t('todos.calendar.due_this_month', :month => Time.zone.now.strftime("%B")) %>

+

<%= t('todos.calendar.due_this_month', :month => l(Time.zone.now, :format => "%B")) %>

> <%= t('todos.calendar.no_actions_due_this_month') %>
@@ -41,7 +41,7 @@
-

<%= t('todos.calendar.due_next_month_and_later', :month => (Time.zone.now+1.month).strftime("%B")) %>

+

<%= t('todos.calendar.due_next_month_and_later', :month => l(Time.zone.now+1.month, :format => "%B")) %>

> <%= t('todos.calendar.no_actions_due_after_this_month') %>
diff --git a/app/views/todos/check_deferred.js.erb b/app/views/todos/check_deferred.js.erb index ecd8bed6..4f2c0be2 100644 --- a/app/views/todos/check_deferred.js.erb +++ b/app/views/todos/check_deferred.js.erb @@ -1,3 +1,3 @@ <% unless @due_tickles.empty? -%> - TracksPages.page_notify('notice', "<%=t('todos.tickler_items_due', :count => @due_tickles.length)%>", 5); + TracksPages.page_notify('notice', "<%=t('todos.tickler_items_due', :count => @due_tickles.length)%>", 8); <% end -%> diff --git a/app/views/todos/completed.html.erb b/app/views/todos/completed.html.erb deleted file mode 100644 index 40682bea..00000000 --- a/app/views/todos/completed.html.erb +++ /dev/null @@ -1,25 +0,0 @@ -
-

<%= t('todos.completed_today', :count => @due_tickles.nil? ? 0 : @due_tickles.length) %>

-
-

<%= t('todos.completed_last_day') %>

- - <%= render :partial => "done", :collection => @done_today %> -
-
- -
-

<%= t('todos.completed_last_x_days', :count => 7) %>

- - <%= render :partial => "done", :collection => @done_this_week %> -
-
- -
-

<%= t('todos.completed_last_x_days', :count => 28) %>

- - <%= render :partial => "done", :collection => @done_this_month %> -
-
- -

<%= t('todos.older_completed_items') %>: <%= link_to( t('todos.older_than_days', :count => 31), done_archive_path ) %>

-
diff --git a/app/views/todos/completed_archive.html.erb b/app/views/todos/completed_archive.html.erb deleted file mode 100644 index c3f87bba..00000000 --- a/app/views/todos/completed_archive.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -
- -

<%= t('todos.completed_in_archive', :count => @done_archive.length) %>

-
-

<%= t('todos.completed_more_than_x_days_ago', :count => 31) %>

- - <%= render :partial => "done", :collection => @done_archive %> -
-
- -
diff --git a/app/views/todos/create.js.erb b/app/views/todos/create.js.erb index c8b22407..52d241ad 100644 --- a/app/views/todos/create.js.erb +++ b/app/views/todos/create.js.erb @@ -1,5 +1,5 @@ <% if @saved -%> - TracksPages.page_notify('notice', "<%=escape_javascript @status_message%>", 5); + TracksPages.page_notify('notice', "<%=escape_javascript @status_message%>", 8); TracksPages.hide_errors(); TracksPages.set_page_badge(<%= @down_count %>); <% if should_show_new_item -%> @@ -20,20 +20,27 @@ function clear_form() { $('#todo-form-new-action').clearDeps(); TracksForm.set_context_name('<%=escape_javascript @initial_context_name%>'); TracksForm.set_project_name('<%=escape_javascript @initial_project_name%>'); - TracksForm.set_tag_list('<%=escape_javascript @default_tags%>'); + TracksForm.set_tag_list('<%=escape_javascript @initial_tags%>'); $('#todo-form-new-action input:text:first').focus(); + $('#new_todo_starred_link .todo_star').removeClass('starred'); + $('#new_todo_starred').val('false'); } function insert_new_context_with_new_todo() { - $('#no_todos_in_view').slideUp(100); + <%- + empty_id = '#no_todos_in_view' + empty_id = '#tickler-empty-nd' if source_view_is :tickler + -%> + $('<%=empty_id%>').slideUp(100); $('#display_box').prepend(html_for_new_context()); } function add_todo_to_existing_context() { <% if source_view_is_one_of(:todo, :deferred, :tag) -%> - <% unless source_view_is_one_of(:todo, :tag) && @todo.deferred? -%> + <% unless source_view_is_one_of(:todo, :tag) && (@todo.deferred?||@todo.hidden?) -%> $('#c<%= @todo.context_id %>').fadeIn(500, function() {}); $('#no_todos_in_view').slideUp(100); + <%= "$('#tickler-empty-nd').slideUp(100);" if source_view_is(:deferred) && @todo.deferred? %> <% end -%> <% end -%> $('#<%=empty_container_msg_div_id%>').hide(); @@ -59,4 +66,4 @@ function html_for_new_context() { function html_for_new_todo() { return "<%= @saved ? escape_javascript(render(:partial => @todo, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view })) : "" %>"; -} \ No newline at end of file +} diff --git a/app/views/todos/create_multiple.js.erb b/app/views/todos/create_multiple.js.erb index 5d9fdc17..0de67336 100644 --- a/app/views/todos/create_multiple.js.erb +++ b/app/views/todos/create_multiple.js.erb @@ -28,7 +28,7 @@ function clear_form() { $('#todo-form-multi-new-action').clearForm(); TracksForm.set_context_name_for_multi_add('<%=escape_javascript @initial_context_name%>'); TracksForm.set_project_name_for_multi_add('<%=escape_javascript @initial_project_name%>'); - TracksForm.set_tag_list_for_multi_add('<%=escape_javascript @default_tags%>'); + TracksForm.set_tag_list_for_multi_add('<%=escape_javascript @initial_tags%>'); $('#todo-form-multi-new-action input:text:first').focus(); } diff --git a/app/views/todos/destroy.js.erb b/app/views/todos/destroy.js.erb index 3b264ea9..8d9b1d43 100644 --- a/app/views/todos/destroy.js.erb +++ b/app/views/todos/destroy.js.erb @@ -4,12 +4,13 @@ remove_todo_from_page(); show_new_todo_if_todo_was_recurring(); activate_pending_todos(); + update_predecessors(); show_empty_messages(); <%- else -%> TracksPages.page_notify('error', "<%= t('todos.error_deleting_item', :description => @todo.description) %>", 8); <%- end -%> -<% if @saved +<% if @saved # do not send the js in case of an error -%> @@ -32,19 +33,24 @@ function show_empty_messages() { function remove_todo_from_page() { <% if (@remaining_in_context == 0) && update_needs_to_hide_context - # remove context with deleted todo + # remove context with deleted todo -%> - $('#c<%=@todo.context_id%>').fadeOut(400, function() { - $('#<%=dom_id(@todo)%>').remove(); - }); - <%= show_empty_message_in_source_container -%> + $('#c<%=@todo.context_id%>').fadeOut(400, function() { + $('#<%=dom_id(@todo)%>').remove(); + }); + <%= show_empty_message_in_source_container -%> <% else - # remove only the todo + # remove only the todo -%> - <%= show_empty_message_in_source_container %> - $('#<%=dom_id(@todo)%>').slideUp(400, function() { - $('#<%=dom_id(@todo)%>').remove(); - }); + <%= show_empty_message_in_source_container %> + $('#<%=dom_id(@todo)%>').slideUp(400, function() { + $('#<%=dom_id(@todo)%>').remove(); + <% if source_view_is :calendar + # in calendar view it is possible to have a todo twice on the page + -%> + $('#<%=dom_id(@todo)%>').remove(); + <% end %> + }); <% end -%> } @@ -64,7 +70,7 @@ function show_new_todo_if_todo_was_recurring() { } function activate_pending_todos() { - <% # Activate pending todos that are successors of the completed + <% # Activate pending todos that are successors of the deleted if @saved && @pending_to_activate # do not render the js in case of an error or if no todos to activate @pending_to_activate.each do |t| @@ -84,10 +90,22 @@ function activate_pending_todos() { <% end -%> } +function update_predecessors() { +<% + if @todo_was_destroyed_from_pending_state + @uncompleted_predecessors.each do |p| -%> + if ($('#<%=item_container_id(p)%>')) { + $('#<%=dom_id(p)%>').html('<%=escape_javascript(render(:partial => p, :locals => { :parent_container_type => parent_container_type }))%>'); + } +<% end + end +%> +} + function html_for_new_recurring_todo() { return "<%= @saved && @new_recurring_todo ? escape_javascript(render(:partial => @new_recurring_todo, :locals => { :parent_container_type => parent_container_type })) : "" %>"; } -<% end +<% end # if @saved -%> diff --git a/app/views/todos/done.html.erb b/app/views/todos/done.html.erb new file mode 100644 index 00000000..b5a24941 --- /dev/null +++ b/app/views/todos/done.html.erb @@ -0,0 +1,31 @@ +
+
+

<%= t('todos.completed_today') %>

+ <% if @done_today.empty? -%> +

<%= t('todos.no_completed_actions') %>

+ <% else -%> + <%= render :partial => "todos/todo", :collection => @done_today, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> + <% end -%> +
+ +
+

<%= t('todos.completed_rest_of_week') %>

+ <% if @done_this_week.empty? -%> +

<%= t('todos.no_completed_actions') %>

+ <% else -%> + <%= render :partial => "todos/todo", :collection => @done_this_week, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> + <% end -%> +
+ +
+

<%= t('todos.completed_rest_of_month') %>

+ <% if @done_this_month.empty? -%> +

<%= t('todos.no_completed_actions') %>

+ <% else -%> + <%= render :partial => "todos/todo", :collection => @done_this_month, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> + <% end -%> +
+ +

You can see all completed actions <%= link_to "here", determine_all_done_path %>

+ +
diff --git a/app/views/todos/edit_mobile.html.erb b/app/views/todos/edit_mobile.html.erb new file mode 100644 index 00000000..0cf73eb4 --- /dev/null +++ b/app/views/todos/edit_mobile.html.erb @@ -0,0 +1,5 @@ +<% form_tag todo_path(@todo, :format => 'm'), :name => 'mobileEdit', :method => :put do %> + <%= render :partial => 'edit_mobile_form', :locals => { :parent_container_type => "show_mobile" } %> +

+<% end -%> +<%= link_to t('common.cancel'), @return_path %> diff --git a/app/views/todos/new.m.erb b/app/views/todos/new.m.erb index 44da0853..cf6403a4 100644 --- a/app/views/todos/new.m.erb +++ b/app/views/todos/new.m.erb @@ -1,5 +1,5 @@ <% form_tag todos_path(:format => 'm'), :method => :post do %> - <%= render :partial => 'edit_mobile' %> + <%= render :partial => 'edit_mobile_form' %>

<% end -%> <%= link_to t('common.back'), @return_path %> diff --git a/app/views/todos/remove_predecessor.js.erb b/app/views/todos/remove_predecessor.js.erb index dbcf67bd..e186991b 100644 --- a/app/views/todos/remove_predecessor.js.erb +++ b/app/views/todos/remove_predecessor.js.erb @@ -1,7 +1,7 @@ <% # TODO: lots of overlap with add_predecessor --> helpers? if @removed -%> TracksPages.page_notify('notice', "<%= t('todos.removed_predecessor', :successor => @successor.description, :predecessor => @predecessor.description) %>", 8); - + replace_updated_predecessor(); regenerate_predecessor_family(); update_successor(); @@ -15,7 +15,7 @@ function replace_updated_predecessor() { function regenerate_predecessor_family() { <% - parents = @predecessor.predecessors + parents = @predecessors until parents.empty? parent = parents.pop parents += parent.predecessors -%> diff --git a/app/views/todos/show.m.erb b/app/views/todos/show.m.erb index 0ab19a9b..5db38371 100644 --- a/app/views/todos/show.m.erb +++ b/app/views/todos/show.m.erb @@ -1,5 +1,29 @@ -<% form_tag todo_path(@todo, :format => 'm'), :name => 'mobileEdit', :method => :put do %> - <%= render :partial => 'edit_mobile', :locals => { :parent_container_type => "show_mobile" } %> -

-<% end -%> -<%= link_to t('common.cancel'), @return_path %> +

Description

+<%= @todo.description %>
+ +

Actions

+ +
+ + +

+ +
+ + +

+ +
+ + +

+ +
+ + +

+ +
+ + +

\ No newline at end of file diff --git a/app/views/todos/toggle_check.js.erb b/app/views/todos/toggle_check.js.erb index 935f4866..14bb168d 100644 --- a/app/views/todos/toggle_check.js.erb +++ b/app/views/todos/toggle_check.js.erb @@ -5,17 +5,22 @@ redirect_after_complete(); <% else animation = [] - animation << "remove_todo" - if @todo.completed? - animation << "add_to_completed_container" unless source_view_is(:calendar) - animation << "add_new_recurring_todo" - animation << "activate_pending_todos" - animation << "remove_source_container" + unless source_view_is(:search) + animation << "remove_todo" + if @todo.completed? + animation << "add_to_completed_container" unless source_view_is_one_of(:calendar, :deferred) + animation << "add_new_recurring_todo" + animation << "activate_pending_todos" + animation << "remove_source_container" + else + animation << "add_todo_to_context" unless source_view_is(:done) + animation << "block_predecessors" + end + animation << "update_empty_container" if source_view_is_one_of(:tag, :todo) + animation << "regenerate_predecessor_family" else - animation << "add_todo_to_context" - animation << "block_predecessors" - end - animation << "update_empty_container" if source_view_is_one_of(:tag, :todo) -%> + animation << "replace_todo" + end -%> <%= render_animation(animation) %> TracksPages.set_page_badge(<%= @down_count %>); <% end -%> @@ -54,6 +59,11 @@ function add_to_completed_container(next_steps) { <% end -%> } +function replace_todo(next_steps) { + $('#<%= dom_id(@todo) %>').html(html_for_todo()); + next_steps.go(); +} + function add_todo_to_context(next_steps) { $('#<%= item_container_id(@todo) %>').append(html_for_todo()); <% if should_make_context_visible -%> @@ -65,12 +75,15 @@ function add_todo_to_context(next_steps) { $("#<%= empty_container_msg_div_id(@todo) %>").slideUp(100); highlight_updated_todo(next_steps); <% end -%> + <% if @completed_count == 0 -%> + $("#empty-d").slideDown(100); + <% end -%> } function add_new_recurring_todo(next_steps) { <% # show new todo if the completed todo was recurring if @todo.from_recurring_todo? - unless @new_recurring_todo.nil? || @new_recurring_todo.deferred? -%> + unless @new_recurring_todo.nil? || (@new_recurring_todo.deferred? && !source_view_is(:deferred)) -%> $('#<%= item_container_id(@new_recurring_todo) %>').append(html_for_recurring_todo()); $('#c<%= @new_recurring_todo.context_id %>').fadeIn(500, function() { highlight_updated_recurring_todo(next_steps); @@ -108,7 +121,7 @@ function highlight_updated_todo(next_steps) { function activate_pending_todos(next_steps) { <% # Activate pending todos that are successors of the completed - if @saved && @pending_to_activate + if @saved && @pending_to_activate # do not render the js in case of an error or if no todos to activate @pending_to_activate.each do |t| html = escape_javascript(render(:partial => t, :locals => { :parent_container_type => parent_container_type })) @@ -121,7 +134,7 @@ function activate_pending_todos(next_steps) { }); <% else -%> $('#<%= item_container_id(t) %>').append("<%= html%>"); - <% end -%> + <% end -%> TodoItems.highlight_todo('#<%= dom_id(t)%>'); <% end -%> <% end -%> @@ -129,7 +142,7 @@ function activate_pending_todos(next_steps) { } function block_predecessors(next_steps) { - <% # Activate pending todos that are successors of the completed + <% # Block active todos that are successors of the uncompleted if @saved && @active_to_block # do not render the js in case of an error or if no todos to block @active_to_block.each do |t| %> @@ -145,6 +158,20 @@ function block_predecessors(next_steps) { next_steps.go(); } +function regenerate_predecessor_family(next_steps) { +<% +if @predecessors + parents = @predecessors + until parents.empty? + parent = parents.pop + parents += parent.predecessors -%> + $('#<%= dom_id(parent) %>').html("<%= escape_javascript(render(:partial => parent, :locals => { :parent_container_type => parent_container_type })) %>"); +<%end +end +-%> + next_steps.go(); +} + function remove_source_container(next_steps) { <% if (@remaining_in_context == 0 && source_view_is_one_of(:todo, :tag)) # remove context with deleted todo @@ -158,7 +185,7 @@ function remove_source_container(next_steps) { } function html_for_todo() { - return "<%= @saved ? escape_javascript(render(:partial => @todo, :locals => { + return "<%= @saved && !source_view_is(:done) ? escape_javascript(render(:partial => @todo, :locals => { :parent_container_type => parent_container_type, :suppress_project => source_view_is(:project), :suppress_context => source_view_is(:context) @@ -167,4 +194,4 @@ function html_for_todo() { function html_for_recurring_todo() { return "<%= @saved ? escape_javascript(render(:partial => @new_recurring_todo, :locals => { :parent_container_type => parent_container_type })) : "" %>"; -} +} \ No newline at end of file diff --git a/app/views/todos/toggle_star.js.erb b/app/views/todos/toggle_star.js.erb index 9ec02520..eaf4a2af 100644 --- a/app/views/todos/toggle_star.js.erb +++ b/app/views/todos/toggle_star.js.erb @@ -1,5 +1,5 @@ <%- if @saved -%> - $('div#line_todo_<%= @todo.id %> a.star_item img').toggleClass('starred_todo').toggleClass('unstarred_todo'); + $('div#line_todo_<%= @todo.id %> a.star_item img').toggleClass('starred'); <%- else -%> TracksPages.page_notify('error', '<%= t('todos.error_starring', :description => @todo.description) %>', 8); <%- end -%> diff --git a/app/views/todos/update.js.erb b/app/views/todos/update.js.erb index 7d2e62ad..d732662e 100644 --- a/app/views/todos/update.js.erb +++ b/app/views/todos/update.js.erb @@ -27,6 +27,11 @@ function remove_todo(next_steps) { $('#<%= dom_id(@todo) %>').fadeOut(400, function() { $('#<%= dom_id(@todo) %>').remove(); + <% if source_view_is :calendar + # in calendar view it is possible to have a todo twice on the page + -%> + $('#<%= dom_id(@todo) %>').remove(); + <% end %> <%= show_empty_message_in_source_container -%> next_steps.go(); }); @@ -41,7 +46,7 @@ function add_to_existing_container(next_steps) { <% end -%> <% else -%> <% unless (@todo_hidden_state_changed && @todo.hidden?) || @todo_was_deferred_from_active_state -%> - $('#c<%= @todo.context_id %>').fadeIn(500, function() { + $('#c<%= @todo.context_id %>').fadeIn(500, function() { next_steps.go(); <% if @target_context_count==1 -%> $("#<%= empty_container_msg_div_id %>").slideUp(100); @@ -64,6 +69,7 @@ function replace_todo(next_steps) { function hide_context(next_steps) { <% context_id = @context_changed ? @original_item_context_id : @todo.context_id -%> $('#c<%= context_id %>').fadeOut(400, function(){ next_steps.go(); }); + <%= "$('#tickler-empty-nd').slideDown(400);" if source_view_is(:deferred) && @down_count == 0 %> } function highlight_updated_todo(next_steps) { @@ -104,7 +110,7 @@ function html_for_error_messages() { return "<%= escape_javascript(error_messages_for('todo')) %>"; } -function update_predecessors() { +function update_predecessors(next_steps) { <% @todo.uncompleted_predecessors.each do |p| -%> if ($('#<%=item_container_id(p)%>')) { $('#<%=dom_id(p)%>').html('<%=escape_javascript(render(:partial => p, :locals => { :parent_container_type => parent_container_type }))%>'); @@ -117,4 +123,5 @@ function update_predecessors() { } <% end -%> <% end -%> + next_steps.go(); } \ No newline at end of file diff --git a/app/views/users/_update_password.html.erb b/app/views/users/_update_password.html.erb new file mode 100644 index 00000000..1bb6ecfe --- /dev/null +++ b/app/views/users/_update_password.html.erb @@ -0,0 +1,4 @@ +
+<%= password_field "user", "password", :size => 40 %>
+
+<%= password_field "user", "password_confirmation", :size => 40 %>
diff --git a/app/views/users/change_password.html.erb b/app/views/users/change_password.html.erb index e16183e4..cc3fe546 100644 --- a/app/views/users/change_password.html.erb +++ b/app/views/users/change_password.html.erb @@ -1,5 +1,5 @@
- +

<%= @page_title %>

<%= error_messages_for 'user' %> @@ -7,20 +7,10 @@

<%= t('users.change_password_prompt') %>

<% form_tag :action => 'update_password' do %> - - - - - - - - - - - - - -
<%= password_field "updateuser", "password", :size => 40 %>
<%= password_field "updateuser", "password_confirmation", :size => 40 %>
<%= link_to t('common.cancel'), preferences_path %><%= submit_tag t('users.change_password_submit') %>
+ <%= render :partial => 'update_password' %> +
+ <%= link_to t('common.cancel'), preferences_path %> + <%= submit_tag t('users.change_password_submit') %> <% end %>
\ No newline at end of file diff --git a/app/views/users/destroy.js.erb b/app/views/users/destroy.js.erb index 1f97f075..97f3c2b6 100644 --- a/app/views/users/destroy.js.erb +++ b/app/views/users/destroy.js.erb @@ -1,7 +1,7 @@ <% if @saved -%> remove_user_from_page(); TracksPages.set_page_badge(<%= @total_users %>); - TracksPages.page_notify('notice', '<%= t('users.destroy_successful', :login => @deleted_user.login) %>', 5); + TracksPages.page_notify('notice', '<%= t('users.destroy_successful', :login => @deleted_user.login) %>', 8); <% else -%> TracksPages.page_notify('error', '<%= t('users.destroy_error', :login => @deleted_user.login) %>', 8); <% end -%> diff --git a/config/boot.rb b/config/boot.rb index 6686664c..57528ecc 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -110,5 +110,19 @@ module Rails end end +class Rails::Boot + def run + load_initializer + + Rails::Initializer.class_eval do + def load_gems + @bundler_loaded ||= Bundler.require :default, Rails.env + end + end + + Rails::Initializer.run(:set_load_path) + end +end + # All that for this: Rails.boot! diff --git a/config/environment.rb b/config/environment.rb index ff02891b..1fc8f03b 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -21,15 +21,6 @@ Rails::Initializer.run do |config| # config.frameworks -= [ :action_web_service, :action_mailer ] config.autoload_paths += %W( #{RAILS_ROOT}/app/apis ) - config.gem "highline" - config.gem "RedCloth" - config.gem "soap4r", :lib => false - config.gem 'datanoise-actionwebservice', :lib => 'actionwebservice', :source => "http://gems.github.com" - config.gem 'sanitize', :version => '~> 1.2.1' - config.gem 'rack', :version => '1.1.0' - config.gem 'will_paginate', :version => '~> 2.3.15' - config.gem 'has_many_polymorphs' - config.action_controller.use_accept_header = true # Use the database for sessions instead of the file system @@ -69,12 +60,7 @@ Rails::Initializer.run do |config| # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de - - # See Rails::Configuration for more options - if ( SITE_CONFIG['authentication_schemes'].include? 'cas') - #requires rubycas-client gem to be installed - config.gem "rubycas-client", :lib => 'casclient' - end + end # Add new inflection rules using the following format @@ -121,7 +107,7 @@ if ( SITE_CONFIG['authentication_schemes'].include? 'cas') end end -tracks_version='2.0devel' +tracks_version='2.1devel' # comment out next two lines if you do not want (or can not) the date of the # last git commit in the footer info=`git log --pretty=format:"%ai" -1` diff --git a/config/environments/cucumber.rb b/config/environments/cucumber.rb index a7392a85..d2f604d6 100644 --- a/config/environments/cucumber.rb +++ b/config/environments/cucumber.rb @@ -26,8 +26,3 @@ config.action_mailer.delivery_method = :test config.action_controller.session_store = :cookie_store config.action_controller.session = { :key => 'TracksCucumber', :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil } -config.gem 'cucumber', :lib => false, :version => '<0.10.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber')) -config.gem 'cucumber-rails', :lib => false, :version => '>=0.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails')) -config.gem 'gherkin', :lib => false, :version => '2.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/gherkin')) -config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner')) -config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat')) \ No newline at end of file diff --git a/config/environments/selenium.rb b/config/environments/selenium.rb index 10eb9aa0..f7e812a6 100644 --- a/config/environments/selenium.rb +++ b/config/environments/selenium.rb @@ -24,6 +24,3 @@ config.action_mailer.delivery_method = :test # Unique cookies config.action_controller.session = { :key => 'TracksSelenium' } -config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner')) -config.gem 'selenium-client', :lib => false unless File.directory?(File.join(Rails.root, 'vendor/plugins/selenium-client')) -config.gem 'mongrel' # required by webrat for selenium \ No newline at end of file diff --git a/config/environments/test.rb b/config/environments/test.rb index 049cffe7..2b031cb9 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -23,7 +23,7 @@ config.action_controller.allow_forgery_protection = false config.action_controller.session_store = :cookie_store config.action_controller.session = { :key => 'TracksTest', :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil } -# Overwrite the default settings for fixtures in tests. See Fixtures +# Overwrite the default settings for fixtures in tests. See Fixtures # for more details about these settings. # config.transactional_fixtures = true # config.instantiated_fixtures = false @@ -31,15 +31,3 @@ config.action_controller.session = { :key => 'TracksTest', :secret => SITE_CONFI SITE_CONFIG['salt'] ||= 'change-me' config.time_zone = 'UTC' - -config.after_initialize do - require File.expand_path(File.dirname(__FILE__) + "/../../test/selenium_helper") -end - -config.gem "flexmock" -config.gem "ZenTest", :lib => "zentest", :version => ">=4.0.0" -config.gem "hpricot" -config.gem "hoe" -config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat')) -config.gem 'rspec-rails', :lib => false, :version => '~>1.3.3' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails')) -config.gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com" diff --git a/vendor/rails/railties/configs/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb similarity index 100% rename from vendor/rails/railties/configs/initializers/backtrace_silencers.rb rename to config/initializers/backtrace_silencers.rb diff --git a/vendor/rails/railties/configs/initializers/cookie_verification_secret.rb b/config/initializers/cookie_verification_secret.rb similarity index 64% rename from vendor/rails/railties/configs/initializers/cookie_verification_secret.rb rename to config/initializers/cookie_verification_secret.rb index 9f05cd5a..b824a8a0 100644 --- a/vendor/rails/railties/configs/initializers/cookie_verification_secret.rb +++ b/config/initializers/cookie_verification_secret.rb @@ -4,4 +4,4 @@ # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. -ActionController::Base.cookie_verifier_secret = '<%= app_secret %>'; +ActionController::Base.cookie_verifier_secret = 'cdb112742619b87ea7cdcfc9a0f664abaf49dbd12bbc22d9d94ef990b4a0eb9776a9a62ca225e01a014ca8ac8bfda8ae704ce3367b4f75dea3082cea00d6609f'; diff --git a/vendor/rails/railties/configs/initializers/inflections.rb b/config/initializers/inflections.rb similarity index 100% rename from vendor/rails/railties/configs/initializers/inflections.rb rename to config/initializers/inflections.rb diff --git a/config/initializers/mongrel_workaround.rb b/config/initializers/mongrel_workaround.rb index fcf11e71..dcad6931 100644 --- a/config/initializers/mongrel_workaround.rb +++ b/config/initializers/mongrel_workaround.rb @@ -1,6 +1,21 @@ # adapted from https://gist.github.com/471663 and https://rails.lighthouseapp.com/projects/8994/tickets/4690-mongrel-doesnt-work-with-rails-238 -if Rails.version == '2.3.11' && Gem.available?('mongrel', '~>1.1.5') && self.class.const_defined?(:Mongrel) +def check_mongrel_around_115 +begin + # Gem.available? is deprecated from rubygems 1.8.2 + Gem::Specification::find_by_name "mongrel", "~>1.1.5" + rescue Gem::LoadError + if RUBY_VERSION[2] == "9" + false + else + Gem.available?('mongrel', '~>1.1.5') + end + end +end + +mongrel115 = check_mongrel_around_115 + +if Rails.version == '2.3.14' && mongrel115 && self.class.const_defined?(:Mongrel) # Pulled right from latest rack. Old looked like this in 1.1.0 version. # @@ -89,4 +104,4 @@ if Rails.version == '2.3.11' && Gem.available?('mongrel', '~>1.1.5') && self.cla end end end -end \ No newline at end of file +end diff --git a/vendor/rails/railties/configs/initializers/new_rails_defaults.rb b/config/initializers/new_rails_defaults.rb similarity index 100% rename from vendor/rails/railties/configs/initializers/new_rails_defaults.rb rename to config/initializers/new_rails_defaults.rb diff --git a/config/locales/de.yml b/config/locales/de.yml index 4c4d6ead..174c0a8c 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1,50 +1,67 @@ --- de: + integrations: + opensearch_description: In Tracks suchen + applescript_next_action_prompt: "Beschreibung der n\xC3\xA4chsten Aufgabe:" + gmail_description: "Gadget, um Tracks als Gadget zu Googlemail hinzuzuf\xC3\xBCgen" + applescript_success_after_id: erstellt + applescript_success_before_id: "N\xC3\xA4chste neue Aufgabe mit ID" common: + recurring_todos: Wiederholenden Aktionen back: "Zur\xC3\xBCck" actions: Aktionen third: Dritte - go_back: "Zur\xC3\xBCck" add: "Hinzuf\xC3\xBCgen" logout: Abmelden + go_back: "Zur\xC3\xBCck" + previous: Vorherige none: Keine + week: Woche + second: Zweite cancel: Abbrechen optional: optional - second: Zweite - notes: Notizen + month: Monat server_error: Auf dem Server ist ein Fehler aufgetreten. forum: Forum - action: Aktion + notes: Notizen last: Letzte + action: Aktion projects: Projekte project: Projekt - ok: Ok contribute: Mitwirken - numbered_step: Schritt %{number} + ok: Ok first: Erste website: Website - drag_handle: Verschieben + numbered_step: Schritt %{number} sort: by_task_count_title: Nach Anzahl der Aufgaben sortieren by_task_count_title_confirm: Sollen diese Projekte wirklich nach Anzahl der Aufgaben sortiert werden? Die bisherige Sortier-Reihenfolge wird damit überschrieben. alphabetically: Alphabetisch sort: Sortieren - alphabetically_title: Projekte alphabetisch sortieren alphabetically_confirm: Sollen diese Projekte wirklich alphabetisch sortiert werden? Die bisherige Sortier-Reihenfolge wird damit überschrieben. + alphabetically_title: Projekte alphabetisch sortieren by_task_count: Nach Anzahl der Aufgaben - create: Erstellen - contexts: Kontexte fourth: Vierte - context: Kontext + create: Erstellen errors_with_fields: "Mit folgenden Feldern sind Probleme aufgetreten:" description: Beschreibung + context: Kontext + drag_handle: Verschieben + contexts: Kontexte + next: "N\xC3\xA4chste" + todo: Aktione + months: Monate + forth: Vierte update: Aktualisieren - bugs: Bugs + weeks: Woche wiki: Wiki - ajaxError: Fehler beim Empfangen vom Server + bugs: Bugs email: E-Mail + ajaxError: Fehler beim Empfangen vom Server search: Suchen layouts: + toggle_contexts_title: Machen Sie brach Kontexten (un)sichtbare + toggle_contexts: Toggle zusammengebrochen Kontexten toggle_notes: Notizen umschalten next_actions_rss_feed: RSS-Feed kommende Aufgaben toggle_notes_title: Alle Notizen umschalten @@ -63,37 +80,31 @@ de: api_docs: REST API Docs feeds: Feeds starred: Markiert - notes_title: Alle Notizen anzeigen stats: Statistiken - tickler_title: Notizbuch + notes_title: Alle Notizen anzeigen manage_users: Benutzer verwalten - preferences: Einstellungen + tickler_title: Notizbuch export_title: Daten importieren und exportieren + preferences: Einstellungen integrations_: Tracks integrieren calendar_title: "Kalender mit \xC3\xBCberf\xC3\xA4lligen Aufgaben" feeds_title: "Liste der verf\xC3\xBCgbaren Feeds anzeigen" recurring_todos_title: Sich wiederholende To-Dos verwalten completed_tasks: Erledigt stats_title: Statistiken anzeigen - tickler: Notizbuch home_title: Start + tickler: Notizbuch starred_title: Markierte Aufgaben betrachten organize: Organisieren view: Betrachten completed_tasks_title: "Vollst\xC3\xA4ndig" home: Start - export: Export contexts_title: Kontexte + export: Export projects_title: Projekte preferences_title: Meine Einstellungen - calendar: Kalender search: "Alle Eintr\xC3\xA4ge durchsuchen" - integrations: - opensearch_description: In Tracks suchen - gmail_description: "Gadget, um Tracks als Gadget zu Googlemail hinzuzuf\xC3\xBCgen" - applescript_next_action_prompt: "Beschreibung der n\xC3\xA4chsten Aufgabe:" - applescript_success_after_id: erstellt - applescript_success_before_id: "N\xC3\xA4chste neue Aufgabe mit ID" + calendar: Kalender number: format: separator: "," @@ -134,13 +145,15 @@ de: feed_description: "Listet alle Projekte f\xC3\xBCr %{username} auf" todo: error_date_must_be_future: muss ein Datum in der Zukunft sein - preference: - due_styles: - - "F\xC3\xA4llig in ___ Tagen" - - "F\xC3\xA4llig am _______" user: error_context_not_associated: "Kontext-ID %{context} nicht mit Benutzer-ID %{user} verkn\xC3\xBCpft." error_project_not_associated: "Projekt-ID %{project} nicht mit User-ID %{user} verkn\xC3\xBCpft." + preference: + due_on: "F\xC3\xA4llig auf %{date}" + due_in: "F\xC3\xA4llig in %{days} Tagen" + due_styles: + - "F\xC3\xA4llig in ___ Tagen" + - "F\xC3\xA4llig am _______" data: import_successful: Import war erfolgreich. import_errors: Beim Import sind Fehler aufgetreten. @@ -156,19 +169,32 @@ de: predecessors: "H\xC3\xA4ngt ab von" notes: Notizen project: Projekt - context: Kontext description: Beschreibung + context: Kontext due: Fällig - preference: - mobile_todos_per_page: Aufgaben pro Seite (Mobile Version) - sms_context: Standard-E-Mail-Kontext - refresh: Aktualisierungsintverall (in Minuten) - week_starts: Woche startet am - show_project_on_todo_done: Zur Projektseite wechseln, wenn To-Do abgeschlossen - sms_email: Per E-Mail user: last_name: Nachname first_name: Vorname + preference: + show_hidden_projects_in_sidebar: Zeige Versteckte Projekte in der Sidebar + date_format: Datum Format + show_hidden_contexts_in_sidebar: "Zeige Versteckte Zusammenh\xC3\xA4nge in der Sidebar" + mobile_todos_per_page: Aufgaben pro Seite (Mobile Version) + staleness_starts: Anfang des Abgestandenheit + verbose_action_descriptors: "Ausf\xC3\xBChrlich Aktion Deskriptoren" + sms_context: Standard-E-Mail-Kontext + show_number_completed: "Zeige Zahl der abgeschlossenen Ma\xC3\x9Fnahmen" + title_date_format: Titel Datumsformat + refresh: Aktualisierungsintverall (in Minuten) + week_starts: Woche startet am + last_name: Nachname + time_zone: Zeit Zone + due_style: "F\xC3\xA4llig stijl" + locale: Zahle + sms_email: Per E-Mail + show_project_on_todo_done: Zur Projektseite wechseln, wenn To-Do abgeschlossen + first_name: Name + show_completed_projects_in_sidebar: Zeige abgeschlossene Projekte in der Sidebar errors: models: project: @@ -183,275 +209,94 @@ de: less_than_or_equal_to: muss kleiner oder gleich %{count} sein confirmation: "stimmt nicht mit der Best\xC3\xA4tigung \xC3\xBCberein" blank: "muss ausgef\xC3\xBCllt werden" - invalid: "ist nicht g\xC3\xBCltig" exclusion: "ist nicht verf\xC3\xBCgbar" + invalid: "ist nicht g\xC3\xBCltig" odd: muss ungerade sein too_short: ist zu kurz (nicht weniger als %{count} Zeichen) wrong_length: "hat die falsche L\xC3\xA4nge (muss genau %{count} Zeichen haben)" - empty: "muss ausgef\xC3\xBCllt werden" even: muss gerade sein + empty: "muss ausgef\xC3\xBCllt werden" less_than: muss kleiner als %{count} sein equal_to: muss genau %{count} sein greater_than: "muss gr\xC3\xB6\xC3\x9Fer als %{count} sein" too_long: ist zu lang (nicht mehr als %{count} Zeichen) - accepted: muss akzeptiert werden taken: ist bereits vergeben + accepted: muss akzeptiert werden not_a_number: ist keine Zahl inclusion: "ist kein g\xC3\xBCltiger Wert" + full_messages: + format: "%{attribute} %{message}" template: body: "Bitte \xC3\xBCberpr\xC3\xBCfen Sie die folgenden Felder:" header: one: "Konnte dieses %{model} Objekt nicht speichern: 1 Fehler." other: "Konnte dieses %{model} Objekt nicht speichern: %{count} Fehler." - full_messages: - format: "%{attribute} %{message}" - todos: - error_starring_recurring: Konnte die Hervorhebung der wiederkehrenden Aufgabe \'%{description}\' nicht durchführen - show_from: Anzeigen ab dem - recurring_action_deleted: Die Aktion wurde gelöscht. Da dies eine wiederkehrende Aktion ist, wurde eine neue erstellt. - completed_actions: Erledigte Aufgaben - completed_recurring: Abgeschlossene wiederkehrende To-Dos - added_new_next_action: Neue Aktion angelegt - blocked_by: Blockiert durch %{predecessors} - done: Erledigt? - star_action: Aktion markieren - completed_recurrence_completed: Es gibt keine weitere Aktion nach der soeben gelöschten. Die Wiederholung ist abgeschlossen. - defer_date_after_due_date: "Zur\xC3\xBCckstellungsdatum nach Ablaufdatum. Bitte passe das Ablaufdatum an, dass es vor dem Zur\xC3\xBCckstellungsdatum liegt." - unable_to_add_dependency: Abhängigkeit nicht hinzufügbar - star_action_with_description: Aktion '%{description}' markieren - tagged_with: getagged mit ‘%{tag_name}’ - completed: Erledigt - no_deferred_actions_with: "Keine zur\xC3\xBCckgestellten Aktionen mit dem Tag '%{tag_name}'" - no_hidden_actions: Momentan sind keine versteckten Aufgaben vorhanden - edit_action_with_description: Aktion '%{description}' bearbeiten - action_due_on: "(Aktion f\xC3\xA4llig am %{date})" - list_incomplete_next_actions: Unerledigte Folge-Aufgaben anzeigen - archived_tasks_title: TRACKS::Archivierte erledigte Aufgaben - remove_dependency: Abhängigkeit löschen (löscht nicht die Aufgabe) - action_deleted_success: Die nächste Aktion erfolgreich gelöscht - tags: Tags (Komma-separiert) - context_changed: Kontext zu %{name} gewechselt - new_related_todo_created: "Eine neue To-Do wurde hinzugef\xC3\xBCgt, die zu dieser wiederkehrenden To-Do geh\xC3\xB6rt" - mobile_todos_page_title: Alle Aufgaben - add_another_dependency: "F\xC3\xBCgen Sie eine andere Abh\xC3\xA4ngigkeit" - delete_recurring_action_title: "Wiederkehrende Aktion '%{description}' l\xC3\xB6schen" - removed_predecessor: "%{successor} entfernt als Abh\xC3\xA4ngigkeit von %{predecessor}." - recurring_actions_title: TRACKS::Wiederkehrende Aktionen - next_action_needed: Es muss mindestens eine folgende Aktion angelegt werden - action_saved: Aktion gespeichert - scheduled_overdue: "Planm\xC3\xA4\xC3\x9Fig angezeigt vor %{days} Tagen" - action_deleted_error: Fehler beim Löschen der Aufgabe - edit_action: Aktion bearbeiten - added_new_context: "Neuer Kontext hinzugef\xC3\xBCgt" - next_actions_description: "Filter:" - set_to_pending: "%{task} als ausstehend markiert" - list_incomplete_next_actions_with_limit: Zeige die letzten %{count} unerledigten Folge-Aufgaben - added_new_project: "Neues Projekt hinzugef\xC3\xBCgt" - next_actions_title_additions: - completed: Aufgaben erledigt - due_today: heute fällig - due_within_a_week: diese Woche fällig - older_completed_items: "Ältere erledigte Aufgaben" - append_in_this_project: in diesem Projekt - error_deleting_item: Beim Löschen von %{description} trat ein Fehler auf - task_list_title: TRACKS::Aufgaben anzeigen - no_actions_due_this_week: Keine zu erledigenden Aufgaben für den Rest der Woche - no_recurring_todos: Im Augenblick gibt es keine wiederkehrenden To-Dos - error_completing_todo: Beim Abschliessen/Aktivieren der wiederkehrenden To-Do %{description} ist ein Fehler aufgetreten - convert_to_project: In Projekt umwandeln - no_deferred_pending_actions: Momentan sind keine aufgeschobenen oder ausstehenden Aufgaben vorhanden. - completed_last_day: In den letzten 24 Stunden erledigt - delete_recurring_action_confirm: Soll die wiederkehrende Aktion '%{description}' wirklich gelöscht werden? - new_related_todo_created_short: hat einen neuen todo - show_in_days: Anzeigen in %{days} Tagen - no_project: --Kein Projekt-- - error_saving_recurring: Es gab einen Fehler beim Speichern der wiederkehrenden todo '%{description}' - completed_more_than_x_days_ago: Vor mehr als %{count} Tagen erledigt - feed_title_in_context: im Kontext '%{context}' - completed_actions_with: Abgeschlossene Aktionen mit dem Tag %{tag_name} - older_than_days: "Älter als %{count} Tage" - edit: Bearbeiten - pending: Ausstehend - deleted_success: "Die Aktion wurde erfolgreich gel\xC3\xB6scht." - completed_tasks_title: TRACKS::Erledigte Aufgaben - feed_title_in_project: im Projekt '%{project}' - clear_due_date: Fälligkeitsdatum leeren - error_removing_dependency: "Beim Entfernen der Abh\xC3\xA4ngigkeit ist ein Fehler aufgetreten" - hidden_actions: Verstecke Aufgaben - was_due_on_date: war am %{date} fällig - show_on_date: Anzeigen am %{date} - recurrence_period: Wiederholungszeitraum - deferred_actions_with: "Zur\xC3\xBCckgestellte Aktionen mit dem Tag '%{tag_name}'" - confirm_delete: "Bist du sicher, dass du die Aktion '%{description}' l\xC3\xB6schen m\xC3\xB6chtest?" - recurring_deleted_success: "Die wiederkehrende Aktion wurde erfolgreich gel\xC3\xB6scht." - next_actions_title: TRACKS::Weitere Aufgaben - next_action_description: "Beschreibung der n\xC3\xA4chsten Aktion" - deferred_tasks_title: TRACKS::Notizbuch - no_completed_actions_with: Keine abgeschlossenen Aktionen mit dem Tag '%{tag_name}' - clear_show_from_date: Datum leeren - in_hidden_state: als versteckt markiert - calendar_page_title: TRACKS::Kalender - show_today: Heute anzeigen - no_actions_found_title: Keine Aktionen gefunden - completed_last_x_days: In den letzten %{count} Tagen erledigt - no_actions_with: "Im Augenblick gibt es keine unvollst\xC3\xA4ndigen Aktionen mit dem Tag '%{tag_name}'" - defer_x_days: - one: "Einen Tag zur\xC3\xBCckstellen" - other: "%{count} Tage zur\xC3\xBCckstellen" - added_new_next_action_singular: Neue weiterführende Aufgabe angelegt - no_completed_actions: Momentan sind keine erledigten Aufgaben vorhanden. - deferred_pending_actions: Aufgeschobene/ausstehende Aufgaben - has_x_pending: - one: Hat eine ausstehende Aktion - other: Hat %{count} ausstehende Aktionen - feeds: - completed: "Erledigt: %{date}" - due: "F&auuml;llig: %{date}" - delete_action: "Aktion l\xC3\xB6schen" - error_deleting_recurring: "Beim L\xC3\xB6schen der wiederkehrenden To-Do %{description} ist ein Fehler aufgetreten" - recurring_todos: Wiederkehrende To-Dos - delete: "L\xC3\xB6schen" - drag_action_title: "Auf andere Aktion ziehen, um sie als Abh\xC3\xA4ngigkeit zu definieren" - cannot_add_dependency_to_completed_todo: "Kann nicht hinzugef\xC3\xBCgt werden diese Aktion als eine Abh\xC3\xA4ngigkeit zu einer abgeschlossenen Aktion!" - depends_on: "H\xC3\xA4ngt ab von" - tickler_items_due: - one: Ein Notizbuch-Eintrag ist nun fällig - lade die Seite neu, um sie zu sehen. - other: "%{count} Notizbuch-Einträge sind nun fällig - lade die Seite neu, um sie zu sehen." - action_marked_complete: Die Aktion '%{description}' wurde als %{completed} markiert. - completed_today: - one: Du hast heute bereits eine Aufgabe erledigt. - other: Du hast heute bereits %{count} Aufgaben erledigt. - added_new_next_action_plural: Neue weiterführende Aufgaben angelegt - new_related_todo_not_created_short: nicht schaffen todo - error_starring: Konnte die Hervorhebung von \'%{description}\' nicht durchführen - show_tomorrow: Morgen anzeigen - calendar: - get_in_ical_format: Diesen Kalender im iCal Format herunterladen - due_next_week: Nächste Woche fällig - due_this_week: Die restliche Woche zu erledigen - no_actions_due_next_week: Keine Aufgaben für die kommende Woche - due_today: Heute zu erledigen - no_actions_due_today: Heute sind keine Aufgaben fällig - due_next_month_and_later: Im %{month} und später fällig - no_actions_due_after_this_month: Nach diesem Monat sind keine Aufgaben fällig - due_this_month: Im %{month} fällig - no_actions_due_this_month: Keine Aktionen für den Rest des Monats - tagged_page_title: TRACKS::Als '%{tag_name}' markiert - recurrence: - every_work_day: Jeden Arbeitstag - ends_on_number_times: Endet nach %{number} Mal - ends_on_date: Endet am %{date} - recurrence_on_due_date: Das Datum der To-Do ist verstrichen. - weekly_options: "Einstellungen f\xC3\xBCr sich w\xC3\xB6chentlich wiederholende Aktionen" - weekly: "W\xC3\xB6chentlich" - monthly_options: "Einstellungen f\xC3\xBCr sich monatlich wiederholende Aktionen" - starts_on: Beginnt am - daily_options: "Einstellungen f\xC3\xBCr sich t\xC3\xA4glich wiederholenden Aktionen" - monthly: Monatlich - daily: "T\xC3\xA4glich" - show_option_always: immer - recurrence_on_options: Setze Wiederholung auf - yearly_every_x_day: "Jeden %{day}. %{month} " - daily_every_number_day: Alle %{number} Tage - ends_on: Endet am - weekly_every_number_week: Kehrt jede %{number}. Woche wieder am - show_options: To-Do anzeigen - yearly_options: "Einstellungen f\xC3\xBCr sich j\xC3\xA4hrlich wiederholende Aktionen" - show_days_before: "%{days} Tage bevor die To-Do f\xC3\xA4llig ist" - yearly_every_xth_day: Den %{day} %{day_of_week} des %{month} - from_tickler: the date todo comes from tickler (no due date set) - no_end_date: Kein Enddatum - day_x_on_every_x_month: Tag %{day} in jedem %{month}. Monat - monthly_every_xth_day: Der %{day} %{day_of_week} eines jeden %{month}. Monats - yearly: "J\xC3\xA4hrlich" - no_completed_recurring: Im Augenblick gibt es keine abgeschlossenen wiederkehrenden To-Dos - added_dependency: "%{dependency} als Abhängigkeit hinzugefügt." - no_deferred_actions: Zur Zeit sind keine zurückgestellten Aktionen vorhanden. - recurrence_completed: Nach dieser wiederkehrenden Aktion, die du gerade abgeschlossen hast, folgt keine mehr. Die Wiederholung endet hiermit - no_actions_found: "Momentan gibt es keine unvollst\xC3\xA4ndigen Aktionen." - in_pending_state: und als ausstehend markiert - error_toggle_complete: "K\xC3\xB6nnte nicht diese Marke todo komplett" - due: Fällig - action_marked_complete_error: Die Aktion '%{description}' wurde aufgrund eines Fehlers NICHT als %{completed} markiert. - action_saved_to_tickler: Aktion im Notizbuch gespeichert - depends_on_separate_with_commas: Hängt ab von (Komma-separiert) - recurring_action_saved: Wiederkehrende Aktion gespeichert - completed_in_archive: - one: Es befindet sich eine erledigte Aufgabe im Archiv. - other: Es befinden sich %{count} erledigte Aufgaben im Archiv. - to_tickler: ", im Notizbuch hinterlegt" - next_actions_description_additions: - completed: In den letzten %{count} Tagen - due_date: mit einem Datum %{due_date} oder früher - overdue: "Überfällig" - add_new_recurring: "F\xC3\xBCge eine neue wiederkehrende Aktion hinzu" - no_incomplete_actions: Es gibt keine unerledigten Aufgaben stats: - tag_cloud_description: Diese Tag-Cloud beinhaltet Tags aller Aktionen (abgeschlossen, nicht abgeschlossen, sichtbar und/oder unsichtbar) tag_cloud_90days_title: Tag-Cloud-Aktionen in den letzten 90 Tagen - actions: Aktionen totals_active_project_count: Von diesen sind %{count} aktive Projekte + actions: Aktionen tag_cloud_title: Tag-Cloud aller Aktionen + tag_cloud_description: Diese Tag-Cloud beinhaltet Tags aller Aktionen (abgeschlossen, nicht abgeschlossen, sichtbar und/oder unsichtbar) + actions_avg_completion_time: Durchschnittlich hast du %{count} Tage gebraucht, um eine Aktion abzuschliessen. actions_last_year_legend: number_of_actions: Anzahl Aktionen months_ago: Monate zuvor totals_first_action: Seit deiner ersten Aktion am %{date} - actions_avg_completion_time: Durchschnittlich hast du %{count} Tage gebraucht, um eine Aktion abzuschliessen. - totals_action_count: hattest du insgesamt %{count} Aktionen - legend: - number_of_days: Anzahl vergangene Tage - actions: Aktionen - number_of_actions: Anzahl Aktionen - day_of_week: Wochentag - running_time: Laufzeit einer Aktion (Wochen) - percentage: Prozentsatz - months_ago: Monate zuvor top10_longrunning: "Top 10 der am l\xC3\xA4ngsten laufenden Projekte" - actions_dow_30days_title: Wochentag (letzte 30 Tage) - totals_deferred_actions: "von denen %{count} im Notizbuch zur\xC3\xBCckgestellt sind" - current_running_time_of_incomplete_visible_actions: "Aktuelle Laufzeit unvollst\xC3\xA4ndiger sichtbarer Aufgaben" + totals_action_count: hattest du insgesamt %{count} Aktionen running_time_legend: actions: Aufgaben percentage: Prozentsatz weeks: "Vergangene Zeit einer Aktion (Wochen). Klick auf eine Leiste f\xC3\xBCr mehr Informationen." + totals_deferred_actions: "von denen %{count} im Notizbuch zur\xC3\xBCckgestellt sind" + current_running_time_of_incomplete_visible_actions: "Aktuelle Laufzeit unvollst\xC3\xA4ndiger sichtbarer Aufgaben" + legend: + actions: Aktionen + number_of_days: Anzahl vergangene Tage + number_of_actions: Anzahl Aktionen + day_of_week: Wochentag + percentage: Prozentsatz + running_time: Laufzeit einer Aktion (Wochen) + months_ago: Monate zuvor + actions_dow_30days_title: Wochentag (letzte 30 Tage) + totals_actions_completed: "%{count} davon sind abgeschlossen." totals_incomplete_actions: "Du hast %{count} unvollst\xC3\xA4ndige Aktionen" totals_unique_tags: Von diesen Tags sind %{count} einmalig.. actions_avg_completed_30days: und %{count} durchschnittlich davon erledigt. top5_contexts: Top 5 aller Kontexte actions_lastyear_title: Aktionen der letzten 12 Monate - totals_actions_completed: "%{count} davon sind abgeschlossen." actions_last_year: Aktionen im letzten Jahr totals_context_count: Du hast %{count} Kontexte. totals_visible_context_count: Von diesen sind %{count} sichtbare Kontexte - totals_blocked_actions: "%{count} h\xC3\xA4ngen vom Abschluss anderer Aktionen ab." projects: Projekte + totals_blocked_actions: "%{count} h\xC3\xA4ngen vom Abschluss anderer Aktionen ab." action_completion_time_title: Fertigstellungszeit (alle abgeschlossenen Aktionen) + no_tags_available: "keine Tags verf\xC3\xBCgbar" actions_day_of_week_title: Wochentag (alle Aktionen) tags: Tags totals_project_count: Du hast %{count} Projekte. actions_min_max_completion_days: "Das Minimum/Maximum an Tagen einer Vervollst\xC3\xA4ndigung ist %{min}/%{max}." actions_min_completion_time: "Die minimale Zeit betr\xC3\xA4gt %{time}." - no_tags_available: "keine Tags verf\xC3\xBCgbar" - totals_hidden_project_count: "%{count} sind versteckt" - tag_cloud_90days_description: Diese Tag-Cloud beinhaltet Tags der Aktionen, die in den letzten 90 Tagen erstellt oder abgeschlossen wurden. - more_stats_will_appear: "Weitere Statistiken werden verf\xC3\xBCgbar, wenn einige Aufgaben hinzugef\xC3\xBCgt wurden." - running_time_all: "Aktuelle Laufzeit aller unvollst\xC3\xA4ndigen Aktionen." - totals_tag_count: Du hast %{count} Tags in Aktionen. - top5_visible_contexts_with_incomplete_actions: "Top 5 der sichtbaren Kontexte mit unvollst\xC3\xA4ndigen Aktionen" time_of_day: Tageszeit (alle Aktionen) - actions_further: und danach + totals_tag_count: Du hast %{count} Tags in Aktionen. + tag_cloud_90days_description: Diese Tag-Cloud beinhaltet Tags der Aktionen, die in den letzten 90 Tagen erstellt oder abgeschlossen wurden. actions_30days_title: _Aktionen der letzten 30 Tage + actions_further: und danach tod30: Tageszeit (letzte 30 Tage) + running_time_all: "Aktuelle Laufzeit aller unvollst\xC3\xA4ndigen Aktionen." + totals_hidden_project_count: "%{count} sind versteckt" + top5_visible_contexts_with_incomplete_actions: "Top 5 der sichtbaren Kontexte mit unvollst\xC3\xA4ndigen Aktionen" + more_stats_will_appear: "Weitere Statistiken werden verf\xC3\xBCgbar, wenn einige Aufgaben hinzugef\xC3\xBCgt wurden." + top10_projects_30days: Top-10-Projekt der letzten 30 Tage + click_to_show_actions_from_week: Klick auf %{link} um die Aktionen von Woche %{week} und danach anzuzeigen. + spread_of_actions_for_all_context: Aufgabenverteilung aller Kontexte + actions_selected_from_week: "Aktionen ausgew\xC3\xA4hlt ab Woche" top10_projects: Top 10 aller Projekte other_actions_label: (andere) spread_of_running_actions_for_visible_contexts: Verteilung der laufenden Aufgaben aller sichtbaren Kontexte - totals_completed_project_count: und %{count} sind abgeschlossene Projekte. - spread_of_actions_for_all_context: Aufgabenverteilung aller Kontexte - click_to_return: "Klick auf %{link} um zur Statistikseite zur\xC3\xBCckzukehren." - top10_projects_30days: Top-10-Projekt der letzten 30 Tage actions_avg_created: In den letzten 12 Monaten hast du im Durchschnitt %{count} Aktionen erstellt - actions_selected_from_week: "Aktionen ausgew\xC3\xA4hlt ab Woche" - click_to_show_actions_from_week: Klick auf %{link} um die Aktionen von Woche %{week} und danach anzuzeigen. + click_to_return: "Klick auf %{link} um zur Statistikseite zur\xC3\xBCckzukehren." + totals_completed_project_count: und %{count} sind abgeschlossene Projekte. totals: Ingesamt time_of_day_legend: number_of_actions: Anzahl Aufgaben @@ -460,12 +305,12 @@ de: totals_hidden_context_count: und %{count} sind versteckte Kontexte. contexts: Kontexte actions_avg_completed: und %{count} durchschnittlich davon monatlich erledigt - no_actions_selected: "Es sind keine Aufgaben ausgew\xC3\xA4hlt." - click_to_update_actions: Klicke auf eine Leiste in der Grafik um die Aktionen unten zu aktualisieren. running_time_all_legend: actions: Aktionen - running_time: "Laufzeit einer Aktion (Wochen). Klick auf eine Leiste f\xC3\xBCr mehr Informationen." percentage: Prozentsatz + running_time: "Laufzeit einer Aktion (Wochen). Klick auf eine Leiste f\xC3\xBCr mehr Informationen." + no_actions_selected: "Es sind keine Aufgaben ausgew\xC3\xA4hlt." + click_to_update_actions: Klicke auf eine Leiste in der Grafik um die Aktionen unten zu aktualisieren. labels: month_avg_completed: "%{months} Monat durchschnittlich fertig gestellt" completed: Erledigt @@ -478,46 +323,284 @@ de: time_of_day: Tageszeit action_selection_title: TRACKS::Aktionsauswahl actions_actions_avg_created_30days: In den letzten 30 Tagen hast du im Durchschnitt %{count} Aktionen erstellt + todos: + show_from: Anzeigen ab dem + error_starring_recurring: Konnte die Hervorhebung der wiederkehrenden Aufgabe \'%{description}\' nicht durchführen + recurring_action_deleted: Die Aktion wurde gelöscht. Da dies eine wiederkehrende Aktion ist, wurde eine neue erstellt. + completed_actions: Erledigte Aufgaben + completed_recurring: Abgeschlossene wiederkehrende To-Dos + added_new_next_action: Neue Aktion angelegt + completed_rest_of_previous_month: Fertiggestellt den Rest des Vormonats + blocked_by: Blockiert durch %{predecessors} + unable_to_add_dependency: Abhängigkeit nicht hinzufügbar + star_action: Aktion markieren + completed_recurrence_completed: Es gibt keine weitere Aktion nach der soeben gelöschten. Die Wiederholung ist abgeschlossen. + defer_date_after_due_date: "Zur\xC3\xBCckstellungsdatum nach Ablaufdatum. Bitte passe das Ablaufdatum an, dass es vor dem Zur\xC3\xBCckstellungsdatum liegt." + done: Erledigt? + star_action_with_description: Aktion '%{description}' markieren + tagged_with: getagged mit ‘%{tag_name}’ + completed: Erledigt + no_deferred_actions_with: "Keine zur\xC3\xBCckgestellten Aktionen mit dem Tag '%{tag_name}'" + no_hidden_actions: Momentan sind keine versteckten Aufgaben vorhanden + edit_action_with_description: Aktion '%{description}' bearbeiten + action_due_on: "(Aktion f\xC3\xA4llig am %{date})" + action_deleted_success: Die nächste Aktion erfolgreich gelöscht + archived_tasks_title: TRACKS::Archivierte erledigte Aufgaben + remove_dependency: Abhängigkeit löschen (löscht nicht die Aufgabe) + list_incomplete_next_actions: Unerledigte Folge-Aufgaben anzeigen + tags: Tags (Komma-separiert) + new_related_todo_created: "Eine neue To-Do wurde hinzugef\xC3\xBCgt, die zu dieser wiederkehrenden To-Do geh\xC3\xB6rt" + context_changed: Kontext zu %{name} gewechselt + mobile_todos_page_title: Alle Aufgaben + add_another_dependency: "F\xC3\xBCgen Sie eine andere Abh\xC3\xA4ngigkeit" + delete_recurring_action_title: "Wiederkehrende Aktion '%{description}' l\xC3\xB6schen" + removed_predecessor: "%{successor} entfernt als Abh\xC3\xA4ngigkeit von %{predecessor}." + recurring_actions_title: TRACKS::Wiederkehrende Aktionen + next_action_needed: Es muss mindestens eine folgende Aktion angelegt werden + action_deleted_error: Fehler beim Löschen der Aufgabe + action_saved: Aktion gespeichert + scheduled_overdue: "Planm\xC3\xA4\xC3\x9Fig angezeigt vor %{days} Tagen" + next_actions_description: "Filter:" + edit_action: Aktion bearbeiten + added_new_context: "Neuer Kontext hinzugef\xC3\xBCgt" + added_new_project: "Neues Projekt hinzugef\xC3\xBCgt" + list_incomplete_next_actions_with_limit: Zeige die letzten %{count} unerledigten Folge-Aufgaben + set_to_pending: "%{task} als ausstehend markiert" + next_actions_title_additions: + completed: Aufgaben erledigt + due_today: heute fällig + due_within_a_week: diese Woche fällig + older_completed_items: "Ältere erledigte Aufgaben" + append_in_this_project: in diesem Projekt + error_deleting_item: Beim Löschen von %{description} trat ein Fehler auf + task_list_title: TRACKS::Aufgaben anzeigen + no_actions_due_this_week: Keine zu erledigenden Aufgaben für den Rest der Woche + delete_recurring_action_confirm: Soll die wiederkehrende Aktion '%{description}' wirklich gelöscht werden? + no_recurring_todos: Im Augenblick gibt es keine wiederkehrenden To-Dos + error_completing_todo: Beim Abschliessen/Aktivieren der wiederkehrenden To-Do %{description} ist ein Fehler aufgetreten + recurring_pattern_removed: Das Wiederauftreten Muster ist aus entfernt %{count} + convert_to_project: In Projekt umwandeln + no_deferred_pending_actions: Momentan sind keine aufgeschobenen oder ausstehenden Aufgaben vorhanden. + completed_last_day: In den letzten 24 Stunden erledigt + new_related_todo_created_short: hat einen neuen todo + no_project: --Kein Projekt-- + show_in_days: Anzeigen in %{days} Tagen + error_saving_recurring: Es gab einen Fehler beim Speichern der wiederkehrenden todo '%{description}' + completed_more_than_x_days_ago: Vor mehr als %{count} Tagen erledigt + all_completed: Alle abgeschlossenen Aktionen + feed_title_in_context: im Kontext '%{context}' + pending: Ausstehend + older_than_days: "Älter als %{count} Tage" + completed_tagged_page_title: "TRACKS:: Erledigte Aufgaben mit Tag %{tag_name}" + edit: Bearbeiten + completed_actions_with: Abgeschlossene Aktionen mit dem Tag %{tag_name} + deleted_success: "Die Aktion wurde erfolgreich gel\xC3\xB6scht." + completed_tasks_title: TRACKS::Erledigte Aufgaben + feed_title_in_project: im Projekt '%{project}' + clear_due_date: Fälligkeitsdatum leeren + error_removing_dependency: "Beim Entfernen der Abh\xC3\xA4ngigkeit ist ein Fehler aufgetreten" + hidden_actions: Verstecke Aufgaben + show_on_date: Anzeigen am %{date} + was_due_on_date: war am %{date} fällig + recurrence_period: Wiederholungszeitraum + deferred_actions_with: "Zur\xC3\xBCckgestellte Aktionen mit dem Tag '%{tag_name}'" + confirm_delete: "Bist du sicher, dass du die Aktion '%{description}' l\xC3\xB6schen m\xC3\xB6chtest?" + recurring_deleted_success: "Die wiederkehrende Aktion wurde erfolgreich gel\xC3\xB6scht." + next_action_description: "Beschreibung der n\xC3\xA4chsten Aktion" + next_actions_title: TRACKS::Weitere Aufgaben + deferred_tasks_title: TRACKS::Notizbuch + no_completed_actions_with: Keine abgeschlossenen Aktionen mit dem Tag '%{tag_name}' + clear_show_from_date: Datum leeren + calendar_page_title: TRACKS::Kalender + unresolved_dependency: "Der Wert, den Sie in die Abh\xC3\xA4ngigkeit Feld eingegeben nicht zu einer bestehenden Aktion zu l\xC3\xB6sen. Dieser Wert wird nicht mit dem Rest der Aktion gerettet werden. Weiter gehen?" + in_hidden_state: als versteckt markiert + completed_last_x_days: In den letzten %{count} Tagen erledigt + show_today: Heute anzeigen + no_actions_found_title: Keine Aktionen gefunden + next_actions_due_date: + overdue_by: "\xC3\x9Cberf\xC3\xA4llig mit %{days} Tag" + due_today: "Heute f\xC3\xA4llig" + due_in_x_days: "F\xC3\xA4llig in %{days} Tagen" + overdue_by_plural: "\xC3\x9Cberf\xC3\xA4llig mit %{days} Tagen" + due_tomorrow: "F\xC3\xA4llig morgen" + added_new_next_action_singular: Neue weiterführende Aufgabe angelegt + no_actions_with: "Im Augenblick gibt es keine unvollst\xC3\xA4ndigen Aktionen mit dem Tag '%{tag_name}'" + defer_x_days: + one: "Einen Tag zur\xC3\xBCckstellen" + other: "%{count} Tage zur\xC3\xBCckstellen" + no_completed_actions: Momentan sind keine erledigten Aufgaben vorhanden. + has_x_pending: + one: Hat eine ausstehende Aktion + other: Hat %{count} ausstehende Aktionen + feeds: + completed: "Erledigt: %{date}" + due: "F&auuml;llig: %{date}" + deferred_pending_actions: Aufgeschobene/ausstehende Aufgaben + delete_action: "Aktion l\xC3\xB6schen" + error_deleting_recurring: "Beim L\xC3\xB6schen der wiederkehrenden To-Do %{description} ist ein Fehler aufgetreten" + recurring_todos: Wiederkehrende To-Dos + delete: "L\xC3\xB6schen" + drag_action_title: "Auf andere Aktion ziehen, um sie als Abh\xC3\xA4ngigkeit zu definieren" + cannot_add_dependency_to_completed_todo: "Kann nicht hinzugef\xC3\xBCgt werden diese Aktion als eine Abh\xC3\xA4ngigkeit zu einer abgeschlossenen Aktion!" + no_last_completed_actions: Keine abgeschlossene Aktionen gefunden + depends_on: "H\xC3\xA4ngt ab von" + tickler_items_due: + one: Ein Notizbuch-Eintrag ist nun fällig - lade die Seite neu, um sie zu sehen. + other: "%{count} Notizbuch-Einträge sind nun fällig - lade die Seite neu, um sie zu sehen." + action_marked_complete: Die Aktion '%{description}' wurde als %{completed} markiert. + new_related_todo_not_created_short: nicht schaffen todo + completed_today: Heute Fertiggestellt + added_new_next_action_plural: Neue weiterführende Aufgaben angelegt + completed_rest_of_week: Fertiggestellt den Rest dieser Woche + calendar: + get_in_ical_format: Diesen Kalender im iCal Format herunterladen + due_next_week: Nächste Woche fällig + no_actions_due_next_week: Keine Aufgaben für die kommende Woche + due_this_week: Die restliche Woche zu erledigen + due_today: Heute zu erledigen + no_actions_due_today: Heute sind keine Aufgaben fällig + due_next_month_and_later: Im %{month} und später fällig + no_actions_due_after_this_month: Nach diesem Monat sind keine Aufgaben fällig + due_this_month: Im %{month} fällig + no_actions_due_this_month: Keine Aktionen für den Rest des Monats + error_starring: Konnte die Hervorhebung von \'%{description}\' nicht durchführen + show_tomorrow: Morgen anzeigen + action_deferred: Die Aktion \'% {description}\' wurde vertagt + recurrence: + ends_on_date: Endet am %{date} + every_work_day: Jeden Arbeitstag + ends_on_number_times: Endet nach %{number} Mal + recurrence_on_due_date: Das Datum der To-Do ist verstrichen. + weekly_options: "Einstellungen f\xC3\xBCr sich w\xC3\xB6chentlich wiederholende Aktionen" + weekly: "W\xC3\xB6chentlich" + monthly_options: "Einstellungen f\xC3\xBCr sich monatlich wiederholende Aktionen" + monthly: Monatlich + starts_on: Beginnt am + daily_options: "Einstellungen f\xC3\xBCr sich t\xC3\xA4glich wiederholenden Aktionen" + pattern: + third: Drittel + month_names: + - + - Januar + - Februar + - !binary | + TcOkcno= + + - April + - Mai + - Juni + - Juli + - August + - September + - Oktober + - November + - Dezember + every_n: jeden %{n} + second: zweite + every_xth_day_of_every_n_months: "jedes %{x} %{day} jedes %{n_months} \xE2\x80\x8B" + on_day_n: am Tag %{n} + weekly: "w\xC3\xB6chentlich" + from: von + last: zuletzt + every_day: jeden Tag + the_xth_day_of_month: der %{x} %{day} von %{month} + times: "f\xC3\xBCr %{number} Zeiten" + day_names: + - Sonntag + - Montag + - Dienstag + - Mittwoch + - Donnerstag + - Freitag + - Samstag + on_work_days: an Wochentagen + every_year_on: jedes Jahr in %{date} + first: erste + show: Show + fourth: vierte + due: "F\xC3\xA4llig" + until: bis + every_month: jeden Monat + show_option_always: immer + daily: "T\xC3\xA4glich" + recurrence_on_options: Setze Wiederholung auf + yearly_every_x_day: "Jeden %{day}. %{month} " + daily_every_number_day: Alle %{number} Tage + show_options: To-Do anzeigen + weekly_every_number_week: Kehrt jede %{number}. Woche wieder am + ends_on: Endet am + yearly_options: "Einstellungen f\xC3\xBCr sich j\xC3\xA4hrlich wiederholende Aktionen" + show_days_before: "%{days} Tage bevor die To-Do f\xC3\xA4llig ist" + from_tickler: the date todo comes from tickler (no due date set) + yearly_every_xth_day: Den %{day} %{day_of_week} des %{month} + no_end_date: Kein Enddatum + day_x_on_every_x_month: Tag %{day} in jedem %{month}. Monat + yearly: "J\xC3\xA4hrlich" + monthly_every_xth_day: Der %{day} %{day_of_week} eines jeden %{month}. Monats + tagged_page_title: TRACKS::Als '%{tag_name}' markiert + no_completed_recurring: Im Augenblick gibt es keine abgeschlossenen wiederkehrenden To-Dos + added_dependency: "%{dependency} als Abhängigkeit hinzugefügt." + all_completed_tagged_page_title: "TRACKS:: Alle erledigten Aufgaben mit Tag %{tag_name}" + no_deferred_actions: Zur Zeit sind keine zurückgestellten Aktionen vorhanden. + completed_rest_of_month: Fertiggestellt den Rest des Monats + recurrence_completed: Nach dieser wiederkehrenden Aktion, die du gerade abgeschlossen hast, folgt keine mehr. Die Wiederholung endet hiermit + no_actions_found: "Momentan gibt es keine unvollst\xC3\xA4ndigen Aktionen." + in_pending_state: und als ausstehend markiert + error_toggle_complete: "K\xC3\xB6nnte nicht diese Marke todo komplett" + due: Fällig + action_marked_complete_error: Die Aktion '%{description}' wurde aufgrund eines Fehlers NICHT als %{completed} markiert. + next_actions_description_additions: + completed: In den letzten %{count} Tagen + due_date: mit einem Datum %{due_date} oder früher + action_saved_to_tickler: Aktion im Notizbuch gespeichert + overdue: "Überfällig" + recurring_action_saved: Wiederkehrende Aktion gespeichert + depends_on_separate_with_commas: Hängt ab von (Komma-separiert) + completed_in_archive: + one: Es befindet sich eine erledigte Aufgabe im Archiv. + other: Es befinden sich %{count} erledigte Aufgaben im Archiv. + to_tickler: ", im Notizbuch hinterlegt" + no_incomplete_actions: Es gibt keine unerledigten Aufgaben + add_new_recurring: "F\xC3\xBCge eine neue wiederkehrende Aktion hinzu" notes: delete_note_title: Notiz '%{id}' löschen delete_confirmation: "Bist du sicher, dass du die Notiz '%{id}' l\xC3\xB6schen m\xC3\xB6chtest?" delete_item_title: Eintrag löschen - show_note_title: Notiz anzeigen deleted_note: "Notiz '%{id}' l\xC3\xB6schen" note_link_title: Notiz %{id} anzeigen + show_note_title: Notiz anzeigen note_location_link: "In:" edit_item_title: Eintrag bearbeiten - note_header: Notiz %{id} no_notes_available: "Derzeit gibt es keine Notizen: f\xC3\xBCge Notizen von der jeweiligen Projektseite hinzu." + note_header: Notiz %{id} delete_note_confirm: Soll die Notiz '%{id}' wirklich gelöscht werden? - time: - am: vormittags - formats: - default: "%A, %d. %B %Y, %H:%M Uhr" - time: "%H:%M" - short: "%d. %B, %H:%M Uhr" - long: "%A, %d. %B %Y, %H:%M Uhr" - pm: nachmittags preferences: open_id_url: "Deine OpenID-URL lautet:" + staleness_starts_after: Abgestandenheit startet nach %{days} Tagen change_identity_url: "\xC3\x84ndere deine Identit\xC3\xA4ts-URL" - staleness_starts_after: Staleness starts after %{days} days - page_title: TRACKS::Einstellungen change_password: "Passwort \xC3\xA4ndern" - title: Deine Einstellungen + page_title: TRACKS::Einstellungen token_description: "Token (f\xC3\xBCr die Verwendung in Feeds und der API)" - show_number_completed: "Zeige %{number} erledigte Eintr\xC3\xA4ge" + title: Deine Einstellungen is_false: Nein - edit_preferences: Einstellungen bearbeiten + show_number_completed: "Zeige %{number} erledigte Eintr\xC3\xA4ge" page_title_edit: "TRACKS::Einstellungen \xC3\xA4ndern" is_true: Ja + edit_preferences: Einstellungen bearbeiten sms_context_none: Keine generate_new_token: Neues Token generieren token_header: Dein Token - authentication_header: Deine Authentifizierung current_authentication_type: Dein Authentifizierungsart ist %{auth_type} + authentication_header: Deine Authentifizierung change_authentication_type: "Authentifzierungsart \xC3\xA4ndern" generate_new_token_confirm: "Bist du sicher? Wenn du ein neues Token generierst, wird dies das alte Token ersetzen und jegliche externe Nutzung st\xC3\xB6ren, die das alte Token verwendet." + tabs: + authentication: Authentication + tracks_behavior: Tracks Verhalten + profile: Profil + date_and_time: Datum und Uhrzeit + errors: + user_unauthorized: "401 Unauthorized: Nur administrative Benutzer d\xC3\xBCrfen auf diese Funktion zugreifen." projects: default_context_set: Standard-Kontext des Projekts auf %{default_context} gesetzt no_actions_in_project: "Momentan gibt es keine unvollst\xC3\xA4ndigen Aktionen in diesem Projekt" @@ -525,48 +608,53 @@ de: was_marked_hidden: wurde als verborgen markiert edit_project_title: Projekt bearbeiten default_tags_removed_notice: Standard-Tags entfernt + all_completed_tasks_title: "TRACKS:: Alle auflisten Abgeschlossene Aktionen in Project '%{project_name}'" hide_form: Fomular verstecken page_title: "TRACKS::Projekt: %{project}" - project_state: Projekt ist %{state} - show_form_title: Neues Projekt anlegen to_new_project_page: Zu neuem Projekt weiterleiten - no_notes_attached: "Im Augenblick sind keine Notizen mit diesem Projekt verkn\xC3\xBCpft." deferred_actions_empty: "Es gibt keine aufgeschobenen Aufgaben f\xC3\xBCr dieses Projekt" + show_form_title: Neues Projekt anlegen this_project: Dieses Projekt - notes: Notizen + project_state: Projekt ist %{state} + list_completed_projects: "TRACKS:: Liste Abgeschlossene Projekte" + no_notes_attached: "Im Augenblick sind keine Notizen mit diesem Projekt verkn\xC3\xBCpft." + no_last_completed_recurring_todos: Keine abgeschlossene sich wiederholende To-Dos gefunden todos_append: an dieses Projekt - hide_form_title: Formular verstecken + notes: Notizen + no_last_completed_projects: Keine abgeschlossene Projekte gefunden notes_empty: "Es gibt keine Notizen f\xC3\xBCr dieses Projekt" no_projects: Keine Projekte vorhanden + hide_form_title: Formular verstecken + delete_project: Projekt löschen completed_actions_empty: "Es gibt keine erledigten Aufgaben f\xC3\xBCr dieses Projekt" with_no_default_context: hat keinen Standardwert Kontext - delete_project: Projekt löschen - delete_project_confirmation: Soll das Projekt '%{name}' wirklich gelöscht werden? - with_default_context: mit einem Standard-Rahmen von '%{context_name}' show_form: Projekt erstellen actions_in_project_title: Die Aktionen in diesem Projekt - add_project: Projekt hinzufügen - with_default_tags: und mit '%{tags}' als Standard-Tags - set_default_tags_notice: Standard-Tags des Projekts auf %{default_tags} setzen + delete_project_confirmation: Soll das Projekt '%{name}' wirklich gelöscht werden? + with_default_context: mit einem Standard-Rahmen von '%{context_name}' + project_saved_status: Projekt gespeichert + is_active: ist aktiv completed_projects: Abgeschlossene Projekte add_note: "Notiz hinzuf\xC3\xBCgen" - is_active: ist aktiv - project_saved_status: Projekt gespeichert + add_project: Projekt hinzufügen list_projects: TRACKS::Projektliste + with_default_tags: und mit '%{tags}' als Standard-Tags settings: Einstellungen - hidden_projects: Versteckte Projekte + set_default_tags_notice: Standard-Tags des Projekts auf %{default_tags} setzen delete_project_title: Projekt löschen - default_context_removed: Standard-Kontext entfernt - completed_actions: "Erledigte Aufgaben f\xC3\xBCr dieses Projekt" + hidden_projects: Versteckte Projekte + completed_tasks_title: "TRACKS:: Liste Abgeschlossene Aktionen in Project '%{project_name}'" add_note_submit: "Notiz hinzuf\xC3\xBCgen" + completed_actions: "Erledigte Aufgaben f\xC3\xBCr dieses Projekt" was_marked_complete: wurde als erledigt markiert - edit_project_settings: Edit Project Settings + default_context_removed: Standard-Kontext entfernt state: Dieses Projekt ist %{state} status_project_name_changed: "Projektname ge\xC3\xA4ndert" default_context: Der Standard-Kontext dieses Projektes ist %{context} - no_default_context: Dieses Projekt hat keinen Standard-Kontext active_projects: Aktive Projekte + no_default_context: Dieses Projekt hat keinen Standard-Kontext with_no_default_tags: und hat keinen Standardwert Tags + edit_project_settings: Edit Project Settings states: hidden_plural: Versteckte completed: Erledigt @@ -574,10 +662,17 @@ de: visible_plural: Sichtbare active_plural: Aktive visible: Sichtbar - active: Aktiv hidden: Versteckt - errors: - user_unauthorized: "401 Unauthorized: Nur administrative Benutzer d\xC3\xBCrfen auf diese Funktion zugreifen." + active: Aktiv + time: + am: vormittags + formats: + default: "%A, %d. %B %Y, %H:%M Uhr" + time: "%H:%M" + short: "%d. %B, %H:%M Uhr" + month_day: "%d. %B" + long: "%A, %d. %B %Y, %H:%M Uhr" + pm: nachmittags date: month_names: - @@ -595,10 +690,6 @@ de: - Oktober - November - Dezember - order: - - :day - - :month - - :year abbr_day_names: - So - Mo @@ -607,10 +698,16 @@ de: - Do - Fr - Sa + order: + - :day + - :month + - :year formats: only_day: "%e" + longer: "%A, %d. %B %Y" default: "%d.%m.%Y" short: "%e. %b" + month_day: "%d. %B" long: "%e. %B %Y" day_names: - Sonntag @@ -636,10 +733,29 @@ de: - Okt - Nov - Dez + will_paginate: + previous_label: !binary | + wqsgWnVyw7xjaw== + + page_entries_info: + multi_page: Angezeigte %{model} %{from} - %{to} von %{count} insgesamt + single_page_html: + one: Angezeigte 1 %{model} + other: Anzeige aller %{count} %{model} + zero: Kein %{model} gefunden + single_page: + one: Angezeigte 1 %{model} + other: Anzeige aller %{count} %{model} + zero: Kein %{model} gefunden + multi_page_html: Angezeigte %{model} %{from} - %{to} von %{count} insgesamt + page_gap: ... + next_label: !binary | + TsOkY2hzdGUgwrs= + support: array: - words_connector: ", " last_word_connector: " und " + words_connector: ", " two_words_connector: " und " select: prompt: "Bitte w\xC3\xA4hlen Sie" @@ -647,110 +763,19 @@ de: send_feedback: Senden Sie Feedback zu %{version} shared: multiple_next_actions: Mehrere neue Aufgaben (eine pro Zeile) + make_actions_dependent: "Machen Sie Aktionen voneinander abh\xC3\xA4ngig" hide_form: Formular verstecken toggle_single: Weitere Aktion erstellen - add_action: "Aufgabe hinzuf\xC3\xBCgen" add_actions: "Aufgaben hinzuf\xC3\xBCgen" + add_action: "Aufgabe hinzuf\xC3\xBCgen" tags_for_all_actions: "Tags f\xC3\xBCr alle Aufgaben (mit Kommas trennen)" - project_for_all_actions: "Projekt f\xC3\xBCr alle Aufgaben" context_for_all_actions: "Kontext f\xC3\xBCr alle Aufgaben" toggle_multi: "Mehrere neue Aufgabeneintr\xC3\xA4ge hinzuf\xC3\xBCgen" toggle_single_title: Eine weitere Aktion hinzufügen + project_for_all_actions: "Projekt f\xC3\xBCr alle Aufgaben" separate_tags_with_commas: mit Kommas trennen toggle_multi_title: "Zwischen Einzel- und Mehrfachformular f\xC3\xBCr neue Aufgaben umschalten" hide_action_form_title: "Formular f\xC3\xBCr neue Aufgaben verstecken" - users: - auth_type_update_error: "Beim Ändern der Authentifizierung trat ein Fehler auf: %{error_messages}" - total_contexts: Alle Kontexte - successfully_deleted_user: Benutzer %{username} erfolgreich gelöscht. - first_user_heading: "Willkommen bei TRACKS. Als erstes legen Sie bitte einen Administrator-Zugang an:" - failed_to_delete_user: Löschen des Benutzers %{username} fehlgeschlagen - openid_url_verified: Die URL %{url} wurde erfolgreich als Identität verifiziert und Deine Authentifizierung auf OpenID umgestellt. - destroy_successful: "Benutzer %{login} wurde erfolgreich gel\xC3\xB6scht" - signup_successful: Benutzer %{username} erfolgreich angelegt. - new_token_generated: Neuer Token erfolgreich generiert - total_projects: Alle Projekte - change_password_submit: "Passwort \xC3\xA4ndern" - no_signups_title: TRACKS::Anmeldung nicht erlaubt - user_created: Benutzer angelegt. - password_updated: Passwort aktualisiert. - manage_users: Benutzer verwalten - account_signup: Accounteinrichtung - signup: Registrieren - total_actions: Alle Aufgaben - desired_login: "Gew\xC3\xBCnschter Benutzername" - confirm_password: "Passwort best\xC3\xA4tigen" - new_user_heading: "Einen neuen Benutzer anlegen:" - auth_type_updated: Authentifizierungs-Art erfolgreich geändert. - password_confirmation_label: "Passwort best\xC3\xA4tigen" - destroy_error: "Beim L\xC3\xB6schen des Benutzers %{login} ist ein Fehler aufgetreten." - choose_password: "Passwort w\xC3\xA4hlen" - change_password_title: TRACKS::Passwort ändern - change_auth_type_title: TRACKS::Authentifizierungstyp ändern - change_password_prompt: "Gib dein neues Passwort in die unten stehenden Felder ein und klicke auf 'Passwort \xC3\xA4ndern' um dein altes Passwort durch das neue zu ersetzen." - new_password_label: Neues Passwort - register_with_cas: Mit deinem CAS-Benutzernamen - label_auth_type: Authentifizierungsart - total_users_count: Derzeit existieren %{count} Benutzer - new_user_title: TRACKS::Als Administrator anmelden - destroy_user: "Benutzer l\xC3\xB6schen" - signup_new_user: Neuen Benutzer anlegen - destroy_confirmation: "Achtung: der Benutzer '%{login}' wird mit all seinen Aufgaben, Kontexten, Projekten und Notizen gel\xC3\xB6scht. Bist du sicher, dass du fortfahren m\xC3\xB6chtest?" - identity_url: Identity-URL - auth_change_submit: "Authentifizierungsart \xC3\xA4ndern" - openid_ok_pref_failed: Die URL %{url} wurde erfolgreich als Identität verifiziert, beim Speichern der Einstellungen trat jedoch ein Fehler auf. - change_authentication_type: "Authentifizierungsart \xC3\xA4ndern" - select_authentication_type: "W\xC3\xA4hle deine neue Authentifizierungsart und klicke 'Authentifizierungsart \xC3\xA4ndern' an, um deine aktuellen Einstellungen zu \xC3\xBCberschreiben." - total_notes: Alle Notizen - contexts: - delete_context_title: Kontext löschen - hide_form: Formular verstecken - show_form_title: Neuen Kontext erstellen - delete_context_confirmation: Soll der Kontext '%{name}' wirklich gelöscht werden? Alle (wiederholenden) Aufgaben dieses Kontexts werden hierdurch ebenfalls gelöscht. - delete_context: Kontext löschen - hide_form_title: Formular für neuen Kontext verstecken - edit_context: Kontext bearbeiten - context_hide: Auf Startseite ausblenden? - hidden_contexts: Versteckte Kontexte - no_contexts_active: Derzeit gibt es keine aktiven Kontexte - save_status_message: Kontext gespeichert - show_form: Neuen Kontext erstellen - add_context: "Kontext hinzuf\xC3\xBCgen" - visible_contexts: Sichtbare Kontexte - context_name: Kontextname - update_status_message: "Kontextname wurde ge\xC3\xA4ndert" - status_active: Kontext ist aktiv - new_context_post: "' wird ebenfalls angelegt. Fortfahren?" - last_completed_in_context: in diesem Kontext (letzte %{number}) - context_deleted: "Gel\xC3\xB6schter Kontext '%{name}'" - no_contexts_hidden: Derzeit gibt es keine versteckten Kontexte - new_context_pre: Der neue Kontext ' - no_actions: "Momentan gibt es keine unvollst\xC3\xA4ndigen Aufgaben in diesem Kontext" - status_hidden: Kontext ist versteckt - feedlist: - choose_context: "Kontext f\xC3\xBCr den Feed w\xC3\xA4hlen" - actions_due_today: "Heute oder fr\xC3\xBCher f\xC3\xA4llig" - all_contexts: Alle Kontexte - legend: "Legende:" - rss_feed: RSS-Feed - ical_feed: iCal-Feed - all_projects: Alle Projekte - choose_project: "Projekt f\xC3\xBCr den Feed w\xC3\xA4hlen" - select_feed_for_project: "Feed f\xC3\xBCr dieses Projekt ausw\xC3\xA4hlen" - active_projects_wo_next: Aktive Projekte ohne ausstehende Aufgaben - project_needed: Es muss mindestens ein Projekt existieren, bevor ein Feed abonniert werden kann. - active_starred_actions: Alle markierten, aktiven Aufgaben - projects_and_actions: Aktive Projekte und deren Aufgaben - context_needed: Es muss mindestens ein Kontext existieren, bevor ein Feed abonniert werden kann. - select_feed_for_context: "Feed f\xC3\xBCr diesen Kontext ausw\xC3\xA4hlen" - notice_incomplete_only: "Hinweis: Alle Feeds zeigen nur Aufgaben, die noch nicht als erledigt markiert wurden." - actions_due_next_week: "In den n\xC3\xA4chsten 7 Tagen oder fr\xC3\xBCher f\xC3\xA4llige Aufgaben" - actions_completed_last_week: In den letzten 7 Tagen abgeschlossene Aufgaben - context_centric_actions: "Feeds f\xC3\xBCr unvollst\xC3\xA4ndige Aufgaben in einem bestimmten Kontext" - plain_text_feed: Plain-Text-Feed - last_fixed_number: Die letzten %{number} Aufgaben - all_actions: Alle Aufgaben - project_centric: "Feeds f\xC3\xBCr unvollst\xC3\xA4ndige Aufgaben in einem bestimmten Kontext" sidebar: list_name_active_contexts: Aktive Kontexte list_name_active_projects: Aktive Projekte @@ -758,11 +783,106 @@ de: list_name_completed_projects: Abgeschlossene Projekte list_name_hidden_projects: Versteckte Projekte list_name_hidden_contexts: Versteckte Kontexte + contexts: + delete_context_title: Kontext löschen + all_completed_tasks_title: "TRACKS:: Alle Abgeschlossene Ma\xC3\x9Fnahmen im context '%{context_name}'" + hide_form: Formular verstecken + show_form_title: Neuen Kontext erstellen + delete_context_confirmation: Soll der Kontext '%{name}' wirklich gelöscht werden? Alle (wiederholenden) Aufgaben dieses Kontexts werden hierdurch ebenfalls gelöscht. + delete_context: Kontext löschen + hide_form_title: Formular für neuen Kontext verstecken + edit_context: Kontext bearbeiten + hidden_contexts: Versteckte Kontexte + no_contexts_active: Derzeit gibt es keine aktiven Kontexte + context_hide: Auf Startseite ausblenden? + show_form: Neuen Kontext erstellen + visible_contexts: Sichtbare Kontexte + save_status_message: Kontext gespeichert + add_context: "Kontext hinzuf\xC3\xBCgen" + update_status_message: "Kontextname wurde ge\xC3\xA4ndert" + context_name: Kontextname + status_active: Kontext ist aktiv + new_context_post: "' wird ebenfalls angelegt. Fortfahren?" + completed_tasks_title: "TRACKS:: Abgeschlossene Ma\xC3\x9Fnahmen im context '%{context_name}'" + last_completed_in_context: in diesem Kontext (letzte %{number}) + context_deleted: "Gel\xC3\xB6schter Kontext '%{name}'" + no_contexts_hidden: Derzeit gibt es keine versteckten Kontexte + new_context_pre: Der neue Kontext ' + no_actions: "Momentan gibt es keine unvollst\xC3\xA4ndigen Aufgaben in diesem Kontext" + status_hidden: Kontext ist versteckt + users: + failed_to_delete_user: Löschen des Benutzers %{username} fehlgeschlagen + destroy_successful: "Benutzer %{login} wurde erfolgreich gel\xC3\xB6scht" + total_contexts: Alle Kontexte + openid_url_verified: Die URL %{url} wurde erfolgreich als Identität verifiziert und Deine Authentifizierung auf OpenID umgestellt. + first_user_heading: "Willkommen bei TRACKS. Als erstes legen Sie bitte einen Administrator-Zugang an:" + auth_type_update_error: "Beim Ändern der Authentifizierung trat ein Fehler auf: %{error_messages}" + successfully_deleted_user: Benutzer %{username} erfolgreich gelöscht. + new_token_generated: Neuer Token erfolgreich generiert + total_projects: Alle Projekte + signup_successful: Benutzer %{username} erfolgreich angelegt. + user_created: Benutzer angelegt. + change_password_submit: "Passwort \xC3\xA4ndern" + no_signups_title: TRACKS::Anmeldung nicht erlaubt + account_signup: Accounteinrichtung + password_updated: Passwort aktualisiert. + manage_users: Benutzer verwalten + auth_type_updated: Authentifizierungs-Art erfolgreich geändert. + total_actions: Alle Aufgaben + desired_login: "Gew\xC3\xBCnschter Benutzername" + signup: Registrieren + confirm_password: "Passwort best\xC3\xA4tigen" + new_user_heading: "Einen neuen Benutzer anlegen:" + change_password_prompt: "Gib dein neues Passwort in die unten stehenden Felder ein und klicke auf 'Passwort \xC3\xA4ndern' um dein altes Passwort durch das neue zu ersetzen." + password_confirmation_label: "Passwort best\xC3\xA4tigen" + destroy_error: "Beim L\xC3\xB6schen des Benutzers %{login} ist ein Fehler aufgetreten." + choose_password: "Passwort w\xC3\xA4hlen" + change_password_title: TRACKS::Passwort ändern + change_auth_type_title: TRACKS::Authentifizierungstyp ändern + label_auth_type: Authentifizierungsart + new_password_label: Neues Passwort + register_with_cas: Mit deinem CAS-Benutzernamen + new_user_title: TRACKS::Als Administrator anmelden + destroy_user: "Benutzer l\xC3\xB6schen" + total_users_count: Derzeit existieren %{count} Benutzer + signup_new_user: Neuen Benutzer anlegen + destroy_confirmation: "Achtung: der Benutzer '%{login}' wird mit all seinen Aufgaben, Kontexten, Projekten und Notizen gel\xC3\xB6scht. Bist du sicher, dass du fortfahren m\xC3\xB6chtest?" + you_have_to_reset_your_password: "Sie haben Ihr Passwort zur\xC3\xBCcksetzen" + openid_ok_pref_failed: Die URL %{url} wurde erfolgreich als Identität verifiziert, beim Speichern der Einstellungen trat jedoch ein Fehler auf. + auth_change_submit: "Authentifizierungsart \xC3\xA4ndern" + identity_url: Identity-URL + change_authentication_type: "Authentifizierungsart \xC3\xA4ndern" + select_authentication_type: "W\xC3\xA4hle deine neue Authentifizierungsart und klicke 'Authentifizierungsart \xC3\xA4ndern' an, um deine aktuellen Einstellungen zu \xC3\xBCberschreiben." + total_notes: Alle Notizen + feedlist: + actions_due_today: "Heute oder fr\xC3\xBCher f\xC3\xA4llig" + choose_context: "Kontext f\xC3\xBCr den Feed w\xC3\xA4hlen" + all_contexts: Alle Kontexte + rss_feed: RSS-Feed + legend: "Legende:" + ical_feed: iCal-Feed + choose_project: "Projekt f\xC3\xBCr den Feed w\xC3\xA4hlen" + all_projects: Alle Projekte + active_projects_wo_next: Aktive Projekte ohne ausstehende Aufgaben + project_needed: Es muss mindestens ein Projekt existieren, bevor ein Feed abonniert werden kann. + select_feed_for_project: "Feed f\xC3\xBCr dieses Projekt ausw\xC3\xA4hlen" + active_starred_actions: Alle markierten, aktiven Aufgaben + context_needed: Es muss mindestens ein Kontext existieren, bevor ein Feed abonniert werden kann. + select_feed_for_context: "Feed f\xC3\xBCr diesen Kontext ausw\xC3\xA4hlen" + projects_and_actions: Aktive Projekte und deren Aufgaben + notice_incomplete_only: "Hinweis: Alle Feeds zeigen nur Aufgaben, die noch nicht als erledigt markiert wurden." + actions_due_next_week: "In den n\xC3\xA4chsten 7 Tagen oder fr\xC3\xBCher f\xC3\xA4llige Aufgaben" + last_fixed_number: Die letzten %{number} Aufgaben + all_actions: Alle Aufgaben + actions_completed_last_week: In den letzten 7 Tagen abgeschlossene Aufgaben + context_centric_actions: "Feeds f\xC3\xBCr unvollst\xC3\xA4ndige Aufgaben in einem bestimmten Kontext" + plain_text_feed: Plain-Text-Feed + project_centric: "Feeds f\xC3\xBCr unvollst\xC3\xA4ndige Aufgaben in einem bestimmten Kontext" datetime: prompts: minute: Minuten - month: Monat second: Sekunden + month: Monat hour: Stunden day: Tag year: Jahr @@ -780,9 +900,6 @@ de: x_seconds: one: 1 Sekunde other: "%{count} Sekunden" - about_x_hours: - one: etwa 1 Stunde - other: etwa %{count} Stunden less_than_x_seconds: one: weniger als 1 Sekunde other: weniger als %{count} Sekunden @@ -793,6 +910,9 @@ de: x_minutes: one: 1 Minute other: "%{count} Minuten" + about_x_hours: + one: etwa 1 Stunde + other: etwa %{count} Stunden about_x_months: one: etwa 1 Monat other: etwa %{count} Monate @@ -804,30 +924,30 @@ de: other: mehr als %{count} Jahre half_a_minute: eine halbe Minute login: - openid_identity_url_not_found: "Sorry, aber es existiert kein Benutzer mit der Identit\xC3\xA4ts-URL (%{identity_url})" + login_cas: zum CAS gehen user_no_expiry: Angemeldet bleiben sign_in: Anmeldung - login_cas: zum CAS gehen + openid_identity_url_not_found: "Sorry, aber es existiert kein Benutzer mit der Identit\xC3\xA4ts-URL (%{identity_url})" + cas_no_user_found: Hallo, %{username}! Du hast leider keinen Tracks-Account. cas_login: CAS-Anmeldung successful_with_session_info: "Anmeldung erfolgreich:" please_login: Bitte melde dich an, um Tracks zu nutzen cas_logged_in_greeting: Hallo, %{username}! Du bist authentifiziert. - cas_no_user_found: Hallo, %{username}! Du hast leider keinen Tracks-Account. cas_username_not_found: Sorry, aber es existiert kein Benutzer mit dem CAS-Benutzernamen (%{username}) - cas_create_account: "Wenn du die Anfrage fortsetzen m\xC3\xB6chtest, klicke bitte hier: %{signup_link}" mobile_use_openid: "\xE2\x80\xA6oder mit einer OpenID anmelden" + cas_create_account: "Wenn du die Anfrage fortsetzen m\xC3\xB6chtest, klicke bitte hier: %{signup_link}" cas_signup_link: Account beantragen account_login: Account-Anmeldung - session_will_not_expire: Sitzung wird nicht ablaufen. successful: "Anmeldung erfolgreich. Willkommen zur\xC3\xBCck!" + session_will_not_expire: Sitzung wird nicht ablaufen. session_time_out: Sitzung abgelaufen. Bitte %{link} session_will_expire: "Sitzung wird nach %{hours} Stunde(n) der Inaktivit\xC3\xA4t ablaufen." option_separator: oder, login_standard: "zur\xC3\xBCck zum Standard-Login" - login_with_openid: Mit einer OpenID anmelden unsuccessful: Anmeldung war nicht erfolgreich. log_in_again: Erneut anmelden. logged_out: Sie wurden von Tracks abgemeldet. + login_with_openid: Mit einer OpenID anmelden search: contexts_matching_query: Kontexte entsprechen der Suche tags_matching_query: Tags entsprechen der Suche diff --git a/config/locales/en.yml b/config/locales/en.yml index a7cd035f..3c908e1d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,646 +1,942 @@ +--- en: + layouts: + toggle_notes: Toggle notes + toggle_contexts: "Toggle collapsed contexts" + toggle_contexts_title: "Make collapsed contexts (in)visible" + next_actions_rss_feed: RSS feed of next actions + toggle_notes_title: Toggle all notes + mobile_navigation: + new_action: 0-New action + logout: Logout + feeds: Feeds + starred: 4-Starred + projects: 3-Projects + tickler: Tickler + contexts: 2-Contexts + home: 1-Home + navigation: + manage_users_title: Add or delete users + recurring_todos: Repeating todos + api_docs: REST API Docs + feeds: Feeds + starred: Starred + notes_title: Show all notes + review_title: Make review + stats: Statistics + tickler_title: Tickler + manage_users: Manage users + export_title: Import and export data + preferences: Preferences + integrations_: Integrate Tracks + feeds_title: See a list of available feeds + calendar_title: Calendar of due actions + completed_tasks: Done + stats_title: See your statistics + tickler: Tickler + home_title: Home + starred_title: See your starred actions + recurring_todos_title: Manage recurring actions + view: View + organize: Organize + completed_tasks_title: Completed + home: Home + export: Export + contexts_title: Contexts + calendar: Calendar + projects_title: Projects + search: Search All Items + preferences_title: Show my preferences + integrations: + opensearch_description: Search in Tracks + applescript_next_action_prompt: "Description of next action:" + gmail_description: Gadget to add Tracks to Gmail as a gadget + applescript_success_after_id: created + applescript_success_before_id: New next action with ID + number: + format: + separator: . + precision: 3 + delimiter: "," + human: + format: + precision: 1 + delimiter: "" + storage_units: + format: "%n %u" + units: + kb: KB + tb: TB + gb: GB + byte: + one: Byte + other: Bytes + mb: MB + percentage: + format: + delimiter: "" + currency: + format: + format: "%u%n" + unit: $ + separator: . + precision: 2 + delimiter: "," + precision: + format: + delimiter: "" + common: + back: Back + third: Third + recurring_todos: Repeating Actions + actions: Actions + add: Add + previous: Previous + logout: Logout + go_back: Go back + optional: optional + week: week + cancel: Cancel + none: None + second: Second + month: month + server_error: An error occurred on the server. + forum: Forum + notes: Notes + review: Review + last: Last + projects: Projects + action: Action + project: Project + ok: Ok + contribute: Contribute + website: Website + first: First + numbered_step: Step %{number} + sort: + by_task_count_title: Sort by number of tasks + by_task_count_title_confirm: Are you sure that you want to sort these projects by the number of tasks? This will replace the existing sort order. + alphabetically: Alphabetically + alphabetically_confirm: Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order. + alphabetically_title: Sort projects alphabetically + sort: Sort + by_task_count: By number of tasks + fourth: Fourth + create: Create + months: months + contexts: Contexts + errors_with_fields: "There were problems with the following fields:" + next: Next + todo: todo + context: Context + drag_handle: DRAG + description: Description + bugs: Bugs + update: Update + forth: Forth + weeks: weeks + wiki: Wiki + email: Email + search: Search + ajaxError: There was an error retrieving from server + data: + import_successful: Import was successful. + import_errors: Some errors occurred during import + models: + project: + feed_title: Tracks Projects + feed_description: Lists all the projects for %{username} + todo: + error_date_must_be_future: must be a date in the future + user: + error_context_not_associated: Context id %{context} not associated with user id %{user}. + error_project_not_associated: Project id %{project} not associated with user id %{user}. + preference: + due_on: Due on %{date} + due_in: Due in %{days} days + due_styles: + - Due in ___ days + - Due on _______ activerecord: + attributes: + project: + name: Name + default_tags: Default Tags + default_context_name: Default context + description: Description + todo: + predecessors: Depends on + show_from: Show from + notes: Notes + project: Project + context: Context + description: Description + due: Due + user: + last_name: Last name + first_name: First name + preference: + show_hidden_projects_in_sidebar: Show hidden projects in sidebar + date_format: Date format + show_hidden_contexts_in_sidebar: Show hidden contexts in sidebar + mobile_todos_per_page: Actions per page (Mobile View) + verbose_action_descriptors: Verbose action descriptors + staleness_starts: Start of staleness + review_period: Project review interval + sms_context: Default email context + title_date_format: Title date format + show_number_completed: Show number of completed actions + refresh: Refresh interval (in minutes) + week_starts: Week starts on + last_name: Last name + locale: Locale + due_style: Due style + time_zone: Time zone + show_project_on_todo_done: Go to project page on completing todo + sms_email: From email + first_name: First name + show_completed_projects_in_sidebar: Show completed projects in sidebar errors: + messages: + greater_than_or_equal_to: must be greater than or equal to %{count} + record_invalid: "Validation failed: %{errors}" + confirmation: doesn't match confirmation + less_than_or_equal_to: must be less than or equal to %{count} + blank: can't be blank + invalid: cannot contain the comma (',') character + exclusion: is reserved + odd: must be odd + even: must be even + too_short: is too short (minimum is %{count} characters) + empty: can't be empty + wrong_length: is the wrong length (should be %{count} characters) + less_than: must be less than %{count} + greater_than: must be greater than %{count} + equal_to: must be equal to %{count} + accepted: must be accepted + too_long: is too long (maximum is %{count} characters) + taken: has already been taken + inclusion: is not included in the list + not_a_number: is not a number models: project: attributes: name: - blank: "project must have a name" - too_long: "project name must be less than 256 characters" - taken: "already exists" - messages: - invalid: "cannot contain the comma (',') character" - attributes: - user: - first_name: "First name" - last_name: "Last name" - todo: - predecessors: "Depends on" - preference: - week_starts: "Week starts on" - show_project_on_todo_done: "Go to project page on todo complete" - refresh: "Refresh interval (in minutes)" - mobile_todos_per_page: "Actions per page (Mobile View)" - sms_email: "From email" - sms_context: "Default email context" - models: - project: - feed_title: "Tracks Projects" - feed_description: "Lists all the projects for %{username}" - preference: - due_styles: ['Due in ___ days', 'Due on _______'] - user: - error_context_not_associated: "Context id %{context} not associated with user id %{user}." - error_project_not_associated: "Project id %{project} not associated with user id %{user}." - todo: - error_date_must_be_future: "must be a date in the future" - common: - update: "Update" - logout: "Logout" - cancel: "Cancel" - ok: "Ok" - add: "Add" - project: "Project" - projects: "Projects" - context: "Context" - action: "Action" - actions: "Actions" - server_error: "An error occurred on the server." - contexts: "Contexts" - numbered_step: "Step %{number}" - errors_with_fields: "There were problems with the following fields:" - back: "Back" - create: "Create" - go_back: "Go back" - search: "Search" - none: "None" - description: "Description" - notes: "Notes" - optional: "optional" - ajaxError: 'There was an error retrieving from server' - sort: - sort: "Sort" - alphabetically: "Alphabetically" - alphabetically_title: "Sort projects alphabetically" - alphabetically_confirm: "Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order." - by_task_count: "By number of tasks" - by_task_count_title: "Sort by number of tasks" - by_task_count_title_confirm: "Are you sure that you want to sort these projects by the number of tasks? This will replace the existing sort order." - drag_handle: DRAG - bugs: Bugs - forum: Forum - wiki: Wiki - email: Email - website: Website - contribute: Contribute - first: First - second: Second - third: Third - fourth: Fourth - last: Last + blank: project must have a name + too_long: project name must be less than 256 characters + taken: already exists + full_messages: + format: "%{attribute} %{message}" + template: + body: "There were problems with the following fields:" + header: + one: 1 error prohibited this %{model} from being saved + other: "%{count} errors prohibited this %{model} from being saved" + stats: + tag_cloud_title: Tag cloud for all actions + tag_cloud_description: This tag cloud includes tags of all actions (completed, not completed, visible and/or hidden) + tag_cloud_90days_title: Tag cloud actions in past 90 days + actions: Actions + totals_active_project_count: Of those %{count} are active projects + actions_last_year_legend: + number_of_actions: Number of actions + months_ago: Months ago + totals_first_action: Since your first action on %{date} + actions_avg_completion_time: Of all your completed actions, the average time to complete is %{count} days. + top10_longrunning: Top 10 longest running projects + actions_dow_30days_title: Day of week (past 30 days) + legend: + actions: Actions + number_of_days: Number of days ago + number_of_actions: Number of actions + day_of_week: Day of week + percentage: Percentage + running_time: Running time of an action (weeks) + months_ago: Months ago + current_running_time_of_incomplete_visible_actions: Current running time of incomplete visible actions + totals_deferred_actions: of which %{count} are deferred actions in the tickler + running_time_legend: + actions: Actions + percentage: Percentage + weeks: Running time of an action (weeks). Click on a bar for more info + totals_action_count: you have a total of %{count} actions + totals_incomplete_actions: You have %{count} incomplete actions + totals_unique_tags: Of those tags, %{count} are unique. + actions_avg_completed_30days: and completed an average of %{count} actions per day. + top5_contexts: Top 5 contexts + actions_lastyear_title: Actions in the last 12 months + totals_actions_completed: "%{count} of these are completed." + totals_context_count: You have %{count} contexts. + totals_visible_context_count: Of those %{count} are visible contexts + totals_blocked_actions: "%{count} are dependent on the completion of their actions." + projects: Projects + action_completion_time_title: Completion time (all completed actions) + actions_last_year: Actions in the last years + actions_min_max_completion_days: The Max-/minimum days to complete is %{min}/%{max}. + tags: Tags + actions_min_completion_time: The minimum time to complete is %{time}. + no_tags_available: no tags available + actions_day_of_week_title: Day of week (all actions) + totals_project_count: You have %{count} projects. + running_time_all: Current running time of all incomplete actions + actions_30days_title: Actions in the last 30 days + time_of_day: Time of day (all actions) + totals_hidden_project_count: "%{count} are hidden" + tod30: Time of day (last 30 days) + tag_cloud_90days_description: This tag cloud includes tags of actions that were created or completed in the past 90 days. + more_stats_will_appear: More statistics will appear here once you have added some actions. + top5_visible_contexts_with_incomplete_actions: Top 5 visible contexts with incomplete actions + actions_further: " and further" + totals_tag_count: You have %{count} tags placed on actions. + top10_projects_30days: Top 10 project in past 30 days + spread_of_running_actions_for_visible_contexts: Spread of running actions for visible contexts + actions_selected_from_week: "Actions selected from week " + spread_of_actions_for_all_context: Spread of actions for all context + click_to_show_actions_from_week: Click %{link} to show the actions from week %{week} and further. + other_actions_label: (others) + top10_projects: Top 10 projects + totals_completed_project_count: and %{count} are completed projects. + actions_avg_created: In the last 12 months you created on average %{count} actions + click_to_return: Click %{link} to return to the statistics page. + actions_avg_completed: and completed an average of %{count} actions per month. + totals: Totals + time_of_day_legend: + number_of_actions: Number of actions + time_of_day: Time of day + contexts: Contexts + click_to_return_link: here + totals_hidden_context_count: and %{count} are hidden contexts. + labels: + month_avg_completed: "%{months} Month avg completed" + completed: Completed + month_avg_created: "%{months} Month avg created" + avg_created: Avg created + avg_completed: Avg completed + created: Created + running_time_all_legend: + actions: Actions + percentage: Percentage + running_time: Running time of an action (weeks). Click on a bar for more info + click_to_update_actions: Click on a bar in the chart to update the actions below. + no_actions_selected: There are no actions selected. + actions_actions_avg_created_30days: In the last 30 days you created on average %{count} actions + tod30_legend: + number_of_actions: Number of actions + time_of_day: Time of day + action_selection_title: TRACKS::Action selection + todos: + show_from: Show from + error_starring_recurring: Could not toggle the star of recurring todo \'%{description}\' + recurring_action_deleted: Action was deleted. Because this action is recurring, a new action was added + completed_actions: Completed actions + completed_recurring: Completed recurring todos + added_new_next_action: Added new next action + completed_rest_of_previous_month: Completed in the rest of the previous month + blocked_by: Blocked by %{predecessors} + star_action: Star this action + completed_recurrence_completed: There is no next action after the recurring action you just deleted. The recurrence is completed + defer_date_after_due_date: Defer date is after due date. Please edit and adjust due date before deferring. + unable_to_add_dependency: Unable to add dependency + done: Done? + star_action_with_description: star the action '%{description}' + tagged_with: tagged with ‘%{tag_name}’ + completed: Completed + no_deferred_actions_with: No deferred actions with the tag '%{tag_name}' + edit_action_with_description: Edit the action '%{description}' + no_hidden_actions: Currently there are no hidden actions found + action_due_on: (action due on %{date}) + remove_dependency: Remove dependency (does not delete the action) + archived_tasks_title: TRACKS::Archived completed tasks + list_incomplete_next_actions: Lists incomplete next actions + tags: Tags (separate with commas) + action_deleted_success: Successfully deleted next action + new_related_todo_created: A new todo was added which belongs to this recurring todo + context_changed: Context changed to %{name} + add_another_dependency: Add another dependency + mobile_todos_page_title: All actions + delete_recurring_action_title: Delete the recurring action + removed_predecessor: Removed %{successor} as dependency from %{predecessor}. + recurring_actions_title: TRACKS::Recurring Actions + next_action_needed: You need to submit at least one next action + action_saved: Action saved + scheduled_overdue: Scheduled to show %{days} days ago + action_deleted_error: Failed to delete the action + edit_action: Edit action + added_new_context: Added new context + next_actions_description: "Filter:" + list_incomplete_next_actions_with_limit: Lists the last %{count} incomplete next actions + set_to_pending: "%{task} set to pending" + added_new_project: Added new project + next_actions_title_additions: + completed: actions completed + due_today: due today + due_within_a_week: due within a week + older_completed_items: "" + append_in_this_project: in this project + error_deleting_item: There was an error deleting the item %{description} + task_list_title: TRACKS::List tasks + no_actions_due_this_week: No actions due in rest of this week + no_deferred_pending_actions: Currently there are no deferred or pending actions + no_recurring_todos: Currently there are no recurring todos + error_completing_todo: There was an error completing / activating the recurring todo %{description} + recurring_pattern_removed: The recurrence pattern is removed from %{count} + convert_to_project: Make project + delete_recurring_action_confirm: Are you sure that you want to delete the recurring action '%{description}'? + completed_last_day: Completed in the last 24 hours + completed_more_than_x_days_ago: "" + show_in_days: Show in %{days} days + no_project: --No project-- + error_saving_recurring: There was an error saving the recurring todo \'%{description}\' + new_related_todo_created_short: created a new todo + all_completed: All completed actions + feed_title_in_context: in context '%{context}' + older_than_days: "" + completed_tagged_page_title: TRACKS::Completed tasks with tag %{tag_name} + edit: Edit + pending: Pending + completed_actions_with: Completed actions with the tag %{tag_name} + deleted_success: The action was deleted succesfully. + completed_tasks_title: TRACKS::Completed tasks + feed_title_in_project: in project '%{project}' + clear_due_date: Clear due date + hidden_actions: Hidden actions + error_removing_dependency: There was an error removing the dependency + was_due_on_date: was due on %{date} + show_on_date: Show on %{date} + recurrence_period: Recurrence period + deferred_actions_with: Deferred actions with the tag '%{tag_name}' + recurring_deleted_success: The recurring action was deleted succesfully. + confirm_delete: Are you sure that you want to delete the action '%{description}'? + deferred_tasks_title: TRACKS::Tickler + next_actions_title: Tracks - Next Actions + next_action_description: Next action description + no_completed_actions_with: No completed actions with the tag '%{tag_name}' + clear_show_from_date: Clear show from date + calendar_page_title: TRACKS::Calendar + unresolved_dependency: The value you entered in the dependency field did not resolve to an existing action. This value will not be saved with the rest of the action. Continue? + in_hidden_state: in hidden state + show_today: Show Today + no_actions_found_title: No actions found + next_actions_due_date: + overdue_by: Overdue by %{days} day + due_today: Due Today + due_in_x_days: Due in %{days} days + overdue_by_plural: Overdue by %{days} days + due_tomorrow: Due Tomorrow + completed_last_x_days: Completed in the last %{count} days + no_actions_with: Currently there are no incomplete actions with the tag '%{tag_name}' + defer_x_days: + one: Defer one day + other: Defer %{count} days + added_new_next_action_singular: Added new next action + no_completed_actions: Currently there are no completed actions. + feeds: + completed: "Completed: %{date}" + due: "Due: %{date}" + deferred_pending_actions: Deferred/pending actions + has_x_pending: + one: Has one pending action + other: Has %{count} pending actions + delete_action: Delete action + error_deleting_recurring: There was an error deleting the recurring todo \'%{description}\' + recurring_todos: Recurring todos + delete: Delete + cannot_add_dependency_to_completed_todo: Cannot add this action as a dependency to a completed action! + drag_action_title: Drag onto another action to make it depend on that action + no_last_completed_actions: No completed actions found + depends_on: Depends on + tickler_items_due: + one: One tickler item is now due - refresh the page to see it. + other: "%{count} tickler items are now due - refresh the page to see them." + action_marked_complete: The action '%{description}' was marked as %{completed} + completed_today: Completed today + added_new_next_action_plural: Added new next actions + new_related_todo_not_created_short: did not create todo + completed_rest_of_week: Completed in the rest of this week + error_starring: Could not toggle the star of this todo '%{description}' + calendar: + get_in_ical_format: Get this calendar in iCal format + due_next_week: Due next week + no_actions_due_next_week: No actions due in next week + due_this_week: Due in rest of this week + due_today: Due today + no_actions_due_today: No actions due today + due_next_month_and_later: Due in %{month} and later + no_actions_due_after_this_month: No actions due after this month + due_this_month: Due in rest of %{month} + no_actions_due_this_month: No actions due in rest of this month + show_tomorrow: Show Tomorrow + tagged_page_title: TRACKS::Tagged with '%{tag_name}' + action_deferred: The action '%{description}' was deferred + recurrence: + ends_on_number_times: Ends after %{number} times + ends_on_date: Ends on %{date} + every_work_day: Every work day + recurrence_on_due_date: the date that the todo is due + weekly_options: Settings for weekly recurring actions + weekly: Weekly + monthly_options: Settings for monthly recurring actions + starts_on: Starts on + daily_options: Settings for daily recurring actions + monthly: Monthly + pattern: + month_names: + - + - January + - February + - Match + - April + - May + - June + - July + - August + - September + - October + - November + - December + third: third + every_n: every %{n} + on_day_n: on day %{n} + second: second + every_xth_day_of_every_n_months: every %{x} %{day} of every %{n_months} + from: from + weekly: weekly + last: last + every_day: every day + the_xth_day_of_month: the %{x} %{day} of %{month} + times: for %{number} times + on_work_days: on work days + first: first + every_year_on: every year on %{date} + day_names: + - sunday + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + show: show + fourth: fourth + due: due + until: until + every_month: every month + show_option_always: always + daily: Daily + yearly_every_x_day: Every %{month} %{day} + recurrence_on_options: Set recurrence on + daily_every_number_day: Every %{number} day(s) + show_options: Show the todo + weekly_every_number_week: Returns every %{number} week on + ends_on: Ends on + show_days_before: "%{days} days before the todo is due" + from_tickler: the date todo comes from tickler (no due date set) + no_end_date: No end date + day_x_on_every_x_month: Day %{day} on every %{month} month + yearly_options: Settings for yearly recurring actions + yearly_every_xth_day: The %{day} %{day_of_week} of %{month} + monthly_every_xth_day: The %{day} %{day_of_week} of every %{month} month + yearly: Yearly + no_completed_recurring: Currently there are no completed recurring todos + added_dependency: Added %{dependency} as dependency. + no_deferred_actions: Currently there are no deferred actions. + all_completed_tagged_page_title: TRACKS::All completed tasks with tag %{tag_name} + completed_rest_of_month: Completed in the rest of this month + recurrence_completed: There is no next action after the recurring action you just finished. The recurrence is completed + error_toggle_complete: Could not mark this todo complete + no_actions_found: Currently there are no incomplete actions. + in_pending_state: in pending state + due: Due + action_marked_complete_error: The action '%{description}' was NOT marked as %{completed} due to an error on the server. + depends_on_separate_with_commas: Depends on (separate with commas) + action_saved_to_tickler: Action saved to tickler + recurring_action_saved: Recurring action saved + completed_in_archive: + one: There is a completed action in the archive. + other: There are %{count} completed actions in the archive. + to_tickler: to tickler + next_actions_description_additions: + completed: in the last %{count} days + due_date: with a due date %{due_date} or earlier + overdue: Overdue + add_new_recurring: Add a new recurring action + no_incomplete_actions: There are no incomplete actions + notes: + delete_confirmation: Are you sure that you want to delete the note '%{id}'? + delete_item_title: Delete item + delete_note_title: Delete the note '%{id}' + note_link_title: Show note %{id} + show_note_title: Show note + deleted_note: Deleted note '%{id}' + edit_item_title: Edit item + note_location_link: "In:" + no_notes_available: "Currently there are no notes: add notes to projects from individual project pages." + note_header: Note %{id} + delete_note_confirm: Are you sure that you want to delete the note '%{id}'? + states: + hidden_plural: Hidden + completed: Completed + completed_plural: Completed + visible_plural: Visible + visible: Visible + active_plural: Active + hidden: Hidden + active: Active + review_plural: Dated + review: Dated + stalled_plural: Stalled + stalled: Stalled + blocked_plural: Blocked + blocked: Blocked + current_plural: Up-to-date + current: Up-to-date + projects: + was_marked_hidden: has been marked as hidden + edit_project_title: Edit project + default_tags_removed_notice: Removed the default tags + default_context_set: Set project's default context to %{default_context} + no_actions_in_project: Currently there are no incomplete actions in this project + deferred_actions: Deferred actions for this project + all_completed_tasks_title: TRACKS::List All Completed Actions in Project '%{project_name}' + hide_form: Hide form + page_title: "TRACKS::Project: %{project}" + show_form_title: Create a new project + list_completed_projects: TRACKS::List Completed Projects + to_new_project_page: Take me to the new project page + no_notes_attached: Currently there are no notes attached to this project + deferred_actions_empty: There are no deferred actions for this project + this_project: This project + project_state: Project is %{state}. + todos_append: in this project + no_last_completed_projects: No completed projects found + notes: Notes + no_last_completed_recurring_todos: No completed recurring todos found + notes_empty: There are no notes for this project + no_projects: Currently there are no projects + hide_form_title: Hide new project form + with_no_default_context: with no default context + delete_project: Delete project + completed_actions_empty: There are no completed actions for this project + show_form: Add a project + actions_in_project_title: Actions in this project + delete_project_confirmation: Are you sure that you want to delete the project '%{name}'? + with_default_context: with a default context of '%{context_name}' + set_default_tags_notice: Set project's default tags to %{default_tags} + is_active: is active + settings: Settings + completed_projects: Completed projects + with_default_tags: and with '%{tags}' as the default tags + list_projects: TRACKS::List Projects + list_reviews: TRACKS::Review + project_saved_status: Project saved + add_project: Add Project + add_note: Add a note + completed_tasks_title: TRACKS::List Completed Actions in Project '%{project_name}' + delete_project_title: Delete the project + hidden_projects: Hidden projects + add_note_submit: Add note + was_marked_complete: has been marked as completed + completed_actions: Completed actions for this project + default_context_removed: Removed default context + default_context: The default context for this project is %{context} + status_project_name_changed: Name of project was changed + active_projects: Active projects + no_default_context: This project does not have a default context + with_no_default_tags: and with no default tags + edit_project_settings: Edit Project Settings + state: This project is %{state} + time: + am: am + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + time: "" + short: "%d %b %H:%M" + month_day: "%B %d" + long: "%B %d, %Y %H:%M" + pm: pm + preferences: + open_id_url: Your OpenID URL is + staleness_starts_after: Staleness starts after %{days} days + change_identity_url: Change Your Identity URL + change_password: Change your password + page_title: TRACKS::Preferences + title: Your preferences + token_description: Token (for feeds and API use) + is_false: "false" + show_number_completed: Show %{number} completed items + page_title_edit: TRACKS::Edit Preferences + is_true: "true" + edit_preferences: Edit preferences + sms_context_none: None + generate_new_token: Generate a new token + token_header: Your token + authentication_header: Your authentication + current_authentication_type: Your authentication type is %{auth_type} + change_authentication_type: Change your authentication type + tabs: + authentication: Authentication + tracks_behavior: Tracks behavior + profile: Profile + date_and_time: Date and time + generate_new_token_confirm: Are you sure? Generating a new token will replace the existing one and break any external usages of this token. errors: user_unauthorized: "401 Unauthorized: Only administrative users are allowed access to this function." + date: + month_names: + - + - January + - February + - March + - April + - May + - June + - July + - August + - September + - October + - November + - December + abbr_day_names: + - Sun + - Mon + - Tue + - Wed + - Thu + - Fri + - Sat + order: + - :year + - :month + - :day + formats: + only_day: "" + default: "%Y-%m-%d" + short: "%b %d" + month_day: "" + long: "%B %d, %Y" + longer: "%A %B %d, %Y" + day_names: + - Sunday + - Monday + - Tuesday + - Wednesday + - Thursday + - Friday + - Saturday + abbr_month_names: + - + - Jan + - Feb + - Mar + - Apr + - May + - Jun + - Jul + - Aug + - Sep + - Oct + - Nov + - Dec + support: + array: + words_connector: ", " + last_word_connector: ", and " + two_words_connector: " and " + select: + prompt: Please select footer: send_feedback: Send feedback on %{version} - contexts: - status_hidden: "Context is hidden" - status_active: "Context is active" - no_actions: "Currently there are no incomplete actions in this context" - context_name: "Context name" - update_status_message: "Name of context was changed" - save_status_message: "Context saved" - last_completed_in_context: "in this context (last %{number})" - add_context: "Add Context" - context_hide: "Hide from front page?" - hide_form: "Hide form" - hide_form_title: "Hide new context form" - show_form: "Create a new context" - show_form_title: "Add a context" - visible_contexts: "Visible contexts" - hidden_contexts: "Hidden contexts" - context_deleted: "Deleted context '%{name}'" - no_contexts_hidden: "Currently there are no hidden contexts" - no_contexts_active: "Currently there are no active contexts" - delete_context: "Delete context" - delete_context_title: "Delete context" - delete_context_confirmation: "Are you sure that you want to delete the context '%{name}'? Be aware that this will also delete all (repeating) actions in this context!" - new_context_pre: "New context '" - new_context_post: "' will be also created. Are you sure?" - edit_context: "Edit context" - data: - import_errors: "Some errors occurred during import" - import_successful: "Import was successful." - feedlist: - legend: "Legend:" - rss_feed: "RSS Feed" - plain_text_feed: "Plain Text Feed" - ical_feed: "iCal feed" - notice_incomplete_only: "Note: All feeds show only actions that have not been marked as done, unless stated otherwise." - last_fixed_number: "Last %{number} actions" - all_actions: "All actions" - actions_due_today: "Actions due today or earlier" - actions_due_next_week: "Actions due in 7 days or earlier" - actions_completed_last_week: "Actions completed in the last 7 days" - all_contexts: "All Contexts" - all_projects: "All Projects" - active_projects_wo_next: "Active projects with no next actions" - active_starred_actions: "All starred, active actions" - projects_and_actions: "Active projects with their actions" - context_centric_actions: "Feeds for incomplete actions in a specific context" - context_needed: "There needs to be at least one context before you can request a feed" - choose_context: "Choose the context you want a feed of" - select_feed_for_context: "Select the feed for this context" - project_centric: "Feeds for incomplete actions in a specific project" - project_needed: "There needs to be at least one project before you can request a feed" - choose_project: "Choose the project you want a feed of" - select_feed_for_project: "Select the feed for this project" - integrations: - opensearch_description: "Search in Tracks" - applescript_next_action_prompt: "Description of next action:" - applescript_success_before_id: "New next action with ID" - applescript_success_after_id: "created" - gmail_description: "Gadget to add Tracks to Gmail as a gadget" - layouts: - toggle_notes: "Toggle notes" - toggle_notes_title: "Toggle all notes" - navigation: - home: "Home" - home_title: "Home" - starred: "Starred" - starred_title: "See your starred actions" - projects_title: "Projects" - tickler: "Tickler" - tickler_title: "Tickler" - organize: "Organize" - contexts_title: "Contexts" - notes_title: "Show all notes" - recurring_todos: "Repeating todos" - recurring_todos_title: "Manage recurring actions" - calendar: "Calendar" - completed_tasks: "Done" - completed_tasks_title: "Completed" - feeds: "Feeds" - feeds_title: "See a list of available feeds" - stats: "Statistics" - stats_title: "See your statistics" - view: "View" - calendar_title: "Calendar of due actions" - preferences: "Preferences" - preferences_title: "Show my preferences" - export_title: "Import and export data" - export: "Export" - manage_users: "Manage users" - manage_users_title: "Add or delete users" - integrations_: "Integrate Tracks" - api_docs: "REST API Docs" - search: "Search All Items" - next_actions_rss_feed: "RSS feed of next actions" - mobile_navigation: - new_action: "0-New action" - home: "1-Home" - contexts: "2-Contexts" - projects: "3-Projects" - starred: "4-Starred" - logout: "Logout" - tickler: "Tickler" - feeds: "Feeds" - login: - successful: "Logged in successfully. Welcome back!" - unsuccessful: "Login unsuccessful." - log_in_again: "log in again." - session_time_out: "Session has timed out. Please %{link}" - logged_out: "You have been logged out of Tracks." - session_will_expire: "session will expire after %{hours} hour(s) of inactivity." - session_will_not_expire: "session will not expire." - successful_with_session_info: "Login successful:" - cas_username_not_found: "Sorry, no user by that CAS username exists (%{username})" - openid_identity_url_not_found: "Sorry, no user by that identity URL exists (%{identity_url})" - account_login: "Account login" - please_login: "Please log in to use Tracks" - user_no_expiry: "Stay logged in" - sign_in: "Sign in" - cas_logged_in_greeting: "Hello, %{username}! You are authenticated." - cas_no_user_found: "Hello, %{username}! You do not have an account on Tracks." - cas_create_account: "If you like to request on please go here to %{signup_link}" - cas_signup_link: "Request account" - cas_login: "CAS Login" - login_with_openid: "login with an OpenID" - login_standard: "go back to the standard login" - login_cas: "go to the CAS" - option_separator: "or," - mobile_use_openid: "…or login with an OpenID" - notes: - note_location_link: "In:" - note_header: "Note %{id}" - note_link_title: "Show note %{id}" - delete_note_title: "Delete this note" - delete_confirmation: "Are you sure that you want to delete the note '%{id}'?" - edit_item_title: "Edit item" - delete_item_title: "Delete item" - show_note_title: "Show note" - deleted_note: "Deleted note '%{id}'" - delete_note_title: "Delete the note '%{id}'" - delete_note_confirm: "Are you sure that you want to delete the note '%{id}'?" - no_notes_available: "Currently there are no notes: add notes to projects from individual project pages." - preferences: - title: "Your preferences" - show_number_completed: "Show %{number} completed items" - staleness_starts_after: "Staleness starts after %{days} days" - sms_context_none: "None" - edit_preferences: "Edit preferences" - token_header: "Your token" - token_description: "Token (for feeds and API use)" - generate_new_token: "Generate a new token" - generate_new_token_confirm: "Are you sure? Generating a new token will replace the existing one and break any external usages of this token." - authentication_header: "Your authentication" - current_authentication_type: "Your authentication type is %{auth_type}" - change_authentication_type: "Change your authentication type" - change_password: "Change your password" - open_id_url: "Your OpenID URL is" - change_identity_url: "Change Your Identity URL" - page_title: "TRACKS::Preferences" - page_title_edit: "TRACKS::Edit Preferences" - is_true: "true" - is_false: "false" - projects: - status_project_name_changed: "Name of project was changed" - default_tags_removed_notice: "Removed the default tags" - set_default_tags_notice: "Set project's default tags to %{default_tags}" - default_context_removed: "Removed default context" - default_context_set: "Set project's default context to %{default_context}" - project_saved_status: "Project saved" - no_notes_attached: "Currently there are no notes attached to this project" - add_note: "Add a note" - todos_append: "in this project" - add_note_submit: "Add note" - deferred_actions: "Deferred actions for this project" - deferred_actions_empty: "There are no deferred actions for this project" - completed_actions: "Completed actions for this project" - completed_actions_empty: "There are no completed actions for this project" - no_actions_in_project: "Currently there are no incomplete actions in this project" - actions_in_project_title: "Actions in this project" - notes: "Notes" - notes_empty: "There are no notes for this project" - settings: "Settings" - state: "This project is %{state}" - this_project: "This project" - active_projects: "Active projects" - hidden_projects: "Hidden projects" - completed_projects: "Completed projects" - was_marked_complete: "has been marked as completed" - was_marked_hidden: "has been marked as hidden" - is_active: "is active" - with_no_default_context: "with no default context" - with_default_context: "with a default context of '%{context_name}'" - with_no_default_tags: "and with no default tags" - with_default_tags: "and with '%{tags}' as the default tags" - edit_project_settings: "Edit Project Settings" - page_title: "TRACKS::Project: %{project}" - list_projects: "TRACKS::List Projects" - no_default_context: "This project does not have a default context" - default_context: "The default context for this project is %{context}" - project_state: "Project is %{state}." - no_projects: "Currently there are no projects" - hide_form_title: "Hide new project form" - hide_form: "Hide form" - show_form_title: "Create a new project" - show_form: "Add a project" - add_project: "Add Project" - to_new_project_page: "Take me to the new project page" - delete_project_title: "Delete the project" - delete_project_confirmation: "Are you sure that you want to delete the project '%{name}'?" - delete_project: "Delete project" - edit_project_title: "Edit project" - states: - active: "Active" - active_plural: "Active" - completed: "Completed" - completed_plural: "Completed" - hidden: "Hidden" - hidden_plural: "Hidden" - visible: "Visible" - visible_plural: "Visible" - search: - no_results: "Your search yielded no results." - todos_matching_query: "Todos matching query" - projects_matching_query: "Projects matching query" - notes_matching_query: "Notes matching query" - contexts_matching_query: "Contexts matching query" - tags_matching_query: "Tags matching query" shared: - hide_action_form_title: "Hide new action form" - hide_form: "Hide form" - toggle_multi_title: "Toggle single/multi new action form" - toggle_multi: "Add multiple next actions" - toggle_single: 'Add a next action' - toggle_single_title: 'Add a new next action' - separate_tags_with_commas: "separate with commas" - add_action: "Add action" - multiple_next_actions: "Multiple next actions (one on each line)" - project_for_all_actions: "Project for all actions" - context_for_all_actions: "Context for all actions" - tags_for_all_actions: "Tags for all actions (sep. with commas)" - add_actions: "Add actions" - sidebar: - list_empty: "None" - list_name_active_projects: "Active projects" - list_name_active_contexts: "Active contexts" - list_name_hidden_projects: "Hidden projects" - list_name_completed_projects: "Completed projects" - list_name_hidden_contexts: "Hidden contexts" - stats: - tod30_legend: - time_of_day: "Time of day" - number_of_actions: "Number of actions" - tod30: "Time of day (last 30 days)" - no_actions_selected: "There are no actions selected." - totals: "Totals" - tags: "Tags" - more_stats_will_appear: "More statistics will appear here once you have added some actions." - spread_of_actions_for_all_context: "Spread of actions for all context" - spread_of_running_actions_for_visible_contexts: "Spread of running actions for visible contexts" - current_running_time_of_incomplete_visible_actions: "Current running time of incomplete visible actions" - running_time_legend: - actions: "Actions" - percentage: "Percentage" - weeks: "Running time of an action (weeks). Click on a bar for more info" - time_of_day: "Time of day (all actions)" - time_of_day_legend: - number_of_actions: "Number of actions" - time_of_day: "Time of day" - labels: - created: "Created" - completed: "Completed" - avg_created: "Avg created" - avg_completed: "Avg completed" - month_avg_created: "%{months} Month avg created" - month_avg_completed: "%{months} Month avg completed" - click_to_update_actions: "Click on a bar in the chart to update the actions below." - click_to_return: "Click %{link} to return to the statistics page." - click_to_return_link: "here" - click_to_show_actions_from_week: "Click %{link} to show the actions from week %{week} and further." - running_time_all: "Current running time of all incomplete actions" - running_time_all_legend: - actions: "Actions" - percentage: "Percentage" - running_time: "Running time of an action (weeks). Click on a bar for more info" - actions_last_year: "Actions in the last years" - actions_last_year_legend: - number_of_actions: "Number of actions" - months_ago: "Months ago" - other_actions_label: "(others)" - action_selection_title: "TRACKS::Action selection" - actions_selected_from_week: "Actions selected from week " - actions_further: " and further" - totals_project_count: "You have %{count} projects." - totals_active_project_count: "Of those %{count} are active projects" - totals_hidden_project_count: "%{count} are hidden" - totals_completed_project_count: "and %{count} are completed projects." - totals_context_count: "You have %{count} contexts." - totals_visible_context_count: "Of those %{count} are visible contexts" - totals_hidden_context_count: "and %{count} are hidden contexts." - totals_first_action: "Since your first action on %{date}" - totals_action_count: "you have a total of %{count} actions" - totals_actions_completed: "%{count} of these are completed." - totals_incomplete_actions: "You have %{count} incomplete actions" - totals_deferred_actions: "of which %{count} are deferred actions in the tickler" - totals_blocked_actions: "%{count} are dependent on the completion of their actions." - totals_tag_count: "You have %{count} tags placed on actions." - totals_unique_tags: "Of those tags, %{count} are unique." - actions_avg_completion_time: "Of all your completed actions, the average time to complete is %{count} days." - actions_min_max_completion_days: "The Max-/minimum days to complete is %{min}/%{max}." - actions_min_completion_time: "The minimum time to complete is %{time}." - actions_actions_avg_created_30days: "In the last 30 days you created on average %{count} actions" - actions_avg_completed_30days: "and completed an average of %{count} actions per day." - actions_avg_created: "In the last 12 months you created on average %{count} actions" - actions_avg_completed: "and completed an average of %{count} actions per month." - tag_cloud_title: "Tag cloud for all actions" - tag_cloud_description: "This tag cloud includes tags of all actions (completed, not completed, visible and/or hidden)" - no_tags_available: "no tags available" - tag_cloud_90days_title: "Tag cloud actions in past 90 days" - tag_cloud_90days_description: "This tag cloud includes tags of actions that were created or completed in the past 90 days." - top10_projects: "Top 10 projects" - top10_projects_30days: "Top 10 project in past 30 days" - top10_longrunning: "Top 10 longest running projects" - top5_contexts: "Top 5 contexts" - top5_visible_contexts_with_incomplete_actions: "Top 5 visible contexts with incomplete actions" - actions_30days_title: "Actions in the last 30 days" - actions_lastyear_title: "Actions in the last 12 months" - legend: - number_of_actions: "Number of actions" - months_ago: "Months ago" - number_of_days: "Number of days ago" - day_of_week: "Day of week" - actions: "Actions" - percentage: "Percentage" - running_time: "Running time of an action (weeks)" - actions_day_of_week_title: "Day of week (all actions)" - actions_dow_30days_title: "Day of week (past 30 days)" - action_completion_time_title: "Completion time (all completed actions)" - actions: Actions - contexts: Contexts - projects: Projects - todos: - action_saved: "Action saved" - recurring_action_saved: "Recurring action saved" - action_saved_to_tickler: "Action saved to tickler" - added_new_project: "Added new project" - added_new_context: "Added new context" - error_starring: "Could not toggle the star of this todo \'%{description}\'" - error_toggle_complete: "Could not mark this todo complete" - recurrence_completed: "There is no next action after the recurring action you just finished. The recurrence is completed" - tagged_with: "tagged with ‘%{tag_name}’" - no_actions_found_title: "No actions found" - no_actions_found: "Currently there are no incomplete actions." - no_actions_with: "Currently there are no incomplete actions with the tag '%{tag_name}'" - removed_predecessor: "Removed %{successor} as dependency from %{predecessor}." - add_another_dependency: "Add another dependency" - error_removing_dependency: "There was an error removing the dependency" - deferred_actions_with: "Deferred actions with the tag '%{tag_name}'" - no_deferred_actions_with: "No deferred actions with the tag '%{tag_name}'" - completed_actions_with: "Completed actions with the tag %{tag_name}" - no_completed_actions_with: "No completed actions with the tag '%{tag_name}'" - next_action_description: "Next action description" - new_related_todo_created: "A new todo was added which belongs to this recurring todo" - new_related_todo_created_short: "created a new todo" - new_related_todo_not_created_short: "did not create todo" - error_completing_todo: "There was an error completing / activating the recurring todo %{description}" - recurring_todos: "Recurring todos" - no_recurring_todos: "Currently there are no recurring todos" - completed_recurring: "Completed recurring todos" - no_completed_recurring: "Currently there are no completed recurring todos" - add_new_recurring: "Add a new recurring action" - recurring_deleted_success: "The recurring action was deleted succesfully." - deleted_success: "The action was deleted succesfully." - error_deleting_recurring: "There was an error deleting the recurring todo \'%{description}\'" - error_saving_recurring: "There was an error saving the recurring todo \'%{description}\'" - error_starring_recurring: "Could not toggle the star of recurring todo \'%{description}\'" - recurrence_period: "Recurrence period" - action_marked_complete: "The action '%{description}' was marked as %{completed}" - action_marked_complete_error: "The action '%{description}' was NOT marked as %{completed} due to an error on the server." - recurrence: - daily: "Daily" - weekly: "Weekly" - monthly: "Monthly" - yearly: "Yearly" - starts_on: "Starts on" - ends_on: "Ends on" - no_end_date: "No end date" - ends_on_number_times: "Ends after %{number} times" - ends_on_date: "Ends on %{date}" - daily_options: "Settings for daily recurring actions" - daily_every_number_day: "Every %{number} day(s)" - every_work_day: "Every work day" - weekly_options: "Settings for weekly recurring actions" - weekly_every_number_week: "Returns every %{number} week on" - monthly_options: "Settings for monthly recurring actions" - day_x_on_every_x_month: "Day %{day} on every %{month} month" - monthly_every_xth_day: "The %{day} %{day_of_week} of every %{month} month" - yearly_options: "Settings for yearly recurring actions" - yearly_every_x_day: "Every %{month} %{day}" - yearly_every_xth_day: "The %{day} %{day_of_week} of %{month}" - recurrence_on_options: "Set recurrence on" - recurrence_on_due_date: "the date that the todo is due" - show_options: "Show the todo" - show_option_always: "always" - show_days_before: "%{days} days before the todo is due" - from_tickler: "the date todo comes from tickler (no due date set)" - delete_recurring_action_confirm: "Are you sure that you want to delete the recurring action '%{description}'?" - delete_recurring_action_title: "Delete the recurring action" - star_action_with_description: "star the action '%{description}'" - star_action: "Star this action" - delete_action: "Delete action" - edit_action: "Edit action" - edit_action_with_description: "Edit the action '%{description}'" - confirm_delete: "Are you sure that you want to delete the action '%{description}'?" - delete: "Delete" - edit: "Edit" - defer_date_after_due_date: "Defer date is after due date. Please edit and adjust due date before deferring." - convert_to_project: "Make project" - blocked_by: "Blocked by %{predecessors}" - depends_on: "Depends on" - pending: "Pending" - drag_action_title: "Drag onto another action to make it depend on that action" - action_due_on: "(action due on %{date})" - scheduled_overdue: "Scheduled to show %{days} days ago" - show_today: "Show Today" - show_tomorrow: "Show Tomorrow" - show_on_date: "Show on %{date}" - show_in_days: "Show in %{days} days" - defer_x_days: - one: "Defer one day" - other: "Defer %{count} days" - has_x_pending: - one: "Has one pending action" - other: "Has %{count} pending actions" - recurring_actions_title: "TRACKS::Recurring Actions" - next_action_needed: "You need to submit at least one next action" - context_changed: "Context changed to %{name}" - action_deleted_success: "Successfully deleted next action" - action_deleted_error: "Failed to delete the action" - completed_tasks_title: "TRACKS::Completed tasks" - archived_tasks_title: "TRACKS::Archived completed tasks" - deferred_tasks_title: "TRACKS::Tickler" - tagged_page_title: "TRACKS::Tagged with '%{tag_name}'" - calendar_page_title: "TRACKS::Calendar" - next_actions_title: "Tracks - Next Actions" - next_actions_description: "Filter:" - next_actions_title_additions: - due_today: "due today" - due_within_a_week: "due within a week" - completed: "actions completed" - next_actions_description_additions: - due_date: "with a due date %{due_date} or earlier" - completed: "in the last %{count} days" - feed_title_in_context: "in context '%{context}'" - feed_title_in_project: "in project '%{project}'" - list_incomplete_next_actions_with_limit: "Lists the last %{count} incomplete next actions" - list_incomplete_next_actions: "Lists incomplete next actions" - task_list_title: "TRACKS::List tasks" - mobile_todos_page_title: "All actions" - feeds: - due: "Due: %{date}" - completed: "Completed: %{date}" - deferred_pending_actions: "Deferred/pending actions" - no_deferred_pending_actions: "Currently there are no deferred or pending actions" - completed_actions: "Completed actions" - no_completed_actions: "Currently there are no completed actions." - was_due_on_date: "was due on %{date}" - tags: "Tags (separate with commas)" - clear_due_date: "Clear due date" - show_from: "Show from" - clear_show_from_date: "Clear show from date" - depends_on_separate_with_commas: "Depends on (separate with commas)" - done: "Done?" - no_project: "--No project--" - due: "Due" - hidden_actions: "Hidden actions" - no_hidden_actions: "Currently there are no hidden actions found" - no_incomplete_actions: "There are no incomplete actions" - remove_dependency: "Remove dependency (does not delete the action)" - completed: "Completed" - added_dependency: "Added %{dependency} as dependency." - set_to_pending: "%{task} set to pending" - append_in_this_project: "in this project" - unable_to_add_dependency: "Unable to add dependency" - cannot_add_dependency_to_completed_todo : "Cannot add this action as a dependency to a completed action!" - calendar: - due_today: "Due today" - no_actions_due_today: "No actions due today" - due_this_week: "Due in rest of this week" - due_next_week: "Due next week" - no_actions_due_next_week: "No actions due in next week" - due_this_month: "Due in rest of %{month}" - no_actions_due_this_month: "No actions due in rest of this month" - due_next_month_and_later: "Due in %{month} and later" - no_actions_due_after_this_month: "No actions due after this month" - get_in_ical_format: "Get this calendar in iCal format" - no_actions_due_this_week: "No actions due in rest of this week" - overdue: "Overdue" - tickler_items_due: - one: "One tickler item is now due - refresh the page to see it." - other: "%{count} tickler items are now due - refresh the page to see them." - completed_today: - one: "You have completed one action so far today." - other: "You have completed %{count} actions so far today." - completed_last_day: "Completed in the last 24 hours" - completed_last_x_days: "Completed in last %{count} days" - older_completed_items: "Older completed items" - older_than_days: "Older than %{count} days" - completed_in_archive: - one: "There is one completed action in the archive." - other: "There are %{count} completed actions in the archive." - completed_more_than_x_days_ago: "Completed more than %{count} days ago" - added_new_next_action: "Added new next action" - added_new_next_action_singular: "Added new next action" - added_new_next_action_plural: "Added new next actions" - to_tickler: "to tickler" - in_pending_state: "in pending state" - in_hidden_state: "in hidden state" - recurring_action_deleted: "Action was deleted. Because this action is recurring, a new action was added" - completed_recurrence_completed: "There is no next action after the recurring action you just deleted. The recurrence is completed" - error_deleting_item: "There was an error deleting the item %{description}" - no_deferred_actions: "Currently there are no deferred actions." + multiple_next_actions: Multiple next actions (one on each line) + hide_form: Hide form + toggle_single: Add a next action + add_action: Add action + add_actions: Add actions + tags_for_all_actions: Tags for all actions (sep. with commas) + toggle_single_title: Add a new next action + project_for_all_actions: Project for all actions + context_for_all_actions: Context for all actions + toggle_multi: Add multiple next actions + separate_tags_with_commas: separate with commas + toggle_multi_title: Toggle single/multi new action form + hide_action_form_title: Hide new action form + make_actions_dependent: Make actions dependent on each other users: - change_authentication_type: "Change authentication type" - select_authentication_type: "Select your new authentication type and click 'Change authentication type' to replace your current settings." - label_auth_type: "Authentication type" - identity_url: "Identity URL" - auth_change_submit: "Change authentication type" - change_password_prompt: "Enter your new password in the fields below and click 'Change password' to replace your current password with your new one." - new_password_label: "New password" - password_confirmation_label: "Confirm password" - change_password_submit: "Change password" - destroy_successful: "User %{login} was successfully destroyed" - destroy_error: "There was an error deleting the user %{login}" - total_actions: "Total actions" - total_contexts: "Total contexts" - total_projects: "Total projects" - total_notes: "Total notes" - destroy_user: "Destroy user" - destroy_confirmation: "Warning: this will delete user '%{login}', all their actions, contexts, project and notes. Are you sure that you want to continue?" - signup_new_user: "Sign up new user" - manage_users: "Manage users" - total_users_count: "You have a total of %{count} users" - account_signup: "Account signup" - register_with_cas: "With your CAS username" - desired_login: "Desired login" - choose_password: "Choose password" - confirm_password: "Confirm password" - signup: "Signup" - new_user_title: "TRACKS::Sign up as the admin user" + successfully_deleted_user: Successfully deleted user %{username} + failed_to_delete_user: Failed to delete user %{username} + total_contexts: Total contexts first_user_heading: "Welcome to TRACKS. To get started, please create an admin account:" - new_user_heading: "Sign up a new user:" - no_signups_title: "TRACKS::No signups" - signup_successful: "Signup successful for user %{username}." - user_created: "User created." - successfully_deleted_user: "Successfully deleted user %{username}" - failed_to_delete_user: "Failed to delete user %{username}" - change_password_title: "TRACKS::Change password" - password_updated: "Password updated." - change_auth_type_title: "TRACKS::Change authentication type" - openid_url_verified: "You have successfully verified %{url} as your identity and set your authentication type to OpenID." - openid_ok_pref_failed: "You have successfully verified %{url} as your identity but there was a problem saving your authentication preferences." - auth_type_updated: "Authentication type updated." + openid_url_verified: You have successfully verified %{url} as your identity and set your authentication type to OpenID. auth_type_update_error: "There was a problem updating your authentication type: %{error_messages}" - new_token_generated: "New token successfully generated" \ No newline at end of file + destroy_successful: User %{login} was successfully destroyed + new_token_generated: New token successfully generated + total_projects: Total projects + signup_successful: Signup successful for user %{username}. + change_password_submit: Change password + no_signups_title: TRACKS::No signups + user_created: User created. + manage_users: Manage users + account_signup: Account signup + password_updated: Password updated. + desired_login: Desired login + signup: Signup + confirm_password: Confirm password + new_user_heading: "Sign up a new user:" + auth_type_updated: Authentication type updated. + total_actions: Total actions + change_password_title: TRACKS::Change password + change_auth_type_title: TRACKS::Change authentication type + change_password_prompt: Enter your new password in the fields below and click 'Change password' to replace your current password with your new one. + password_confirmation_label: Confirm password + destroy_error: There was an error deleting the user %{login} + choose_password: Choose password + register_with_cas: With your CAS username + label_auth_type: Authentication type + new_password_label: New password + you_have_to_reset_your_password: "You have to reset your password" + new_user_title: TRACKS::Sign up as the admin user + destroy_user: Destroy user + total_users_count: You have a total of %{count} users + destroy_confirmation: "Warning: this will delete user '%{login}', all their actions, contexts, project and notes. Are you sure that you want to continue?" + signup_new_user: Sign up new user + openid_ok_pref_failed: You have successfully verified %{url} as your identity but there was a problem saving your authentication preferences. + identity_url: Identity URL + auth_change_submit: Change authentication type + change_authentication_type: Change authentication type + total_notes: Total notes + select_authentication_type: Select your new authentication type and click 'Change authentication type' to replace your current settings. + sidebar: + list_name_active_contexts: Active contexts + list_name_active_projects: Active projects + list_empty: None + list_name_completed_projects: Completed projects + list_name_hidden_projects: Hidden projects + list_name_hidden_contexts: Hidden contexts + feedlist: + choose_context: Choose the context you want a feed of + actions_due_today: Actions due today or earlier + rss_feed: RSS Feed + ical_feed: iCal feed + all_contexts: All Contexts + legend: "Legend:" + all_projects: All Projects + choose_project: Choose the project you want a feed of + select_feed_for_project: Select the feed for this project + active_projects_wo_next: Active projects with no next actions + project_needed: There needs to be at least one project before you can request a feed + active_starred_actions: All starred, active actions + select_feed_for_context: Select the feed for this context + projects_and_actions: Active projects with their actions + context_needed: There needs to be at least one context before you can request a feed + actions_due_next_week: Actions due in 7 days or earlier + notice_incomplete_only: "Note: All feeds show only actions that have not been marked as done, unless stated otherwise." + all_actions: All actions + actions_completed_last_week: Actions completed in the last 7 days + context_centric_actions: Feeds for incomplete actions in a specific context + plain_text_feed: Plain Text Feed + last_fixed_number: Last %{number} actions + project_centric: Feeds for incomplete actions in a specific project + contexts: + delete_context_title: Delete context + all_completed_tasks_title: TRACKS::All Completed actions in the context '%{context_name}' + hide_form: Hide form + show_form_title: Add a context + delete_context_confirmation: Are you sure that you want to delete the context '%{name}'? Be aware that this will also delete all (repeating) actions in this context! + delete_context: Delete context + edit_context: Edit context + hide_form_title: Hide new context form + context_hide: Hide from front page? + hidden_contexts: Hidden contexts + no_contexts_active: Currently there are no active contexts + show_form: Create a new context + visible_contexts: Visible contexts + save_status_message: Context saved + add_context: Add Context + context_name: Context name + update_status_message: Name of context was changed + completed_tasks_title: TRACKS::Completed actions in the context '%{context_name}' + new_context_post: "' will be also created. Are you sure?" + status_active: Context is active + no_actions: Currently there are no incomplete actions in this context + last_completed_in_context: in this context (last %{number}) + context_deleted: Deleted context '%{name}' + no_contexts_hidden: Currently there are no hidden contexts + new_context_pre: New context ' + status_hidden: Context is hidden + login: + login_cas: go to the CAS + sign_in: Sign in + openid_identity_url_not_found: Sorry, no user by that identity URL exists (%{identity_url}) + user_no_expiry: Stay logged in + cas_no_user_found: Hello, %{username}! You do not have an account on Tracks. + cas_login: CAS Login + successful_with_session_info: "Login successful:" + please_login: Please log in to use Tracks + cas_logged_in_greeting: Hello, %{username}! You are authenticated. + cas_username_not_found: Sorry, no user by that CAS username exists (%{username}) + mobile_use_openid: "\xE2\x80\xA6or login with an OpenID" + cas_create_account: If you like to request on please go here to %{signup_link} + account_login: Account login + cas_signup_link: Request account + session_will_not_expire: session will not expire. + successful: Logged in successfully. Welcome back! + option_separator: or, + session_time_out: Session has timed out. Please %{link} + session_will_expire: session will expire after %{hours} hour(s) of inactivity. + login_standard: go back to the standard login + logged_out: You have been logged out of Tracks. + login_with_openid: login with an OpenID + unsuccessful: Login unsuccessful. + log_in_again: log in again. + datetime: + prompts: + minute: Minute + second: Seconds + month: Month + hour: Hour + day: Day + year: Year + distance_in_words: + less_than_x_minutes: + one: less than a minute + other: less than %{count} minutes + zero: less than 1 minute + x_days: + one: 1 day + other: "%{count} days" + almost_x_years: + one: almost 1 year + other: almost %{count} years + x_seconds: + one: 1 second + other: "%{count} seconds" + about_x_hours: + one: about 1 hour + other: about %{count} hours + less_than_x_seconds: + one: less than 1 second + other: less than %{count} seconds + zero: less than 1 second + x_months: + one: 1 month + other: "%{count} months" + x_minutes: + one: 1 minute + other: "%{count} minutes" + about_x_years: + one: about 1 year + other: about %{count} years + about_x_months: + one: about 1 month + other: about %{count} months + over_x_years: + one: over 1 year + other: over %{count} years + half_a_minute: half a minute + search: + contexts_matching_query: Contexts matching query + tags_matching_query: Tags matching query + notes_matching_query: Notes matching query + no_results: Your search yielded no results. + todos_matching_query: Todos matching query + projects_matching_query: Projects matching query diff --git a/config/locales/es.yml b/config/locales/es.yml new file mode 100644 index 00000000..28cf6c18 --- /dev/null +++ b/config/locales/es.yml @@ -0,0 +1,940 @@ +--- +es: + integrations: + opensearch_description: Buscar en las Tracks + applescript_next_action_prompt: "Descripci\xC3\xB3n de la pr\xC3\xB3xima tarea:" + gmail_description: "Gadget para a\xC3\xB1adir pistas a Gmail como un gadget" + applescript_success_after_id: creado + applescript_success_before_id: "Nueva acci\xC3\xB3n junto con la identificaci\xC3\xB3n" + common: + back: !binary | + QXRyw6Fz + + recurring_todos: "Repetici\xC3\xB3n de acciones" + actions: Tareas + third: Tercero + add: "A\xC3\xB1adir" + logout: Salir + go_back: "Volver atr\xC3\xA1s" + previous: Anterior + none: Ninguno + second: Segundo + week: semana + cancel: Cancelar + month: mes + optional: opcional + server_error: Ha ocurrido un error en el servidor. + forum: Foro + notes: Notas + last: "\xC3\x9Altimo" + action: Tarea + projects: Proyectos + project: Proyecto + contribute: Contribuir + ok: Ok + first: Primero + website: Website + numbered_step: Paso %{number} + create: Crear + fourth: Cuarto + sort: + by_task_count_title: "Ordenar por n\xC3\xBAmero de tareas" + by_task_count_title_confirm: "\xC2\xBFEst\xC3\xA1 seguro que desea ordenar los proyectos por el n\xC3\xBAmero de tareas? Esto reemplazar\xC3\xA1 el orden existente." + alphabetically: "Alfab\xC3\xA9ticamente" + sort: Ordenar + alphabetically_confirm: "\xC2\xBFEst\xC3\xA1 seguro que desea ordenar los proyectos por orden alfab\xC3\xA9tico? Esto reemplazar\xC3\xA1 el orden existente." + alphabetically_title: "Proyectos de ordenar alfab\xC3\xA9ticamente" + by_task_count: "Por n\xC3\xBAmero de tareas" + errors_with_fields: "Ha habido problemas con los siguientes campos:" + description: "Descripci\xC3\xB3n" + drag_handle: ARRASTRAR + context: Contexto + next: "Pr\xC3\xB3ximo" + contexts: Contextos + todo: Todo + months: meses + update: Actualizar + forth: Siguiente + wiki: Wiki + weeks: semanas + bugs: Errores + email: Email + ajaxError: Hubo un error al recuperar desde el servidor + search: Buscar + layouts: + toggle_contexts_title: "Haga contextos se derrumb\xC3\xB3 (in)visible" + toggle_contexts: "Cambiar los contextos se derrumb\xC3\xB3" + toggle_notes: Activar/Desactivar notas + next_actions_rss_feed: RSS feed of next actions + toggle_notes_title: Activar/Desactivar todas las notas + mobile_navigation: + logout: "Cerrar sesi\xC3\xB3n" + feeds: Feeds + new_action: 0-Nueva tarea + starred: 4-Favoritos + projects: 3-Proyectos + tickler: Tickler + contexts: 2-Contextos + home: 1-Inicio + navigation: + recurring_todos: Tareas repetitivas + manage_users_title: "A\xC3\xB1adir o eliminar usuarios" + api_docs: REST API Docs + feeds: Feeds + stats: "Estad\xC3\xADsticas" + starred: Estrellas + notes_title: Mostrar todas las notas + manage_users: Administrar usuarios + tickler_title: Tickler + export_title: Import and export data + preferences: Preferencias + integrations_: Integrar Tracks + calendar_title: Calendario de las acciones por + feeds_title: See a list of available feeds + recurring_todos_title: Manage recurring actions + completed_tasks: Hecho + stats_title: See your statistics + tickler: Tickler + home_title: Inicio + starred_title: See your starred actions + organize: Organizar + view: Ver + completed_tasks_title: Completed + home: Inicio + contexts_title: Contexts + export: Export + projects_title: Proyectos + preferences_title: Mostrar mis preferencias + search: Search All Items + calendar: Calendario + number: + format: + separator: . + delimiter: "," + human: + storage_units: + format: "%n %u" + units: + kb: KB + tb: Tuberculosis + gb: GB + byte: + one: Byte + other: Bytes + mb: MB + currency: + format: + format: "%u%n" + unit: !binary | + 4oKs + + separator: . + delimiter: "," + models: + project: + feed_title: Tracks Projects + feed_description: Lists all the projects for %{username} + todo: + error_date_must_be_future: must be a date in the future + user: + error_context_not_associated: Context id %{context} not associated with user id %{user}. + error_project_not_associated: Project id %{project} not associated with user id %{user}. + preference: + due_on: Due on %{date} + due_in: Due in %{days} days + due_styles: + - Due in ___ days + - Due on _______ + data: + import_successful: "Importaci\xC3\xB3n se realiz\xC3\xB3 correctamente." + import_errors: "Han ocurrido algunos errores durante la importaci\xC3\xB3n" + activerecord: + attributes: + project: + name: Nombre + default_tags: "Etiquetas est\xC3\xA1ndar" + default_context_name: Default contexto + description: "Descripci\xC3\xB3n" + todo: + show_from: Mostrar + predecessors: Depende de la + notes: Notas + project: Proyecto + description: "Descripci\xC3\xB3n" + context: Contexto + due: "Fecha l\xC3\xADmite" + user: + last_name: Apellido + first_name: Primer nombre + preference: + show_hidden_projects_in_sidebar: Mostrar proyectos ocultos en el lateral + date_format: Formato de fecha + show_hidden_contexts_in_sidebar: Mostrar los contextos ocultos en el lateral + mobile_todos_per_page: "Tareas por p\xC3\xA1gina (Vista M\xC3\xB3vil)" + verbose_action_descriptors: "Descriptores detallado de acci\xC3\xB3n" + staleness_starts: Comienzo de estancamiento + sms_context: Contexto por defecto para el email + show_number_completed: "Mostrar n\xC3\xBAmero de tareas completadas" + title_date_format: "T\xC3\xADtulo del formato de fecha" + refresh: "Intervalo de actualizaci\xC3\xB3n (en minutos)" + week_starts: La semana comienza + last_name: Apellido + time_zone: Zona horaria + due_style: Debido al estilo + locale: Lugar + sms_email: Email origen + show_project_on_todo_done: "Ir a la p\xC3\xA1gina del proyecto al completar la tarea" + first_name: Nombre + show_completed_projects_in_sidebar: Show completed projects in sidebar + errors: + models: + project: + attributes: + name: + blank: proyecto debe tener un nombre + too_long: El nombre del proyecto tiene que tener menos de 256 caracteres + taken: ya existe + messages: + record_invalid: "La validaci\xC3\xB3n ha fallado: %{errores}" + greater_than_or_equal_to: debe ser mayor que o igual a %{count} + less_than_or_equal_to: debe ser menor o igual a %{count} + confirmation: "no coincide con la confirmaci\xC3\xB3n" + blank: no puede estar en blanco + exclusion: "est\xC3\xA1 reservado" + invalid: "no puede contener el car\xC3\xA1cter de coma (',')" + odd: tiene que ser impar + too_short: "es demasiado corto (m\xC3\xADnimo %{count} caracteres)" + wrong_length: es la longitud del mal (debe ser %{count} caracteres) + empty: "no puede estar vac\xC3\xADo" + even: "debe ser a\xC3\xBAn" + less_than: debe ser menor que %{count} + equal_to: debe ser igual a %{count} + greater_than: debe ser mayor que %{count} + too_long: "es demasiado largo (el m\xC3\xA1ximo es %{count} caracteres)" + taken: Ya se ha dado + accepted: debe ser aceptada + not_a_number: "no es un n\xC3\xBAmero" + inclusion: "no est\xC3\xA1 incluido en la lista" + template: + body: "Hubo problemas con los campos siguientes:" + header: + one: Un error esta prohibido %{model} se guarden + other: "%{count} errores proh\xC3\xADbe este %{model} que se guarden" + full_messages: + format: "%{attribute} %{message}" + stats: + tag_cloud_90days_title: Tag cloud actions in past 90 days + actions: Actions + totals_active_project_count: Of those %{count} are active projects + tag_cloud_title: Tag cloud for all actions + tag_cloud_description: This tag cloud includes tags of all actions (completed, not completed, visible and/or hidden) + actions_avg_completion_time: Of all your completed actions, the average time to complete is %{count} days. + actions_last_year_legend: + number_of_actions: Number of actions + months_ago: Months ago + totals_first_action: Since your first action on %{date} + top10_longrunning: Top 10 longest running projects + totals_action_count: you have a total of %{count} actions + running_time_legend: + actions: Tareas + percentage: Percentage + weeks: Running time of an action (weeks). Click on a bar for more info + totals_deferred_actions: of which %{count} are deferred actions in the tickler + legend: + actions: Tareas + number_of_days: Number of days ago + number_of_actions: "N\xC3\xBAmero de tareas" + day_of_week: Day of week + percentage: Percentage + running_time: Running time of an action (weeks) + months_ago: Months ago + current_running_time_of_incomplete_visible_actions: Current running time of incomplete visible actions + actions_dow_30days_title: Day of week (past 30 days) + totals_actions_completed: "%{count} of these are completed." + totals_incomplete_actions: You have %{count} incomplete actions + totals_unique_tags: Of those tags, %{count} are unique. + actions_avg_completed_30days: and completed an average of %{count} actions per day. + top5_contexts: Top 5 contexts + actions_lastyear_title: Actions in the last 12 months + actions_last_year: Actions in the last years + totals_context_count: You have %{count} contexts. + totals_visible_context_count: Of those %{count} are visible contexts + totals_blocked_actions: "%{count} are dependent on the completion of their actions." + projects: Projects + action_completion_time_title: Completion time (all completed actions) + no_tags_available: no tags available + actions_day_of_week_title: Day of week (all actions) + tags: Tags + totals_project_count: You have %{count} projects. + actions_min_max_completion_days: The Max-/minimum days to complete is %{min}/%{max}. + actions_min_completion_time: The minimum time to complete is %{time}. + time_of_day: Time of day (all actions) + totals_tag_count: You have %{count} tags placed on actions. + tag_cloud_90days_description: This tag cloud includes tags of actions that were created or completed in the past 90 days. + actions_30days_title: Actions in the last 30 days + actions_further: " and further" + tod30: Time of day (last 30 days) + running_time_all: Current running time of all incomplete actions + totals_hidden_project_count: "%{count} are hidden" + top5_visible_contexts_with_incomplete_actions: Top 5 visible contexts with incomplete actions + more_stats_will_appear: More statistics will appear here once you have added some actions. + top10_projects_30days: Top 10 project in past 30 days + click_to_show_actions_from_week: Click %{link} to show the actions from week %{week} and further. + spread_of_actions_for_all_context: Spread of actions for all context + actions_selected_from_week: "Actions selected from week " + top10_projects: Top 10 projects + other_actions_label: (otros) + spread_of_running_actions_for_visible_contexts: Spread of running actions for visible contexts + actions_avg_created: In the last 12 months you created on average %{count} actions + click_to_return: Click %{link} to return to the statistics page. + totals_completed_project_count: and %{count} are completed projects. + totals: Totals + time_of_day_legend: + number_of_actions: "N\xC3\xBAmero de tareas" + time_of_day: Time of day + click_to_return_link: here + contexts: Contexts + totals_hidden_context_count: and %{count} are hidden contexts. + actions_avg_completed: and completed an average of %{count} actions per month. + running_time_all_legend: + actions: Tareas + percentage: Percentage + running_time: Running time of an action (weeks). Click on a bar for more info + no_actions_selected: No hay tareas seleccionadas. + click_to_update_actions: Click on a bar in the chart to update the actions below. + labels: + month_avg_completed: "%{months} Month avg completed" + completed: Completed + month_avg_created: "%{months} Month avg created" + avg_created: Avg created + avg_completed: Avg completed + created: Created + tod30_legend: + number_of_actions: "N\xC3\xBAmero de tareas" + time_of_day: Time of day + action_selection_title: TRACKS::Action selection + actions_actions_avg_created_30days: In the last 30 days you created on average %{count} actions + todos: + show_from: Show from + error_starring_recurring: Could not toggle the star of recurring todo \'%{description}\' + recurring_action_deleted: Action was deleted. Because this action is recurring, a new action was added + completed_actions: Completed actions + completed_recurring: Completed recurring todos + added_new_next_action: Added new next action + completed_rest_of_previous_month: Completado en el resto del mes anterior + blocked_by: Blocked by %{predecessors} + unable_to_add_dependency: Unable to add dependency + star_action: Star this action + completed_recurrence_completed: There is no next action after the recurring action you just deleted. The recurrence is completed + defer_date_after_due_date: Defer date is after due date. Please edit and adjust due date before deferring. + done: Done? + star_action_with_description: star the action '%{description}' + tagged_with: tagged with ‘%{tag_name}’ + completed: Completed + no_deferred_actions_with: No deferred actions with the tag '%{tag_name}' + no_hidden_actions: Currently there are no hidden actions found + edit_action_with_description: Edit the action '%{description}' + action_due_on: (action due on %{date}) + action_deleted_success: Successfully deleted next action + archived_tasks_title: TRACKS::Archived completed tasks + remove_dependency: Remove dependency (does not delete the action) + list_incomplete_next_actions: Lista las siguientes tareas incompletas + tags: Tags (separate with commas) + new_related_todo_created: "Una nueva tarea fue a\xC3\xB1adida y que pertenece a esta tarea recurrente" + context_changed: Context changed to %{name} + mobile_todos_page_title: Todas las tareas + add_another_dependency: Add another dependency + delete_recurring_action_title: Delete the recurring action + removed_predecessor: Removed %{successor} as dependency from %{predecessor}. + recurring_actions_title: TRACKS::Recurring Actions + next_action_needed: You need to submit at least one next action + action_deleted_error: Failed to delete the action + action_saved: Action saved + scheduled_overdue: Scheduled to show %{days} days ago + next_actions_description: "Filter:" + edit_action: Edit action + added_new_context: Added new context + added_new_project: Added new project + list_incomplete_next_actions_with_limit: Lists the last %{count} incomplete next actions + set_to_pending: "%{task} set to pending" + next_actions_title_additions: + completed: actions completed + due_today: due today + due_within_a_week: due within a week + older_completed_items: Older completed items + append_in_this_project: in this project + error_deleting_item: There was an error deleting the item %{description} + task_list_title: TRACKS::List tasks + no_actions_due_this_week: No actions due in rest of this week + delete_recurring_action_confirm: Are you sure that you want to delete the recurring action '%{description}'? + no_recurring_todos: Currently there are no recurring todos + error_completing_todo: There was an error completing / activating the recurring todo %{description} + recurring_pattern_removed: "El patr\xC3\xB3n de repetici\xC3\xB3n se retira de %{count}" + convert_to_project: Make project + no_deferred_pending_actions: Currently there are no deferred or pending actions + completed_last_day: Completed in the last 24 hours + new_related_todo_created_short: creada una nueva tarea + no_project: --No project-- + show_in_days: Show in %{days} days + error_saving_recurring: There was an error saving the recurring todo \'%{description}\' + completed_more_than_x_days_ago: Completed more than %{count} days ago + all_completed: Todas las acciones realizadas + feed_title_in_context: in context '%{context}' + pending: Pending + older_than_days: Older than %{count} days + completed_tagged_page_title: "TRACKS:: Las tareas completadas con etiqueta %{tag_name}" + edit: Edit + completed_actions_with: Completed actions with the tag %{tag_name} + deleted_success: The action was deleted succesfully. + completed_tasks_title: TRACKS::Completed tasks + feed_title_in_project: in project '%{project}' + clear_due_date: Clear due date + error_removing_dependency: There was an error removing the dependency + hidden_actions: Tareas ocultas + show_on_date: Show on %{date} + was_due_on_date: was due on %{date} + recurrence_period: Recurrence period + deferred_actions_with: Deferred actions with the tag '%{tag_name}' + confirm_delete: Are you sure that you want to delete the action '%{description}'? + recurring_deleted_success: The recurring action was deleted succesfully. + next_action_description: "Descripci\xC3\xB3n de la nueva tarea" + next_actions_title: Tracks - Next Actions + deferred_tasks_title: TRACKS::Tickler + no_completed_actions_with: No completed actions with the tag '%{tag_name}' + clear_show_from_date: Clear show from date + calendar_page_title: TRACKS::Calendar + unresolved_dependency: The value you entered in the dependency field did not resolve to an existing action. This value will not be saved with the rest of the action. Continue? + in_hidden_state: en estado oculto + completed_last_x_days: Completed in last %{count} days + show_today: Show Today + no_actions_found_title: No actions found + next_actions_due_date: + overdue_by: Overdue by %{days} day + due_today: Vence hoy + due_in_x_days: "Vence en %{days} d\xC3\xADas" + overdue_by_plural: Overdue by %{days} days + due_tomorrow: "Vence ma\xC3\xB1ana" + added_new_next_action_singular: Added new next action + no_actions_with: Currently there are no incomplete actions with the tag '%{tag_name}' + defer_x_days: + one: Defer one day + other: Defer %{count} days + no_completed_actions: Currently there are no completed actions. + has_x_pending: + one: Tiene una tarea pendiente + other: Tiene %{count} tareas pendientes + feeds: + completed: "Completed: %{date}" + due: "Due: %{date}" + deferred_pending_actions: Deferred/pending actions + delete_action: Delete action + error_deleting_recurring: There was an error deleting the recurring todo \'%{description}\' + recurring_todos: Recurring todos + delete: Delete + drag_action_title: Drag onto another action to make it depend on that action + cannot_add_dependency_to_completed_todo: Cannot add this action as a dependency to a completed action! + no_last_completed_actions: "No encontr\xC3\xB3 las acciones realizadas" + depends_on: Depends on + tickler_items_due: + one: One tickler item is now due - refresh the page to see it. + other: "%{count} tickler items are now due - refresh the page to see them." + action_marked_complete: The action '%{description}' was marked as %{completed} + new_related_todo_not_created_short: "no se cre\xC3\xB3 la tarea" + completed_today: Completed Today + added_new_next_action_plural: Added new next actions + completed_rest_of_week: Completado en el resto de esta semana + calendar: + get_in_ical_format: Get this calendar in iCal format + due_next_week: Due next week + no_actions_due_next_week: No actions due in next week + due_this_week: Due in rest of this week + due_today: Due today + no_actions_due_today: No actions due today + due_next_month_and_later: Due in %{month} and later + no_actions_due_after_this_month: No actions due after this month + due_this_month: Due in rest of %{month} + no_actions_due_this_month: No actions due in rest of this month + error_starring: Could not toggle the star of this todo \'%{description}\' + show_tomorrow: Show Tomorrow + action_deferred: "La acci\xC3\xB3n \\'%{description}\\' se aplaz\xC3\xB3" + recurrence: + ends_on_date: Ends on %{date} + every_work_day: Every work day + ends_on_number_times: Ends after %{number} times + recurrence_on_due_date: the date that the todo is due + weekly_options: Settings for weekly recurring actions + weekly: Weekly + monthly_options: Settings for monthly recurring actions + monthly: Monthly + starts_on: Starts on + daily_options: Settings for daily recurring actions + pattern: + third: third + month_names: + - + - January + - February + - Match + - April + - May + - June + - July + - August + - September + - October + - November + - December + every_n: every %{n} + second: second + every_xth_day_of_every_n_months: every %{x} %{day} of every %{n_months} + on_day_n: on day %{n} + weekly: weekly + from: from + last: last + every_day: every day + the_xth_day_of_month: the %{x} %{day} of %{month} + times: for %{number} times + day_names: + - sunday + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + on_work_days: on work days + first: first + every_year_on: every year on %{date} + show: show + fourth: fourth + due: due + until: until + every_month: every month + show_option_always: always + daily: Daily + recurrence_on_options: Set recurrence on + yearly_every_x_day: Every %{month} %{day} + daily_every_number_day: Every %{number} day(s) + show_options: Show the todo + weekly_every_number_week: Returns every %{number} week on + ends_on: Ends on + yearly_options: Settings for yearly recurring actions + show_days_before: "%{days} days before the todo is due" + from_tickler: the date todo comes from tickler (no due date set) + yearly_every_xth_day: The %{day} %{day_of_week} of %{month} + no_end_date: No end date + day_x_on_every_x_month: Day %{day} on every %{month} month + yearly: Yearly + monthly_every_xth_day: The %{day} %{day_of_week} of every %{month} month + tagged_page_title: TRACKS::Tagged with '%{tag_name}' + no_completed_recurring: Currently there are no completed recurring todos + added_dependency: Added %{dependency} as dependency. + all_completed_tagged_page_title: "TRACKS:: Todas las tareas realizadas con etiqueta %{tag_name}" + no_deferred_actions: Currently there are no deferred actions. + completed_rest_of_month: Completado en el resto de este mes + recurrence_completed: There is no next action after the recurring action you just finished. The recurrence is completed + no_actions_found: Currently there are no incomplete actions. + in_pending_state: en estado pendiente + error_toggle_complete: Could not mark this todo complete + due: "Fecha l\xC3\xADmite" + action_marked_complete_error: The action '%{description}' was NOT marked as %{completed} due to an error on the server. + next_actions_description_additions: + completed: in the last %{count} days + due_date: with a due date %{due_date} or earlier + action_saved_to_tickler: Action saved to tickler + overdue: Overdue + recurring_action_saved: Recurring action saved + depends_on_separate_with_commas: Depende de (separar con comas) + completed_in_archive: + one: There is one completed action in the archive. + other: There are %{count} completed actions in the archive. + to_tickler: to tickler + no_incomplete_actions: There are no incomplete actions + add_new_recurring: Add a new recurring action + notes: + delete_note_title: Delete the note '%{id}' + delete_confirmation: Are you sure that you want to delete the note '%{id}'? + delete_item_title: Delete item + deleted_note: Deleted note '%{id}' + note_link_title: Show note %{id} + show_note_title: Show note + note_location_link: "In:" + edit_item_title: Edit item + no_notes_available: "Currently there are no notes: add notes to projects from individual project pages." + note_header: Note %{id} + delete_note_confirm: Are you sure that you want to delete the note '%{id}'? + preferences: + open_id_url: Your OpenID URL is + staleness_starts_after: Staleness starts after %{days} days + change_identity_url: Change Your Identity URL + change_password: Change your password + page_title: TRACKS::Preferences + token_description: Token (for feeds and API use) + title: Your preferences + is_false: "false" + show_number_completed: Show %{number} completed items + page_title_edit: TRACKS::Edit Preferences + is_true: "true" + edit_preferences: Edit preferences + sms_context_none: None + generate_new_token: Generate a new token + token_header: Your token + current_authentication_type: Your authentication type is %{auth_type} + change_authentication_type: Change your authentication type + authentication_header: Your authentication + generate_new_token_confirm: Are you sure? Generating a new token will replace the existing one and break any external usages of this token. + tabs: + authentication: "Autenticaci\xC3\xB3n" + tracks_behavior: Rastrea el comportamiento de + profile: Perfil + date_and_time: Fecha y hora + errors: + user_unauthorized: "401 No autorizado: Solo los usuarios administrativos pueden acceder a esta funci\xC3\xB3n." + time: + am: soy + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + time: "" + short: "%d %b %H:%M" + month_day: "%B %d" + long: "%B %d, %Y %H:%M" + pm: pm + states: + hidden_plural: Hidden + completed: Completed + completed_plural: Completed + visible_plural: Visible + active_plural: Active + visible: Visible + hidden: Hidden + active: Active + projects: + default_context_set: Set project's default context to %{default_context} + no_actions_in_project: Currently there are no incomplete actions in this project + deferred_actions: Tareas pospuestas para este proyecto + was_marked_hidden: has been marked as hidden + edit_project_title: Editar proyecto + default_tags_removed_notice: Removed the default tags + all_completed_tasks_title: "TRACKS:: Lista de todas las acciones terminado en '%{project_name}' Proyecto" + hide_form: Esconder formulario + page_title: "TRACKS::Project: %{project}" + to_new_project_page: Take me to the new project page + deferred_actions_empty: There are no deferred actions for this project + show_form_title: Create a new project + this_project: This project + project_state: Project is %{state}. + list_completed_projects: "TRACKS:: Lista de Proyectos Realizados" + no_notes_attached: Currently there are no notes attached to this project + no_last_completed_recurring_todos: No se ha completado las acciones repetitivas que se encuentran + todos_append: in this project + notes: Notes + no_last_completed_projects: No hay proyectos terminados encontrado + notes_empty: There are no notes for this project + no_projects: Currently there are no projects + hide_form_title: Hide new project form + delete_project: Delete project + completed_actions_empty: No hay tareas completadas para este proyecto + with_no_default_context: with no default context + show_form: Add a project + actions_in_project_title: Actions in this project + delete_project_confirmation: Are you sure that you want to delete the project '%{name}'? + with_default_context: with a default context of '%{context_name}' + project_saved_status: Project saved + is_active: "est\xC3\xA1 activo" + completed_projects: Proyectos completados + add_note: "A\xC3\xB1adir una nota" + add_project: "A\xC3\xB1adir Proyecto" + list_projects: TRACKS::Lista de Proyectos + settings: Settings + with_default_tags: and with '%{tags}' as the default tags + set_default_tags_notice: Set project's default tags to %{default_tags} + delete_project_title: Delete the project + hidden_projects: Proyectos ocultos + completed_tasks_title: "TRACKS:: Lista de Acciones completadas en '%{project_name}' Proyecto" + add_note_submit: "A\xC3\xB1adir nota" + completed_actions: Tareas completadas para este proyecto + was_marked_complete: has been marked as completed + default_context_removed: Eliminado el contexto por defecto + state: This project is %{state} + status_project_name_changed: Name of project was changed + default_context: The default context for this project is %{context} + active_projects: Active projects + no_default_context: Este proyecto no tiene un contexto por defecto + with_no_default_tags: and with no default tags + edit_project_settings: Edit Project Settings + date: + month_names: + - + - Enero + - Febrero + - Marzo + - Abril + - Mayo + - Junio + - Julio + - Agosto + - Septiembre + - Octubre + - Noviembre + - Diciembre + abbr_day_names: + - Dom + - Lun + - Mar + - Mie + - Jue + - Vie + - Sab + formats: + only_day: "" + longer: "%A, %d %b %Y" + default: "%Y-%m-%d" + short: "%b %d" + month_day: "" + long: "%B %d, %Y" + day_names: + - Domingo + - Lunes + - Martes + - "Mi\xC3\xA9rcoles" + - Jueves + - Viernes + - "S\xC3\xA1bado" + abbr_month_names: + - + - Ene + - Feb + - Mar + - Abr + - May + - Jun + - Jul + - Ago + - Sep + - Oct + - Nov + - Dic + will_paginate: + previous_label: "\xC2\xAB Anterior" + page_entries_info: + multi_page: Viendo %{model} {%from} - %{to} de %{count} en el total de + single_page_html: + one: Viendo del 1 %{model} + other: Viendo todos los %{count} %{model} + zero: No %{model} encontrado + single_page: + one: Viendo del 1 %{model} + other: Viendo todos los %{count} %{model} + zero: No %{model} encontrado + multi_page_html: Viendo %{model} %{from} - %{to} de %{count} en el total de + page_gap: ... + next_label: "Siguiente \xC2\xBB" + support: + array: + last_word_connector: ", y" + words_connector: "," + two_words_connector: y + select: + prompt: Por favor seleccione + footer: + send_feedback: "Env\xC3\xADa comentarios sobre el %{version}" + shared: + multiple_next_actions: Multiple next actions (one on each line) + make_actions_dependent: "Aseg\xC3\xBArese que las acciones dependen unos de otros" + hide_form: Esconder formulario + toggle_single: Add a next action + add_actions: "A\xC3\xB1adir tareas" + add_action: "A\xC3\xB1adir tarea" + tags_for_all_actions: Tags for all actions (sep. with commas) + context_for_all_actions: Context for all actions + toggle_multi: Add multiple next actions + toggle_single_title: Add a new next action + project_for_all_actions: Project for all actions + separate_tags_with_commas: separar con comas + toggle_multi_title: Toggle single/multi new action form + hide_action_form_title: Hide new action form + sidebar: + list_name_active_contexts: Active contexts + list_name_active_projects: Active projects + list_empty: None + list_name_completed_projects: Completed projects + list_name_hidden_projects: Hidden projects + list_name_hidden_contexts: Hidden contexts + contexts: + delete_context_title: Eliminar contexto + all_completed_tasks_title: "TRACKS:: Todas las acciones completadas en '%{context_name}' contexto" + hide_form: Esconder formulario + show_form_title: "A\xC3\xB1adir un contexto" + delete_context_confirmation: "\xC2\xBFEst\xC3\xA1 seguro que desea eliminar '%{name}' el contexto? Tenga en cuenta que esto tambi\xC3\xA9n se eliminar\xC3\xA1n todas las acciones (la repetici\xC3\xB3n) en este contexto!" + delete_context: Eliminar contexto + hide_form_title: Ocultar el formulario nuevo contexto + edit_context: Editar contexto + hidden_contexts: Contextos ocultos + no_contexts_active: Actualmente no hay contextos activos + context_hide: "\xC2\xBFEsconder de la p\xC3\xA1gina principal?" + show_form: Crear un nuevo contexto + visible_contexts: Contextos visible + save_status_message: Contexto guardado + add_context: "A\xC3\xB1adir contexto" + update_status_message: Nombre de contexto ha cambiado + context_name: Nombre del contexto + status_active: "El contexto est\xC3\xA1 activo" + completed_tasks_title: "TRACKS:: Las acciones completadas en '%{context_name}' el contexto" + new_context_post: "' Tambi\xC3\xA9n se ha creado. \xC2\xBFEst\xC3\xA1 seguro?" + last_completed_in_context: "en este contexto (\xC3\xBAltimos %{number})" + context_deleted: Contexto eliminado '%{name}' + no_contexts_hidden: Actualmente no hay contextos ocultos + new_context_pre: Nuevo contexto ' + no_actions: Actualmente no hay acciones incompletas en este contexto + status_hidden: Contexto se oculta + feedlist: + actions_due_today: Acciones pendientes hoy o antes + choose_context: Elija el contexto en el que desea un canal de + all_contexts: Todos los contextos + rss_feed: RSS Feed + legend: "Leyenda:" + ical_feed: "iCal alimentaci\xC3\xB3n" + choose_project: Elegir el proyecto que quiere un canal de + all_projects: Todos los proyectos + active_projects_wo_next: "Proyectos activos, sin las pr\xC3\xB3ximas acciones" + project_needed: Es necesario que haya al menos un proyecto antes de poder solicitar un feed + select_feed_for_project: Seleccione la fuente para este proyecto + active_starred_actions: "Todas las acciones que protagoniz\xC3\xB3, activa" + context_needed: Es necesario que haya al menos un contexto antes de poder solicitar un feed + select_feed_for_context: "Seleccione la alimentaci\xC3\xB3n de este contexto" + projects_and_actions: Proyectos activos con sus acciones + notice_incomplete_only: "Nota: Todos los alimentos muestran s\xC3\xB3lo las acciones que no han sido marcadas como realizadas, a menos que se indique lo contrario." + actions_due_next_week: "Tareas pendientes en 7 d\xC3\xADas o menos" + last_fixed_number: "\xC3\x9Altima %{number} acciones" + all_actions: Todas las tareas + actions_completed_last_week: "Tareas completadas en los \xC3\xBAltimos 7 d\xC3\xADas" + context_centric_actions: "Feeds de acciones incompletas en un contexto espec\xC3\xADfico" + plain_text_feed: Canal Texto sin formato + project_centric: "Feeds de acciones incompletas en un proyecto espec\xC3\xADfico" + users: + failed_to_delete_user: Failed to delete user %{username} + destroy_successful: User %{login} was successfully destroyed + total_contexts: Total contexts + openid_url_verified: You have successfully verified %{url} as your identity and set your authentication type to OpenID. + first_user_heading: "Welcome to TRACKS. To get started, please create an admin account:" + auth_type_update_error: "There was a problem updating your authentication type: %{error_messages}" + successfully_deleted_user: Successfully deleted user %{username} + new_token_generated: New token successfully generated + total_projects: Total projects + signup_successful: Signup successful for user %{username}. + user_created: User created. + change_password_submit: Change password + no_signups_title: TRACKS::No signups + account_signup: Account signup + password_updated: Password updated. + manage_users: Manage users + auth_type_updated: Authentication type updated. + total_actions: Total actions + desired_login: Desired login + signup: Signup + confirm_password: Confirm password + new_user_heading: "Sign up a new user:" + change_password_prompt: Enter your new password in the fields below and click 'Change password' to replace your current password with your new one. + password_confirmation_label: Confirm password + destroy_error: There was an error deleting the user %{login} + choose_password: Choose password + change_password_title: TRACKS::Change password + change_auth_type_title: TRACKS::Change authentication type + label_auth_type: Authentication type + new_password_label: New password + register_with_cas: With your CAS username + new_user_title: TRACKS::Sign up as the admin user + destroy_user: Destroy user + total_users_count: You have a total of %{count} users + signup_new_user: Sign up new user + destroy_confirmation: "Warning: this will delete user '%{login}', all their actions, contexts, project and notes. Are you sure that you want to continue?" + you_have_to_reset_your_password: "Usted tiene que restablecer su contrase\xC3\xB1a" + openid_ok_pref_failed: You have successfully verified %{url} as your identity but there was a problem saving your authentication preferences. + auth_change_submit: Change authentication type + identity_url: Identity URL + change_authentication_type: Change authentication type + select_authentication_type: Select your new authentication type and click 'Change authentication type' to replace your current settings. + total_notes: Total notes + datetime: + prompts: + minute: Minuto + second: Segundos + month: Mes + hour: Hora + day: !binary | + RMOtYQ== + + year: !binary | + QcOxbw== + + distance_in_words: + less_than_x_minutes: + one: menos de un minuto + other: menos de %{count} minutos + zero: menos de 1 minuto + almost_x_years: + one: "casi 1 a\xC3\xB1o" + other: "Casi %{count} a\xC3\xB1os" + x_days: + one: !binary | + MSBkw61h + + other: "%{count} d\xC3\xADas" + x_seconds: + one: Un segundo + other: "%{count} segundos" + less_than_x_seconds: + one: menos de 1 segundo + other: menos de %{count} segundos + zero: menos de 1 segundo + x_months: + one: 1 mes + other: "%{count} meses" + x_minutes: + one: 1 minuto + other: "%{count} minutos" + about_x_hours: + one: alrededor de 1 hora + other: Acerca de %{count} horas + about_x_months: + one: alrededor de 1 mes + other: Acerca de %{count} meses + about_x_years: + one: "alrededor de 1 a\xC3\xB1o" + other: "Acerca de %{count} a\xC3\xB1os" + over_x_years: + one: "m\xC3\xA1s de 1 a\xC3\xB1o" + other: "en %{count} a\xC3\xB1os" + half_a_minute: medio minuto + login: + user_no_expiry: Stay logged in + login_cas: go to the CAS + sign_in: Entrar + openid_identity_url_not_found: Sorry, no user by that identity URL exists (%{identity_url}) + cas_no_user_found: Hello, %{username}! You do not have an account on Tracks. + cas_login: CAS Login + successful_with_session_info: "Login successful:" + please_login: Please log in to use Tracks + cas_logged_in_greeting: Hello, %{username}! You are authenticated. + cas_username_not_found: Sorry, no user by that CAS username exists (%{username}) + mobile_use_openid: "\xE2\x80\xA6or login with an OpenID" + cas_create_account: If you like to request on please go here to %{signup_link} + cas_signup_link: Request account + account_login: Acceso a la cuenta + successful: "Has entrado con \xC3\xA9xito. Bienvenido!" + session_will_not_expire: session will not expire. + session_time_out: Session has timed out. Please %{link} + session_will_expire: session will expire after %{hours} hour(s) of inactivity. + option_separator: or, + login_standard: go back to the standard login + unsuccessful: Login unsuccessful. + log_in_again: log in again. + logged_out: You have been logged out of Tracks. + login_with_openid: login with an OpenID + search: + contexts_matching_query: Contexts matching query + tags_matching_query: Tags matching query + notes_matching_query: Notes matching query + no_results: Your search yielded no results. + todos_matching_query: Todos matching query + projects_matching_query: Projects matching query diff --git a/config/locales/fr.yml b/config/locales/fr.yml new file mode 100644 index 00000000..6551e803 --- /dev/null +++ b/config/locales/fr.yml @@ -0,0 +1,972 @@ +--- +fr: + integrations: + opensearch_description: Rechercher dans Tracks + applescript_next_action_prompt: "Description de l'action suivante:" + gmail_description: "Gadget pour ajouter Tracks \xC3\xA0 Gmail" + applescript_success_after_id: !binary | + Q3LDqcOp + + applescript_success_before_id: Nouvelle action suivante avec ID + common: + recurring_todos: "R\xC3\xA9p\xC3\xA9tition d'actions" + back: Retour + actions: Actions + third: "Troisi\xC3\xA8me" + add: Ajouter + logout: "D\xC3\xA9connexion" + go_back: Retour + previous: !binary | + UHLDqWPDqWRlbnRl + + none: Aucun + week: semaine + second: Seconde + cancel: Annuler + optional: optionnel + month: mois + server_error: Une erreur s\'est produite sur le serveur + forum: Forum + notes: Notes + last: Dernier + action: Action + projects: Projets + project: Projet + contribute: Contribuer + ok: Ok + first: Premier + website: Site Web + numbered_step: Etape %{number} + sort: + by_task_count_title: "Trier par nombre de t\xC3\xA2ches" + by_task_count_title_confirm: "Etes vous s\xC3\xBBr de vouloir trier ces projets par nombre de t\xC3\xA2ches ? L\\'ordre actuel sera remplac\xC3\xA9." + alphabetically: "Par ordre alphab\xC3\xA9tique" + sort: Trier + alphabetically_confirm: "Etes vous s\xC3\xBBr de vouloir trier ces projets par ordre alphab\xC3\xA9tique ? L\\'ordre actuel sera remplac\xC3\xA9." + alphabetically_title: "Trier les projets par ordre alphab\xC3\xA9tique" + by_task_count: "Par nombre de t\xC3\xA2ches" + fourth: "Quatri\xC3\xA8me" + create: !binary | + Q3LDqWVy + + errors_with_fields: "Il y a des probl\xC3\xA8me avec les champs suivants :" + description: Description + context: Contexte + drag_handle: DRAG + contexts: Contextes + next: Suivant + todo: Action + months: Mois + forth: FORTH + update: "Mettre \xC3\xA0 jour" + weeks: semaines + wiki: Wiki + bugs: Bugs + email: Email + ajaxError: "Une erreur s'est produite en acc\xC3\xA9dant un serveur" + search: Rechercher + layouts: + toggle_contexts_title: "Faire des contextes effondr\xC3\xA9 (in)visibles" + toggle_contexts: "Basculer contextes effondr\xC3\xA9" + toggle_notes: Afficher/Cacher notes + next_actions_rss_feed: Flux RSS des prochaines actions + toggle_notes_title: Afficher/Cacher toutes les notes + mobile_navigation: + logout: "D\xC3\xA9connexion" + feeds: Flux + new_action: 0-Nouvelle action + starred: "4-Marqu\xC3\xA9" + projects: 3-Projets + tickler: Reporteur + contexts: 2-Contextes + home: 1-Accueil + navigation: + recurring_todos: "T\xC3\xA2ches (todos) r\xC3\xA9p\xC3\xA9titives" + manage_users_title: Ajouter ou supprimer des utilisateurs + api_docs: Doc REST API + feeds: Flux + starred: "Marqu\xC3\xA9" + stats: Statistiques + notes_title: Voir toutes les notes + manage_users: Gestion des utilisateurs + tickler_title: Reporteur + export_title: "Importer et exporter des donn\xC3\xA9es" + preferences: !binary | + UHLDqWbDqXJlbmNlcw== + + integrations_: "Int\xC3\xA9grer Tracks" + calendar_title: "Calendrier des actions \xC3\xA0 \xC3\xA9ch\xC3\xA9ance" + feeds_title: Voir une liste des flux disponibles + recurring_todos_title: "Gerer les actions r\xC3\xA9currentes" + completed_tasks: "Termin\xC3\xA9" + stats_title: Voir vos statistiques + home_title: Accueil + tickler: Reporteur + starred_title: "Voir vos actions pr\xC3\xA9f\xC3\xA9r\xC3\xA9es" + organize: Organiser + view: Vue + completed_tasks_title: "Termin\xC3\xA9" + home: Accueil + contexts_title: Contextes + export: Exporter + projects_title: Projets + preferences_title: "Voir mes pr\xC3\xA9f\xC3\xA9rences" + search: Recherches tous les items + calendar: Calendrier + number: + format: + separator: . + precision: 2 + delimiter: "," + human: + format: + precision: 1 + delimiter: "" + storage_units: + format: "%n %u" + units: + kb: KB + tb: TB + gb: GB + byte: + one: Octet + other: Octets + mb: MB + percentage: + format: + delimiter: "" + currency: + format: + format: "%u%n" + unit: $ + separator: . + delimiter: "," + precision: + format: + delimiter: "" + models: + project: + feed_title: Projets Tracks + feed_description: Liste de tous les projets de %{username} + todo: + error_date_must_be_future: "doit \xC3\xAAtre une date dans le futur" + user: + error_context_not_associated: "L'identifiant contexte %{context} n'est pas associ\xC3\xA9 \xC3\xA0 l'identifiant utilisateur %{user}." + error_project_not_associated: "L'identifiant projet %{context} n'est pas associ\xC3\xA9 \xC3\xA0 l'identifiant utilisateur %{user}." + preference: + due_on: "Ech\xC3\xA9ance le %{date}" + due_in: "Ech\xC3\xA9ance dans %{days} jours" + due_styles: + - "Ech\xC3\xA9ance dans ____ jours" + - "Ech\xC3\xA9ance le ____" + data: + import_successful: "L'import a r\xC3\xA9ussi." + import_errors: Des erreurs se sont produites durant l'import + activerecord: + attributes: + project: + name: Nom + default_tags: Tags par defaut + default_context_name: Contexte par defaut + description: Description + todo: + show_from: Afficher depuis + predecessors: "D\xC3\xA9pend de" + notes: Note + project: Projet + description: Description + context: Contexte + due: "Ech\xC3\xA9ance" + user: + last_name: Nom + first_name: "Pr\xC3\xA9nom" + preference: + show_hidden_projects_in_sidebar: "Montrer les projets cach\xC3\xA9s dans le panneau lat\xC3\xA9ral" + date_format: Format date + show_hidden_contexts_in_sidebar: "Montrer les contextes cach\xC3\xA9s dans le panneau lat\xC3\xA9ral" + mobile_todos_per_page: Actions par page (Vue Mobile) + staleness_starts: "D\xC3\xA9but de d\xC3\xA9passement" + verbose_action_descriptors: "Descripteurs d\\'action d\xC3\xA9taill\xC3\xA9s" + sms_context: Contexte Email par default + show_number_completed: "Montrer le nombre d\\'action compl\xC3\xA9t\xC3\xA9es" + title_date_format: Format de la date en titre + refresh: Intervalle de rafraichissement (en minutes) + week_starts: Les semaines commencent un + last_name: Nom + time_zone: Fuseau horaire + due_style: "Style Ech\xC3\xA9ance" + locale: Langue + sms_email: De l\'Email + show_project_on_todo_done: "Aller au projet quand la t\xC3\xA2che est termin\xC3\xA9e" + first_name: Nom + show_completed_projects_in_sidebar: "Montrer les projets compl\xC3\xA9t\xC3\xA9s dans le panneau lat\xC3\xA9ral" + errors: + models: + project: + attributes: + name: + blank: le projet doit avoir un nom + too_long: "le nom du projet doit faire moins de 256 caract\xC3\xA8res" + taken: !binary | + RXhpc3RlIGTDqWrDoA== + + messages: + record_invalid: "La validation \xC3\xA0 \xC3\xA9chou\xC3\xA9 : %{errors}" + greater_than_or_equal_to: "doit \xC3\xAAtre plus grand ou \xC3\xA9gal \xC3\xA0 %{count}" + less_than_or_equal_to: "doit \xC3\xAAtre inf\xC3\xA9rieur ou \xC3\xA9gal \xC3\xA0 %{count}" + confirmation: "n\\'est pas identique \xC3\xA0 la confirmation" + blank: "ne peux \xC3\xAAtre vide" + exclusion: exclusion? + invalid: "ne peut contenir le caract\xC3\xA8re virgule (\\',\\')" + odd: "doit \xC3\xAAtre impair" + too_short: "est trop court (minimum de %{count} charact\xC3\xA8res)" + wrong_length: "est de longueur incorrecte (doit \xC3\xAAtre de %{count} caract\xC3\xA8res)" + even: "doit \xC3\xAAtre pair" + empty: "ne peut \xC3\xAAtre vide" + less_than: "doit \xC3\xAAtre inf\xC3\xA9rieur \xC3\xA0 %{count}" + equal_to: "doit \xC3\xAAtre \xC3\xA9gal \xC3\xA0 %{count}" + greater_than: "doit \xC3\xAAtre plus grand que %{count}" + too_long: "est trop long (maximum de %{count} caract\xC3\xA8res)" + taken: "est d\xC3\xA9j\xC3\xA0 pris" + accepted: "doit \xC3\xAAtre accept\xC3\xA9" + not_a_number: n\'est pas un nombre + inclusion: n\'est pas inclus dans la liste + full_messages: + format: "%{attribute} %{message}" + template: + body: "Il y a des probl\xC3\xA8mes avec les champs suivants :" + header: + one: "1 erreur a emp\xC3\xA9ch\xC3\xA9 ce %{model} d\\'\xC3\xAAtre sauvegard\xC3\xA9" + other: "%{count} erreurs ont emp\xC3\xA9ch\xC3\xA9 ce %{model} d\\'\xC3\xAAtre sauvegard\xC3\xA9" + stats: + tag_cloud_90days_title: Nuage de tag des actions des 90 derniers jours + totals_active_project_count: De ceux-ci %{count} sont des projets actifs + actions: Actions + tag_cloud_title: Nuage de tag pour toutes les actions + tag_cloud_description: "Ce nuage de tags contient les tags de toutes les actions (r\xC3\xA9alis\xC3\xA9es, en cours, visibles ou cach\xC3\xA9es)" + actions_avg_completion_time: "Pour toutes vos actions r\xC3\xA9alis\xC3\xA9s, le temps moyen de r\xC3\xA9alisation est %{count} jours." + actions_last_year_legend: + number_of_actions: Nombre d'actions + months_ago: "Mois pr\xC3\xA9c\xC3\xA9dents" + totals_first_action: "Depuis votre premi\xC3\xA8re action du %{date}" + top10_longrunning: Top 10 des plus long projets en cours + totals_action_count: vous avez un total de %{count} actions + running_time_legend: + actions: Actions + percentage: Pourcentage + weeks: Temps en cours d'une action (en semaines). Cliquer sur une barre pour plus d'info + totals_deferred_actions: "desquels %{count} sont des actions report\xC3\xA9s dans le Reporteur" + current_running_time_of_incomplete_visible_actions: "Dur\xC3\xA9e en cours des actions incompl\xC3\xA8tes visibles" + legend: + actions: Actions + number_of_days: Il y a ... jours + number_of_actions: Nombre d'actions + day_of_week: Jour de la semaine + percentage: Pourcentage + running_time: Temps en cours d'une action (en semaines) + months_ago: Il y a ... mois + actions_dow_30days_title: Jour de la semaine (les 30 derniers jours) + totals_actions_completed: "dont %{count} sont r\xC3\xA9alis\xC3\xA9es." + totals_incomplete_actions: Vous avez %{count} actions en cours + totals_unique_tags: De ces tags, %{count} sont uniques. + actions_avg_completed_30days: "et r\xC3\xA9alis\xC3\xA9 une moyenne de %{count} actions par jour." + top5_contexts: Top 5 des contextes + actions_lastyear_title: Actions des 12 derniers mois + actions_last_year: "Actions des derni\xC3\xA8res ann\xC3\xA9es" + totals_context_count: Vous avez %{count} contextes. + totals_visible_context_count: De ceux-ci %{count} sont des contextes visibles + projects: Projets + totals_blocked_actions: "%{count} d\xC3\xA9pendent de la r\xC3\xA9alisation de leurs actions" + action_completion_time_title: "Temps de r\xC3\xA9alisation (toutes les actions r\xC3\xA9alis\xC3\xA9es)" + no_tags_available: pas de tags disponibles + actions_day_of_week_title: Jour de la semaine (toutes les actions) + tags: Tags + totals_project_count: Vous avez %{count} projets + actions_min_max_completion_days: "Le nombre max/min de jours pour r\xC3\xA9aliser est %{min}/%{max}." + actions_min_completion_time: "Le temps minimum de r\xC3\xA9alisation est %{time}." + time_of_day: Heure (toutes les actions) + totals_tag_count: Vous avez %{count} tags sur des actions. + tag_cloud_90days_description: "Ce nuage de tag contient les tags des actions cr\xC3\xA9\xC3\xA9es ou r\xC3\xA9alis\xC3\xA9es dans les 90 derniers jours." + actions_30days_title: Actions des 30 derniers jours + actions_further: et plus + tod30: Heure (30 derniers jours) + running_time_all: "Temps en cours de toutes les actions incompl\xC3\xA8tes" + totals_hidden_project_count: "%{count} sont cach\xC3\xA9s" + top5_visible_contexts_with_incomplete_actions: Top 5 des contextes visible avec des actions en cours + more_stats_will_appear: Plus de statistiques apparaitront quand vous aurez ajouter quelques actions. + top10_projects_30days: Top 10 des projets des 30 derniers jours + click_to_show_actions_from_week: Cliquer %{link} pour voir les actions depuis la semaine %{week}. + spread_of_actions_for_all_context: Vue des actions pour tous les contextes + actions_selected_from_week: "Actions selectionn\xC3\xA9es depuis la semaine" + top10_projects: Top 10 des projets + other_actions_label: (autres) + spread_of_running_actions_for_visible_contexts: Vue des actions en cours pour tous les contextes + actions_avg_created: "Dans les 12 derniers mois vous avez cr\xC3\xA9\xC3\xA9 une moyenne de %{count} actions" + click_to_return: "Cliquer %{link} pour revenir \xC3\xA0 la page des statistiques" + totals_completed_project_count: "et %{count} sont des projets r\xC3\xA9alis\xC3\xA9s." + totals: Totaux + time_of_day_legend: + number_of_actions: Nombre d'actions + time_of_day: Heure + click_to_return_link: ici + totals_hidden_context_count: "et %{count} sont des contextes cach\xC3\xA9s." + contexts: Contextes + actions_avg_completed: "et r\xC3\xA9alis\xC3\xA9 une moyenne de %{count} actions par mois." + running_time_all_legend: + actions: Actions + percentage: Pourcentage + running_time: Temps en cours d'une action (en semaines). Cliquer sur une barre pour plus d'info + no_actions_selected: "Il n'y a pas d'actions s\xC3\xA9lectionn\xC3\xA9es." + click_to_update_actions: Cliquer sur une barre du graphique pour mettre a jour les actions ci-dessous. + labels: + month_avg_completed: "%{month} mois moy. r\xC3\xA9alis\xC3\xA9" + completed: !binary | + Q29tcGzDqXTDqQ== + + month_avg_created: "%{month} mois moy. cr\xC3\xA9\xC3\xA9" + avg_created: !binary | + TW95LiBDcsOpw6k= + + avg_completed: "Moy. R\xC3\xA9alis\xC3\xA9" + created: !binary | + Q3LDqcOp + + tod30_legend: + number_of_actions: Nombre d'actions + time_of_day: Heure + action_selection_title: TRACKS::Selection action + actions_actions_avg_created_30days: "Dans les 30 jours vous avez cr\xC3\xA9er en moyenne %{count} actions" + todos: + show_from: Afficher depuis + error_starring_recurring: "Impossible d'actionner l'\xC3\xA9toile de la tache r\xC3\xA9currente \\'%{description}\\'" + recurring_action_deleted: "L'action a \xC3\xA9t\xC3\xA9 supprim\xC3\xA9e. Parce que cette action est r\xC3\xA9currente, une nouvelle action \xC3\xA0 \xC3\xA9t\xC3\xA9 ajout\xC3\xA9e" + completed_actions: "Action compl\xC3\xA9t\xC3\xA9es" + completed_recurring: "T\xC3\xA2ches reccurents compl\xC3\xA9t\xC3\xA9s" + added_new_next_action: "Nouvelle action suivante ajout\xC3\xA9e" + completed_rest_of_previous_month: "Compl\xC3\xA9t\xC3\xA9 dans le reste du mois pr\xC3\xA9c\xC3\xA9dent" + blocked_by: "Bloqu\xC3\xA9 par %{predecessors}" + unable_to_add_dependency: "Impossible d'ajouter la d\xC3\xA9pendance" + star_action: Elire cette action + completed_recurrence_completed: "Il n'y pas d'action suivante apr\xC3\xA8s l'action r\xC3\xA9currente que vous avez supprim\xC3\xA9e. La r\xC3\xA9currence est termin\xC3\xA9e" + defer_date_after_due_date: "La date de report est apr\xC3\xA8s la date d'\xC3\xA9ch\xC3\xA9ance. Veuillez ajuster la date d'\xC3\xA9cheance avant de reporter." + done: "Termin\xC3\xA9 ?" + star_action_with_description: Elire l'action '%{description}' + tagged_with: "tagg\xC3\xA9 avec ‘%{tag_name}’" + completed: !binary | + Q29tcGzDqXTDqQ== + + no_deferred_actions_with: "Pas d'actions report\xC3\xA9es avec le tag '%{tag_name}'" + no_hidden_actions: "Il n'y a pas d'actions cach\xC3\xA9es actuellement" + edit_action_with_description: Modifier l'action '%{description}' + action_due_on: "(action \xC3\xA0 terminer avant le %{date})" + action_deleted_success: "L'action suivante \xC3\xA0 \xC3\xA9t\xC3\xA9 supprim\xC3\xA9e avec succ\xC3\xA8s" + archived_tasks_title: "TRACKS::T\xC3\xA2ches r\xC3\xA9alis\xC3\xA9es archiv\xC3\xA9es" + remove_dependency: "Enlever les d\xC3\xA9pendances (l'action n'est pas supprim\xC3\xA9e)" + list_incomplete_next_actions: "Liste les prochaines actions incompl\xC3\xA8tes" + tags: "Tags (s\xC3\xA9par\xC3\xA9s par des virgules)" + new_related_todo_created: "Une nouvelle t\xC3\xA2che a \xC3\xA9t\xC3\xA9 ajout\xC3\xA9e qui appartient \xC3\xA0 cette t\xC3\xA2che r\xC3\xA9currente" + context_changed: "Contexte chang\xC3\xA9 en %{name}" + mobile_todos_page_title: Toutes les actions + add_another_dependency: "Ajouter une autre d\xC3\xA9pendance" + delete_recurring_action_title: "Supprimer l'action r\xC3\xA9currente" + removed_predecessor: "Suppression de %{successor} comme d\xC3\xA9pendance de %{predecessor}" + recurring_actions_title: "TRACKS::Actions r\xC3\xA9currentes" + next_action_needed: Vous devez soumettre au moins une prochaine action + action_deleted_error: "La suppression de l'action a \xC3\xA9chou\xC3\xA9" + action_saved: "Action sauvegard\xC3\xA9e" + scheduled_overdue: "Programm\xC3\xA9e pour apparaitre il y a %{days} jours" + next_actions_description: "Filtre:" + edit_action: Modifier action + added_new_context: "Nouveau context ajout\xC3\xA9" + added_new_project: "Nouveau projet ajout\xC3\xA9" + list_incomplete_next_actions_with_limit: "Liste les %{count} derni\xC3\xA8res actions suivantes incompl\xC3\xA8tes" + set_to_pending: "%{task} mise en attente" + next_actions_title_additions: + completed: "Actions compl\xC3\xA9t\xC3\xA9es" + due_today: "\xC3\xA9ch\xC3\xA9ance aujourd'hui" + due_within_a_week: "\xC3\xA9ch\xC3\xA9ance dans la semaine" + older_completed_items: "Anciens \xC3\xA9l\xC3\xA9ments compl\xC3\xA9t\xC3\xA9s" + append_in_this_project: dans ce projet + error_deleting_item: "Il s'est produit une erreur lors de la suppression de l'\xC3\xA9l\xC3\xA9ment %{description}" + task_list_title: "TRACKS::Lister les t\xC3\xA2ches" + no_actions_due_this_week: "Pas actions \xC3\xA0 faire cette semaine" + delete_recurring_action_confirm: "Etes-vous s\xC3\xBBr de vouloir supprimer l'action r\xC3\xA9currente '%{description'}?" + no_recurring_todos: "Il n'y a pas de t\xC3\xA2ches r\xC3\xA9currentes actuellement" + error_completing_todo: "Il s'est produit une erreur lors de l'execution de l'action r\xC3\xA9currente %{description}" + recurring_pattern_removed: "La p\xC3\xA9riodicit\xC3\xA9 est retir\xC3\xA9 de %{count}" + convert_to_project: Faire projet + no_deferred_pending_actions: "Il n'y pas d'actions report\xC3\xA9es ou en attente actuellement" + completed_last_day: "Compl\xC3\xA9t\xC3\xA9 ces derni\xC3\xA8res 24 heures" + new_related_todo_created_short: "\xC3\xA0 cr\xC3\xA9\xC3\xA9 une nouvelle t\xC3\xA2che" + no_project: --Pas de projet-- + show_in_days: Afficher dans %{days} jours + error_saving_recurring: "Il s'est produit une erreur lors de la sauvegarde de la t\xC3\xA2che r\xC3\xA9currente \\'%{description}\\'" + completed_more_than_x_days_ago: "Compl\xC3\xA9t\xC3\xA9 il y a plus de %{count} jours" + all_completed: "Toutes les actions r\xC3\xA9alis\xC3\xA9es" + feed_title_in_context: dans le contexte '%{context}' + pending: En attente + older_than_days: Plus ancien que %{count} jours + completed_tagged_page_title: "TRACKS::Les t\xC3\xA2ches termin\xC3\xA9es avec marquer %{tag_name}" + edit: Modifier + completed_actions_with: "Action compl\xC3\xA9t\xC3\xA9es avec le tag %{tag_name}" + deleted_success: "Action supprim\xC3\xA9e avec succ\xC3\xA8s." + completed_tasks_title: "TRACKS::T\xC3\xA2ches compl\xC3\xA9t\xC3\xA9es" + feed_title_in_project: dans le projet '%{project}' + clear_due_date: "Effacer la date d'\xC3\xA9ch\xC3\xA9ance" + error_removing_dependency: "Il s'est produit une erreur lors de la suppression de la d\xC3\xA9pendance" + hidden_actions: "Actions cach\xC3\xA9es" + show_on_date: Afficher le %{date} + was_due_on_date: "arriv\xC3\xA9e \xC3\xA0 \xC3\xA9ch\xC3\xA9ance le %{date}" + recurrence_period: "Periode de r\xC3\xA9currence" + deferred_actions_with: "Action report\xC3\xA9es avec le tag '%{tag_name}'" + confirm_delete: "Etes-vous s\xC3\xBBr de vouloir supprimer l'action '%{description}' ?" + recurring_deleted_success: "L'action r\xC3\xA9currente a \xC3\xA9t\xC3\xA9 supprim\xC3\xA9e avec succ\xC3\xA8s." + next_action_description: Description de la prochaine action + next_actions_title: Tracks - Prochaines Actions + deferred_tasks_title: TRACKS::Reporteur + no_completed_actions_with: "Pas d'actions compl\xC3\xA9t\xC3\xA9es avec le tag '%{tag_name}'" + clear_show_from_date: Effacer show from date + calendar_page_title: TRACKS::Calendrier + unresolved_dependency: "La valeur saisie dans le champ d\xC3\xA9pendance ne correspond pas \xC3\xA0 une action existante. Cette valeur ne sera pas sauvegard\xC3\xA9e avec le reste de l'action. Continuer ?" + in_hidden_state: "a l\\'\xC3\xA9tat cach\xC3\xA9" + completed_last_x_days: "Compl\xC3\xA9t\xC3\xA9 ces %{count} jours" + show_today: Afficher aujourd'hui + no_actions_found_title: "Aucune action trouv\xC3\xA9e" + next_actions_due_date: + overdue_by: "D\xC3\xA9pass\xC3\xA9e de %{days} jour" + due_today: "Ech\xC3\xA9ance aujourd'hui" + due_in_x_days: "Ech\xC3\xA9ance dans %{days} days" + overdue_by_plural: "D\xC3\xA9pass\xC3\xA9e de %{days} jours" + due_tomorrow: "Ech\xC3\xA9ance demain" + added_new_next_action_singular: "Nouvelle action suivante ajout\xC3\xA9e" + no_actions_with: "Il n'y pas d'actions incompl\xC3\xA8tes avec le tag '%{tag_name}' actuellement" + defer_x_days: + one: Reporter d'un jour + other: Report de %{count} jours + no_completed_actions: "Il n'y a pas d'actions compl\xC3\xA9t\xC3\xA9es actuellement." + has_x_pending: + one: A une action en attente + other: A %{count} actions en attente + feeds: + completed: "Compl\xC3\xA9t\xC3\xA9 : %{date}" + due: "Ech\xC3\xA9ance : %{date}" + deferred_pending_actions: "Actions report\xC3\xA9es ou en attente" + delete_action: Supprimer action + error_deleting_recurring: "Il s'est produit une erreur lors de la suppression de la t\xC3\xA2che r\xC3\xA9currente \\'%{description}\\'" + recurring_todos: "T\xC3\xA2ches r\xC3\xA9currentes" + delete: Supprimer + drag_action_title: "D\xC3\xA9placer sur une autre action pour la rendre d\xC3\xA9pendante de cette action" + cannot_add_dependency_to_completed_todo: "Impossible d'ajouter cette action comme d\xC3\xA9pendance d'une action compl\xC3\xA9t\xC3\xA9e !" + no_last_completed_actions: "Aucune action achev\xC3\xA9e trouve" + depends_on: "D\xC3\xA9pend de" + tickler_items_due: + one: "Un \xC3\xA9l\xC3\xA9ment du reporteur est arriv\xC3\xA9 \xC3\xA0 \xC3\xA9ch\xC3\xA9ance - rafraichir la page pour le voir." + other: "%{count} \xC3\xA9l\xC3\xA9ments du reporteur sont arriv\xC3\xA9s \xC3\xA0 \xC3\xA9ch\xC3\xA9ance - rafraichir la page pour les voir." + action_marked_complete: "L'action '%{description}' a \xC3\xA9t\xC3\xA9 marqu\xC3\xA9e comme %{completed}" + new_related_todo_not_created_short: "n'a pas cr\xC3\xA9\xC3\xA9 la t\xC3\xA2che" + completed_today: + one: "Vous avez compl\xC3\xA9t\xC3\xA9 une action aujourd'hui" + other: "Vous avez compl\xC3\xA9t\xC3\xA9 %{count} action aujourd'hui" + added_new_next_action_plural: "Nouvelles actions suivantes ajout\xC3\xA9es" + completed_rest_of_week: "Compl\xC3\xA9t\xC3\xA9 dans le reste de cette semaine" + calendar: + get_in_ical_format: Obtenir ce calendrier au format iCal + due_next_week: "A r\xC3\xA9aliser la semaine prochaine" + no_actions_due_next_week: "Pas d'actions \xC3\xA0 terminer la semaine prochaine" + due_this_week: "A r\xC3\xA9aliser avant la fin de cette semaine" + due_today: "A r\xC3\xA9aliser aujourd'hui" + no_actions_due_today: "Pas d'action \xC3\xA0 terminer aujourd'hui" + due_next_month_and_later: "A r\xC3\xA9aliser dans %{month} et plus" + no_actions_due_after_this_month: "Pas d'actions \xC3\xA0 r\xC3\xA9aliser apr\xC3\xA8s ce mois" + due_this_month: "A r\xC3\xA9aliser avant la fin de %{month}" + no_actions_due_this_month: "Pas d'actions \xC3\xA0 terminer pour ce mois" + error_starring: "Impossible d'actionner l'\xC3\xA9toile de cette tache \\'%{description}\\'" + show_tomorrow: Afficher demain + action_deferred: "L'action '%{description}' a \xC3\xA9t\xC3\xA9 report\xC3\xA9" + recurrence: + ends_on_date: Fini le %{date} + every_work_day: "Chaque jour ouvr\xC3\xA9" + ends_on_number_times: Fini au bout de %{number} fois + recurrence_on_due_date: "La date d'\xC3\xA9ch\xC3\xA9ance de la t\xC3\xA2che" + weekly_options: "Param\xC3\xA8tres pour les actions r\xC3\xA9currentes hebdomadaires" + weekly: Toutes les semaines + monthly_options: "Param\xC3\xA8tres pour les actions r\xC3\xA9currentes mensuelles" + monthly: Mensuellement + starts_on: "D\xC3\xA9marre le" + daily_options: "Param\xC3\xA8tres des actions r\xC3\xA9currentes quotidiennes" + pattern: + third: "troisi\xC3\xA8me" + month_names: + - + - Janvier + - "F\xC3\xA9vrier" + - Mars + - Avril + - Mai + - Juin + - Juillet + - Aout + - Septembre + - Octobre + - Novembre + - "D\xC3\xA9cembre" + every_n: tous les %{n} + second: seconde + every_xth_day_of_every_n_months: tous les %{x} %{day} tous les %{n_months} + on_day_n: le %{n}e jour + weekly: Toutes les semaines + from: de + last: dernier + every_day: chaque jour + the_xth_day_of_month: le %{x} %{day} de %{month} + times: pour %{number} fois + day_names: + - Dimanche + - Lundi + - Mardi + - Mercredi + - Jeudi + - Vendredi + - Samedi + on_work_days: "les jours ouvr\xC3\xA9s" + every_year_on: "chaque ann\xC3\xA9e le %{date}" + first: premier + show: montrer + fourth: "quatri\xC3\xA8me" + due: "Ech\xC3\xA9ance" + until: jusqu'a + every_month: chaque mois + show_option_always: toujours + daily: Quotidiennement + recurrence_on_options: "Activer la r\xC3\xA9currence" + yearly_every_x_day: Chaque %{month} %{day} + daily_every_number_day: Tous les %{number} jour(s) + show_options: "Montrer la t\xC3\xA2che" + weekly_every_number_week: Returns every %{number} week on + ends_on: Fini le + yearly_options: "Param\xC3\xA8tres pour les actions r\xC3\xA9currentes annuelles" + show_days_before: "%{days} jours avant la date d'\xC3\xA9ch\xC3\xA9ance de la t\xC3\xA2che" + from_tickler: "la date de la t\xC3\xA2che provient du reporteur (pas de date d\\'\xC3\xA9ch\xC3\xA9ance d\xC3\xA9finie)" + yearly_every_xth_day: Chaque %{day} %{day_of_week} de %{month} + no_end_date: Pas de date de fin + day_x_on_every_x_month: Le %{day} tous les %{month} mois + yearly: Tous les ans + monthly_every_xth_day: Le %{day} %{day_of_week} tous les %{month} mois + tagged_page_title: "TRACKS::Tagg\xC3\xA9 avec %{tag_name}'" + no_completed_recurring: "Il n'y a pas d'actions r\xC3\xA9currentes compl\xC3\xA9t\xC3\xA9es actuellement" + added_dependency: "%{dependency} ajout\xC3\xA9e comme d\xC3\xA9pendance" + all_completed_tagged_page_title: "TRACKS::Toutes les t\xC3\xA2ches accomplies par marquer %{tag_name}" + no_deferred_actions: "Il n'y a pas d'actions report\xC3\xA9es actuellement" + completed_rest_of_month: "Compl\xC3\xA9t\xC3\xA9 dans le reste de ce mois-ci" + recurrence_completed: "Il n'y a pas d'action suivante apr\xC3\xA8s l'action r\xC3\xA9currente que vous venez de terminer. Fin de la r\xC3\xA9currence" + no_actions_found: "Il n'y pas d'actions incompl\xC3\xA8tes actuellement." + in_pending_state: en attente + error_toggle_complete: "Impossible de marquer cette tache comme compl\xC3\xA9t\xC3\xA9e" + due: "Ech\xC3\xA9ance" + action_marked_complete_error: "L'action '%{description}' n'a PAS \xC3\xA9t\xC3\xA9 marqu\xC3\xA9e comme %{completed} a cause d'une erreur sur le serveur " + next_actions_description_additions: + completed: dans les %{count} derniers jours + due_date: "avec au plus la date d'\xC3\xA9ch\xC3\xA9ance %{due_date}" + action_saved_to_tickler: "Action sauvegard\xC3\xA9e dans le Reporteur" + overdue: En retard + recurring_action_saved: "Action r\xC3\xA9currente sauv\xC3\xA9e" + depends_on_separate_with_commas: "D\xC3\xA9pend de (s\xC3\xA9parer avec des virgules)" + completed_in_archive: + one: "Il n'y a pas d'action compl\xC3\xA9t\xC3\xA9e dans l'archive" + other: "Il y a %{count} actions compl\xC3\xA9t\xC3\xA9es dans l'archive" + to_tickler: Vers le reporteur + no_incomplete_actions: "Il n'y a pas d'actions incompl\xC3\xA8tes" + add_new_recurring: "Ajouter une nouvelle action r\xC3\xA9currente" + notes: + delete_note_title: Supprimer la note '%{id}' + delete_confirmation: Etes-vous sur de vouloir supprimer la note '%{id}' ? + delete_item_title: "Supprimer l'\xC3\xA9l\xC3\xA9ment" + deleted_note: Supprimer la note '%{id}' + note_link_title: Voir note %{id} + show_note_title: Voir note + note_location_link: "ln:" + edit_item_title: "Modifier l'\xC3\xA9l\xC3\xA9ment" + no_notes_available: "Il n'y a actuellement aucune note: ajouter des notes aux projets sur les pages individuelles des projets." + note_header: Note %{id} + delete_note_confirm: Etes-vous sur de vouloir supprimer la note '%{id}' ? + preferences: + open_id_url: Votre URL OpenID est + staleness_starts_after: "\"date de fraicher\" d\xC3\xA9pass\xC3\xA9e \xC3\xA0 pr\xC3\xA8s %{days} days" + change_identity_url: "Modifier votre URL d'identit\xC3\xA9" + change_password: Modifier votre mot de passe + page_title: "TRACKS::Pr\xC3\xA9f\xC3\xA9rences" + token_description: Jeton (pour flux et utilisation API) + title: "Vos pr\xC3\xA9f\xC3\xA9rences" + is_false: faux + show_number_completed: "Montrer %{number} items r\xC3\xA9alis\xC3\xA9s" + page_title_edit: "TRACKS::Editer les pr\xC3\xA9f\xC3\xA9rences" + is_true: vrai + edit_preferences: "Editer les pr\xC3\xA9f\xC3\xA9rences" + sms_context_none: Aucun + generate_new_token: "G\xC3\xA9n\xC3\xA9rer un nouveau jeton" + token_header: Votre jeton + current_authentication_type: Votre type d'authentification est %{auth_type} + authentication_header: Votre authentification + change_authentication_type: Modifier votre type d'authentification + generate_new_token_confirm: "Etes vous s\xC3\xBBr ? G\xC3\xA9n\xC3\xA9rer un nouveau jeton va remplacer le jeton existant et en interdire les utilisations externes." + tabs: + authentication: Authentification + tracks_behavior: Comportements Tracks + profile: Profil + date_and_time: Date et heure + errors: + user_unauthorized: "401 Non autoris\xC3\xA9: Administrateur seulement." + projects: + default_context_set: "D\xC3\xA9finir le contexte par d\xC3\xA9faut du projet \xC3\xA0 %{default_context}" + no_actions_in_project: "Il n'y pas d'action incompl\xC3\xA8tes pour ce projet" + deferred_actions: "Actions report\xC3\xA9es pour ce projet" + was_marked_hidden: "est cach\xC3\xA9" + edit_project_title: Editer le projet + default_tags_removed_notice: Supprimer les tags par defaut + all_completed_tasks_title: "TRACKS::Tous les Actions Achev\xC3\xA9 en Projet '%{project_name}'" + hide_form: Cacher le formulaire + page_title: "TRACKS::Projet: %{project}" + to_new_project_page: "Aller \xC3\xA0 la page du nouveau projet" + deferred_actions_empty: "Il n'y a pas d'actions report\xC3\xA9es pour ce projet" + show_form_title: "Cr\xC3\xA9er un nouveau projet" + this_project: Ce projet + project_state: Le projet est %{state} + list_completed_projects: "TRACKS::Liste des projets achev\xC3\xA9s" + no_notes_attached: "Il n'y a actuellement aucune note attach\xC3\xA9e \xC3\xA0 ce projet" + no_last_completed_recurring_todos: "Non termin\xC3\xA9 actions r\xC3\xA9p\xC3\xA9titives trouv\xC3\xA9es" + todos_append: dans ce projet + notes: Notes + no_last_completed_projects: "Pas de projets termin\xC3\xA9s trouv\xC3\xA9s" + notes_empty: Il n'y a pas de notes pour ce projet + no_projects: Il n'y a actuellement aucun projet + hide_form_title: Cacher le formulaire nouveau projet + delete_project: Supprimer projet + completed_actions_empty: "Il n'y a pas d'actions r\xC3\xA9alis\xC3\xA9es pour ce projet" + with_no_default_context: "sans contexte par d\xC3\xA9faut" + show_form: Ajouter un projet + actions_in_project_title: Actions pour ce projet + delete_project_confirmation: "Etes vous s\xC3\xBBr de vouloir supprimer le projet '%{name}' ?" + with_default_context: "avec '%{context_name}' comme contexte par d\xC3\xA9faut" + project_saved_status: "Projet sauvegard\xC3\xA9" + is_active: est actif + completed_projects: "Projets r\xC3\xA9alis\xC3\xA9s" + add_note: Ajouter une note + add_project: Ajouter projet + list_projects: TRACKS::Liste des Projets + with_default_tags: et avec '%{tags'} comme tags par defaut + settings: "Param\xC3\xA8tres" + set_default_tags_notice: "D\xC3\xA9finir les tags par d\xC3\xA9faut du projet \xC3\xA0 %{default_tags}" + delete_project_title: Supprimer le projet + hidden_projects: "Projets cach\xC3\xA9s" + completed_tasks_title: "TRACKS::Liste des actions men\xC3\xA9es \xC3\xA0 terme dans Projet '%{project_name}'" + add_note_submit: Ajouter note + completed_actions: "Actions r\xC3\xA9alis\xC3\xA9es pour ce projet" + was_marked_complete: "est compl\xC3\xA9t\xC3\xA9" + default_context_removed: "Contexte par d\xC3\xA9faut supprim\xC3\xA9" + state: Le projet est %{state} + status_project_name_changed: "Le nom du projet a \xC3\xA9t\xC3\xA9 modifi\xC3\xA9" + default_context: "Le contexte par d\xC3\xA9faut pour ce projet est %{context}" + active_projects: Projets actifs + no_default_context: Ce projet n'a pas de contexte par defaut + with_no_default_tags: "et sans tags par d\xC3\xA9faut" + edit_project_settings: "Modifier les param\xC3\xA8tres du projet" + states: + hidden_plural: "Cach\xC3\xA9s" + completed: "Complet\xC3\xA9" + completed_plural: "Complet\xC3\xA9s" + visible_plural: Visibles + active_plural: Actifs + visible: Visible + hidden: !binary | + Q2FjaMOp + + active: Actif + time: + am: am + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + time: "%H:%M" + short: "%d %b %H:%M" + month_day: "%B %d" + long: "%B %d, %Y %H:%M" + pm: pm + date: + month_names: + - + - janvier + - "f\xC3\xA9vrier" + - mars + - avril + - mai + - juin + - juillet + - Aout + - septembre + - octobre + - novembre + - "d\xC3\xA9cembre" + abbr_day_names: + - dim + - lun + - mar + - mer + - jeu + - ven + - sam + order: + - :day + - :month + - :year + formats: + only_day: "%e" + longer: "%A, %d %b %Y" + default: "%d/%m/%Y" + short: "%e %b" + month_day: "%d. %B" + long: "%e %B %Y" + day_names: + - dimanche + - lundi + - mardi + - mercredi + - jeudi + - vendredi + - samedi + abbr_month_names: + - + - jan. + - !binary | + RsOpdi4= + + - mar. + - avr. + - mai + - juin + - juil. + - aout + - sept. + - oct. + - nov. + - d\xC3\xA9c. + will_paginate: + previous_label: !binary | + wqtQcsOpY8OpZGVudA== + + page_entries_info: + multi_page: "Affiche %{model} de %{from} - %{to} \xC3\xA0 %{count} au total" + single_page_html: + one: Voir de 1 %{model} + other: Afficher tous les %{count} %{model} + zero: "Aucun %{model} trouv\xC3\xA9s" + single_page: + one: Voir de 1 %{model} + other: Afficher tous les %{count} %{model} + zero: "Aucun %{model} trouv\xC3\xA9s" + multi_page_html: "Affiche %{model} %{from} - %{to} \xC3\xA0 la %{count} au total" + page_gap: ... + next_label: "Suivant \xC2\xBB" + support: + array: + last_word_connector: ", et" + words_connector: "," + two_words_connector: et + select: + prompt: "Veuillez s\xC3\xA9lectionner" + footer: + send_feedback: Envoyer un feedback sur %{version} + shared: + multiple_next_actions: Actions suivante multiples (une sur chaque ligne) + make_actions_dependent: "Faire actions d\xC3\xA9pendantes les unes des autres" + hide_form: Cacher le formulaire + toggle_single: Ajouter action suivante + add_actions: Ajouter actions + add_action: Ajouter action + tags_for_all_actions: Tags pour toutes les actions (sep. avec des virgules) + context_for_all_actions: Contexte pour toutes les actions + toggle_multi: Ajouter plusieurs actions suivantes + toggle_single_title: Ajouter une nouvelle action suivante + project_for_all_actions: Projet pour toutes les actions + separate_tags_with_commas: "s\xC3\xA9parer avec des virgules" + toggle_multi_title: Basculer formulaire action simple/multiple + hide_action_form_title: Cacher le formulaire nouvelle action + sidebar: + list_name_active_contexts: Contextes actifs + list_name_active_projects: Projets actifs + list_empty: Aucun + list_name_completed_projects: "Projets r\xC3\xA9alis\xC3\xA9s" + list_name_hidden_projects: "Projets cach\xC3\xA9s" + list_name_hidden_contexts: "Contextes cach\xC3\xA9s" + contexts: + delete_context_title: Supprimer contexte + all_completed_tasks_title: "TRACKS::Toutes les actions Achev\xC3\xA9 en le contexte '%{context_name}'" + hide_form: Cacher le formulaire + show_form_title: Ajouter un contexte + delete_context_confirmation: "Etes vous s\xC3\xBBr de vouloir supprimer le contexte %{name}? Toutes les actions (r\xC3\xA9p\xC3\xA9titives) de ce contexte seront \xC3\xA9galement supprim\xC3\xA9es !" + delete_context: Supprimer contexte + hide_form_title: Cacher le formulaire nouveau contexte + edit_context: Modifier contexte + hidden_contexts: "Contextes cach\xC3\xA9s" + no_contexts_active: Actuellement, il n'y a pas de contextes actifs + context_hide: "Cach\xC3\xA9 de la premi\xC3\xA8re page ?" + show_form: "Cr\xC3\xA9er un nouveau contexte" + visible_contexts: Contextes visibles + save_status_message: "Contexte sauvegard\xC3\xA9" + add_context: Ajouter un contexte + update_status_message: "Le nom du contexte \xC3\xA0 \xC3\xA9t\xC3\xA9 modifi\xC3\xA9" + context_name: Nom du Contexte + status_active: Le Contexte est actif + new_context_post: "'sera aussi cr\xC3\xA9\xC3\xA9. Etes-vous s\xC3\xBBr ?" + completed_tasks_title: "TRACKS::actions Achev\xC3\xA9 en le contexte '%{context_name}'" + last_completed_in_context: dans ce contexte (dernier %{number}) + context_deleted: "Contexte \\'%{name}\\' supprim\xC3\xA9" + no_contexts_hidden: "Actuellement, il n'y a pas de contextes cach\xC3\xA9s" + new_context_pre: Nouveau contexte ' + no_actions: "Actuellement, il n'y pas d'actions incompl\xC3\xA8tes dans ce contexte" + status_hidden: "Le Contexte est cach\xC3\xA9" + feedlist: + actions_due_today: Actions devant se terminer aujourd'hui ou avant + choose_context: Choisir le contexte dont vous voulez un flux + all_contexts: Tous les contextes + rss_feed: Flux RSS + legend: "L\xC3\xA9gende" + ical_feed: Flux iCal + choose_project: Choisir le projet dont vous voulez un flux + all_projects: Tous les projets + active_projects_wo_next: Projets actifs avec aucune action suivante + project_needed: Il faut au moins un projet pour le flux + select_feed_for_project: Selectionner le flux pour ce projet + active_starred_actions: "Toutes les actions pr\xC3\xA9ferr\xC3\xA9es actives" + context_needed: Il faut au moins un contexte pour le flux + select_feed_for_context: Selectionner un flux pour ce contexte + projects_and_actions: Projets actifs et leurs actions + notice_incomplete_only: "NB: Les flux ne montrent que les actions incompl\xC3\xA8tes, sauf indication contraire" + actions_due_next_week: Actions devant se terminer dans les 7 prochains jours ou moins + last_fixed_number: "Derni\xC3\xA8res %{number} actions" + all_actions: Toutes les actions + actions_completed_last_week: "Actions r\xC3\xA9alis\xC3\xA9es dans les 7 derniers jours" + context_centric_actions: "Flux des actions dans un contexte sp\xC3\xA9cifique" + plain_text_feed: Flux texte + project_centric: "Flux des actions incompl\xC3\xA8tes d'un projet sp\xC3\xA9cifique" + users: + failed_to_delete_user: "La suppression de l'utilisateur {username} \xC3\xA0 \xC3\xA9chou\xC3\xA9" + destroy_successful: "Utilisateur %{login} supprim\xC3\xA9 avec succ\xC3\xA8s" + total_contexts: Total contextes + openid_url_verified: "Vous avez v\xC3\xA9rifi\xC3\xA9 avec succ\xC3\xA8s votre identit\xC3\xA9 comme %{url} et d\xC3\xA9fini votre type authentification comme OpenID" + first_user_heading: "Bienvenu \xC3\xA0 TRAKS. Pour commencer, veuillez cr\xC3\xA9er un compte administrateur" + auth_type_update_error: "Un probl\xC3\xA8me est survenu lors de la modification du type d'authentification : %{error_messages}" + successfully_deleted_user: "Utilisateur %{username} supprim\xC3\xA9 avec succ\xC3\xA8s" + new_token_generated: "Nouveau token g\xC3\xA9n\xC3\xA9r\xC3\xA9 avec succ\xC3\xA9s" + total_projects: Total projets + signup_successful: "Utilisateur %{username} cr\xC3\xA9\xC3\xA9 avec succ\xC3\xA8s." + user_created: "Utilisateur cr\xC3\xA9\xC3\xA9." + change_password_submit: Modifier mot de passe + no_signups_title: TRACKS::Pas de signups + account_signup: "Cr\xC3\xA9er un compte" + password_updated: "Mot de passe modifi\xC3\xA9." + manage_users: "G\xC3\xA9rer utilisateurs" + auth_type_updated: "Type d'authentification modifi\xC3\xA9." + total_actions: Total actions + desired_login: "Login souhait\xC3\xA9" + signup: "Cr\xC3\xA9ation" + confirm_password: Confirmer le mot de passe + new_user_heading: "Cr\xC3\xA9er un nouvel utilisateur:" + change_password_prompt: Entrer votre nouveau mot de passe dans les champs ci-dessous et cliquer sur 'Modifier mot de passe' pour remplacer votre mot de passe actuel par le nouveau. + password_confirmation_label: Confirmer mot de passe + destroy_error: Une erreur s'est produite lors de la suppression de l'utilisateur %{login} + choose_password: Choisir le mot de passe + change_password_title: TRACKS::Modifier mot de passe + change_auth_type_title: TRACKS::Modifier le type d'authentification + label_auth_type: Type d'authentification + new_password_label: Nouveau mot de passe + register_with_cas: Avec votre nom d'utilisateur CAS + new_user_title: "TRACKS::Cr\xC3\xA9er un administrateur" + destroy_user: Supprimer utilisateur + total_users_count: Vous avez %{count} utilisateurs + signup_new_user: "Cr\xC3\xA9er un nouvel utilisateur" + destroy_confirmation: "Attention : cela va supprimer l'utilisateur '%{login}', toutes ses actions, contextes, projets et notes. Etes-vous s\xC3\xBBr de vouloir continuer ?" + you_have_to_reset_your_password: "Vous devez r\xC3\xA9initialiser votre mot de passe" + openid_ok_pref_failed: "Vous avez v\xC3\xA9rifi\xC3\xA9 avec succ\xC3\xA8s votre identit\xC3\xA9 comme %{url} mais un probl\xC3\xA8me est survenu lors de la sauvegarde de vos pr\xC3\xA9f\xC3\xA9rences d'authentification." + auth_change_submit: Modifier le type d'authenfication + identity_url: "URL Identit\xC3\xA9" + change_authentication_type: Modifier le type d'authentification + select_authentication_type: "S\xC3\xA9lectionner votre nouveau type d'authentification et cliquer sur 'Modifier type d'authenfication' pour remplacer les param\xC3\xA8tres actuels." + total_notes: Total notes + datetime: + prompts: + minute: Minute + second: Secondes + month: Mois + hour: Heure + day: Jour + year: !binary | + QW5uw6ll + + distance_in_words: + less_than_x_minutes: + one: moins d'une minute + other: moins de %{count} minutes + zero: Moins de 1 minute + almost_x_years: + one: presque 1 an + other: presque %{count} ans + x_days: + one: 1 jour + other: "%{count} jours" + x_seconds: + one: 1 seconde + other: "%{count} secondes" + less_than_x_seconds: + one: moins d'1 seconde + other: moins de %{count} secondes + zero: Moins de 1 seconde + x_months: + one: 1 mois + other: "%{count} mois" + x_minutes: + one: 1 minute + other: "%{count} minutes" + about_x_hours: + one: environ 1 heure + other: environ %{count} heures + about_x_months: + one: environ 1 mois + other: environ %{count} mois + about_x_years: + one: environ 1 an + other: environ %{count} ans + over_x_years: + one: plus d'1 an + other: plus de %{count} ans + half_a_minute: une demi-minute + login: + login_cas: Aller au CAS + user_no_expiry: "Rester connect\xC3\xA9" + sign_in: Se connecter + openid_identity_url_not_found: "D\xC3\xA9sol\xC3\xA9, aucun utilisateur avec cette identit\xC3\xA9 URL n'existe (%{identity_url})" + cas_no_user_found: Bonjour, %{username}! Vous n'avez pas de compte sur Tracks. + cas_login: Login CAS + successful_with_session_info: "La connexion \xC3\xA0 r\xC3\xA9ussi:" + please_login: Veuillez vous connecter pour utiliser Tracks + cas_logged_in_greeting: "Bonjour, %{username}! Vous \xC3\xAAtes authentifi\xC3\xA9." + cas_username_not_found: "D\xC3\xA9sol\xC3\xA9, aucun utilisateur avec ce nom CAS n'existe (%{username})" + mobile_use_openid: ... ou ce connecter avec un OpenID + cas_create_account: "Si vous voulez vous inscrire aller \xC3\xA0 %{signup_link}" + cas_signup_link: Demander un compte + account_login: Identifiant du compte + successful: "La connexion \xC3\xA0 r\xC3\xA9ussi. Bienvenue !" + session_will_not_expire: la session n'expire jamais. + session_time_out: "La session \xC3\xA0 expir\xC3\xA9. Merci de %{link}" + session_will_expire: "la session expire apr\xC3\xA8s %{hours} heure(s) d'inactivit\xC3\xA9." + option_separator: ou, + login_standard: "retourner \xC3\xA0 l'\xC3\xA9cran de connexion standard" + unsuccessful: "La connexion \xC3\xA0 \xC3\xA9chou\xC3\xA9." + log_in_again: Se reconnecter + logged_out: "Vous avez \xC3\xA9t\xC3\xA9 d\xC3\xA9connect\xC3\xA9 de Tracks." + login_with_openid: se connecter avec un OpenID + search: + contexts_matching_query: "Contextes correspondant \xC3\xA0 la requ\xC3\xAAte" + tags_matching_query: "Tags correspondant \xC3\xA0 la requ\xC3\xAAte" + notes_matching_query: "Notes correspondant \xC3\xA0 la requ\xC3\xAAte" + no_results: "Aucun r\xC3\xA9sultat \xC3\xA0 votre recherche." + todos_matching_query: "AFaire (todos) correspondant \xC3\xA0 la requ\xC3\xAAte" + projects_matching_query: "Projets correspondant \xC3\xA0 la requ\xC3\xAAte" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index c2c320c5..668b0d9e 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1,50 +1,67 @@ --- nl: + integrations: + opensearch_description: Zoek in Tracks + applescript_next_action_prompt: "Omschrijving van de actie:" + gmail_description: Gadget om Tracks toe te voegen aan Gmail als een gadget + applescript_success_after_id: gemaakt + applescript_success_before_id: Nieuwe actie met ID common: + recurring_todos: Herhalende acties back: Terug actions: Acties third: Derde - go_back: Ga terug add: Toevoegen logout: Log uit + go_back: Ga terug + previous: Vorige none: Geen + week: week + second: Tweede cancel: Annuleer optional: optioneel - second: Tweede - notes: Notities + month: maand server_error: Een fout heeft op de server plaatsgevonden forum: Forum - action: Actie + notes: Notities last: Laatste + action: Actie projects: Projecten project: Project - ok: Ok contribute: Bijdragen - numbered_step: Stap %{number} + ok: Ok first: Eerste website: Website - drag_handle: SLEEP + numbered_step: Stap %{number} sort: by_task_count_title: Sorteer op aantal acties - by_task_count_title_confirm: Weet u zeker dat u deze projecten alphabetisch wilt sorteren? Dat zal de huidige sorteervolgorde aanpassen. - alphabetically: Alphabetisch + by_task_count_title_confirm: Weet u zeker dat u deze op aantal acties wilt sorteren? Dat zal de huidige sorteervolgorde aanpassen. + alphabetically: Alfabetisch sort: Sorteer - alphabetically_title: Sorteer projecten alphabetisch - alphabetically_confirm: Weet u zeker dat u deze projecten alphabetisch wilt sorteren? Dat zal de huidige sorteervolgorde aanpassen. - by_task_count: Bij aantal acties - create: Maken - contexts: Contexten + alphabetically_confirm: Weet u zeker dat u deze projecten alfabetisch wilt sorteren? Dat zal de huidige sorteervolgorde aanpassen. + alphabetically_title: Sorteer projecten alfabetisch + by_task_count: Op aantal acties fourth: Vierde - context: Context + create: Maken errors_with_fields: Er waren problemen met de volgende velden description: Beschrijving + context: Context + drag_handle: SLEEP + contexts: Contexten + next: Volgende + todo: actie + months: maanden + forth: Vierde update: Bijwerken - bugs: Fouten + weeks: weken wiki: Wiki - ajaxError: Er is een fout opgetreden bij het ophalen van gegevens van de server + bugs: Fouten email: E-mail + ajaxError: Er is een fout opgetreden bij het ophalen van gegevens van de server search: Zoeken layouts: + toggle_contexts_title: Maak ingeklapte contexten (on)zichtbaar + toggle_contexts: Toggle ingeklapte contexten toggle_notes: Toggle notities next_actions_rss_feed: RSS-feed van de acties toggle_notes_title: Toggle alle notities @@ -63,37 +80,31 @@ nl: api_docs: REST API Docs feeds: Feeds starred: Ster - notes_title: Toon alle notities stats: Statistieken - tickler_title: Tickler + notes_title: Toon alle notities manage_users: Beheren gebruikers - preferences: Voorkeuren + tickler_title: Tickler export_title: Import en export van gegevens + preferences: Voorkeuren integrations_: Integreer Tracks calendar_title: Kalender met acties met deadline feeds_title: Zie een lijst met beschikbare feeds recurring_todos_title: Beheren terugkerende acties completed_tasks: Gereed stats_title: Zie je statistieken - tickler: Tickler home_title: Start + tickler: Tickler starred_title: Zie je ster acties organize: Organiseer view: Bekijk completed_tasks_title: Afgerond home: Start - export: Export contexts_title: Contexten + export: Export projects_title: Projecten preferences_title: Toon mijn voorkeuren - calendar: Agenda search: Zoeken in alle items - integrations: - opensearch_description: Zoek in Tracks - gmail_description: Gadget om Tracks toe te voegen aan Gmail als een gadget - applescript_next_action_prompt: "Omschrijving van de actie:" - applescript_success_after_id: gemaakt - applescript_success_before_id: Nieuwe actie met ID + calendar: Agenda number: format: separator: "," @@ -123,13 +134,15 @@ nl: feed_description: Een overzicht van alle projecten voor %{username} todo: error_date_must_be_future: moet een datum in de toekomst zijn - preference: - due_styles: - - Deadline over ____ dagen - - Deadline op ____ user: error_context_not_associated: Context %{context} niet geassocieerd met gebruikers %{user}. error_project_not_associated: Project %{project} niet geassocieerd met gebruikers %{user}. + preference: + due_on: Deadline op %{date} + due_in: Deadline over %{days} dagen + due_styles: + - Deadline over ____ dagen + - Deadline op ____ data: import_successful: De import was succesvol import_errors: Er hebben zich fouten voorgedaan bij de import @@ -145,30 +158,32 @@ nl: predecessors: Afhankelijkheden notes: Notities project: Project - context: Context description: Beschrijving + context: Context due: Deadline + user: + last_name: Achternaam + first_name: Voornaam preference: show_hidden_projects_in_sidebar: Toon verborgen projecten in sidebar date_format: Datum formaat show_hidden_contexts_in_sidebar: Toon verborgen contexten in sidebar mobile_todos_per_page: Acties per pagina (mobiel) + staleness_starts: Begin van markeren openstaande actie verbose_action_descriptors: Context en project uitschrijven in actielijst sms_context: Standaard context voor email - staleness_starts: Begin van markeren openstaande actie show_number_completed: Aantal te tonen afgeronde acties title_date_format: Datum formaat in titel refresh: Ververs interval (in minuten) week_starts: Week start op - due_style: Deadline stijl - time_zone: Tijdzone - locale: Taal - show_project_on_todo_done: Ga naar project pagina wanneer actie gereed is - sms_email: Van email - show_completed_projects_in_sidebar: Toon afgeronde projecten in sidebar - user: last_name: Achternaam + time_zone: Tijdzone + due_style: Deadline stijl + locale: Taal + sms_email: Van email + show_project_on_todo_done: Ga naar project pagina wanneer actie gereed is first_name: Voornaam + show_completed_projects_in_sidebar: Toon afgeronde projecten in sidebar errors: models: project: @@ -183,275 +198,94 @@ nl: less_than_or_equal_to: moet kleiner of gelijk zijn aan %{count} confirmation: komt niet overeen met de configuratie blank: mag niet leeg zijn - invalid: mag niet een komma (',') karakter bevatten exclusion: is gereserveerd + invalid: mag niet een komma (',') karakter bevatten odd: moet oneven zijn too_short: is te kort (minimum is %{count} karakters) - empty: mag niet leeg zijn wrong_length: heeft de verkeerde lengte (moet %{count} karakters lang zijn) even: moet even zijn + empty: mag niet leeg zijn less_than: moet kleiner zijn dan %{count} equal_to: moet gelijk zijn aan %{count} greater_than: moet groter zijn dan %{count} too_long: is te lang (maximum is %{count} karakters) - accepted: moet geaccepteerd worden taken: is al gepakt + accepted: moet geaccepteerd worden not_a_number: is niet een getal inclusion: is niet opgenomen in de lijst + full_messages: + format: "%{attribute} %{message}" template: body: Er waren problemen met de volgende velden header: one: 1 fout voorkomt het kunnen bewaren van deze %{model} other: "%{count} fouten voorkomen dat dit %{model} bewaard kan worden" - full_messages: - format: "%{attribute} %{message}" - todos: - error_starring_recurring: Kon niet de ster van deze terugkerende actie niet omgezetten \'%{description}\' - show_from: Toon vanaf - recurring_action_deleted: Actie werd verwijderd. Omdat deze actie herhalend is. werd een nieuwe actie toegevoegd - completed_actions: Voltooide acties - completed_recurring: Afgesloten terugkerende todos - added_new_next_action: Nieuwe actie toegevoegd - blocked_by: Geblokkeerd door %{predecessors} - done: Voltooid? - star_action: Markeer deze actie met een ster - completed_recurrence_completed: Er is geen actie na de terugkerende actie die u new verwijderd heeft. De herhaling is voltooid - defer_date_after_due_date: Uitsteldatum is na de vervaldag. Gelieve vervaldag bewerken alvorens uitsteldatum aan te passen. - unable_to_add_dependency: Niet in staat om de afhankelijkheid toe te voegen - star_action_with_description: markeer de actie '%{description}' met een ster - tagged_with: gelabeld met ‘%{tag_name}’ - completed: Afgerond - no_deferred_actions_with: Geen uitgestelde acties met de tag '%{tag_name}' - no_hidden_actions: Momenteel zijn er geen verborgen acties gevonden - edit_action_with_description: Bewerk de actie '%{description}' - action_due_on: (deadline actie op %{date}) - list_incomplete_next_actions: Toon onvoltooide acties - archived_tasks_title: "TRACKS:: Gearchiveerde voltooide taken" - remove_dependency: Verwijder afhankelijkheid (zal niet de actie zelf verwijderen) - action_deleted_success: Actie succesvol verwijderd - tags: Tags (gescheiden door komma's) - context_changed: Context veranderd in '%{name}' - new_related_todo_created: Een nieuwe actie is toegevoegd, die behoort bij deze terugkerende todo - mobile_todos_page_title: Alle acties - add_another_dependency: Nog een afhankelijkheid toevoegen - delete_recurring_action_title: Verwijder de terugkerende actie - removed_predecessor: "'%{successor}' is verwijderd als afhankelijkheid van '%{predecessor}'." - recurring_actions_title: TRACKS::Terugkerende acties - next_action_needed: U dient ten minste een actie in te vullen - action_saved: Actie opgeslagen - scheduled_overdue: Gepland om %{days} dagen geleden te tonen - action_deleted_error: Verwijderen van de actie is mislukt - edit_action: Actie bewerken - added_new_context: Nieuwe context toegevoegd - next_actions_description: "Filter:" - set_to_pending: "'%{task}' als wachtend ingesteld" - list_incomplete_next_actions_with_limit: Toont de laatste %{count} onvoltooide acties - added_new_project: Nieuw project toegevoegd - next_actions_title_additions: - completed: acties voltooid - due_today: deadline vandaag - due_within_a_week: deadline binnen een week - older_completed_items: Oudere voltooide items - append_in_this_project: in dit project - error_deleting_item: Er is een fout opgetreden bij het verwijderen van het item '%{description}' - task_list_title: TRACKS::Toon acties - no_actions_due_this_week: Geen acties met deadline in rest van deze week - no_recurring_todos: Momenteel zijn er geen terugkerende acties - error_completing_todo: Er was een fout bij het voltooien / activeren van de terugkerende actie '%{description}' - convert_to_project: Maak project - no_deferred_pending_actions: Momenteel zijn er geen uitgestelde of wachtende acties - completed_last_day: Voltooid in de laatste 24 uur - delete_recurring_action_confirm: Weet u zeker dat u wilt de terugkerende actie '%{description}' wilt verwijderen? - new_related_todo_created_short: een nieuwe actie gemaakt - show_in_days: Toon over %{days} dagen - no_project: -- Geen project -- - error_saving_recurring: Er is een fout opgetreden het opslaan van de terugkerende actie '%{description}' - completed_more_than_x_days_ago: Voltooid meer dan %{count} dagen geleden - feed_title_in_context: in context '%{context}' - completed_actions_with: Afgeronde acties met de tag %{tag_name} - older_than_days: Ouder dan %{count} dagen - edit: Bewerken - pending: Wachtend - deleted_success: De actie werd met succes verwijderd. - completed_tasks_title: TRACKS::Voltooide taken - feed_title_in_project: In het project '%{project}' - clear_due_date: Maak deadline leeg - error_removing_dependency: Er is een fout opgetreden het verwijderen van de afhankelijke actie - hidden_actions: Verborgen acties - was_due_on_date: had deadline op %{date} - show_on_date: Toon op %{date} - recurrence_period: Herhaling periode - deferred_actions_with: Uitgestelde acties met de tag '%{tag_name}' - confirm_delete: Weet u zeker dat u de actie '%{description}' wilt verwijderen? - recurring_deleted_success: De recurrente actie is succesvol verwijderd. - next_actions_title: Tracks - Acties - next_action_description: Actie beschrijving - deferred_tasks_title: TRACKS::Tickler - no_completed_actions_with: Geen voltooide acties met de tag '%{tag_name}' - clear_show_from_date: Maak de datum Tonen Vanaf leeg - in_hidden_state: in verborgen toestand - calendar_page_title: TRACKS::Agenda - show_today: Toon vandaag - no_actions_found_title: Geen acties gevonden - completed_last_x_days: Voltooid in de laatste %{count} dagen - no_actions_with: Momenteel zijn er geen onvoltooide acties met de tag '%{tag_name}' - defer_x_days: - one: Een dag uitstellen - other: "%{count} dagen uitstellen" - added_new_next_action_singular: Nieuwe actie toegevoegd - no_completed_actions: Momenteel zijn er geen voltooide acties. - deferred_pending_actions: Uitgestelde/wachtende acties - has_x_pending: - one: Heeft een wachtende actie - other: Heeft %{count} wachtende acties - feeds: - completed: "Voltooid: %{date}" - due: "Deadline: %{date}" - delete_action: Verwijder actie - error_deleting_recurring: Er is een fout opgetreden bij het verwijderen van het item \'%{description}\' - recurring_todos: Terugkerende acties - delete: Verwijder - drag_action_title: Sleep naar een andere actie om deze afhankelijk te maken van die actie - cannot_add_dependency_to_completed_todo: Kan deze actie niet als een afhankelijkheid van een voltooide actie toevoegen! - depends_on: Hangt af van - tickler_items_due: - one: Een tickler item wordt nu zichtbaar - vernieuw de pagina om het te zien. - other: "%{count} tickerl items zijn nu zichtbaar - vernieuw de pagina om ze te zien." - action_marked_complete: De actie '%{description}' werd gemarkeerd als %{completed} - completed_today: - one: U heeft een actie tot nu toe vandaag voltooid. - other: U heeft %{count} acties tot nu toe vandaag voltooid. - added_new_next_action_plural: Nieuwe acties toegevoegd - new_related_todo_not_created_short: een nieuwe actie is niet gemaakt - error_starring: Kon niet de ster van deze actie niet omzetten \'%{description}\' - show_tomorrow: Toon morgen - calendar: - get_in_ical_format: Ontvang deze agenda in iCal-formaat - due_next_week: Deadline deze week - due_this_week: Deadline in rest van deze week - no_actions_due_next_week: Geen acties met deadline in volgende week - due_today: Deadline vandaag - no_actions_due_today: Geen acties met deadline vandaag - due_next_month_and_later: Deadline in %{month} en later - no_actions_due_after_this_month: Geen acties met deadline na deze maand - due_this_month: Deadline in rest van %{month} - no_actions_due_this_month: Geen acties met deadline in de rest van deze maand - tagged_page_title: TRACKS::Tagged met '%{tag_name}' - recurrence: - every_work_day: Elke werkdag - ends_on_number_times: Eindigt na %{number} keer - ends_on_date: Eindigt op %{date} - recurrence_on_due_date: de datum dat deadline van de actie is - weekly_options: Instellingen voor de wekelijkse terugkerende acties - weekly: Wekelijks - monthly_options: Instellingen voor maandelijks terugkerende acties - starts_on: Begint op - daily_options: Instellingen voor dagelijks terugkerende acties - monthly: Maandelijks - daily: Dagelijks - show_option_always: altijd - recurrence_on_options: Stel herhaling in op - yearly_every_x_day: Elke %{month} %{day} - daily_every_number_day: Elke %{number} dag(en) - ends_on: Eindigt op - weekly_every_number_week: Herhaalt elke %{number} weken op - show_options: Toon de actie - yearly_options: Instellingen voor jaarlijks terugkerende acties - show_days_before: "%{days} dagen v\xC3\xB3\xC3\xB3r de deadline van actie" - yearly_every_xth_day: De %{day} %{day_of_week} van %{month} - from_tickler: de datum dat de actie uit de tickler komt (geen deadline ingesteld) - no_end_date: Geen einddatum - day_x_on_every_x_month: Dag %{day} op elke %{month} maand - monthly_every_xth_day: De %{day} %{day_of_week} van elke %{month} maand - yearly: Jaarlijks - no_completed_recurring: Momenteel zijn er geen voltooide terugkerende acties - added_dependency: "%{dependency} als afhankelijkheid toegevoegd." - no_deferred_actions: Momenteel zijn er geen uitgestelde acties. - recurrence_completed: Er is geen volgende actie na de terugkerende actie die u zojuist hebt voltooid. De herhaling is voltooid - no_actions_found: Momenteel zijn er geen onafgeronde acties. - in_pending_state: in wachtende toestand - error_toggle_complete: Kon deze actie niet als afgerond markeren - due: Deadline - action_marked_complete_error: De actie '%{description}' is niet gemarkeerd als %{completed} vanwege een fout op de server. - action_saved_to_tickler: Actie opgeslagen in tickler - depends_on_separate_with_commas: Afhankelijk van (gescheiden door komma's) - recurring_action_saved: Terugkerende actie opgeslagen - completed_in_archive: - one: Er is een voltooide actie in het archief. - other: Er zijn %{count} afgeronde acties in het archief. - to_tickler: naar tickler - next_actions_description_additions: - completed: in de afgelopen %{count} dagen - due_date: met een deadline %{due_date} of eerder - overdue: Achterstallig - add_new_recurring: Voeg een nieuwe terugkerende actie toe - no_incomplete_actions: Er zijn geen onvoltooide acties stats: - tag_cloud_description: Deze tag cloud bevat tags van alle acties (afgerond, niet voltooid, zichtbaar en / of verborgen) tag_cloud_90days_title: Tag cloud met acties in afgelopen 90 dagen - actions: Acties totals_active_project_count: Van deze zijn %{count} actieve projecten + actions: Acties tag_cloud_title: Tag Cloud voor alle acties + tag_cloud_description: Deze tag cloud bevat tags van alle acties (afgerond, niet voltooid, zichtbaar en / of verborgen) + actions_avg_completion_time: Van al uw afgeronde acties, de gemiddelde tijd dat dit in beslag nam is %{count} dagen. actions_last_year_legend: number_of_actions: Aantal acties months_ago: Maanden geleden totals_first_action: Sinds uw eerste actie op %{date} - actions_avg_completion_time: Van al uw afgeronde acties, de gemiddelde tijd dat dit in beslag nam is %{count} dagen. - totals_action_count: u heeft een totaal van %{count} acties - legend: - number_of_days: Aantal dagen geleden - actions: Acties - number_of_actions: Aantal acties - day_of_week: Dag van de week - running_time: Looptijd van een actie (weken) - percentage: Percentage - months_ago: Maanden geleden top10_longrunning: Top 10 langstlopende projecten - actions_dow_30days_title: Dag van de week (laatste 30 dagen) - totals_deferred_actions: waarvan %{count} uitgestelde acties in de tickler zijn - current_running_time_of_incomplete_visible_actions: Huidige looptijd van onvolledige zichtbare acties + totals_action_count: u heeft een totaal van %{count} acties running_time_legend: actions: Acties percentage: Percentage weeks: Looptijd van een actie (weken). Klik op een balk voor meer info + totals_deferred_actions: waarvan %{count} uitgestelde acties in de tickler zijn + current_running_time_of_incomplete_visible_actions: Huidige looptijd van onvolledige zichtbare acties + legend: + actions: Acties + number_of_days: Aantal dagen geleden + number_of_actions: Aantal acties + day_of_week: Dag van de week + percentage: Percentage + running_time: Looptijd van een actie (weken) + months_ago: Maanden geleden + actions_dow_30days_title: Dag van de week (laatste 30 dagen) + totals_actions_completed: "%{count} van deze zijn voltooid." totals_incomplete_actions: U heeft %{count} onvolledige acties totals_unique_tags: Van deze tags zijn %{count} uniek. actions_avg_completed_30days: en voltooide een gemiddelde van %{count} acties per dag. top5_contexts: Top 5 contexten actions_lastyear_title: Acties in de afgelopen 12 maanden - totals_actions_completed: "%{count} van deze zijn voltooid." actions_last_year: Acties in de afgelopen jaren totals_context_count: U heeft %{count} contexten. totals_visible_context_count: Van deze zijn %{count} zichtbare contexten - totals_blocked_actions: "%{count} zijn afhankelijk van de voltooiing van hun acties." projects: Projecten + totals_blocked_actions: "%{count} zijn afhankelijk van de voltooiing van hun acties." action_completion_time_title: Doorlooptijd (alle voltooide acties) + no_tags_available: geen tags beschikbaar actions_day_of_week_title: Dag van de week (alle acties) tags: Tags totals_project_count: U heeft %{count} projecten. actions_min_max_completion_days: De max-/minimum dagen tot voltooiing is %{min}/%{max}. actions_min_completion_time: De minimale tijd tot afronding is %{time}. - no_tags_available: geen tags beschikbaar - totals_hidden_project_count: "%{count} zijn verborgen" - tag_cloud_90days_description: Deze tag cloud bevat tags van acties die zijn gemaakt of voltooid in de afgelopen 90 dagen. - more_stats_will_appear: Meer statistieken zullen hier verschijnen zodra u acties hebt toegevoegd. - running_time_all: Huidige looptijd van alle onvolledige acties - totals_tag_count: U heeft %{count} tags geplaatst op acties. - top5_visible_contexts_with_incomplete_actions: Top 5 zichtbare contexten met onvolledige acties time_of_day: Tijd van de dag (alle acties) - actions_further: en verder + totals_tag_count: U heeft %{count} tags geplaatst op acties. + tag_cloud_90days_description: Deze tag cloud bevat tags van acties die zijn gemaakt of voltooid in de afgelopen 90 dagen. actions_30days_title: Acties in de afgelopen 30 dagen + actions_further: en verder tod30: Tijd van de dag (laatste 30 dagen) + running_time_all: Huidige looptijd van alle onvolledige acties + totals_hidden_project_count: "%{count} zijn verborgen" + top5_visible_contexts_with_incomplete_actions: Top 5 zichtbare contexten met onvolledige acties + more_stats_will_appear: Meer statistieken zullen hier verschijnen zodra u acties hebt toegevoegd. + top10_projects_30days: Top 10 project in de laatste 30 dagen + click_to_show_actions_from_week: Klik %{link} om de acties van week %{week} en verder te zien. + spread_of_actions_for_all_context: Verdeling van acties voor alle contexten + actions_selected_from_week: Gekozen acties van week top10_projects: Top 10 projecten other_actions_label: (anderen) spread_of_running_actions_for_visible_contexts: Verdeling van actieve acties voor zichtbare contexten - totals_completed_project_count: en %{count} zijn afgeronde projecten. - spread_of_actions_for_all_context: Verdeling van acties voor alle contexten - click_to_return: Klik %{link} om terug te keren naar de statistieken pagina. - top10_projects_30days: Top 10 project in de laatste 30 dagen actions_avg_created: In de afgelopen 12 maanden heeft u gemiddeld%{count} acties aangemaakt - actions_selected_from_week: Gekozen acties van week - click_to_show_actions_from_week: Klik %{link} om de acties van week %{week} en verder te zien. + click_to_return: Klik %{link} om terug te keren naar de statistieken pagina. + totals_completed_project_count: en %{count} zijn afgeronde projecten. totals: Totalen time_of_day_legend: number_of_actions: Aantal acties @@ -460,12 +294,12 @@ nl: totals_hidden_context_count: en %{count} zijn verborgen contexten. contexts: Contexten actions_avg_completed: en voltooide een gemiddelde van %{count} acties per maand. - no_actions_selected: Er zijn geen acties geselecteerd. - click_to_update_actions: Klik op een balk in de grafiek op de acties hieronder aan te passen. running_time_all_legend: actions: Acties - running_time: Looptijd van een actie (weken). Klik op een balk voor meer info percentage: Percentage + running_time: Looptijd van een actie (weken). Klik op een balk voor meer info + no_actions_selected: Er zijn geen acties geselecteerd. + click_to_update_actions: Klik op een balk in de grafiek op de acties hieronder aan te passen. labels: month_avg_completed: "%{months} gem afgerond per maand" completed: Afgerond @@ -478,46 +312,282 @@ nl: time_of_day: Tijd van de dag action_selection_title: "TRACKS:: Actie selectie" actions_actions_avg_created_30days: In de afgelopen 30 dagen heeft u gemiddeld %{count} acties gemaakt + todos: + show_from: Toon vanaf + error_starring_recurring: Kon niet de ster van deze terugkerende actie niet omzetten \'%{description}\' + recurring_action_deleted: Actie werd verwijderd. Omdat deze actie herhalend is. werd een nieuwe actie toegevoegd + completed_actions: Voltooide acties + completed_recurring: Afgesloten terugkerende todos + added_new_next_action: Nieuwe actie toegevoegd + completed_rest_of_previous_month: Afgerond in de rest van de vorige maand + blocked_by: Geblokkeerd door %{predecessors} + unable_to_add_dependency: Niet in staat om de afhankelijkheid toe te voegen + star_action: Markeer deze actie met een ster + completed_recurrence_completed: Er is geen actie na de terugkerende actie die u new verwijderd heeft. De herhaling is voltooid + defer_date_after_due_date: Uitsteldatum is na de vervaldag. Gelieve vervaldag bewerken alvorens uitsteldatum aan te passen. + done: Voltooid? + star_action_with_description: markeer de actie '%{description}' met een ster + tagged_with: gelabeld met ‘%{tag_name}’ + completed: Afgerond + no_deferred_actions_with: Geen uitgestelde acties met de tag '%{tag_name}' + no_hidden_actions: Momenteel zijn er geen verborgen acties gevonden + edit_action_with_description: Bewerk de actie '%{description}' + action_due_on: (deadline actie op %{date}) + action_deleted_success: Actie succesvol verwijderd + archived_tasks_title: "TRACKS:: Gearchiveerde voltooide taken" + remove_dependency: Verwijder afhankelijkheid (zal niet de actie zelf verwijderen) + list_incomplete_next_actions: Toon onvoltooide acties + tags: Tags (gescheiden door komma's) + new_related_todo_created: Een nieuwe actie is toegevoegd, die behoort bij deze terugkerende todo + context_changed: Context veranderd in '%{name}' + mobile_todos_page_title: Alle acties + add_another_dependency: Nog een afhankelijkheid toevoegen + delete_recurring_action_title: Verwijder de terugkerende actie + removed_predecessor: "'%{successor}' is verwijderd als afhankelijkheid van '%{predecessor}'." + recurring_actions_title: TRACKS::Terugkerende acties + next_action_needed: U dient ten minste een actie in te vullen + action_deleted_error: Verwijderen van de actie is mislukt + action_saved: Actie opgeslagen + scheduled_overdue: Gepland om %{days} dagen geleden te tonen + next_actions_description: "Filter:" + edit_action: Actie bewerken + added_new_context: Nieuwe context toegevoegd + added_new_project: Nieuw project toegevoegd + list_incomplete_next_actions_with_limit: Toont de laatste %{count} onvoltooide acties + set_to_pending: "'%{task}' als wachtend ingesteld" + next_actions_title_additions: + completed: acties voltooid + due_today: deadline vandaag + due_within_a_week: deadline binnen een week + older_completed_items: Oudere voltooide items + append_in_this_project: in dit project + error_deleting_item: Er is een fout opgetreden bij het verwijderen van het item '%{description}' + task_list_title: TRACKS::Toon acties + no_actions_due_this_week: Geen acties met deadline in rest van deze week + delete_recurring_action_confirm: Weet u zeker dat u wilt de terugkerende actie '%{description}' wilt verwijderen? + no_recurring_todos: Momenteel zijn er geen terugkerende acties + error_completing_todo: Er was een fout bij het voltooien / activeren van de terugkerende actie '%{description}' + recurring_pattern_removed: Het herhalingspatroon is verwijderd van %{count} + convert_to_project: Maak project + no_deferred_pending_actions: Momenteel zijn er geen uitgestelde of wachtende acties + completed_last_day: Voltooid in de laatste 24 uur + new_related_todo_created_short: een nieuwe actie gemaakt + no_project: -- Geen project -- + show_in_days: Toon over %{days} dagen + error_saving_recurring: Er is een fout opgetreden het opslaan van de terugkerende actie '%{description}' + completed_more_than_x_days_ago: Voltooid meer dan %{count} dagen geleden + all_completed: Alle afgeronde acties + feed_title_in_context: in context '%{context}' + pending: Wachtend + older_than_days: Ouder dan %{count} dagen + completed_tagged_page_title: "TRACKS:: Afgeronde acties met tag %{tag_name}" + edit: Bewerken + completed_actions_with: Afgeronde acties met de tag %{tag_name} + deleted_success: De actie werd met succes verwijderd. + completed_tasks_title: TRACKS::Voltooide taken + feed_title_in_project: In het project '%{project}' + clear_due_date: Maak deadline leeg + error_removing_dependency: Er is een fout opgetreden het verwijderen van de afhankelijke actie + hidden_actions: Verborgen acties + show_on_date: Toon op %{date} + was_due_on_date: had deadline op %{date} + recurrence_period: Herhaling periode + deferred_actions_with: Uitgestelde acties met de tag '%{tag_name}' + confirm_delete: Weet u zeker dat u de actie '%{description}' wilt verwijderen? + recurring_deleted_success: De recurrente actie is succesvol verwijderd. + next_action_description: Actie beschrijving + next_actions_title: Tracks - Acties + deferred_tasks_title: TRACKS::Tickler + no_completed_actions_with: Geen voltooide acties met de tag '%{tag_name}' + clear_show_from_date: Maak de datum Tonen Vanaf leeg + calendar_page_title: TRACKS::Agenda + unresolved_dependency: De waarde die u ingevoerd heeft in het afhankelijkheden veld is niet herleidbaar naar een bestaande actie. Deze waarde wordt niet bewaard met de rest van de actie. Doorgaan? + in_hidden_state: in verborgen toestand + completed_last_x_days: Voltooid in de laatste %{count} dagen + show_today: Toon vandaag + no_actions_found_title: Geen acties gevonden + next_actions_due_date: + overdue_by: Over deadline met %{days} dag + due_today: Deadline vandaag + due_in_x_days: Deadline over %{days} dagen + overdue_by_plural: Over deadline met %{days} dagen + due_tomorrow: Deadline morgen + added_new_next_action_singular: Nieuwe actie toegevoegd + no_actions_with: Momenteel zijn er geen onvoltooide acties met de tag '%{tag_name}' + defer_x_days: + one: Een dag uitstellen + other: "%{count} dagen uitstellen" + no_completed_actions: Momenteel zijn er geen voltooide acties. + has_x_pending: + one: Heeft een wachtende actie + other: Heeft %{count} wachtende acties + feeds: + completed: "Voltooid: %{date}" + due: "Deadline: %{date}" + deferred_pending_actions: Uitgestelde/wachtende acties + delete_action: Verwijder actie + error_deleting_recurring: Er is een fout opgetreden bij het verwijderen van het item \'%{description}\' + recurring_todos: Terugkerende acties + delete: Verwijder + drag_action_title: Sleep naar een andere actie om deze afhankelijk te maken van die actie + cannot_add_dependency_to_completed_todo: Kan deze actie niet als een afhankelijkheid van een voltooide actie toevoegen! + no_last_completed_actions: Geen afgeronde acties gevonden + depends_on: Hangt af van + tickler_items_due: + one: Een tickler item wordt nu zichtbaar - vernieuw de pagina om het te zien. + other: "%{count} tickerl items zijn nu zichtbaar - vernieuw de pagina om ze te zien." + action_marked_complete: De actie '%{description}' werd gemarkeerd als %{completed} + new_related_todo_not_created_short: een nieuwe actie is niet gemaakt + completed_today: Vandaag afgerond + added_new_next_action_plural: Nieuwe acties toegevoegd + completed_rest_of_week: Afgerond in de rest van deze week + calendar: + get_in_ical_format: Ontvang deze agenda in iCal-formaat + due_next_week: Deadline volgende week + no_actions_due_next_week: Geen acties met deadline in volgende week + due_this_week: Deadline in rest van deze week + due_today: Deadline vandaag + no_actions_due_today: Geen acties met deadline vandaag + due_next_month_and_later: Deadline in %{month} en later + no_actions_due_after_this_month: Geen acties met deadline na deze maand + due_this_month: Deadline in rest van %{month} + no_actions_due_this_month: Geen acties met deadline in de rest van deze maand + error_starring: Kon niet de ster van deze actie niet omzetten \'%{description}\' + show_tomorrow: Toon morgen + action_deferred: De actie '%{description}' is uitgesteld + recurrence: + ends_on_date: Eindigt op %{date} + every_work_day: Elke werkdag + ends_on_number_times: Eindigt na %{number} keer + recurrence_on_due_date: de datum dat deadline van de actie is + weekly_options: Instellingen voor de wekelijkse terugkerende acties + weekly: Wekelijks + monthly_options: Instellingen voor maandelijks terugkerende acties + monthly: Maandelijks + starts_on: Begint op + daily_options: Instellingen voor dagelijks terugkerende acties + pattern: + third: derde + month_names: + - + - januari + - februari + - maart + - april + - mei + - juni + - juli + - augustus + - september + - oktober + - november + - december + every_n: elke %{n} + second: tweede + every_xth_day_of_every_n_months: elke %{x} %{day} van elke %{n_months} + on_day_n: op dag %{n} + weekly: wekelijks + from: vanaf + last: laatste + every_day: elke dag + the_xth_day_of_month: de %{x} %{day} van %{month} + times: voor %{number} keer + day_names: + - zondag + - maandag + - dinsdag + - woensdag + - donderdag + - vrijdag + - zaterdag + on_work_days: op werkdagen + every_year_on: elk jaar op %{date} + first: eerste + show: Tonen + fourth: vierde + due: Deadline + until: tot + every_month: elke maand + show_option_always: altijd + daily: Dagelijks + recurrence_on_options: Stel herhaling in op + yearly_every_x_day: Elke %{month} %{day} + daily_every_number_day: Elke %{number} dag(en) + show_options: Toon de actie + weekly_every_number_week: Herhaalt elke %{number} weken op + ends_on: Eindigt op + yearly_options: Instellingen voor jaarlijks terugkerende acties + show_days_before: "%{days} dagen v\xC3\xB3\xC3\xB3r de deadline van actie" + from_tickler: de datum dat de actie uit de tickler komt (geen deadline ingesteld) + yearly_every_xth_day: De %{day} %{day_of_week} van %{month} + no_end_date: Geen einddatum + day_x_on_every_x_month: Dag %{day} op elke %{month} maand + yearly: Jaarlijks + monthly_every_xth_day: De %{day} %{day_of_week} van elke %{month} maand + tagged_page_title: TRACKS::Tagged met '%{tag_name}' + no_completed_recurring: Momenteel zijn er geen voltooide terugkerende acties + added_dependency: "%{dependency} als afhankelijkheid toegevoegd." + all_completed_tagged_page_title: "TRACKS:: Alle afgeronde acties met tag %{tag_name}" + no_deferred_actions: Momenteel zijn er geen uitgestelde acties. + completed_rest_of_month: Afgerond in de rest van deze maand + recurrence_completed: Er is geen volgende actie na de terugkerende actie die u zojuist hebt voltooid. De herhaling is voltooid + no_actions_found: Momenteel zijn er geen onafgeronde acties. + in_pending_state: in wachtende toestand + error_toggle_complete: Kon deze actie niet als afgerond markeren + due: Deadline + action_marked_complete_error: De actie '%{description}' is niet gemarkeerd als %{completed} vanwege een fout op de server. + next_actions_description_additions: + completed: in de afgelopen %{count} dagen + due_date: met een deadline %{due_date} of eerder + action_saved_to_tickler: Actie opgeslagen in tickler + overdue: Achterstallig + recurring_action_saved: Terugkerende actie opgeslagen + depends_on_separate_with_commas: Afhankelijk van (gescheiden door komma's) + completed_in_archive: + one: Er is een voltooide actie in het archief. + other: Er zijn %{count} afgeronde acties in het archief. + to_tickler: naar tickler + no_incomplete_actions: Er zijn geen onvoltooide acties + add_new_recurring: Voeg een nieuwe terugkerende actie toe notes: delete_note_title: Verwijder de notitie '%{id}' delete_confirmation: Weet u zeker dat u de notitie '%{id}' wilt verwijderen? delete_item_title: Verwijder item - show_note_title: Toon notitie deleted_note: Verwijder notitie '%{id}' note_link_title: Toon notitie %{id} + show_note_title: Toon notitie note_location_link: "In:" edit_item_title: Item bewerken - note_header: Notitie %{id} no_notes_available: "Momenteel zijn er geen notities: voeg notities toe aan projecten vanaf de individuele project pagina's." + note_header: Notitie %{id} delete_note_confirm: Weet u zeker dat u de notitie '%{id}' wilt verwijderen? - time: - am: ochtend - formats: - default: "%A, %d %B %Y %H:%M:%S %z" - time: "%H:%M" - short: "%d %B %H:%M" - long: "%A, %d. %B %Y, %H:%M" - pm: middag preferences: open_id_url: Uw OpenID URL is + staleness_starts_after: Markeren openstaande acties begint na %{days} dagen change_identity_url: Verander uw Identity URL - staleness_starts_after: Ophopen begint na %{days} dagen - page_title: "TRACKS:: Voorkeuren" change_password: Wijzig uw wachtwoord - title: Uw voorkeuren + page_title: "TRACKS:: Voorkeuren" token_description: Token (voor feeds en API gebruik) - show_number_completed: Toon %{number} voltooide items + title: Uw voorkeuren is_false: Nee - edit_preferences: Voorkeuren bewerken + show_number_completed: Toon %{number} voltooide items page_title_edit: "TRACKS:: Voorkeuren bewerken" is_true: Ja + edit_preferences: Voorkeuren bewerken sms_context_none: Geen generate_new_token: Genereer een nieuwe token token_header: Uw token - authentication_header: Uw authenticatie current_authentication_type: Uw authenticatietype is %{auth_type} + authentication_header: Uw authenticatie change_authentication_type: Verander uw authenticatietype generate_new_token_confirm: Weet u dit zeker? Het genereren van een nieuw token zal de bestaande te vervangen en dit zal het extern gebruiken van de oude token laten mislukken. + tabs: + authentication: Authenticatie + tracks_behavior: Tracks gedrag + profile: Profiel + date_and_time: Datum en tijd + errors: + user_unauthorized: "401 Unauthorized: Alleen administratieve gebruikers mogen deze functie gebruiken." projects: default_context_set: Stel project standaard context in op %{default_context} no_actions_in_project: Momenteel zijn er geen onafgeronde acties in dit project @@ -525,48 +595,53 @@ nl: was_marked_hidden: is gemarkeerd als verborgen edit_project_title: Bewerk project default_tags_removed_notice: De standaard tags zijn verwijderd + all_completed_tasks_title: TRACKS::Toon alle afgeronde acties in het project '{project_name}' hide_form: Verberg formulier page_title: "TRACKS:: Project: %{project}" - project_state: Project is %{state}. - show_form_title: Maak een nieuw project to_new_project_page: Ga naar de nieuwe projectpagina - no_notes_attached: Momenteel zijn er geen notities toegevoegd aan dit project deferred_actions_empty: Er zijn geen uitgestelde acties voor dit project + show_form_title: Maak een nieuw project this_project: Dit project - notes: Notities + project_state: Project is %{state}. + list_completed_projects: TRACKS::Toon afgeronde projecten + no_notes_attached: Momenteel zijn er geen notities toegevoegd aan dit project + no_last_completed_recurring_todos: Geen afgeronde herhalende acties gevonden todos_append: in dit project - hide_form_title: Verberg nieuw project formulier + notes: Notities + no_last_completed_projects: Geen afgeronde projecten gevonden notes_empty: Er zijn geen notities voor dit project no_projects: Momenteel zijn er geen projecten + hide_form_title: Verberg nieuw project formulier + delete_project: Project verwijderen completed_actions_empty: Er zijn nog geen afgeronde acties voor dit project with_no_default_context: zonder standaard context - delete_project: Project verwijderen - delete_project_confirmation: Weet u zeker dat u wilt het project '%{name} wilt verwijderen? - with_default_context: met een standaard context '%{context_name}' show_form: Toevoegen van een project actions_in_project_title: Acties in dit project - add_project: Voeg project toe - with_default_tags: en met '%{tags}' als de standaard tags - set_default_tags_notice: Stel project standaard tags in op %{default_tags} + delete_project_confirmation: Weet u zeker dat u wilt het project '%{name} wilt verwijderen? + with_default_context: met een standaard context '%{context_name}' + project_saved_status: Project opgeslagen + is_active: is actief completed_projects: Voltooide projecten add_note: Een notitie toevoegen - is_active: is actief - project_saved_status: Project opgeslagen + add_project: Voeg project toe list_projects: "TRACKS:: Overzicht van projecten" + with_default_tags: en met '%{tags}' als de standaard tags settings: Instellingen - hidden_projects: Verborgen projecten + set_default_tags_notice: Stel project standaard tags in op %{default_tags} delete_project_title: Verwijder het project - default_context_removed: Standaard context verwijderd - completed_actions: Afgeronde acties voor dit project + hidden_projects: Verborgen projecten + completed_tasks_title: TRACKS::Toon afgeronde acties in het project '%{project_name}' add_note_submit: Notitie toevoegen + completed_actions: Afgeronde acties voor dit project was_marked_complete: is gemarkeerd als voltooid - edit_project_settings: Bewerk project instellingen + default_context_removed: Standaard context verwijderd state: Dit project is %{state} - default_context: De standaard context voor dit project is %{context} status_project_name_changed: Naam van het project werd gewijzigd - no_default_context: Dit project heeft geen standaard context + default_context: De standaard context voor dit project is %{context} active_projects: Actieve projecten + no_default_context: Dit project heeft geen standaard context with_no_default_tags: en zonder standaard tags + edit_project_settings: Bewerk project instellingen states: hidden_plural: Verborgen completed: Afgerond @@ -574,10 +649,17 @@ nl: visible_plural: Zichtbare active_plural: Actieve visible: Zichtbaar - active: Actief hidden: Verborgen - errors: - user_unauthorized: "401 Unauthorized: Alleen administratieve gebruikers mogen deze functie gebruiken." + active: Actief + time: + am: ochtend + formats: + default: "%A, %d %B %Y %H:%M:%S %z" + time: "%H:%M" + short: "%d %B %H:%M" + month_day: "%d %B" + long: "%A, %d. %B %Y, %H:%M" + pm: middag date: month_names: - @@ -593,10 +675,6 @@ nl: - Oktober - November - December - order: - - :day - - :month - - :year abbr_day_names: - Zo - Ma @@ -605,10 +683,16 @@ nl: - Do - Vr - Za + order: + - :day + - :month + - :year formats: only_day: "%e" + longer: "%A %d %B %Y" default: "%d-%m-%Y" short: "%e %b" + month_day: "%B %d" long: "%e %B %Y" day_names: - Zondag @@ -632,13 +716,30 @@ nl: - Okt - Nov - Dec + will_paginate: + previous_label: "\xC2\xABVorige" + page_entries_info: + multi_page: Toon %{model} %{from} - %{to} van %{count} in totaal + single_page_html: + one: Toon 1 %{model} + other: Toon alle %{count} %{model} + zero: Geen %{model} gevonden + single_page: + one: Toon 1 %{model} + other: Toon alle %{count} %{model} + zero: Geen %{model} gevonden + multi_page_html: Toon %{model} %{from} - %{to} van %{count} in totaal + page_gap: "…" + next_label: "Volgende \xC2\xBB" support: array: - words_connector: "," last_word_connector: ", en" + words_connector: "," two_words_connector: en select: prompt: Selecteer + footer: + send_feedback: Stuur reactie op %{version} dates: month_names: - Januari @@ -661,114 +762,21 @@ nl: - Donderdag - Vrijdag - Zaterdag - footer: - send_feedback: Stuur reactie op %{version} shared: multiple_next_actions: Meerdere acties (een op elke regel) + make_actions_dependent: Maak acties afhankelijk van elkaar hide_form: Verberg formulier toggle_single: Voeg een actie toe - add_action: Actie toevoegen add_actions: Toevoegen acties + add_action: Actie toevoegen tags_for_all_actions: Tags voor alle acties (scheiden met een komma) - project_for_all_actions: Project voor alle acties context_for_all_actions: Context voor alle acties toggle_multi: Voeg meerdere acties toe toggle_single_title: Voeg een nieuwe actie toe + project_for_all_actions: Project voor alle acties separate_tags_with_commas: gescheiden door komma's toggle_multi_title: Toggle single / multi actie formulier hide_action_form_title: Verberg nieuwe actie formulier - users: - auth_type_update_error: "Er was een probleem met het bijwerken van uw authenticatietype: %{error_messages}" - total_contexts: Totaal aantal contexten - successfully_deleted_user: Succesvol gebruiker %{username} verwijderd - first_user_heading: "Welkom bij TRACKS. Om te beginnen, maak dan een admin account:" - failed_to_delete_user: Mislukt de gebruiker %{username} te verwijderen - openid_url_verified: Je hebt %{url} met succes geverifieerd als je identiteit en uw authenticatie type OpenID opgeslagen. - destroy_successful: Gebruiker %{login} met succes verwijderd - signup_successful: Aanmelding succesvol voor gebruiker %{username}. - new_token_generated: Nieuwe token met succes gegenereerd - total_projects: Totaal aantal projecten - change_password_submit: Wachtwoord wijzigen - no_signups_title: "TRACKS:: Geen nieuwe aanmeldingen" - user_created: Gebruiker aangemaakt. - password_updated: Wachtwoord bijgewerkt. - manage_users: Beheren gebruikers - account_signup: Aanmelden voor een account - signup: Aanmelden - total_actions: Totaal aanal acties - desired_login: Gewenste login - confirm_password: Bevestig wachtwoord - new_user_heading: "Registreer een nieuwe gebruiker:" - auth_type_updated: Authenticatietype bijgewerkt. - password_confirmation_label: Bevestig wachtwoord - destroy_error: Er is een fout opgetreden bij het verwijderen van de gebruiker '%{login}' - choose_password: Kies een wachtwoord - change_password_title: TRACKS::Wachtwoord wijzigen - change_auth_type_title: TRACKS::Wijzig authenticatietype - change_password_prompt: Voer uw nieuwe wachtwoord in de onderstaande velden in en kies 'Wachtwoord wijzigen' om uw huidige wachtwoord met uw nieuwe te vervangen. - new_password_label: Nieuw wachtwoord - register_with_cas: Met uw CAS gebruikersnaam - label_auth_type: Authenticatietype - total_users_count: Je hebt een totaal van %{count} gebruikers - new_user_title: "TRACKS:: Aanmelden als de admin gebruiker" - destroy_user: Verwijder de gebruiker - signup_new_user: Registreer nieuwe gebruiker - destroy_confirmation: "Waarschuwing: dit zal de gebruiker '%{login} verwijderen met al zijn acties, contexten, projecten en notities. Weet u zeker dat u wilt doorgaan?" - identity_url: Identiteit URL - auth_change_submit: Wijzigen authenticatietype - openid_ok_pref_failed: Je hebt succesvol de %{url} geverifieerd als je identiteit, maar er was een probleem met het opslaan van uw authenticatie voorkeuren. - change_authentication_type: Wijzigen authenticatietype - select_authentication_type: Selecteer uw nieuwe authenticatie type en klik op 'Wijzigen authenticatietype' om uw huidige instellingen te vervangen. - total_notes: Totaal aantal notities - contexts: - delete_context_title: Verwijder context - hide_form: Verberg formulier - show_form_title: Voeg een context toe - delete_context_confirmation: Weet u zeker dat u de context '%{name}' wilt verwijderen? Merk op dat dit ook alle (herhalende) acties in deze context zal verwijderen! - delete_context: Verwijder context - hide_form_title: "Verberg formulier voor nieuwe context " - edit_context: Bewerk context - context_hide: Verberg van de start pagina? - hidden_contexts: Verborgen contexten - no_contexts_active: Momenteel zijn er geen actieve contexten - save_status_message: Context bewaard - show_form: Maak een nieuwe context - add_context: Context toevoegen - visible_contexts: Zichtbare contexten - context_name: Context naam - update_status_message: Naam van de context was veranderd - status_active: Context is actief - new_context_post: "' zal ook gemaakt worden. Weet u dit zeker?" - last_completed_in_context: in deze context (laatste %{number}) - context_deleted: De context '%{name}' is verwijderd - no_contexts_hidden: Momenteel zijn er geen verborgen contexten - new_context_pre: Nieuwe context ' - no_actions: Momenteel zijn er geen onafgeronde acties in deze context - status_hidden: Context is verborgen - feedlist: - choose_context: Kies de context waar je een feed van wilt - actions_due_today: Acties die vandaag of eerder af moeten - all_contexts: Alle contexten - legend: Legenda - rss_feed: RSS Feed - ical_feed: iCal feed - all_projects: Alle projecten - choose_project: Kies het project waar je een feed van wilt - select_feed_for_project: Kies de feed voor dit project - active_projects_wo_next: Actieve projecten zonder acties - project_needed: "Er moet ten minste \xC3\xA9\xC3\xA9n project zijn voor een feed opgevraagd kan worden" - active_starred_actions: Alle gesterde, actieve acties - projects_and_actions: Actieve projecten met hun acties - context_needed: "Er moet eerst ten minste \xC3\xA9\xC3\xA9n context zijn voor je een feed kan opvragen" - select_feed_for_context: Kies de feed voor deze context - notice_incomplete_only: "Merk op: alle feeds laten alleen acties zien die niet afgerond zijn, tenzij anders vermeld." - actions_due_next_week: Acties die binnen 7 dagen afgerond moeten - actions_completed_last_week: Acties afgerond in de afgelopen 7 dagen - context_centric_actions: Feeds voor onafgeronde acties in een specifieke context - plain_text_feed: Reguliere tekst feed - last_fixed_number: Laatste %{number} acties - all_actions: Alle acties - project_centric: Feeds voor onafgeronde acties in een specifiek project sidebar: list_name_active_contexts: Actieve contexten list_name_active_projects: Actieve projecten @@ -776,11 +784,106 @@ nl: list_name_completed_projects: Voltooide projecten list_name_hidden_projects: Verborgen projecten list_name_hidden_contexts: Verborgen contexten + contexts: + delete_context_title: Verwijder context + all_completed_tasks_title: "TRACKS:: Alle voltooide acties in context '%{context_name}'" + hide_form: Verberg formulier + show_form_title: Voeg een context toe + delete_context_confirmation: Weet u zeker dat u de context '%{name}' wilt verwijderen? Merk op dat dit ook alle (herhalende) acties in deze context zal verwijderen! + delete_context: Verwijder context + hide_form_title: "Verberg formulier voor nieuwe context " + edit_context: Bewerk context + hidden_contexts: Verborgen contexten + no_contexts_active: Momenteel zijn er geen actieve contexten + context_hide: Verberg van de start pagina? + show_form: Maak een nieuwe context + visible_contexts: Zichtbare contexten + save_status_message: Context bewaard + add_context: Context toevoegen + update_status_message: Naam van de context was veranderd + context_name: Context naam + status_active: Context is actief + new_context_post: "' zal ook gemaakt worden. Weet u dit zeker?" + completed_tasks_title: "TRACKS:: Voltooid acties in de context '%{context_name}'" + last_completed_in_context: in deze context (laatste %{number}) + context_deleted: De context '%{name}' is verwijderd + no_contexts_hidden: Momenteel zijn er geen verborgen contexten + new_context_pre: Nieuwe context ' + no_actions: Momenteel zijn er geen onafgeronde acties in deze context + status_hidden: Context is verborgen + feedlist: + actions_due_today: Acties die vandaag of eerder af moeten + choose_context: Kies de context waar je een feed van wilt + all_contexts: Alle contexten + rss_feed: RSS Feed + legend: Legenda + ical_feed: iCal feed + choose_project: Kies het project waar je een feed van wilt + all_projects: Alle projecten + active_projects_wo_next: Actieve projecten zonder acties + project_needed: "Er moet ten minste \xC3\xA9\xC3\xA9n project zijn voor een feed opgevraagd kan worden" + select_feed_for_project: Kies de feed voor dit project + active_starred_actions: Alle gesterde, actieve acties + context_needed: "Er moet eerst ten minste \xC3\xA9\xC3\xA9n context zijn voor je een feed kan opvragen" + select_feed_for_context: Kies de feed voor deze context + projects_and_actions: Actieve projecten met hun acties + notice_incomplete_only: "Merk op: alle feeds laten alleen acties zien die niet afgerond zijn, tenzij anders vermeld." + actions_due_next_week: Acties die binnen 7 dagen afgerond moeten + last_fixed_number: Laatste %{number} acties + all_actions: Alle acties + actions_completed_last_week: Acties afgerond in de afgelopen 7 dagen + context_centric_actions: Feeds voor onafgeronde acties in een specifieke context + plain_text_feed: Reguliere tekst feed + project_centric: Feeds voor onafgeronde acties in een specifiek project + users: + failed_to_delete_user: Mislukt de gebruiker %{username} te verwijderen + destroy_successful: Gebruiker %{login} met succes verwijderd + total_contexts: Totaal aantal contexten + openid_url_verified: Je hebt %{url} met succes geverifieerd als je identiteit en uw authenticatie type OpenID opgeslagen. + first_user_heading: "Welkom bij TRACKS. Om te beginnen, maak dan een admin account:" + auth_type_update_error: "Er was een probleem met het bijwerken van uw authenticatietype: %{error_messages}" + successfully_deleted_user: Succesvol gebruiker %{username} verwijderd + new_token_generated: Nieuwe token met succes gegenereerd + total_projects: Totaal aantal projecten + signup_successful: Aanmelding succesvol voor gebruiker %{username}. + user_created: Gebruiker aangemaakt. + change_password_submit: Wachtwoord wijzigen + no_signups_title: "TRACKS:: Geen nieuwe aanmeldingen" + account_signup: Aanmelden voor een account + password_updated: Wachtwoord bijgewerkt. + manage_users: Beheren gebruikers + auth_type_updated: Authenticatietype bijgewerkt. + total_actions: Totaal aanal acties + desired_login: Gewenste login + signup: Aanmelden + confirm_password: Bevestig wachtwoord + new_user_heading: "Registreer een nieuwe gebruiker:" + change_password_prompt: Voer uw nieuwe wachtwoord in de onderstaande velden in en kies 'Wachtwoord wijzigen' om uw huidige wachtwoord met uw nieuwe te vervangen. + password_confirmation_label: Bevestig wachtwoord + destroy_error: Er is een fout opgetreden bij het verwijderen van de gebruiker '%{login}' + choose_password: Kies een wachtwoord + change_password_title: TRACKS::Wachtwoord wijzigen + change_auth_type_title: TRACKS::Wijzig authenticatietype + label_auth_type: Authenticatietype + new_password_label: Nieuw wachtwoord + register_with_cas: Met uw CAS gebruikersnaam + new_user_title: "TRACKS:: Aanmelden als de admin gebruiker" + destroy_user: Verwijder de gebruiker + total_users_count: Je hebt een totaal van %{count} gebruikers + signup_new_user: Registreer nieuwe gebruiker + destroy_confirmation: "Waarschuwing: dit zal de gebruiker '%{login} verwijderen met al zijn acties, contexten, projecten en notities. Weet u zeker dat u wilt doorgaan?" + you_have_to_reset_your_password: Je moet je wachtwoord opnieuw instellen + openid_ok_pref_failed: Je hebt succesvol de %{url} geverifieerd als je identiteit, maar er was een probleem met het opslaan van uw authenticatie voorkeuren. + auth_change_submit: Wijzigen authenticatietype + identity_url: Identiteit URL + change_authentication_type: Wijzigen authenticatietype + select_authentication_type: Selecteer uw nieuwe authenticatie type en klik op 'Wijzigen authenticatietype' om uw huidige instellingen te vervangen. + total_notes: Totaal aantal notities datetime: prompts: minute: Minuut - month: Maand second: Seconden + month: Maand hour: Uur day: Dag year: Jaar @@ -798,9 +901,6 @@ nl: x_seconds: one: 1 seconde other: "%{count} seconden" - about_x_hours: - one: ongeveer 1 uur - other: ongeveer %{count} uren less_than_x_seconds: one: minder dan 1 seconde other: minder dan %{count} seconden @@ -811,6 +911,9 @@ nl: x_minutes: one: 1 minuut other: "%{count} minuten" + about_x_hours: + one: ongeveer 1 uur + other: ongeveer %{count} uren about_x_months: one: ongeveer 1 maand other: ongeveer %{count} maanden @@ -822,30 +925,30 @@ nl: other: over %{count} jaren half_a_minute: halve minuut login: - openid_identity_url_not_found: Sorry, geen gebruiker met die identiteit URL bestaat (%{identity_url}) + login_cas: Ga naar het CAS user_no_expiry: Blijf ingelogd sign_in: Meld aan - login_cas: Ga naar het CAS + openid_identity_url_not_found: Sorry, geen gebruiker met die identiteit URL bestaat (%{identity_url}) + cas_no_user_found: Hallo,%{username}! Je hebt nog geen account op Tracks. cas_login: CAS Inloggen successful_with_session_info: "Login succesvol:" please_login: Log in om Tracks te gebruiken cas_logged_in_greeting: Hallo, %{username}! U bent geauthenticeerd. - cas_no_user_found: Hallo,%{username}! Je hebt nog geen account op Tracks. cas_username_not_found: Sorry, geen gebruiker met die CAS gebruikersnaam bestaat (%{username}) - cas_create_account: Als u willen vragen ga hier om %{signup_link} mobile_use_openid: ... if inloggen met een OpenID + cas_create_account: Als u willen vragen ga hier om %{signup_link} cas_signup_link: Aanvragen account account_login: Account login - session_will_not_expire: sessie zal niet verlopen. successful: Succesvol aangemeld. Welkom terug! + session_will_not_expire: sessie zal niet verlopen. session_time_out: Sessie is verlopen. Gelieve %{link} session_will_expire: sessie zal verlopen na %{hours} u(u)r(en) van inactiviteit. option_separator: of, login_standard: Ga terug naar de standaard login - login_with_openid: inloggen met een OpenID unsuccessful: Login mislukt. log_in_again: opnieuw in te loggen. logged_out: Je bent afgemeld bij Tracks. + login_with_openid: inloggen met een OpenID search: contexts_matching_query: Contexten passend bij zoekopdracht tags_matching_query: Tags passend bij zoekopdracht diff --git a/config/preinitializer.rb b/config/preinitializer.rb new file mode 100644 index 00000000..a6b4d1e6 --- /dev/null +++ b/config/preinitializer.rb @@ -0,0 +1,21 @@ +begin + require "rubygems" + require "bundler" +rescue LoadError + raise "Could not load the bundler gem. Install it with `gem install bundler`." +end + +if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24") + raise RuntimeError, "Your bundler version is too old for Rails 2.3." + + "Run `gem install bundler` to upgrade." +end + +begin + # Set up load paths for all bundled gems + ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__) + Bundler.setup +rescue Bundler::GemNotFound + raise RuntimeError, "Bundler couldn't find some gems." + + "Did you run `bundle install`?" +end + diff --git a/config/routes.rb b/config/routes.rb index 00a96a10..60f777cd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,58 +3,74 @@ ActionController::Routing::Routes.draw do |map| :member => {:change_password => :get, :update_password => :post, :change_auth_type => :get, :update_auth_type => :post, :complete => :get, :refresh_token => :post } - map.with_options :controller => "users" do |users| + + map.with_options :controller => :users do |users| users.signup 'signup', :action => "new" end - map.resources :contexts, :collection => {:order => :post} do |contexts| + map.resources :contexts, :collection => {:order => :post, :done => :get}, :member => {:done_todos => :get, :all_done_todos => :get} do |contexts| contexts.resources :todos, :name_prefix => "context_" end - map.resources :projects, :collection => {:order => :post, :alphabetize => :post, :actionize => :post} do |projects| - projects.resources :todos, :name_prefix => "project_" + map.resources :projects, + :collection => {:order => :post, :alphabetize => :post, :actionize => :post, :done => :get}, + :member => {:done_todos => :get, :all_done_todos => :get, :set_reviewed => :get} do |projects| + projects.resources :todos, :name_prefix => "project_" + end + + map.with_options :controller => :projects do |projects| + projects.review 'review', :action => :review end map.resources :notes map.resources :todos, - :member => {:toggle_check => :put, :toggle_star => :put}, - :collection => {:check_deferred => :post, :filter_to_context => :post, :filter_to_project => :post} - map.with_options :controller => "todos" do |todos| + :member => {:toggle_check => :put, :toggle_star => :put, :defer => :put}, + :collection => {:check_deferred => :post, :filter_to_context => :post, :filter_to_project => :post, :done => :get, :all_done => :get + } + + map.with_options :controller => :todos do |todos| todos.home '', :action => "index" - todos.tickler 'tickler', :action => "list_deferred" + todos.tickler 'tickler.:format', :action => "list_deferred" todos.mobile_tickler 'tickler.m', :action => "list_deferred", :format => 'm' - todos.done 'done', :action => "completed" - todos.done_archive 'done/archive', :action => "completed_archive" - + # This route works for tags with dots like /todos/tag/version1.5 # please note that this pattern consumes everything after /todos/tag # so /todos/tag/version1.5.xml will result in :name => 'version1.5.xml' # UPDATE: added support for mobile view. All tags ending on .m will be # routed to mobile view of tags. - todos.tag 'todos/tag/:name.m', :action => "tag", :format => 'm' + todos.mobile_tag 'todos/tag/:name.m', :action => "tag", :format => 'm' todos.tag 'todos/tag/:name', :action => "tag", :name => /.*/ + todos.done_tag 'todos/done/tag/:name', :action => "done_tag" + todos.all_done_tag 'todos/all_done/tag/:name', :action => "all_done_tag" todos.tags 'tags.autocomplete', :action => "tags", :format => 'autocomplete' todos.auto_complete_for_predecessor 'auto_complete_for_predecessor', :action => 'auto_complete_for_predecessor' - + todos.calendar 'calendar.ics', :action => "calendar", :format => 'ics' + todos.calendar 'calendar.xml', :action => "calendar", :format => 'xml' todos.calendar 'calendar', :action => "calendar" - + + todos.hidden 'hidden.xml', :action => "list_hidden", :format => 'xml' + todos.mobile 'mobile', :action => "index", :format => 'm' todos.mobile_abbrev 'm', :action => "index", :format => 'm' todos.mobile_abbrev_new 'm/new', :action => "new", :format => 'm' todos.mobile_todo_show_notes 'todos/notes/:id.m', :action => "show_notes", :format => 'm' todos.todo_show_notes 'todos/notes/:id', :action => "show_notes" + todos.done_todos 'todos/done', :action => :done + todos.all_done_todos 'todos/all_done', :action => :all_done end map.root :controller => 'todos' # Make OpenID happy because it needs #root_url defined - map.resources :recurring_todos, + map.resources :recurring_todos, :collection => {:done => :get}, :member => {:toggle_check => :put, :toggle_star => :put} - map.recurring_todos 'recurring_todos', :controller => 'recurring_todos', :action => 'index' + map.with_options :controller => :recurring_todos do |rt| + rt.recurring_todos 'recurring_todos', :action => 'index' + end - map.with_options :controller => 'login' do |login| + map.with_options :controller => :login do |login| login.login 'login', :action => 'login' login.login_cas 'login_cas', :action => 'login_cas' login.formatted_login 'login.:format', :action => 'login' @@ -62,24 +78,32 @@ ActionController::Routing::Routes.draw do |map| login.formatted_logout 'logout.:format', :action => 'logout' end - map.with_options :controller => "feedlist" do |fl| + map.with_options :controller => :feedlist do |fl| fl.mobile_feeds 'feeds.m', :action => 'index', :format => 'm' fl.feeds 'feeds', :action => 'index' end - - map.with_options :controller => "integrations" do |i| + + map.with_options :controller => :integrations do |i| i.integrations 'integrations', :action => 'index' i.rest_api_docs 'integrations/rest_api', :action => "rest_api" - i.search_plugin 'integrations/search_plugin.xml', :controller => 'integrations', :action => 'search_plugin', :format => 'xml' - i.google_gadget 'integrations/google_gadget.xml', :controller => 'integrations', :action => 'google_gadget', :format => 'xml' + i.search_plugin 'integrations/search_plugin.xml', :action => 'search_plugin', :format => 'xml' + i.google_gadget 'integrations/google_gadget.xml', :action => 'google_gadget', :format => 'xml' + i.cloudmailin 'integrations/cloudmailin', :action => 'cloudmailin' + end + + map.with_options :controller => :preferences do |p| + p.preferences 'preferences', :action => 'index' + p.preferences_date_format 'preferences/render_date_format', :action => 'render_date_format' + end + + map.with_options :controller => :stats do |stats| + stats.stats 'stats', :action => 'index' + stats.done_overview 'done', :action => 'done' end - map.preferences 'preferences', :controller => 'preferences', :action => 'index' - map.stats 'stats', :controller => 'stats', :action => 'index' map.search 'search', :controller => 'search', :action => 'index' map.data 'data', :controller => 'data', :action => 'index' - map.connect '/selenium_helper/login', :controller => 'selenium_helper', :action => 'login' if Rails.env == 'test' Translate::Routes.translation_ui(map) if Rails.env != "production" # Install the default route as the lowest priority. diff --git a/config/site.yml.tmpl b/config/site.yml.tmpl index 91389652..d5208a6c 100644 --- a/config/site.yml.tmpl +++ b/config/site.yml.tmpl @@ -51,3 +51,8 @@ open_signups: false # - 'localhost' # use_ssl: false # login_format: 'cn=%s,dc=example,dc=com' + +# When integrating your tracks instance with http://cloudmailin.com/ by using the /integrations/cloudmailin URL, +# this value is the cloudmailin-secret for verifying the authenticity of the request. +# (see http://docs.cloudmailin.com/validating_the_sender) +# cloudmailin: asdasd diff --git a/db/migrate/20110526192008_adapt_to_new_aasm.rb b/db/migrate/20110526192008_adapt_to_new_aasm.rb new file mode 100644 index 00000000..206a6ec6 --- /dev/null +++ b/db/migrate/20110526192008_adapt_to_new_aasm.rb @@ -0,0 +1,13 @@ +class AdaptToNewAasm < ActiveRecord::Migration + def self.up + change_column_default :todos, :state, nil + change_column_default :projects, :state, nil + change_column_default :recurring_todos, :state, nil + end + + def self.down + change_column :todos, :state, :string, :limit => 20, :default => "immediate", :null => false + change_column :projects, :state, :string, :limit => 20, :default => "active", :null => false + change_column :recurring_todos, :state, :string, :limit => 20, :default => "active", :null => false + end +end diff --git a/db/migrate/20110621082432_make_old_recurring_todos_validate.rb b/db/migrate/20110621082432_make_old_recurring_todos_validate.rb new file mode 100644 index 00000000..51e06d05 --- /dev/null +++ b/db/migrate/20110621082432_make_old_recurring_todos_validate.rb @@ -0,0 +1,15 @@ +class MakeOldRecurringTodosValidate < ActiveRecord::Migration + def self.up + RecurringTodo.find(:all).each do |rt| + # show_always may not be nil + rt.show_always = false if rt.show_always.nil? + # start date should be filled + rt.start_from = rt.created_at if rt.start_from.nil? || rt.start_from.blank? + rt.save! + end + end + + def self.down + # no down: leave them validatable + end +end diff --git a/db/migrate/20110727073510_change_crypted_password_length.rb b/db/migrate/20110727073510_change_crypted_password_length.rb new file mode 100644 index 00000000..9bd2c639 --- /dev/null +++ b/db/migrate/20110727073510_change_crypted_password_length.rb @@ -0,0 +1,20 @@ +class ChangeCryptedPasswordLength < ActiveRecord::Migration + def self.up + change_column 'users', 'crypted_password', :string, :limit => 60 + end + + def self.down + # Begin with setting all passwords hashed with BCrypt to SHA-1 ones as + # BCrypt's format won't fit into a narrower column. + User.transaction do + User.all.each do |user| + if user.auth_type == 'database' and not user.uses_deprecated_password? + user.password = user.password_confirmation = nil + user.crypted_password = User.sha1 'change_me' + user.save! + end + end + end + change_column 'users', 'crypted_password', :string, :limit => 40 + end +end diff --git a/db/migrate/20110915100000_add_last_reviewed_to_project.rb b/db/migrate/20110915100000_add_last_reviewed_to_project.rb new file mode 100644 index 00000000..ec81a5f2 --- /dev/null +++ b/db/migrate/20110915100000_add_last_reviewed_to_project.rb @@ -0,0 +1,11 @@ +class AddLastReviewedToProject < ActiveRecord::Migration + + def self.up + add_column :projects, :last_reviewed, :timestamp + execute 'UPDATE projects SET last_reviewed = created_at WHERE last_reviewed IS NULL' + end + + def self.down + remove_column :projects, :last_reviewed + end +end diff --git a/db/migrate/20110915100001_add_next_review_preferences.rb b/db/migrate/20110915100001_add_next_review_preferences.rb new file mode 100644 index 00000000..3d48bdd1 --- /dev/null +++ b/db/migrate/20110915100001_add_next_review_preferences.rb @@ -0,0 +1,10 @@ +class AddNextReviewPreferences < ActiveRecord::Migration + + def self.up + add_column :preferences, :review_period, :integer, :default => 14, :null => false + end + + def self.down + remove_column :preferences, :review_period + end +end diff --git a/doc/CHANGELOG b/doc/CHANGELOG index e18e714c..7aad734b 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -1,23 +1,48 @@ = Tracks: a GTD web application, built with Ruby on Rails * Project homepage: http://getontracks.org/ -* Manual: http://bsag.github.com/tracks/ -* Source at GitHub: http://github.com/bsag/tracks/ +* Manual: http://TracksApp.github.com/tracks/ +* Source at GitHub: http://github.com/TracksApp/tracks/ * Assembla space (for bug reports and feature requests): http://www.assembla.com/spaces/tracks-tickets/tickets -* Wiki (community contributed information): http://getontracks.org/wiki/ +* Wiki (community contributed information): https://github.com/TracksApp/tracks/wiki * Forum: http://getontracks.org/forums/ * Mailing list: http://lists.rousette.org.uk/mailman/listinfo/tracks-discuss * Original developer: bsag (http://www.rousette.org.uk/) -* Contributors: http://getontracks.org/wiki/Contributors -* Version: 2.0devel +* Contributors: https://github.com/TracksApp/tracks/wiki/Contributors +* Version: 2.1devel * Copyright: (cc) 2004-2011 rousette.org.uk. * License: GNU GPL -== Version 2.0 (RC) +== Version 2.1devel -(RC1 was never release, but was mentioned in the DOCS for while. People are - referencing RC1 with bug report. So for the release we've bumped the version - to RC2) +NOTE: to use this version you need to migrate your database. Not migrating will +cause new actions not to appear! + +This version of tracks has moved to a new place on github. Also the wiki moved +to github, see the changed URLs above. + +New and changed features: +1. redesign of the completed todos: a new overview page. Also all context and + project pages have a link to their completed actions +2. New locales (es and fr) and updated locales (de, nl) +3. You can star an action right from the form to add a new action +4. redesign of preferences page +5. You can now mark an action complete from the tickler +6. project names can now contain comma (',') in it name +7. There are two example ruby scripts in /doc to use the REST API to add a todo + or a project template with todos from the command line + +Under the hood: +1. Upgraded rails to 2.3.12, jquery to 1.6.2 and jquery-ui to 1.8.14 +2. fixed several issues with the REST API +3. upgraded the act_as_statemachine plugin. This change requires a + migration, see note above! +4. migated to bundler for gem dependencies + +See https://github.com/tracksapp/tracks/compare/v2.0...master for all +detailled changes + +== Version 2.0 New features: 1. Redesign of menus and introduction of a context menu per todo @@ -37,7 +62,7 @@ New features: 11.You can enable open signup (like in tracks.tra.in) 12.Cleanup of context page 13.Support for CAS for login -14.Support for adding Tracks as a GMail Widget with instructions on the +14.Support for adding Tracks as a GMail Widget with instructions on the Integrations page 15.Tracks now support internationalization. First translations are German and Dutch. See http://www.getontracks.org/wiki/Translating-Tracks it you like to @@ -70,7 +95,7 @@ Under the hood: == Version 1.6 1. upgrade to rails 2.0.2 2. new mobile interface (with some iPhone compatibility fixes) -3. new search functionality to search on todos, projects, contexts and notes +3. new search functionality to search on todos, projects, contexts and notes 4. Bugfixes == Version 1.5 @@ -89,7 +114,7 @@ Under the hood: 13. Add optional Default Context for a Project 14. Add ability to sort projects alphabetically 15. Add "starring" of actions -16. Statistics page with graphs +16. Statistics page with graphs 17. Rake task to set password. Usage: rake tracks:password USER=useranme == Version 1.041 @@ -118,7 +143,7 @@ Under the hood: 10. The Completed Items box on the home, context and project pages now shows the same format for the actions as the Done page. 11. The navigation bar now shows which page you are on by underlining the appropriate link and colouring the text black. 12. There are new accesskeys for the notes page (alt/ctrl o) and user preferences (alt/ctrl u). - + == Version 1.04 1. Tidied up the interface a bit, fixing mistakes in the wording. diff --git a/doc/README_DEVELOPERS b/doc/README_DEVELOPERS index 99606779..b0a98d3e 100644 --- a/doc/README_DEVELOPERS +++ b/doc/README_DEVELOPERS @@ -8,6 +8,8 @@ Tracks is using See README for links to the respective sites +Also see the Development pages on the wiki for details on installing, upgrading, etc. + 2. Dependencies The dependencies are maintained by Tracks. For development we try not to vendor them @@ -20,7 +22,7 @@ Install them using 3. Wiki -There are some pointers for setting up your Tracks copy for testing at http://www.getontracks.org/wiki/Testing/ +There are some pointers for setting up your Tracks copy for testing at https://github.com/TracksApp/tracks/wiki/Testing/ 4. SQLITE3 FOR TESTING @@ -34,9 +36,9 @@ If you want to run tests using another database, that's fine, too. Just change y 5. SELENIUM TESTS (Selenium on Rails) -This testing style is deprecated and are being moved over to Selenium via Cucumber. +This testing style is deprecated and tests are being moved over to Selenium via Cucumber. -See the wiki for more information to run the tests that are not yet migrated: http://www.getontracks.org/wiki/Testing +See the wiki for more information to run the tests that are not yet migrated: https://github.com/TracksApp/tracks/wiki/Testing 6. RSPEC tests @@ -52,4 +54,6 @@ To run the cucumber test run and for those using javascript/ajax use - rake cucumber:selenium \ No newline at end of file + rake cucumber:selenium + +See the wiki for more information on testing: https://github.com/TracksApp/tracks/wiki/Testing \ No newline at end of file diff --git a/doc/tracks_cli_client.rb b/doc/tracks_cli_client.rb new file mode 100644 index 00000000..76fde32e --- /dev/null +++ b/doc/tracks_cli_client.rb @@ -0,0 +1,138 @@ +#!/usr/bin/env ruby + +# +# Author: Vitalie Lazu +# Date: Sat, 10 Jan 2009 19:12:43 +0200 +# + +# CLI ruby client for Tracks: rails application for GTD methodology +# http://www.getontracks.org/development/ +# You need to set ENV['GTD_LOGIN'], ENV['GTD_PASSWORD'] +# and set GTD_TODOS_URL to your tracks install. It defaults to 'http://localhost:3000/todos.xml' + +require 'net/https' +require 'optparse' +require 'cgi' +require 'time' + +class Hash + def to_query_string + map { |k, v| + if v.instance_of?(Hash) + v.map { |sk, sv| + "#{k}[#{sk}]=#{sv}" + }.join('&') + else + "#{k}=#{v}" + end + }.join('&') + end +end + +module Gtd + class API + GTD_URI = ENV['GTD_TODOS_URL'] || 'http://localhost:3000/todos.xml' + + def post(lines, options = {}) + uri = URI.parse(GTD_URI) + http = Net::HTTP.new(uri.host, uri.port) + + if uri.scheme == "https" # enable SSL/TLS + http.use_ssl = true + http.ca_path = "/etc/ssl/certs/" # Debian based path + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + http.verify_depth = 5 + end + + lines.each_line do |l| + l.chomp! + next if l.strip.empty? + + description = CGI.escapeHTML(l) + context_id = options[:context_id] ? options[:context_id].to_i : 1 + project_id = options[:project_id] ? options[:project_id].to_i : 1 + props = "#{description}#{project_id}#{context_id}" + + if options[:show_from] + props << "#{Time.at(options[:show_from]).xmlschema}" + end + + req = Net::HTTP::Post.new(uri.path, "Content-Type" => "text/xml") + req.basic_auth ENV['GTD_LOGIN'], ENV['GTD_PASSWORD'] + req.body = "#{props}" + + resp = http.request(req) + + if resp.code == '302' || resp.code == '201' + puts resp['location'] + else + p resp.body + raise Gtd::Error + end + end + end + end + + class Error < StandardError; end + class InvalidParser < StandardError; end + + class ConsoleOptions + attr_reader :parser, :options + + def initialize + @options = {} + + @parser = OptionParser.new do |cmd| + cmd.banner = "Ruby Gtd CLI - takes todos input from STDIN" + + cmd.separator '' + + cmd.on('-h', '--help', 'Displays this help message') do + puts @parser + exit + end + + cmd.on('-p [N]', Integer, "project id to set for new todo") do |v| + @options[:project_id] = v + end + + cmd.on('-c [N]', Integer, 'context id to set') do |v| + @options[:context_id] = v + end + + cmd.on('-w [N]', Integer, 'Postpone task for N weeks') do |v| + @options[:show_from] = Time.now.to_i + 24 * 3600 * 7 * (v || 1) + end + + cmd.on('-m [N]', Integer, 'Postpone task for N months') do |v| + @options[:show_from] = Time.now.to_i + 24 * 3600 * 7 * 4 * (v || 1) + end + end + end + + def run(args) + @parser.parse!(args) + lines = STDIN.read + + if lines.strip.empty? + puts "Please pipe in some content to tracks on STDIN." + exit 1 + end + + gtd = API.new + gtd.post(lines, @options) + exit 0 + rescue InvalidParser + puts "Please specify a valid format parser." + exit 1 + rescue Error + puts "An unknown error occurred" + exit 1 + end + end +end + +if $0 == __FILE__ + app = Gtd::ConsoleOptions.new + app.run(ARGV) +end diff --git a/doc/tracks_template_cli.rb b/doc/tracks_template_cli.rb new file mode 100755 index 00000000..fcf2a728 --- /dev/null +++ b/doc/tracks_template_cli.rb @@ -0,0 +1,336 @@ +#!/usr/bin/env ruby + +# Version 0.2 (Sept 30, 2011) + +# +# Based on the tracks_cli by Vitalie Lazu (https://gist.github.com/45537) +# + +# CLI ruby template client for Tracks: rails application for GTD methodology +# https://github.com/TracksApp/tracks + +# Usage: +# * You need to set ENV['GTD_LOGIN'], ENV['GTD_PASSWORD'] +# * You need to pipe a file with new projets and actions to the script +# * You can use the -k option to customize templates. See the example below. +# +# Default URLs are: +# ENV['GTD_TODOS_URL'] --> 'http://localhost:3000/todos.xml' +# ENV['GTD_PROJECTS_URL'] --> 'http://localhost:3000/projects.xml' +# ENV['GTD_CONTEXT_URL_PREFIX'] --> 'http://localhost:3000/contexts/' +# ENV['GTD_CONTEXT_URL'] --> 'http://localhost:3000/contexts.xml' + +# Format of input file: +# - A token to be replaced in the subsequent lines starts with the string token +# - New Projects start at the beginning of the line +# - New actions start with a '.' at the beginning of the line. To add a note to an action, separate the action from its note by using '|'. You have to stay in the same line. +# - Comments start with '#' + +# Example of an input file. Remove the '# ' string at the beginning and save it in a file. +# token [location] +# token [start] +# token [end] +# Book trip to [location] +# .Check visa requirements for [location]|instantiate template_visa, if visa required +# .Book flight to [location]|starting trip around [start], returning around [end] +# .Print flight details to [location] +# .Book hotel in [location]|checking around [start], leaving around [end] +# .Book rental car in [location]|starting [start], returning [end] +# .Print hotel booking details to [location] +# .Set email vacation reminder|starting [start], returning [end]; Text: I'm off for a vacation. I'll respond to emails after returning ([end]). +# .Mail others that I'll be away|starting [start], returning [end] +# Pack stuff for trip to [location] +# .Pack projector laptop adapter +# .Pack socket adapter for country ([location]) +# .Pack passport +# .Pack flight and hotel detail printout +# Get trip reimbursement for [location] +# .Collect all [location] receipts in a clear plastic folder +# .Set a reminder to check for reimbursement for [location] +# .Mail folder to secretary + +# Instantiate this template: ./tracks_template_cli -c 1 -f template_file.txt + +# Template can also be read from STDIN, however, then you have specify all tokens with -k + +require 'net/https' +require 'optparse' +require 'cgi' +require 'time' +require 'readline' + +class Hash + def to_query_string + map { |k, v| + if v.instance_of?(Hash) + v.map { |sk, sv| + "#{k}[#{sk}]=#{sv}" + }.join('&') + else + "#{k}=#{v}" + end + }.join('&') + end +end + +module Gtd + class API + GTD_URI_TODOS = ENV['GTD_TODOS_URL'] || 'http://localhost:3000/todos.xml' + GTD_URI_PROJECTS = ENV['GTD_PROJECTS_URL'] || 'http://localhost:3000/projects.xml' + GTD_URI_CONTEXTS_PREFIX = ENV['GTD_CONTEXT_URL_PREFIX'] || 'http://localhost:3000/contexts/' + GTD_URI_CONTEXTS = ENV['GTD_CONTEXT_URL'] || 'http://localhost:3000/contexts.xml' + + def post(l, options = {}) + uri = URI.parse(GTD_URI_TODOS) + http = Net::HTTP.new(uri.host, uri.port) + + if uri.scheme == "https" # enable SSL/TLS + http.use_ssl = true + http.ca_path = "/etc/ssl/certs/" # Debian based path + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + http.verify_depth = 5 + end + + l.chomp! + + description = CGI.escapeHTML(l) + context_id = options[:context_id] ? options[:context_id].to_i : 1 + project_id = options[:project_id] ? options[:project_id].to_i : 1 + starred = options[:starred] ? 1 : 0 + props = "#{description}#{project_id}#{context_id}" + + if options[:show_from] + props << "#{Time.at(options[:show_from]).xmlschema}" + end + + if options[:note] + props << "#{options[:note]}" + end + + req = Net::HTTP::Post.new(uri.path, "Content-Type" => "text/xml") + req.basic_auth ENV['GTD_LOGIN'], ENV['GTD_PASSWORD'] + req.body = "#{props}" + + resp = http.request(req) + + if resp.code == '302' || resp.code == '201' + puts resp['location'] + else + p resp.body + raise Gtd::Error + end + end + + def postProject(l, options = {}) + uri = URI.parse(GTD_URI_PROJECTS) + http = Net::HTTP.new(uri.host, uri.port) + + if uri.scheme == "https" # enable SSL/TLS + http.use_ssl = true + http.ca_path = "/etc/ssl/certs/" # Debian based path + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + http.verify_depth = 5 + end + + l.chomp! + + description = CGI.escapeHTML(l) + props = "#{l}#{options[:context_id]}" + + req = Net::HTTP::Post.new(uri.path, "Content-Type" => "text/xml") + req.basic_auth ENV['GTD_LOGIN'], ENV['GTD_PASSWORD'] + req.body = "#{props}" + + resp = http.request(req) + + if resp.code == '302' || resp.code == '201' + puts resp['location'] + + # return the project id + return resp['location'].split("/").last + else + p resp.body + raise Gtd::Error + end + end + + def queryContext(contextID) + return false unless contextID.is_a? Integer + + uri = URI.parse(GTD_URI_CONTEXTS_PREFIX + contextID.to_s + ".xml") + http = Net::HTTP.new(uri.host, uri.port) + + if uri.scheme == "https" # enable SSL/TLS + http.use_ssl = true + http.ca_path = "/etc/ssl/certs/" # Debian based path + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + http.verify_depth = 5 + end + + req = Net::HTTP::Get.new(uri.path) + req.basic_auth ENV['GTD_LOGIN'], ENV['GTD_PASSWORD'] + resp = http.request(req) + + case resp + when Net::HTTPSuccess + return true + else + return false + end + end + + end + + + class Error < StandardError; end + class InvalidParser < StandardError; end + + class ConsoleOptions + attr_reader :parser, :options, :keywords + + def initialize + @options = {} + @keywords = {} + + @parser = OptionParser.new do |cmd| + cmd.banner = "Ruby Gtd CLI - takes todos input from STDIN" + + cmd.separator '' + + cmd.on('-h', '--help', 'Displays this help message') do + puts @parser + exit + end + + cmd.on('-p [N]', Integer, "project id to set for new todo") do |v| + @options[:project_id] = v + end + + cmd.on('-k [S]', "keyword to be replaced") do |v| + @keywords[v.split("=")[0]] = v.split("=")[1] + end + + cmd.on('-f [S]', "filename of the template") do |v| + @filename = v + + if not File.exist?(@filename) + puts "ERROR: file #{@filename} doesn't exist" + exit 1 + end + end + + cmd.on('-c [N]', Integer, 'default context id to set for new projects') do |v| + @options[:context_id] = v + end + + cmd.on('-w [N]', Integer, 'Postpone task for N weeks') do |v| + @options[:show_from] = Time.now.to_i + 24 * 3600 * 7 * (v || 1) + end + + cmd.on('-m [N]', Integer, 'Postpone task for N months') do |v| + @options[:show_from] = Time.now.to_i + 24 * 3600 * 7 * 4 * (v || 1) + end + end + end + + def run(args) + @parser.parse!(args) + # lines = STDIN.read + gtd = API.new + + if ENV['GTD_LOGIN'] == nil + puts "ERROR: no GTD_LOGIN environment variable set" + exit 1 + end + + if ENV['GTD_PASSWORD'] == nil + puts "ERROR: no GTD_PASSWORD environment variable set" + exit 1 + end + + if @filename.nil? + file = STDIN + else + file = File.open(@filename) + end + + # if lines.strip.empty? + # puts "Please pipe in some content to tracks on STDIN." + # exit 1 + # end + + ## check for existence of the context + if !@options[:context_id] + puts "ERROR: need to specify a context_id with -c option. Go here to find one: #{API::GTD_URI_CONTEXTS}" + exit 1 + end + + if !gtd.queryContext(@options[:context_id]) + puts "Error: context_id #{options[:context_id]} doesn't exist" + exit 1 + end + + #lines.each_line do |line| + while line = file.gets + line = line.strip + next if (line.empty? || line[0].chr == "#") + + if (line.split(' ')[0] == "token") + ## defining a new token; ask for input + + newtok=line.split(' ')[1] + + if @keywords[newtok].nil? + print "Input required for "+newtok+": " + @keywords[newtok]=gets.chomp + end + + next + end + + # replace tokens + @keywords.each do |key,val| + line=line.sub(key,val) + end + + # decide whether project or task + + if (line[0].chr == "." ) || (line[0].chr == "*") + @options[:starred]= line[0].chr == "*" ? true : false; + line = line[1..line.length] + + # find notes + tmp= line.split("|") + if tmp.length > 3 + puts "Formatting error: found too many |" + exit 1 + end + + line=tmp[0] + @options[:note]=tmp[1] + + if !@options[:project_id] + puts "Warning: no project specified for task \"#{line}\". Using default project." + end + + gtd.post(line, @options) + else + @options[:project_id]=gtd.postProject(line, @options) + end + end + + exit 0 + rescue InvalidParser + puts "Please specify a valid format parser." + exit 1 + rescue Error + puts "An unknown error occurred" + exit 1 + end + end +end + +if $0 == __FILE__ + app = Gtd::ConsoleOptions.new + app.run(ARGV) +end diff --git a/features/calendar.feature b/features/calendar.feature index ddc68106..db7e6ccb 100644 --- a/features/calendar.feature +++ b/features/calendar.feature @@ -22,7 +22,7 @@ Feature: Show all due actions in a calendar view Then the badge should show 1 And I should see "a new next action" - @selenium + @selenium Scenario: Clearing the due date of a todo will remove it from the calendar When I go to the home page And I submit a new action with description "a new next action" in the context "@calendar" @@ -32,7 +32,7 @@ Feature: Show all due actions in a calendar view When I clear the due date of "a new next action" Then I should not see "a new next action" - @selenium + @selenium Scenario: Marking a todo complete will remove it from the calendar Given I have a todo "a new next action" in the context "@calendar" which is due tomorrow When I go to the calendar page @@ -41,7 +41,7 @@ Feature: Show all due actions in a calendar view Then I should not see "a new next action" @selenium - Scenario: Deleting a todo complete will remove it from the calendar + Scenario: Deleting a todo will remove it from the calendar Given I have a todo "a new next action" in the context "@calendar" which is due tomorrow When I go to the calendar page Then I should see "a new next action" diff --git a/features/context_edit.feature b/features/context_edit.feature index 8cca170d..25cb5c87 100644 --- a/features/context_edit.feature +++ b/features/context_edit.feature @@ -8,6 +8,9 @@ Feature: Edit a context | login | password | is_admin | | testuser | secret | false | And I have logged in as "testuser" with password "secret" + And I have a context called "@pc" + And I have a project called "test project" + And I have 2 todos in project "test project" in context "@pc" with tags "starred" @selenium Scenario: In place edit of context name @@ -19,17 +22,52 @@ Feature: Edit a context Then he should see that a context named "Errands" is not present And he should see that a context named "OutAndAbout" is present + @selenium Scenario: Editing the context of a todo will remove the todo - Given this is a pending scenario + When I go to the the context page for "@pc" + Then the badge should show 2 + When I edit the context of "todo 1" to "@laptop" + Then I should not see "todo 1" + And the badge should show 1 + @selenium Scenario: Editing the description of a a todo will update that todo - Given this is a pending scenario + When I go to the the context page for "@pc" + And I edit the description of "todo 1" to "changed" + Then I should not see "todo 1" + And I should see "changed" + @selenium Scenario: Editing the context of the last todo will remove the todo and show empty message - Given this is a pending scenario + When I go to the the context page for "@pc" + And I edit the context of "todo 1" to "@laptop" + Then I should not see "todo 1" + And the badge should show 1 + When I edit the context of "todo 2" to "@laptop" + Then I should not see "todo 2" + And the badge should show 0 + And I should see "Currently there are no incomplete actions in this context" + @selenium Scenario: Adding a todo to a hidden project will not show the todo - Given this is a pending scenario + Given I have a hidden project called "hidden project" + When I go to the the context page for "@pc" + And I edit the project of "todo 1" to "hidden project" + Then I should not see "todo 1" + When I submit a new action with description "todo X" to project "hidden project" in the context "@pc" + Then I should not see "todo X" + When I go to the "hidden project" project + Then I should see "todo 1" + And I should see "todo X" + And the badge should show 2 + @selenium Scenario: Adding a todo to a hidden context will show that todo - Given this is a pending scenario + Given I have a hidden context called "@personal" + When I go to the the context page for "@pc" + And I edit the context of "todo 1" to "@personal" + Then I should not see "todo 1" + When I go to the context page for "@personal" + Then I should see "todo 1" + When I submit a new action with description "todo X" to project "test project" in the context "@personal" + Then I should see "todo X" diff --git a/features/context_list.feature b/features/context_list.feature index 3b864fef..140189b0 100644 --- a/features/context_list.feature +++ b/features/context_list.feature @@ -11,21 +11,21 @@ Feature: Manage the list of contexts Scenario: The list of contexts contain all contexts Given I have the following contexts - | name | hide | - | @ipad | false | - | @home | false | - | @boss | false | + | context | hide | + | @ipad | false | + | @home | false | + | @boss | false | When I go to the contexts page Then I should see "@ipad" And I should see "@home" And I should see "@boss" And the badge should show 3 - Scenario: Clicking on a project takes me to the context page + Scenario: Clicking on a context takes me to the context page Given I have a context called "@computer" When I go to the contexts page And I follow "@computer" - Then I should be on the context page for "@computer" + Then I should be on the context page for "@computer" @selenium Scenario: Delete context from context page should update badge @@ -76,9 +76,9 @@ Feature: Manage the list of contexts @selenium Scenario Outline: Add a new context with state Given I have the following contexts - | name | hide | - | @ipad | true | - | @home | false | + | context | hide | + | @ipad | true | + | @home | false | When I go to the contexts page And I add a new context "" Then I should see the context "" under "" @@ -97,10 +97,10 @@ Feature: Manage the list of contexts @selenium Scenario: I can drag and drop to order the contexts Given I have the following contexts - | name | - | @ipad | - | @home | - | @boss | + | context | + | @ipad | + | @home | + | @boss | When I go to the contexts page Then context "@ipad" should be above context "@home" When I drag context "@ipad" below context "@home" @@ -114,3 +114,4 @@ Feature: Manage the list of contexts Then the new context form should not be visible When I follow "Create a new context" Then the new context form should be visible + diff --git a/features/dependencies.feature b/features/dependencies.feature index b7dec50a..c3e21b47 100644 --- a/features/dependencies.feature +++ b/features/dependencies.feature @@ -92,8 +92,24 @@ Feature: dependencies And I should not see "test 2" in the deferred container And I should see the empty message in the deferred container + @selenium Scenario: Deleting a successor will update predecessor - Given this is a pending scenario + Given I have a context called "@pc" + And I have a project "dependencies" that has the following todos + | description | context | + | test 1 | @pc | + | test 2 | @pc | + | test 3 | @pc | + And "test 2" depends on "test 1" + And "test 3" depends on "test 1" + When I go to the "dependencies" project + And I expand the dependencies of "test 1" + Then I should see "test 2" within the dependencies of "test 1" + And I should see "test 3" within the dependencies of "test 1" + When I delete the action "test 2" + And I expand the dependencies of "test 1" + Then I should see "test 3" within the dependencies of "test 1" + And I should not see "test 2" @selenium Scenario: Dragging an action to a completed action will not add it as a dependency @@ -106,4 +122,50 @@ Feature: dependencies When I go to the "dependencies" project And I drag "test 1" to "test 3" Then I should see an error flash message saying "Cannot add this action as a dependency to a completed action!" - And I should see "test 1" in project container for "dependencies" \ No newline at end of file + And I should see "test 1" in project container for "dependencies" + + @selenium + Scenario Outline: Marking a successor as complete will update predecessor + Given I have a context called "@pc" + And I have a project "dependencies" that has the following todos + | description | context | completed | tags | + | test 1 | @pc | no | bla | + | test 2 | @pc | no | bla | + | test 3 | @pc | yes | bla | + When I go to the + And I drag "test 1" to "test 2" + When I expand the dependencies of "test 2" + Then I should see "test 1" within the dependencies of "test 2" + And I should see "test 1" in the deferred container + When I mark "test 1" as complete + Then I should see that "test 2" does not have dependencies + And I should see "test 1" in the completed container + + Scenarios: + | page | + | "dependencies" project | + | tag page for "bla" | + + @selenium + Scenario Outline: Marking a successor as active will update predecessor + Given I have a context called "@pc" + And I have a project "dependencies" that has the following todos + | description | context | completed | tags | + | test 1 | @pc | no | bla | + | test 2 | @pc | no | bla | + | test 3 | @pc | yes | bla | + When I go to the + And I drag "test 1" to "test 2" + Then I should see "test 1" in the deferred container + When I mark "test 1" as complete + And I should see "test 1" in the completed container + And I should see that "test 2" does not have dependencies + When I mark the complete todo "test 1" active + Then I should not see "test 1" in the completed container + And I should see "test 1" in the deferred container + And I should see "test 1" within the dependencies of "test 2" + + Scenarios: + | page | + | "dependencies" project | + | tag page for "bla" | \ No newline at end of file diff --git a/features/edit_a_todo.feature b/features/edit_a_todo.feature index 3c77252e..b6fce909 100644 --- a/features/edit_a_todo.feature +++ b/features/edit_a_todo.feature @@ -8,9 +8,16 @@ Feature: Edit a next action from every page | login | password | is_admin | | testuser | secret | false | And I have logged in as "testuser" with password "secret" + And I have a context called "@pc" + @selenium Scenario: I can toggle the star of a todo - Given this is a pending scenario + Given I have a todo "star me" in the context "@home" + When I go to the home page + And I star the action "star me" + Then I should see a starred "star me" + When I go to the tag page for "starred" + Then I should see "star me" @selenium Scenario: I can delete a todo @@ -23,12 +30,12 @@ Feature: Edit a next action from every page @selenium Scenario: Removing the last todo in context will hide context Given I have a todo "delete me" in the context "@home" - And I have a context called "@pc" When I go to the home page Then I should see the container for context "@home" And I should see "delete me" in the context container for "@home" When I mark "delete me" as complete Then I should not see the container for context "@home" + And I should see "delete me" in the completed container When I mark "delete me" as uncompleted Then I should see the container for context "@home" When I edit the context of "delete me" to "@pc" @@ -83,7 +90,7 @@ Feature: Edit a next action from every page Scenario Outline: I can mark a deferred todo complete and it will update empty messages Given I have a context called "visible context" And I have a project called "visible project" - When I go to the + When I go to the Then I should see "" When I submit a new deferred action with description "visible todo" to project "visible project" with tags "starred" in the context "visible context" Then I should see "visible todo" @@ -93,62 +100,186 @@ Feature: Edit a next action from every page And I should see "visible todo" in the completed container Scenarios: - | page | empty message | - | tag page for "starred" | Currently there are no deferred or pending actions | - | "visible project" project | Currently there are no deferred or pending actions | + | page | empty message | + | tag page for "starred" | Currently there are no deferred or pending actions | + | "visible project" project | Currently there are no deferred or pending actions | - @selenium @wip - Scenario Outline: I can mark a completed todo active and it will update empty messages - Given I have a completed todo with description "visible todo" to project "visible project" with tags "test" in the context "visible context" + @selenium + Scenario Outline: I can mark a completed todo active and it will update empty messages and context containers + Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context" When I go to the Then I should see "" - And I should not see "visible context" - And I should see "" + And I should not see the container for context "visible context" + And I should not see "" When I mark the complete todo "visible todo" active - Then I should see "visible context" + Then I should see the container for context "visible context" And I should see "" And I should see "visible todo" in the context container for "visible context" And I should not see "" Scenarios: - | page | empty message | - | tag page for "starred" | No actions found | - | home page | No actions found | - | context page for "visible context" | Currently there are no deferred or pending actions | - | project page for "visible project" | Currently there are no deferred or pending actions | + | page | empty message | empty completed message | + | tag page for "starred" | No actions found | Currently there are no completed actions | + | home page | No actions found | Currently there are no completed actions | - Scenario: I can edit a todo to change its description # do for more pages, see #1094 - Given this is a pending scenario + @selenium + Scenario Outline: I can mark a completed todo active and it will update empty messages for pages without context containers + Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context" + When I go to the + Then I should see "" + And I should not see "" + When I mark the complete todo "visible todo" active + And I should see "" + And I should not see "" - Scenario: I can edit a todo to move it to another context - Given this is a pending scenario + Scenarios: + | page | empty message | empty completed message | + | context page for "visible context" | Currently there are no incomplete actions in this context | Currently there are no completed actions | + | "visible project" project | Currently there are no incomplete actions in this project | Currently there are no completed actions | + @selenium + Scenario Outline: I can edit a todo to change its description + # do for more pages, see #1094 + Given I have a todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context" that is due next week + When I go to the + And I edit the description of "visible todo" to "changed todo" + Then I should not see "visible todo" + And I should see "changed todo" + + Scenarios: + | page | + | home page | + | context page for "visible context" | + | "visible project" project | + | tag page for "starred" | + | calendar page | + + @selenium + Scenario Outline: I can edit a todo to move it to another context + Given I have a context called "@laptop" + And I have a project "my project" that has the following todos + | context | description | tags | + | @pc | first action | bla | + | @laptop | second action | bla | + When I go to the + Then I should see "first action" in the context container for "@pc" + When I edit the context of "first action" to "@laptop" + Then I should not see "first action" in the context container for "@pc" + Then I should see "first action" in the context container for "@laptop" + + Scenarios: + | page | + | home page | + | tag page for "bla" | + + @selenium + Scenario: I can edit a todo to move it to another context in tickler page + Given I have a context called "@laptop" + And I have a project "my project" that has the following deferred todos + | context | description | + | @pc | first action | + | @laptop | second action | + When I go to the tickler page + Then I should see "first action" in the context container for "@pc" + When I edit the context of "first action" to "@laptop" + Then I should not see "first action" in the context container for "@pc" + Then I should see "first action" in the context container for "@laptop" + + @selenium Scenario: I can edit a todo to move it to another project - Given this is a pending scenario + Given I have a project called "project one" + And I have a project "project two" with 1 todos + When I go to the "project two" project + And I edit the project of "todo 1" to "project one" + Then I should not see "todo 1" + When I go to the "project one" project + Then I should see "todo 1" + @selenium Scenario: I can edit a todo to move it to the tickler - Given this is a pending scenario + When I go to the home page + And I submit a new action with description "start later" in the context "@pc" + And I edit the show from date of "start later" to next month + Then I should not see "start later" + When I go to the tickler page + Then I should see "start later" + @selenium Scenario: I can defer a todo - Given this is a pending scenario + When I go to the home page + And I submit a new action with description "start later" in the context "@pc" + And I defer "start later" for 1 day + Then I should not see "start later" + When I go to the tickler page + Then I should see "start later" + @selenium Scenario: I can make a project from a todo - Given this is a pending scenario + When I go to the home page + And I submit a new action with description "buy mediacenter" in the context "@pc" + And I make a project of "buy mediacenter" + #sidebar does not update + Then I should be on the "buy mediacenter" project + When I go to the projects page + Then I should see "buy mediacenter" + @selenium Scenario: I can show the notes of a todo - Given this is a pending scenario + Given I have a todo "read the notes" with notes "several things to read" + When I go to the home page + Then I should see "read the notes" + And I should not see "several things to read" + When I open the notes of "read the notes" + Then I should see "several things to read" + @selenium Scenario: I can tag a todo - Given this is a pending scenario + Given I have a todo "tag me" + When I go to the home page + And I edit the tags of "tag me" to "bla, bli" + Then I should see "bla" + And I should see "bli" Scenario: Clicking a tag of a todo will go to that tag page - Given this is a pending scenario + Given I have a todo "tag you are it" in context "@tags" with tags "taga, tagb" + When I go to the home page + Then I should see "tag you are it" + And I should see "taga" + When I follow "taga" + Then I should be on the tag page for "taga" + @selenium Scenario: I can edit the tags of a todo - Given this is a pending scenario + Given I have a todo "tag you are it" in context "@tags" with tags "taga, tagb" + When I go to the home page + Then I should see "tag you are it" + When I edit the tags of "tag you are it" to "tagb, tagc" + Then I should not see "taga" + And I should see "tagb" + And I should see "tagc" - Scenario: Editing the context of a todo to a new context will show new context - Given this is a pending scenario # for home and tickler and tag + @selenium + Scenario Outline: Editing the context of a todo to a new context will show new context + Given I have a todo "moving" in context "@pc" with tags "tag" + When I go to the + And I edit the context of "moving" to "@new" + And I should see the container for context "@new" + Scenarios: + | page | + | home page | + | tag page for "tag" | + + @selenium + Scenario: Editing the context of a todo in the tickler to a new context will show new context + Given I have a deferred todo "moving" in context "@pc" with tags "tag" + When I go to the tickler page + And I edit the context of "moving" to "@new" + And I should see the container for context "@new" + + @selenium Scenario: Making an error when editing a todo will show error message - Given this is a pending scenario + Given I have a todo "test" + When I go to the home page + And I try to edit the description of "test" to "" + Then I should see an error message diff --git a/features/handling_users_with_deprecated_password_hashes.feature b/features/handling_users_with_deprecated_password_hashes.feature new file mode 100644 index 00000000..4b1b8203 --- /dev/null +++ b/features/handling_users_with_deprecated_password_hashes.feature @@ -0,0 +1,35 @@ +Feature: Handling users with deprecated passwords hashes + In order to have my password hashed with BCrypt + As a user with password hashed with SHA1 + I have to be redirected to the password resetting form + + Background: + Given the following user records with hash algorithm + | login | password | algorithm | + | new_hash_user | first_secret | bcrypt | + | old_hash_user | another_secret | sha1 | + + Scenario Outline: A user with SHA1 password + Given I have logged in as "old_hash_user" with password "another_secret" + When I go to the page + Then I should be redirected to the change password page + And I should see "You have to reset your password" + When I change my password to "newer_better_password" + Then I should be redirected to the preference page + + Examples: + | name | + | home | + | preferences | + | notes | + | tickler | + + Scenario: A user with SHA1 password goes straight to the change password page + Given I have logged in as "old_hash_user" with password "another_secret" + When I go to the change password page + Then I should be on the change password page + + Scenario: A user with BCrypt password + Given I have logged in as "new_hash_user" with password "first_secret" + When I go to the homepage + Then I should be on the homepage diff --git a/features/logging_in.feature b/features/logging_in.feature index f0b4d7cd..10874105 100644 --- a/features/logging_in.feature +++ b/features/logging_in.feature @@ -56,4 +56,4 @@ Feature: Existing user logging in And I submit the login form as user "testuser" with password "secret" Then I should be on the login page When my session expires - Then I should see "Session has timed out" \ No newline at end of file + Then I should be on the login page \ No newline at end of file diff --git a/features/mobile_edit_a_todo.feature b/features/mobile_edit_a_todo.feature index 62b8ad77..5726d99a 100644 --- a/features/mobile_edit_a_todo.feature +++ b/features/mobile_edit_a_todo.feature @@ -17,13 +17,17 @@ Feature: Edit a next action from the mobile view Scenario: I can edit an action on the mobile page When I am on the home page Then the badge should show 1 - Then I should see "test action" + And I should see "test action" When I follow "test action" + Then I should see "Actions" + When I press "Edit this action" + Then I should see "Description" And I fill in "Description" with "changed action" And I press "Update" Then I should see "changed action" And I should not see "test action" When I follow "changed action" + And I press "Edit this action" And I check "done" And I press "Update" Then I should not see "changed action" @@ -36,3 +40,13 @@ Feature: Edit a next action from the mobile view Then the badge should show 0 When I follow "Feeds" Then I should see "Last 15 actions" + + Scenario: I can defer an action on the mobile page + When I am on the home page + Then the badge should show 1 + And I should see "test action" + When I follow "test action" + And I press "Defer 1 day" + Then I should see "There are no incomplete actions" + When I follow "Tickler" + Then I should see "test action" \ No newline at end of file diff --git a/features/notes_manage.feature b/features/notes_manage.feature index 410d61d3..f742b6bf 100644 --- a/features/notes_manage.feature +++ b/features/notes_manage.feature @@ -42,3 +42,26 @@ Feature: View, add, remove notes When I go to the notes page And I edit the first note to "edited note" Then I should see "edited note" + + @selenium + Scenario: Toggle all notes + Given I have a context called "@pc" + And I have a project "take notes" that has the following todos + | description | context | notes | + | test 1 | @pc | note A | + | test 2 | @pc | note B | + | test 3 | @pc | note C | + When I go to the home page + Then I should not see "note A" + And I should not see "note B" + And I should not see "note C" + When I toggle the note of "test 1" + Then I should see "note A" + And I should not see "note B" + And I should not see "note C" + When I toggle the note of "test 1" + Then I should not see "note A" + When I toggle all notes + Then I should see "note A" + And I should see "note B" + And I should see "note C" diff --git a/features/preferences.feature b/features/preferences.feature index 63e57b11..c2f9d389 100644 --- a/features/preferences.feature +++ b/features/preferences.feature @@ -10,10 +10,33 @@ Feature: Manage preferences And I have logged in as "testuser" with password "secret" Scenario: I can change my password - Given this is a pending scenario + When I go to the preferences page + And I set the password and confirmation to "secret123" + When I log out of Tracks + And I go to the login page + And I submit the login form as user "testuser" with password "secret" + Then I should see "Login unsuccessful" + When I submit the login form as user "testuser" with password "secret123" + Then I should see "Login successful" + + Scenario: I can leave password field empty and the password will not be changed + When I go to the preferences page + And I set the password and confirmation to "" + When I log out of Tracks + And I go to the login page + And I submit the login form as user "testuser" with password "" + Then I should see "Login unsuccessful" + When I submit the login form as user "testuser" with password "secret" + Then I should see "Login successful" + + Scenario: The password and the confirmation need to be the same + When I go to the preferences page + And I set the password to "secret" and confirmation to "wrong" + Then I should see "Password doesn't match confirmation" - Scenario: I can generate a new token - Given this is a pending scenario Scenario: I can edit preferences - Given this is a pending scenario + When I go to the preferences page + Then I should see "Logout (testuser)" + When I edit my last name to "Tester" + Then I should see "Logout (Tester)" \ No newline at end of file diff --git a/features/project_edit.feature b/features/project_edit.feature index cb6f38f8..a21dfc2c 100644 --- a/features/project_edit.feature +++ b/features/project_edit.feature @@ -41,6 +41,24 @@ Feature: Edit a project And I edit the project name to "cherries" Then the project title should be "cherries" + @selenium + Scenario: I can change the name of the project and it should update the new todo form + Given I have a project "bananas" with 1 todos + When I go to the "bananas" project + And I edit the project name to "cherries" + Then the project title should be "cherries" + And the project field of the new todo form should contain "cherries" + + @selenium + Scenario: I can change the default context of the project and it should update the new todo form + Given I have a project "bananas" with 1 todos + When I go to the "bananas" project + And I edit the default context to "@pc" + Then the default context of the new todo form should be "@pc" + # the default context should be prefilled ater submitting a new todo + When I submit a new action with description "test" + Then the default context of the new todo form should be "@pc" + # Ticket #1042 @selenium Scenario: I cannot change the name of a project in the project view to the name of another existing project @@ -82,20 +100,53 @@ Feature: Edit a project Then I should not see "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG" And I should see "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456" + @selenium Scenario: Cancelling editing a project will restore project settings - Given this is a pending scenario + Given I have a project called "test" + When I go to the "test" project + Then I should see "This project is active with no default context and with no default tags" + When I open the project edit form + Then I should not see "This project is active with no default context and with no default tags" + When I cancel the project edit form + Then I should see "This project is active with no default context and with no default tags" - Scenario: Editing the description of a todo will update todo - Given this is a pending scenario + @selenium + Scenario: Moving the todo to the tickler will move todo to tickler container and update empty messages + Given I have a project "test" with 1 todos + When I go to the "test" project + Then I should see "todo 1" in the action container + And I should see "Currently there are no deferred or pending actions" + And I should not see "Currently there are no incomplete actions in this project" + When I defer "todo 1" for 1 day + Then I should see "todo 1" in the deferred container + And I should not see "Currently there are no deferred or pending actions" + And I should see "Currently there are no incomplete actions in this project" - Scenario: Moving the todo to the tickler will move todo to tickler container - Given this is a pending scenario - - Scenario: Moving the todo out of the tickler will move todo to active container - Given this is a pending scenario + @selenium + Scenario: Moving the todo out of the tickler will move todo to active container and update empty messages + Given I have a project "test" with 1 deferred todos + When I go to the "test" project + Then I should see "todo 1" in the deferred container + And I should see "Currently there are no incomplete actions in this project" + And I should not see "Currently there are no deferred or pending actions" + When I clear the show from date of "todo 1" + Then I should see "todo 1" in the action container + And I should see "Currently there are no deferred or pending actions" + And I should not see "Currently there are no incomplete actions in this project" + @selenium Scenario: Making all todos inactive will show empty message - Given this is a pending scenario # empty message is in separate container + Given I have a project "test" with 1 todos + When I go to the "test" project + And I mark "todo 1" as complete + Then I should see "Currently there are no incomplete actions in this project" + + @selenium + Scenario: Making all deferred todos inactive will show empty message + Given I have a project "test" with 1 deferred todos + When I go to the "test" project + And I mark "todo 1" as complete + Then I should see "Currently there are no incomplete actions in this project" # Ticket #1043 @selenium @@ -103,6 +154,6 @@ Feature: Edit a project Given I have a project "foo" with 2 todos And I have a project called "bar" When I go to the "foo" project - And I change the project_name field of "Todo 1" to "bar" - Then I should not see "Todo 1" - And I should see "Todo 2" + And I change the project_name field of "todo 1" to "bar" + Then I should not see "todo 1" + And I should see "todo 2" diff --git a/features/project_list.feature b/features/project_list.feature index 862716cd..a57ba857 100644 --- a/features/project_list.feature +++ b/features/project_list.feature @@ -109,7 +109,33 @@ Feature: Manage the list of projects Then the project "very busy" should be above the project "test" @selenium - Scenario: Cannot add a project with comma in the name + Scenario: Can add a project with comma in the name When I go to the projects page And I submit a new project with name "foo,bar" - Then I should see "Name cannot contain the comma" + Then I should see "foo,bar" + And the badge should show 4 + And the project list badge for "active" projects should show 4 + + @selenium + Scenario: Listing projects with only active actions + Given I have a project "do it now" with 2 active todos + When I go to the projects page + Then the project "do it now" should have 2 actions listed + + @selenium + Scenario: Listing projects with both active and deferred actions + Given I have a project "now and later" with 2 active actions and 2 deferred actions + When I go to the projects page + Then the project "now and later" should have 2 actions listed + + @selenium + Scenario: Listing projects with only deferred actions + Given I have a project "only later" with 3 deferred actions + When I go to the projects page + Then the project "only later" should have 3 deferred actions listed + + @selenium + Scenario: Listing projects with no actions + Given I have a project "all done" with 0 active actions and 0 deferred actions + When I go to the projects page + Then the project "all done" should have 0 actions listed diff --git a/features/recurring_todos.feature b/features/recurring_todos.feature index 2792bec8..e541cb7f 100644 --- a/features/recurring_todos.feature +++ b/features/recurring_todos.feature @@ -62,11 +62,26 @@ Feature: Manage recurring todos Then the pattern "I'm done" should be in the state list "active" And the state list "completed" should be empty + @selenium Scenario: Following the recurring todo link of a todo takes me to the recurring todos page - Given this is a pending scenario + When I go to the home page + Then I should see the todo "run tests" + When I follow the recurring todo link of "run tests" + Then I should be on the repeating todos page + @selenium Scenario: Deleting a recurring todo with ending pattern will show message - Given this is a pending scenario + When I go to the repeating todos page + And I mark the pattern "run tests" as complete + And I go to the home page + Then I should see "run tests" + When I delete the action "run tests" + Then I should see "There is no next action after the recurring action you just deleted. The recurrence is completed" + @selenium Scenario: Deleting a recurring todo with active pattern will show new todo - Given this is a pending scenario + When I go to the home page + Then I should see "run tests" + When I delete the action "run tests" + Then I should see "Action was deleted. Because this action is recurring, a new action was added" + And I should see "run tests" in the context container for "test context" \ No newline at end of file diff --git a/features/search.feature b/features/search.feature new file mode 100644 index 00000000..bd069566 --- /dev/null +++ b/features/search.feature @@ -0,0 +1,81 @@ +Feature: Show all due actions in a calendar view + As a Tracks user + In order to keep overview of my due todos + I want to manage due todos in a calendar view + + Background: + Given the following user record + | login | password | is_admin | + | testuser | secret | false | + And I have logged in as "testuser" with password "secret" + + Scenario: I can search for todos by partial description + Given I have the following todos: + | description | context | + | tester of stuff | @home | + | testing search | @work | + | unrelated stuff | @home | + When I go to the search page + And I search for "test" + Then I should see "tester" + And I should see "testing search" + When I go to the search page + And I search for "stuff" + Then I should see "tester of stuff" + And I should see "unrelated stuff" + + @selenium + Scenario: I can edit found todos + Given I have the following todos: + | description | context | + | tester of stuff | @home | + | testing search | @work | + When I go to the search page + And I search for "test" + Then I should see "tester of stuff" + When I star the action "tester of stuff" + Then I should see a starred "tester of stuff" + When I edit the description of "tester of stuff" to "test 1-2-3" + Then I should not see "tester of stuff" + And I should see "test 1-2-3" + When I go to the search page + And I search for "test" + Then I should not see "tester of stuff" + And I should see "test 1-2-3" + + @selenium + Scenario: I can delete found todos + Given I have the following todos: + | description | context | + | tester of stuff | @home | + | testing search | @work | + When I go to the search page + And I search for "test" + Then I should see "tester of stuff" + When I delete the action "tester of stuff" + Then I should not see "tester of stuff" + When I go to the search page + And I search for "test" + Then I should not see "tester of stuff" + + @selenium + Scenario: I can mark found todos complete and uncomplete + Given I have the following todos: + | description | context | + | tester of stuff | @home | + | testing search | @work | + When I go to the search page + And I search for "test" + Then I should see an active todo "tester of stuff" + When I mark "tester of stuff" as complete + Then I should see a completed todo "tester of stuff" + # the completed todo should show up on the next search too + When I go to the search page + And I search for "test" + Then I should see a completed todo "tester of stuff" + When I mark "tester of stuff" as uncompleted + Then I should see an active todo "tester of stuff" + # the active todo should show up on the next search too + When I go to the search page + And I search for "test" + Then I should see an active todo "tester of stuff" diff --git a/features/shared_add_new_todo.feature b/features/shared_add_new_todo.feature index 523446eb..11f1cc65 100644 --- a/features/shared_add_new_todo.feature +++ b/features/shared_add_new_todo.feature @@ -200,15 +200,21 @@ Feature: Add new next action from every page @selenium Scenario: Adding a todo to an empty container hides the empty message # TODO: make outline - And I have a context called "visible context" + Given I have a context called "visible context" When I go to the tag page for "test" Then I should see "Currently there are no incomplete actions with the tag 'test'" When I submit a new action with description "a new todo" and the tags "test" in the context "visible context" Then I should see "a new todo" And I should not see "Currently there are no incomplete actions with the tag 'bla'" + @selenium Scenario: Adding a dependency to a todo updated the successor - Given this is a pending scenario + When I go to the "test project" project + Then I should see "todo 1" + When I submit a new action with description "a new todo" with a dependency on "todo 1" + Then I should not see "a new todo" in the project container of "test project" + When I expand the dependencies of "todo 1" + Then I should see "a new todo" within the dependencies of "todo 1" @selenium Scenario: I can add multiple todos in a new project and a new context diff --git a/features/show_statistics.feature b/features/show_statistics.feature index 7a74aeef..fb8a3951 100644 --- a/features/show_statistics.feature +++ b/features/show_statistics.feature @@ -7,17 +7,16 @@ Feature: Show statistics Given the following user record | login | password | is_admin | | testuser | secret | false | + Given I have logged in as "testuser" with password "secret" Scenario: Show statistics with no history - Given I have logged in as "testuser" with password "secret" - And I have no todos + Given I have no todos When I go to the statistics page Then I should see "Totals" And I should see " More statistics will appear here once you have added some actions." Scenario: Show statistics with history - Given I have logged in as "testuser" with password "secret" - And I have 5 todos + Given I have 5 todos And I have 2 deferred todos And I have 2 completed todos When I go to the statistics page @@ -32,16 +31,14 @@ Feature: Show statistics And I should see "Tags" Scenario: Click through to see chart of all actions per month - Given I have logged in as "testuser" with password "secret" - And I have 5 todos + Given I have 5 todos When I go to the statistics page And I click on the chart for actions done in the last 12 months Then I should see a chart And I should see "to return to the statistics page" Scenario: Click through to see all incomplete actions of a week - Given I have logged in as "testuser" with password "secret" - And I have 5 todos + Given I have 5 todos And I have 2 deferred todos When I go to the statistics page And I click on the chart for running time of all incomplete actions @@ -52,8 +49,7 @@ Feature: Show statistics And I should see "to show the actions from week 0 and further" Scenario: Click through to see all incomplete visible actions of a week - Given I have logged in as "testuser" with password "secret" - And I have 5 todos + Given I have 5 todos And I have 3 deferred todos When I go to the statistics page And I click on the chart for running time of all incomplete actions @@ -63,8 +59,23 @@ Feature: Show statistics And I should see "to return to the statistics page" And I should see "to show the actions from week 0 and further" + @selenium Scenario: I can edit the todos selected from a chart - Given this is a pending scenario + Given I have 5 todos + When I go to the statistics page + And I click on the chart for running time of all incomplete actions + Then I should see 5 todos + And I should see "todo 1" + When I edit the description of "todo 1" to "foo bar" + Then I should not see the todo "todo 1" + And I should see the todo "foo bar" + @selenium Scenario: Marking a todo selected from a chart as complete will remove it from the page - Given this is a pending scenario + Given I have 5 todos + When I go to the statistics page + And I click on the chart for running time of all incomplete actions + Then I should see 5 todos + And I should see "todo 1" + When I mark "todo 1" as complete + Then I should not see the todo "todo 1" \ No newline at end of file diff --git a/features/step_definitions/container_steps.rb b/features/step_definitions/container_steps.rb index 5f811c11..2f09911b 100644 --- a/features/step_definitions/container_steps.rb +++ b/features/step_definitions/container_steps.rb @@ -1,3 +1,19 @@ +When /^I collapse the context container of "([^"]*)"$/ do |context_name| + context = @current_user.contexts.find_by_name(context_name) + context.should_not be_nil + + xpath = "//a[@id='toggle_c#{context.id}']" + selenium.is_visible(xpath).should be_true + + selenium.click(xpath) +end + +When /^I toggle all collapsed context containers$/ do + click_link 'Toggle collapsed contexts' +end + +####### Context ####### + Then /^I should not see the context "([^"]*)"$/ do |context_name| context = @current_user.contexts.find_by_name(context_name) context.should_not be_nil @@ -15,6 +31,10 @@ Then /^I should not see the container for context "([^"]*)"$/ do |context_name| Then "I should not see the context \"#{context_name}\"" end +Then /^I should not see the context container for "([^"]*)"$/ do |context_name| + Then "I should not see the context \"#{context_name}\"" +end + Then /^the container for the context "([^"]*)" should not be visible$/ do |context_name| Then "I should not see the context \"#{context_name}\"" end @@ -23,10 +43,11 @@ Then /^I should see the container for context "([^"]*)"$/ do |context_name| context = @current_user.contexts.find_by_name(context_name) context.should_not be_nil - xpath = "xpath=//div[@id='c#{context.id}']" + xpath = "//div[@id='c#{context.id}']" - selenium.wait_for_element(xpath, :timeout_in_seconds => 5) - selenium.is_visible(xpath).should be_true + wait_for :timeout => 5 do + selenium.is_visible(xpath) + end end Then /^the container for the context "([^"]*)" should be visible$/ do |context_name| @@ -40,8 +61,78 @@ Then /^I should see "([^"]*)" in the context container for "([^"]*)"$/ do |todo_ todo.should_not be_nil xpath = "xpath=//div[@id=\"c#{context.id}\"]//div[@id='line_todo_#{todo.id}']" - selenium.wait_for_element(xpath, :timeout_in_seconds => 5) - selenium.is_visible(xpath).should be_true + wait_for :timeout => 5 do + selenium.is_visible(xpath) + end +end + +Then /^I should not see "([^"]*)" in the context container for "([^"]*)"$/ do |todo_description, context_name| + context = @current_user.contexts.find_by_name(context_name) + context.should_not be_nil + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "xpath=//div[@id=\"c#{context.id}\"]//div[@id='line_todo_#{todo.id}']" + + if selenium.is_element_present(xpath) + # give jquery some time to finish + wait_for :timeout_in_seconds => 5 do + !selenium.is_visible(xpath) + end + end +end + +####### Deferred ####### + +Then /^I should see "([^"]*)" in the deferred container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='tickler']//div[@id='line_todo_#{todo.id}']" + + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end +end + +Then /^I should not see "([^"]*)" in the deferred container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='tickler']//div[@id='line_todo_#{todo.id}']" + + wait_for :timeout => 5 do + !selenium.is_element_present(xpath) + end +end + +####### Project ####### + +Then /^I should see "([^"]*)" in the action container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='p#{todo.project.id}items']//div[@id='line_todo_#{todo.id}']" + + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end +end + +Then /^I should not see "([^"]*)" in the project container of "([^"]*)"$/ do |todo_description, project_name| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + project = @current_user.projects.find_by_name(project_name) + project.should_not be_nil + + xpath = "//div[@id='p#{todo.project.id}items']//div[@id='line_todo_#{todo.id}']" + + if selenium.is_element_present(xpath) + wait_for :timeout => 5 do + !selenium.is_element_present(xpath) + end + end end Then /^I should see "([^"]*)" in project container for "([^"]*)"$/ do |todo_description, project_name| @@ -55,4 +146,83 @@ Then /^I should see "([^"]*)" in project container for "([^"]*)"$/ do |todo_desc selenium.wait_for_element("xpath=#{xpath}", :timeout_in_seconds => 5) selenium.is_visible(xpath).should be_true -end \ No newline at end of file +end + +####### Completed ####### + +Then /^I should see "([^"]*)" in the completed container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='completed_container']//div[@id='line_todo_#{todo.id}']" + + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end +end + +Then /^I should not see "([^"]*)" in the completed container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='completed_container']//div[@id='line_todo_#{todo.id}']" + + if selenium.is_element_present(xpath) + wait_for :timeout => 5 do + !selenium.is_element_present(xpath) + end + end +end + +####### Hidden ####### + +Then /^I should see "([^"]*)" in the hidden container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='hidden']//div[@id='line_todo_#{todo.id}']" + + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end +end + +####### Calendar ####### + +Then /^I should see "([^"]*)" in the due next month container$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='due_after_this_month']//div[@id='line_todo_#{todo.id}']" + + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end +end + +####### Repeat patterns ####### + +Then /^I should see "([^"]*)" in the active recurring todos container$/ do |repeat_pattern| + repeat = @current_user.recurring_todos.find_by_description(repeat_pattern) + + unless repeat.nil? + xpath = "//div[@id='active_recurring_todos_container']//div[@id='recurring_todo_#{repeat.id}']" + selenium.wait_for_element("xpath=#{xpath}", :timeout_in_seconds => 5) + selenium.is_visible(xpath).should be_true + else + Then "I should not see \"#{repeat_pattern}\"" + end +end + +Then /^I should not see "([^"]*)" in the completed recurring todos container$/ do |repeat_pattern| + repeat = @current_user.recurring_todos.find_by_description(repeat_pattern) + + unless repeat.nil? + xpath = "//div[@id='completed_recurring_todos_container']//div[@id='recurring_todo_#{repeat.id}']" + selenium.wait_for_element("xpath=#{xpath}", :timeout_in_seconds => 5) + selenium.is_visible(xpath).should be_true + else + Then "I should not see \"#{repeat_pattern}\"" + end +end + diff --git a/features/step_definitions/context_list_steps.rb b/features/step_definitions/context_list_steps.rb index e7906782..b9e52087 100644 --- a/features/step_definitions/context_list_steps.rb +++ b/features/step_definitions/context_list_steps.rb @@ -42,14 +42,6 @@ When /^I add a new hidden context "([^"]*)"$/ do |context_name| submit_new_context_form end -Then /^context "([^"]*)" should be above context "([^"]*)"$/ do |context_high, context_low| - high_id = @current_user.contexts.find_by_name(context_high).id - low_id = @current_user.contexts.find_by_name(context_low).id - high_pos = selenium.get_element_position_top("//div[@id='context_#{high_id}']").to_i - low_pos = selenium.get_element_position_top("//div[@id='context_#{low_id}']").to_i - (high_pos < low_pos).should be_true -end - When /^I drag context "([^"]*)" below context "([^"]*)"$/ do |context_drag, context_drop| drag_id = @current_user.contexts.find_by_name(context_drag).id drop_id = @current_user.contexts.find_by_name(context_drop).id @@ -67,6 +59,14 @@ When /^I drag context "([^"]*)" below context "([^"]*)"$/ do |context_drag, cont selenium.mouse_up_at(drop_context_container_xpath,coord_string) end +Then /^context "([^"]*)" should be above context "([^"]*)"$/ do |context_high, context_low| + high_id = @current_user.contexts.find_by_name(context_high).id + low_id = @current_user.contexts.find_by_name(context_low).id + high_pos = selenium.get_element_position_top("//div[@id='context_#{high_id}']").to_i + low_pos = selenium.get_element_position_top("//div[@id='context_#{low_id}']").to_i + (high_pos < low_pos).should be_true +end + Then /^I should see that a context named "([^"]*)" is not present$/ do |context_name| Then "I should not see \"#{context_name}\"" end diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb index dc3b9e09..2cbfa34d 100644 --- a/features/step_definitions/context_steps.rb +++ b/features/step_definitions/context_steps.rb @@ -6,7 +6,7 @@ end Given /^there exists an active context called "([^"]*)" for user "([^"]*)"$/ do |context_name, login| user = User.find_by_login(login) user.should_not be_nil - @context = user.contexts.create!(:name => context_name, :hide => false) + @context = user.contexts.find_or_create(:name => context_name, :hide => false) end Given /^there exists a context called "([^"]*)" for user "([^"]*)"$/ do |context_name, login| @@ -34,9 +34,18 @@ end Given /^I have the following contexts:$/ do |table| table.hashes.each do |context| Given 'I have a context called "'+context[:context]+'"' + @context.hide = context[:hide] == "true" unless context[:hide].blank? + # acts_as_list puts the last added context at the top, but we want it + # at the bottom to be consistent with the table in the scenario + @context.move_to_bottom + @context.save! end end +Given /^I have the following contexts$/ do |table| + Given("I have the following contexts:", table) +end + Given /^I have a context "([^\"]*)" with (.*) actions$/ do |context_name, number_of_actions| context = @current_user.contexts.create!(:name => context_name) 1.upto number_of_actions.to_i do |i| @@ -44,17 +53,6 @@ Given /^I have a context "([^\"]*)" with (.*) actions$/ do |context_name, number end end -Given /^I have the following contexts$/ do |table| - Context.delete_all - table.hashes.each do |hash| - context = @current_user.contexts.create!(:name => hash[:name]) - unless hash[:hide].blank? - context.hide = hash[:hide] == true - context.save! - end - end -end - When /^I edit the context name in place to be "([^\"]*)"$/ do |new_context_name| selenium.click "context_name" fill_in "value", :with => new_context_name diff --git a/features/step_definitions/dependencies_steps.rb b/features/step_definitions/dependencies_steps.rb index 5de5cde4..2dd19e67 100644 --- a/features/step_definitions/dependencies_steps.rb +++ b/features/step_definitions/dependencies_steps.rb @@ -65,7 +65,7 @@ When /^I edit the dependency of "([^"]*)" to remove "([^"]*)" as predecessor$/ d wait_for :timeout=>5 do !selenium.is_element_present(delete_dep_button) end - + submit_edit_todo_form(todo) # note that animations will be running after the ajax is completed end @@ -109,7 +109,21 @@ Then /^I should not see "([^"]*)" within the dependencies of "([^"]*)"$/ do |suc successor.should_not be_nil # let selenium look for the presence of the successor xpath = "xpath=//div[@id='line_todo_#{todo.id}']//div[@id='successor_line_todo_#{successor.id}']//span" + wait_for :timeout => 5 do !selenium.is_element_present(xpath) end end + +Then /^I should see that "([^"]*)" does not have dependencies$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + dependencies_icon = "//div[@id='line_todo_#{todo.id}']/div/a[@class='show_successors']/img" + + if selenium.is_element_present(dependencies_icon) + wait_for :timeout => 5 do + !selenium.is_element_present(dependencies_icon) + end + end +end + diff --git a/features/step_definitions/generic_steps.rb b/features/step_definitions/generic_steps.rb index a7568a57..9e12cfde 100644 --- a/features/step_definitions/generic_steps.rb +++ b/features/step_definitions/generic_steps.rb @@ -2,6 +2,10 @@ Given /this is a pending scenario/ do pending end +Given /^I set the locale to "([^"]*)"$/ do |locale| + @locale = locale +end + Given /^I am working on the mobile interface$/ do @mobile_interface = true end @@ -11,7 +15,7 @@ Then /the badge should show (.*)/ do |number| xpath= "//span[@id='badge_count']" if response.respond_to? :selenium - response.should have_xpath(xpath) + response.should have_xpath(xpath) badge = response.selenium.get_text("xpath=#{xpath}").to_i else response.should have_xpath(xpath) do |node| @@ -28,8 +32,25 @@ Then /^I should see the empty message in the deferred container$/ do end end +Then /^I should see the empty tickler message$/ do + wait_for :timeout => 5 do + selenium.is_visible("xpath=//div[@id='tickler-empty-nd']") + end +end + +Then /^I should not see the empty tickler message$/ do + wait_for :timeout => 5 do + !selenium.is_visible("xpath=//div[@id='tickler-empty-nd']") + end +end + Then /^I should see an error flash message saying "([^"]*)"$/ do |message| xpath = "//div[@id='message_holder']/h4[@id='flash']" text = response.selenium.get_text("xpath=#{xpath}") text.should == message end + +Then /^I should see "([^"]*)" $/ do |text| + Then "I should see \"#{text}\"" +end + diff --git a/features/step_definitions/login_steps.rb b/features/step_definitions/login_steps.rb index 3509f959..1fc0d3ec 100644 --- a/features/step_definitions/login_steps.rb +++ b/features/step_definitions/login_steps.rb @@ -25,10 +25,14 @@ When /^my session expires$/ do # use expire_session to force expiry of session js = '$.ajax({type: "GET", url: "/login/expire_session", dataType: "script", async: false});' selenium.run_script(js); - + # force check of expiry bypassing timeout js = '$.ajax({type: "GET", url: "/login/check_expiry", dataType: "script", async: false});' selenium.run_script(js); sleep(2) end + +When /^I log out of Tracks$/ do + When "I go to the logout page" +end diff --git a/features/step_definitions/note_steps.rb b/features/step_definitions/note_steps.rb index 66b1602d..195d6f39 100644 --- a/features/step_definitions/note_steps.rb +++ b/features/step_definitions/note_steps.rb @@ -16,10 +16,6 @@ Given /^I have a project "([^\"]*)" with (.*) notes?$/ do |project_name, num| end end -When /^I click Toggle Notes$/ do - click_link 'Toggle notes' -end - When /^I add note "([^\"]*)" from the "([^\"]*)" project page$/ do |note, project| project = Project.find_by_name(project) project.notes.create!(:user_id => @current_user.id, :body => note) @@ -44,6 +40,23 @@ When /^I edit the first note to "([^"]*)"$/ do |note_body| click_button "submit_note_#{id}" end +When /^I toggle the note of "([^"]*)"$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + xpath = "//div[@id='line_todo_#{todo.id}']/div/a/img" + + selenium.click(xpath) +end + +When /^I click Toggle Notes$/ do + click_link 'Toggle notes' +end + +When /^I toggle all notes$/ do + When "I click Toggle Notes" +end + Then /^(.*) notes should be visible$/ do |number| # count number of project_notes count = 0 diff --git a/features/step_definitions/preferences_steps.rb b/features/step_definitions/preferences_steps.rb new file mode 100644 index 00000000..bd14c8fc --- /dev/null +++ b/features/step_definitions/preferences_steps.rb @@ -0,0 +1,15 @@ +When /^I edit my last name to "([^"]*)"$/ do |last_name| + fill_in "user[last_name]", :with => last_name + click_button "prefs_submit" +end + +When /^I set the password and confirmation to "([^"]*)"$/ do |new_password| + When "I set the password to \"#{new_password}\" and confirmation to \"#{new_password}\"" +end + +When /^I set the password to "([^"]*)" and confirmation to "([^"]*)"$/ do |new_password, new_password_confirmation| + fill_in "user[password]", :with => new_password + fill_in "user[password_confirmation]", :with => new_password_confirmation + click_button "prefs_submit" +end + diff --git a/features/step_definitions/project_list_steps.rb b/features/step_definitions/project_list_steps.rb index 3142e147..270a5f78 100644 --- a/features/step_definitions/project_list_steps.rb +++ b/features/step_definitions/project_list_steps.rb @@ -90,3 +90,52 @@ end Then /^the new project form should not be visible$/ do selenium.is_visible("project_new").should == false end + + +Given /^I have a project "([^"]*)" with (\d+) active todos$/ do |name, count| + @context = @current_user.contexts.find_or_create_by_name("Context A") + @project = @current_user.projects.find_or_create_by_name(name) + + @todos=[] + 1.upto count.to_i do |i| + todo = @current_user.todos.create!( + :project_id => @project.id, + :context_id => @context.id, + :description => "todo #{i}") + @todos << todo + end +end + +Then /^the project "([^"]*)" should have (\d+) actions listed$/ do |name, count| + project = @current_user.projects.find_by_name(name) + project.should_not be_nil + xpath = "//div[@id='list-active-projects-container']//div[@id='project_#{project.id}']//span[@class='needsreview']" + selenium.get_text("xpath=#{xpath}").should == "#{project.name} (#{count} actions)" +end + +Given /^I have a project "([^"]*)" with (\d+) active actions and (\d+) deferred actions$/ do |name, active_count, deferred_count| + Given "I have a project \"#{name}\" with #{active_count} active todos" + Given "I have a project \"#{name}\" with #{deferred_count} deferred actions" +end + +Given /^I have a project "([^"]*)" with (\d+) deferred actions$/ do |name, deferred| + @context = @current_user.contexts.find_or_create_by_name("Context A") + @project = @current_user.projects.find_or_create_by_name(name) + + 1.upto deferred.to_i do |i| + todo = @current_user.todos.create!( + :project_id => @project.id, + :context_id => @context.id, + :description => "deferred todo #{i}") + todo.show_from = Time.zone.now + 1.week + todo.save! + end +end + +Then /^the project "([^"]*)" should have (\d+) deferred actions listed$/ do |name, deferred| + project = @current_user.projects.find_by_name(name) + project.should_not be_nil + xpath = "//div[@id='list-active-projects-container']//div[@id='project_#{project.id}']//span[@class='needsreview']" + selenium.get_text("xpath=#{xpath}").should == "#{project.name} (#{deferred} deferred actions)" +end + diff --git a/features/step_definitions/project_steps.rb b/features/step_definitions/project_steps.rb index 66fd510d..cfb3589d 100644 --- a/features/step_definitions/project_steps.rb +++ b/features/step_definitions/project_steps.rb @@ -1,11 +1,24 @@ -Given /^I have a project "([^\"]*)" with (.*) todos$/ do |project_name, num_todos| - context = @current_user.contexts.find_or_create_by_name("Context A") - project = @current_user.projects.create!(:name => project_name) +Given /^I have a project "([^\"]*)" with ([0-9]+) todos$/ do |project_name, num_todos| + @context = @current_user.contexts.find_or_create_by_name("Context A") + @project = @current_user.projects.create!(:name => project_name) + # acts_as_list adds at top by default, but that is counter-intuitive when reading scenario's, so reverse this + @project.move_to_bottom + + @todos=[] 1.upto num_todos.to_i do |i| - @current_user.todos.create!( - :project_id => project.id, - :context_id => context.id, - :description => "Todo #{i}") + todo = @current_user.todos.create!( + :project_id => @project.id, + :context_id => @context.id, + :description => "todo #{i}") + @todos << todo + end +end + +Given /^I have a project "([^\"]*)" with ([0-9]+) deferred todos$/ do |project_name, num_todos| + Given "I have a project \"#{project_name}\" with #{num_todos} todos" + @todos.each do |todo| + todo.show_from = Time.zone.now + 1.week + todo.save! end end @@ -13,6 +26,8 @@ Given /^there exists a project "([^\"]*)" for user "([^\"]*)"$/ do |project_name user = User.find_by_login(user_name) user.should_not be_nil @project = user.projects.create!(:name => project_name) + # acts_as_list adds at top by default, but that is counter-intuitive when reading scenario's, so reverse this + @project.move_to_bottom end Given /^there exists a project called "([^"]*)" for user "([^"]*)"$/ do |project_name, login| @@ -34,6 +49,23 @@ end Given /^I have the following projects:$/ do |table| table.hashes.each do |project| Given 'I have a project called "'+project[:project_name]+'"' + # acts_as_list puts the last added project at the top, but we want it + # at the bottom to be consistent with the table in the scenario + @project.move_to_bottom + @project.save! + end +end + +Given /^I have a completed project called "([^"]*)"$/ do |project_name| + Given "I have a project called \"#{project_name}\"" + @project.complete! + @project.reload + assert @project.completed? +end + +Given /^I have (\d+) completed projects$/ do |number_of_projects| + 1.upto number_of_projects.to_i do |i| + Given "I have a completed project called \"Project #{i}\"" end end @@ -46,10 +78,32 @@ Given /^I have a hidden project called "([^"]*)"$/ do |project_name| @project.hide! end +When /^I open the project edit form$/ do + click_link "link_edit_project_#{@project.id}" + + wait_for do + selenium.is_element_present("submit_project_#{@project.id}") + end +end + +When /^I cancel the project edit form$/ do + click_link "cancel_project_#{@project.id}" + + if selenium.is_visible("submit_project_#{@project.id}") + wait_for do + !selenium.is_visible("submit_project_#{@project.id}") + end + end +end + When /^I edit the project description to "([^\"]*)"$/ do |new_description| click_link "link_edit_project_#{@project.id}" fill_in "project[description]", :with => new_description click_button "submit_project_#{@project.id}" + + wait_for do + !selenium.is_element_present("submit_project_#{@project.id}") + end end When /^I edit the project name to "([^\"]*)"$/ do |new_title| @@ -58,7 +112,7 @@ When /^I edit the project name to "([^\"]*)"$/ do |new_title| wait_for do selenium.is_element_present("submit_project_#{@project.id}") end - + fill_in "project[name]", :with => new_title selenium.click "submit_project_#{@project.id}", @@ -67,7 +121,7 @@ When /^I edit the project name to "([^\"]*)"$/ do |new_title| :timeout => 5 wait_for do - !selenium.is_element_present("submit_context_#{@project.id}") + !selenium.is_element_present("submit_project_#{@project.id}") end end @@ -86,6 +140,44 @@ When /^I try to edit the project name to "([^\"]*)"$/ do |new_title| :timeout => 5 end +When /^I edit the default context to "([^"]*)"$/ do |default_context| + click_link "link_edit_project_#{@project.id}" + + wait_for do + selenium.is_element_present("submit_project_#{@project.id}") + end + + fill_in "project[default_context_name]", :with => default_context + + selenium.click "submit_project_#{@project.id}", + :wait_for => :text, + :text => "Project saved", + :timeout => 5 + + wait_for :timeout => 5 do + !selenium.is_element_present("submit_project_#{@project.id}") + end +end + +Then /^I edit the default tags to "([^"]*)"$/ do |default_tags| + click_link "link_edit_project_#{@project.id}" + + wait_for do + selenium.is_element_present("submit_project_#{@project.id}") + end + + fill_in "project[default_tags]", :with => default_tags + + selenium.click "submit_project_#{@project.id}", + :wait_for => :text, + :text => "Project saved", + :timeout => 5 + + wait_for :timeout => 5 do + !selenium.is_element_present("submit_project_#{@project.id}") + end +end + When /^I edit the project name of "([^"]*)" to "([^"]*)"$/ do |project_current_name, project_new_name| @project = @current_user.projects.find_by_name(project_current_name) @project.should_not be_nil @@ -167,7 +259,7 @@ Then /^I should see the bold text "([^\"]*)" in the project description$/ do |bo response.should have_xpath(xpath) bold_text = response.selenium.get_text("xpath=#{xpath}") - + bold_text.should =~ /#{bold}/ end @@ -181,7 +273,9 @@ Then /^I should see the italic text "([^\"]*)" in the project description$/ do | end Then /^the project title should be "(.*)"$/ do |title| - selenium.get_text("css=h2#project_name").should == title + wait_for :timeout => 2 do + selenium.get_text("css=h2#project_name") == title + end end Then /^I should see the project name is "([^"]*)"$/ do |project_name| diff --git a/features/step_definitions/recurring_todo_steps.rb b/features/step_definitions/recurring_todo_steps.rb index 810b1e22..a4156078 100644 --- a/features/step_definitions/recurring_todo_steps.rb +++ b/features/step_definitions/recurring_todo_steps.rb @@ -26,6 +26,12 @@ Given /^I have a completed repeat pattern "([^"]*)"$/ do |pattern_name| @recurring_todo.completed?.should be_true end +Given /^I have (\d+) completed repeat patterns$/ do |number_of_patterns| + 1.upto number_of_patterns.to_i do |i| + Given "I have a completed repeat pattern \"Repeating Todo #{i}\"" + end +end + When /^I select "([^\"]*)" recurrence pattern$/ do |recurrence_period| selenium.click("recurring_todo_recurring_period_#{recurrence_period.downcase}") end @@ -78,6 +84,15 @@ When /^I mark the pattern "([^"]*)" as active$/ do |pattern_name| wait_for_ajax end +When /^I follow the recurring todo link of "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + recurring_todo_link = "xpath=//div[@id='todo_#{todo.id}']//a[@class='recurring_icon']/img" + selenium.click( recurring_todo_link ) + selenium.wait_for_page_to_load(5000) +end + Then /^the state list "([^"]*)" should be empty$/ do |state| empty_id = "recurring-todos-empty-nd" if state.downcase == "active" empty_id = "completed-empty-nd" if state.downcase == "completed" @@ -87,7 +102,7 @@ end Then /^the pattern "([^\"]*)" should be starred$/ do |pattern_name| pattern = @current_user.recurring_todos.find_by_description(pattern_name) pattern.should_not be_nil - xpath = "//div[@id='recurring_todo_#{pattern.id}']//img[@class='starred_todo']" + xpath = "//div[@id='recurring_todo_#{pattern.id}']//img[@class='todo_star starred']" response.should have_xpath(xpath) end diff --git a/features/step_definitions/search_steps.rb b/features/step_definitions/search_steps.rb new file mode 100644 index 00000000..1c7327f8 --- /dev/null +++ b/features/step_definitions/search_steps.rb @@ -0,0 +1,4 @@ +When /^I search for "([^"]*)"$/ do |search_arg| + fill_in "search", :with => search_arg + click_button "Search" +end \ No newline at end of file diff --git a/features/step_definitions/todo_create_steps.rb b/features/step_definitions/todo_create_steps.rb index 9a9ee5b6..69b3cc88 100644 --- a/features/step_definitions/todo_create_steps.rb +++ b/features/step_definitions/todo_create_steps.rb @@ -1,11 +1,239 @@ +Given /^I have no todos$/ do + Todo.delete_all +end + +Given /^I have a todo "([^"]*)" in the context "([^"]*)"$/ do |description, context_name| + context = @current_user.contexts.find_or_create(:name => context_name) + @todo = @current_user.todos.create!(:context_id => context.id, :description => description) +end + +Given /^I have a todo "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |description, context_name, tag_names| + Given "I have a todo \"#{description}\" in the context \"#{context_name}\"" + @todo.tag_with(tag_names) + @todo.save! +end + +Given /^I have a todo "([^"]*)" in the context "([^"]*)" which is due tomorrow$/ do |description, context_name| + context = @current_user.contexts.find_or_create(:name => context_name) + @todo = @current_user.todos.create!(:context_id => context.id, :description => description) + @todo.due = @todo.created_at + 1.day + @todo.save! +end + +Given /^I have (\d+) todos in project "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |number_of_todos, project_name, context_name, tag_names| + @context = @current_user.contexts.find_by_name(context_name) + @context.should_not be_nil + + @project = @current_user.projects.find_by_name(project_name) + @project.should_not be_nil + + @todos = [] + number_of_todos.to_i.downto 1 do |i| + todo = @current_user.todos.create!(:context_id => @context.id, :description => "todo #{i}", :project_id => @project.id) + todo.tag_with(tag_names) + todo.save! + @todos << todo + end +end + +Given /^I have a todo "([^"]*)"$/ do |description| + Given "I have a todo \"#{description}\" in the context \"Context A\"" +end + +Given /^I have the following todos:$/ do |table| + table.hashes.each do | todo | + Given "I have a todo \"#{todo[:description]}\" in the context \"#{todo[:context]}\"" + end +end + +Given /^I have a todo "([^"]*)" with notes "([^"]*)"$/ do |description, notes| + Given "I have a todo \"#{description}\" in the context \"Context A\"" + @todo.notes = notes + @todo.save! +end + +Given /^I have ([0-9]+) todos$/ do |count| + count.to_i.downto 1 do |i| + Given "I have a todo \"todo #{i}\" in the context \"Context A\"" + end +end + +Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name| + context = @current_user.contexts.find_or_create(:name => context_name) + project = @current_user.projects.find_or_create(:name => project_name) + @todo = @current_user.todos.create!(:context_id => context.id, :project_id => project.id, :description => action_description) + @todo.tag_with(tags) + @todo.save +end + +Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)" that is due next week$/ do |action_description, project_name, tags, context_name| + Given "I have a todo with description \"#{action_description}\" in project \"#{project_name}\" with tags \"#{tags}\" in the context \"#{context_name}\"" + @todo.due = @current_user.time + 1.week + @todo.save! +end + +###### DEFERRED TODOS ####### + +Given /^I have ([0-9]+) deferred todos$/ do |count| + context = @current_user.contexts.create!(:name => "context B") + count.to_i.downto 1 do |i| + todo = @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}") + todo.show_from = @current_user.time + 1.week + todo.save! + end +end + +Given /^I have a deferred todo "([^"]*)" in the context "([^"]*)"$/ do |description, context_name| + context = @current_user.contexts.find_or_create(:name => context_name) + todo = @current_user.todos.create!(:context_id => context.id, :description => description) + todo.show_from = @current_user.time + 1.week + todo.save! +end + +Given /^I have a deferred todo "([^"]*)"$/ do |description| + Given "I have a deferred todo \"#{description}\" in the context \"context B\"" +end + +Given /^I have a deferred todo "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |action_description, context_name, tag_list| + Given "I have a todo \"#{action_description}\" in context \"#{context_name}\" with tags \"#{tag_list}\"" + @todo.show_from = @current_user.time + 1.week + @todo.save! +end + +####### COMPLETED TODOS ####### + +Given /^I have ([0-9]+) completed todos in project "([^"]*)" in context "([^"]*)"$/ do |count, project_name, context_name| + @context = @current_user.contexts.find_by_name(context_name) + @context.should_not be_nil + + @project = @current_user.projects.find_by_name(project_name) + @project.should_not be_nil + + @todos = [] + count.to_i.downto 1 do |i| + @todo = @current_user.todos.create!(:context_id => @context.id, :description => "todo #{i}", :project_id => @project.id) + @todo.complete! + @todos << @todo + end +end + +Given /^I have a completed todo "([^"]*)" in project "([^"]*)" in context "([^"]*)"$/ do |action_description, project_name, context_name| + Given "I have 1 completed todos in project \"#{project_name}\" in context \"#{context_name}\"" + @todos[0].description = action_description + @todos[0].save! +end + +Given /^I have (\d+) completed todos in project "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |count, project_name, context_name, tags| + Given "I have #{count} completed todos in project \"#{project_name}\" in context \"#{context_name}\"" + @todos.each { |t| t.tag_with(tags); t.save! } +end + +Given /^I have ([0-9]+) completed todos in context "([^"]*)"$/ do |count, context_name| + context = @current_user.contexts.find_by_name(context_name) + context.should_not be_nil + + count.to_i.downto 1 do |i| + todo = @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}") + todo.complete! + end +end + +Given /^I have ([0-9]+) completed todos$/ do |count| + Given "I have a context called \"context D\"" + Given "I have #{count} completed todos in context \"context D\"" +end + +Given /^I have ([0-9]+) completed todos with a note$/ do |count| + Given "I have #{count} completed todos" + @todos.each { |t| t.notes = "note #{t.id}"; t.save!} +end + +Given /^I have ([0-9]+) completed todos with a note in project "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |count, project_name, context_name, tags| + Given "I have #{count} completed todos in project \"#{project_name}\" in context \"#{context_name}\" with tags \"#{tags}\"" + @todos.each { |t| t.notes = "note #{t.id}"; t.save! } +end + +Given /^I have a completed todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name| + Given "I have a todo with description \"#{action_description}\" in project \"#{project_name}\" with tags \"#{tags}\" in the context \"#{context_name}\"" + @todo.complete! +end + +####### PROJECT WITH TODOS ###### + +Given /^I have a project "([^"]*)" that has the following todos$/ do |project_name, todos| + Given "I have a project called \"#{project_name}\"" + @project.should_not be_nil + todos.hashes.each do |todo| + context = @current_user.contexts.find_by_name(todo[:context]) + context.should_not be_nil + new_todo = @current_user.todos.create!( + :description => todo[:description], + :context_id => context.id, + :project_id=>@project.id, + :notes => todo[:notes]) + unless todo[:tags].nil? + new_todo.tag_with(todo[:tags]) + end + unless todo[:completed].nil? + new_todo.complete! if todo[:completed] == 'yes' + end + end +end + +Given /^I have a project "([^"]*)" that has the following deferred todos$/ do |project_name, todos| + Given "I have a project called \"#{project_name}\"" + @project.should_not be_nil + todos.hashes.each do |todo| + context = @current_user.contexts.find_by_name(todo[:context]) + context.should_not be_nil + new_todo = @current_user.todos.create!( + :description => todo[:description], + :context_id => context.id, + :project_id=>@project.id, + :show_from=>Time.zone.now+1.week) + unless todo[:tags].nil? + new_todo.tag_with(todo[:tags]) + end + unless todo[:completed].nil? + new_todo.complete! if todo[:completed] == 'yes' + end + end +end + +####### submitting using sidebar form ####### + When /^I submit a new action with description "([^"]*)"$/ do |description| fill_in "todo[description]", :with => description submit_next_action_form end +When /^I submit a new action with description "([^"]*)" with a dependency on "([^"]*)"$/ do |todo_description, predecessor_description| + predecessor = @current_user.todos.find_by_description(predecessor_description) + predecessor.should_not be_nil + + fill_in "todo[description]", :with => todo_description + + input = "xpath=//form[@id='todo-form-new-action']//input[@id='predecessor_input']" + selenium.focus(input) + selenium.type_keys input, predecessor_description + + # wait for auto complete + autocomplete = "xpath=//a[@id='ui-active-menuitem']" + selenium.wait_for_element(autocomplete, :timeout_in_seconds => 5) + + # click first line + first_elem = "xpath=//ul/li[1]/a[@id='ui-active-menuitem']" + selenium.click(first_elem) + + new_dependency_line = "xpath=//li[@id='pred_#{predecessor.id}']" + selenium.wait_for_element(new_dependency_line, :timeout_in_seconds => 5) + + submit_next_action_form +end + When /^I submit a new action with description "([^"]*)" and the tags "([^"]*)" in the context "([^"]*)"$/ do |description, tags, context_name| fill_in "todo[description]", :with => description - fill_in "tag_list", :with => tags + fill_in "todo_tag_list", :with => tags # fill_in does not seem to work when the field is prefilled with something. Empty the field first clear_context_name_from_next_action_form @@ -13,35 +241,6 @@ When /^I submit a new action with description "([^"]*)" and the tags "([^"]*)" i submit_next_action_form end -When /^I submit a new deferred action with description "([^"]*)" and the tags "([^"]*)" in the context "([^"]*)"$/ do |description, tags, context_name| - fill_in "todo[description]", :with => description - - clear_context_name_from_next_action_form - fill_in "todo_context_name", :with => context_name - - fill_in "tag_list", :with => tags - fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) - submit_next_action_form -end - -When /^I submit a new deferred action with description "([^"]*)" to project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |description, project_name, tags, context_name| - fill_in "todo[description]", :with => description - - clear_project_name_from_next_action_form - clear_context_name_from_next_action_form - - fill_in "todo_project_name", :with => project_name - fill_in "todo_context_name", :with => context_name - fill_in "tag_list", :with => tags - fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) - - submit_next_action_form -end - -When /^I submit a deferred new action with description "([^"]*)" to project "([^"]*)" in the context "([^"]*)"$/ do |description, project_name, context_name| - When "I submit a new deferred action with description \"#{description}\" to project \"#{project_name}\" with tags \"\" in the context \"#{context_name}\"" -end - When /^I submit a new action with description "([^"]*)" to project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |description, project_name, tags, context_name| fill_in "todo[description]", :with => description @@ -50,7 +249,7 @@ When /^I submit a new action with description "([^"]*)" to project "([^"]*)" wit fill_in "todo_project_name", :with => project_name fill_in "todo_context_name", :with => context_name - fill_in "tag_list", :with => tags + fill_in "todo_tag_list", :with => tags submit_next_action_form end @@ -69,6 +268,45 @@ When /^I submit a new action with description "([^"]*)" in the context "([^"]*)" submit_next_action_form end +####### submitting using sidebar form: DEFERRED ####### + +When /^I submit a new deferred action with description "([^"]*)"$/ do |description| + fill_in "todo[description]", :with => description + fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) + submit_next_action_form +end + +When /^I submit a new deferred action with description "([^"]*)" and the tags "([^"]*)" in the context "([^"]*)"$/ do |description, tags, context_name| + fill_in "todo[description]", :with => description + + clear_context_name_from_next_action_form + fill_in "todo_context_name", :with => context_name + + fill_in "todo_tag_list", :with => tags + fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) + submit_next_action_form +end + +When /^I submit a new deferred action with description "([^"]*)" to project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |description, project_name, tags, context_name| + fill_in "todo[description]", :with => description + + clear_project_name_from_next_action_form + clear_context_name_from_next_action_form + + fill_in "todo_project_name", :with => project_name + fill_in "todo_context_name", :with => context_name + fill_in "todo_tag_list", :with => tags + fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) + + submit_next_action_form +end + +When /^I submit a deferred new action with description "([^"]*)" to project "([^"]*)" in the context "([^"]*)"$/ do |description, project_name, context_name| + When "I submit a new deferred action with description \"#{description}\" to project \"#{project_name}\" with tags \"\" in the context \"#{context_name}\"" +end + +####### submitting using sidebar form: MULTIPLE ACTIONS ####### + When /^I submit multiple actions with using$/ do |multiple_actions| fill_in "todo[multiple_todos]", :with => multiple_actions submit_multiple_next_action_form diff --git a/features/step_definitions/todo_edit_steps.rb b/features/step_definitions/todo_edit_steps.rb index d3ac64ee..b46ba376 100644 --- a/features/step_definitions/todo_edit_steps.rb +++ b/features/step_definitions/todo_edit_steps.rb @@ -1,3 +1,65 @@ +####### MARK (UN)COMPLETE ####### + +When /^I mark "([^"]*)" as complete$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + check "mark_complete_#{todo.id}" + + wait_for_ajax +end + +When /^I mark "([^"]*)" as uncompleted$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + check "mark_complete_#{todo.id}" + + wait_for_ajax +end + +When /^I mark the complete todo "([^"]*)" active$/ do |action_description| + When "I mark \"#{action_description}\" as uncompleted" +end + +####### (UN)STARRING ####### + +When /^I star the action "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + xpath_unstarred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star']" + xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']" + + selenium.is_element_present(xpath_unstarred).should be_true + + star_img = "//img[@id='star_img_#{todo.id}']" + selenium.click(star_img, :wait_for => :ajax, :javascript_framework => :jquery) + + wait_for :timeout => 5 do + selenium.is_element_present(xpath_starred) + end +end + +When /^I unstar the action "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + xpath_unstarred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star']" + xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']" + + selenium.is_element_present(xpath_starred).should be_true + + star_img = "//img[@id='star_img_#{todo.id}']" + selenium.click(star_img, :wait_for => :ajax, :javascript_framework => :jquery) + + wait_for :timeout => 5 do + selenium.is_element_present(xpath_unstarred) + end +end + +####### Editing a todo using Edit Form ####### + When /I change the (.*) field of "([^\"]*)" to "([^\"]*)"$/ do |field_name, todo_name, new_value| todo = @current_user.todos.find_by_description(todo_name) todo.should_not be_nil @@ -7,24 +69,48 @@ When /I change the (.*) field of "([^\"]*)" to "([^\"]*)"$/ do |field_name, todo submit_edit_todo_form(todo) end -When /^I edit the context of "([^"]*)" to "([^"]*)"$/ do |context_old_name, context_new_name| - When "I change the context_name field of \"#{context_old_name}\" to \"#{context_new_name}\"" +When /^I edit the context of "([^"]*)" to "([^"]*)"$/ do |todo_name, context_new_name| + When "I change the context_name field of \"#{todo_name}\" to \"#{context_new_name}\"" +end + +When /^I edit the project of "([^"]*)" to "([^"]*)"$/ do |todo_name, project_new_name| + When "I change the project_name field of \"#{todo_name}\" to \"#{project_new_name}\"" +end + +When /^I edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + open_edit_form_for(todo) + fill_in "todo_description", :with => new_description + submit_edit_todo_form(todo) +end + +When /^I try to edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + open_edit_form_for(todo) + fill_in "todo_description", :with => new_description + selenium.click("//div[@id='edit_todo_#{todo.id}']//button[@id='submit_todo_#{todo.id}']", :wait_for => :ajax, :javascript_framework => :jquery) + # do not wait for form to disappear to be able to test failures +end + +When /^I edit the due date of "([^"]*)" to "([^"]*)"$/ do |action_description, date| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + open_edit_form_for(todo) + fill_in "due_todo_#{todo.id}", :with => date + submit_edit_todo_form(todo) end When /^I edit the due date of "([^"]*)" to tomorrow$/ do |action_description| - todo = @current_user.todos.find_by_description(action_description) - todo.should_not be_nil - open_edit_form_for(todo) - fill_in "due_todo_#{todo.id}", :with => format_date(todo.created_at + 1.day) - submit_edit_todo_form(todo) + date = format_date(Time.zone.now + 1.day) + When "I edit the due date of \"#{action_description}\" to \"#{date}\"" end When /^I edit the due date of "([^"]*)" to next month$/ do |action_description| - todo = @current_user.todos.find_by_description(action_description) - todo.should_not be_nil - open_edit_form_for(todo) - fill_in "due_todo_#{todo.id}", :with => format_date(todo.created_at + 1.month) - submit_edit_todo_form(todo) + date = format_date(Time.zone.now + 1.month) + When "I edit the due date of \"#{action_description}\" to \"#{date}\"" end When /^I clear the due date of "([^"]*)"$/ do |action_description| @@ -34,3 +120,65 @@ When /^I clear the due date of "([^"]*)"$/ do |action_description| selenium.click("//div[@id='edit_todo_#{todo.id}']//a[@id='due_x_todo_#{todo.id}']/img", :wait_for => :ajax, :javascript_framework => :jquery) submit_edit_todo_form(todo) end + +When /^I edit the show from date of "([^"]*)" to next month$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + open_edit_form_for(todo) + fill_in "show_from_todo_#{todo.id}", :with => format_date(todo.created_at + 1.month) + submit_edit_todo_form(todo) +end + +When /^I remove the show from date from "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + open_edit_form_for(todo) + selenium.click("//div[@id='edit_todo_#{todo.id}']//a[@id='show_from_x_todo_#{todo.id}']/img", :wait_for => :ajax, :javascript_framework => :jquery) + + submit_edit_todo_form(todo) +end + +When /^I clear the show from date of "([^"]*)"$/ do |action_description| + When "I remove the show from date from \"#{action_description}\"" +end + +When /^I defer "([^"]*)" for 1 day$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + defer_todo_1day_button = "xpath=//a[@id='defer_1_todo_#{todo.id}']/img" + selenium.click defer_todo_1day_button + + wait_for_ajax +end + +When /^I edit the tags of "([^"]*)" to "([^"]*)"$/ do |action_description, tags| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + open_edit_form_for(todo) + fill_in "tag_list", :with => tags + submit_edit_todo_form(todo) +end + +When /^I make a project of "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + make_project_button = "xpath=//a[@id='to_project_todo_#{todo.id}']/img" + selenium.click make_project_button + + wait_for :timeout => 5 do + !selenium.is_element_present("//div[@id='line_todo_#{todo.id}']") + end +end + +####### THEN ####### + +Then /^I should see an error message$/ do + error_block = "xpath=//form/div[@id='edit_error_status']" + wait_for :timeout => 5 do + selenium.is_element_present(error_block) + end +end \ No newline at end of file diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb index d0f27b4a..5ddda5b8 100644 --- a/features/step_definitions/todo_steps.rb +++ b/features/step_definitions/todo_steps.rb @@ -1,108 +1,4 @@ -Given /^I have no todos$/ do - Todo.delete_all -end - -Given /^I have a todo "([^"]*)" in the context "([^"]*)"$/ do |description, context_name| - context = @current_user.contexts.find_or_create(:name => context_name) - @current_user.todos.create!(:context_id => context.id, :description => description) -end - -Given /^I have a todo "([^"]*)" in the context "([^"]*)" which is due tomorrow$/ do |description, context_name| - context = @current_user.contexts.find_or_create(:name => context_name) - @todo = @current_user.todos.create!(:context_id => context.id, :description => description) - @todo.due = @todo.created_at + 1.day - @todo.save! -end - -Given /^I have a todo "([^"]*)"$/ do |description| - Given "I have a todo \"#{description}\" in the context \"Context A\"" -end - -Given /^I have ([0-9]+) todos$/ do |count| - count.to_i.downto 1 do |i| - Given "I have a todo \"todo #{i}\" in the context \"Context A\"" - end -end - -Given /^I have ([0-9]+) deferred todos$/ do |count| - context = @current_user.contexts.create!(:name => "context B") - count.to_i.downto 1 do |i| - @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}", :show_from => @current_user.time + 1.week) - end -end - -Given /^I have a deferred todo "(.*)"$/ do |description| - context = @current_user.contexts.create!(:name => "context B") - @current_user.todos.create!(:context_id => context.id, :description => description, :show_from => @current_user.time + 1.week) -end - -Given /^I have ([0-9]+) completed todos$/ do |count| - context = @current_user.contexts.create!(:name => "context C") - count.to_i.downto 1 do |i| - todo = @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}") - todo.complete! - end -end - -Given /^I have ([0-9]+) completed todos with a note$/ do |count| - context = @current_user.contexts.create!(:name => "context D") - count.to_i.downto 1 do |i| - todo = @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}", :notes => "note #{i}") - todo.complete! - end -end - -Given /^I have a project "([^"]*)" that has the following todos$/ do |project_name, todos| - Given "I have a project called \"#{project_name}\"" - @project.should_not be_nil - todos.hashes.each do |todo| - context = @current_user.contexts.find_by_name(todo[:context]) - context.should_not be_nil - new_todo = @current_user.todos.create!( - :description => todo[:description], - :context_id => context.id, - :project_id=>@project.id) - unless todo[:tags].nil? - new_todo.tag_with(todo[:tags]) - end - unless todo[:completed].nil? - new_todo.complete! if todo[:completed] == 'yes' - end - end -end - -When /^I mark "([^"]*)" as complete$/ do |action_description| - todo = @current_user.todos.find_by_description(action_description) - todo.should_not be_nil - - check "mark_complete_#{todo.id}" - - todo_container = "fail" # fail this test if @source_view is wrong - todo_container = "p#{todo.project_id}items" if @source_view=="project" - todo_container = "c#{todo.context_id}items" if @source_view=="context" || @source_view=="todos" || @source_view=="tag" - - # container should be there - selenium.is_element_present("//div[@id='#{todo_container}']").should be_true - - wait_for :timeout => 5 do - !selenium.is_element_present("//div[@id='#{todo_container}']//div[@id='line_todo_#{todo.id}']") - end - # note that animations could be running after finishing this -end - -When /^I mark "([^"]*)" as uncompleted$/ do |action_description| - # TODO: generalize. this currently only works for context wrt xpath - todo = @current_user.todos.find_by_description(action_description) - todo.should_not be_nil - - check "mark_complete_#{todo.id}" - - xpath="//div[@id='c#{todo.context_id}items']//div[@id='line_todo_#{todo.id}']" - wait_for :timeout => 5 do - selenium.is_element_present(xpath) - end - # note that animations could be running after finishing this -end +####### DELETE ####### When /^I delete the action "([^"]*)"$/ do |action_description| todo = @current_user.todos.find_by_description(action_description) @@ -121,6 +17,42 @@ When /^I delete the todo "([^"]*)"$/ do |action_description| When "I delete the action \"#{action_description}\"" end +####### Notes ####### + +When /^I open the notes of "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + show_notes_img = "xpath=//div[@id='line_todo_#{todo.id}']/div/a/img" + selenium.click show_notes_img + + wait_for :timeout => 5 do + selenium.is_visible "//div[@id='notes_todo_#{todo.id}']" + end +end + +####### THEN ####### + +Then /^I should see a starred "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']" + + selenium.is_element_present(xpath_starred).should be_true +end + +Then /^I should see an unstarred "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star']" + + wait_for :timeout => 5 do + selenium.is_element_present(xpath_starred) + end +end + Then /^I should see ([0-9]+) todos$/ do |count| count.to_i.downto 1 do |i| match_xpath "div[" @@ -128,7 +60,6 @@ Then /^I should see ([0-9]+) todos$/ do |count| end Then /^there should not be an error$/ do - sleep(5) # form should be gone and thus no errors visible wait_for :timeout => 5 do !selenium.is_visible("edit_todo_#{@dep_todo.id}") @@ -140,7 +71,44 @@ Then /^I should see the todo "([^\"]*)"$/ do |todo_description| end Then /^I should not see the todo "([^\"]*)"$/ do |todo_description| - selenium.is_element_present("//span[.=\"#{todo_description}\"]").should be_false + xpath = "//span[.=\"#{todo_description}\"]" + if selenium.is_element_present(xpath) + wait_for :timeout => 5 do + !selenium.is_element_present(xpath) + end + end +end + +Then /^I should see a completed todo "([^"]*)"$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + # only completed todos have a grey span with the completed_at date + xpath = "//div[@id='line_todo_#{todo.id}']/div/span[@class='grey']" + + unless selenium.is_element_present(xpath) + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end + end + selenium.is_visible(xpath).should be_true + +end + +Then /^I should see an active todo "([^"]*)"$/ do |todo_description| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + # only active todos have a grip div + + xpath = "//div[@id='line_todo_#{todo.id}']/img[@class='grip']" + + unless selenium.is_element_present(xpath) + wait_for :timeout => 5 do + selenium.is_element_present(xpath) + end + end + selenium.is_visible(xpath).should be_true end Then /^the number of actions should be (\d+)$/ do |count| @@ -151,61 +119,6 @@ Then /^a confirmation for adding a new context "([^"]*)" should be asked$/ do |c selenium.get_confirmation.should == "New context '#{context_name}' will be also created. Are you sure?" end -Then /^I should see "([^"]*)" in the deferred container$/ do |todo_description| - todo = @current_user.todos.find_by_description(todo_description) - todo.should_not be_nil - - xpath = "//div[@id='tickler']//div[@id='line_todo_#{todo.id}']" - - wait_for :timeout => 5 do - selenium.is_element_present(xpath) - end -end - -Then /^I should see "([^"]*)" in the action container$/ do |todo_description| - todo = @current_user.todos.find_by_description(todo_description) - todo.should_not be_nil - - xpath = "//div[@id='p#{todo.project.id}items']//div[@id='line_todo_#{todo.id}']" - - wait_for :timeout => 5 do - selenium.is_element_present(xpath) - end -end - -Then /^I should see "([^"]*)" in the completed container$/ do |todo_description| - todo = @current_user.todos.find_by_description(todo_description) - todo.should_not be_nil - - xpath = "//div[@id='completed_container']//div[@id='line_todo_#{todo.id}']" - - wait_for :timeout => 5 do - selenium.is_element_present(xpath) - end -end - -Then /^I should not see "([^"]*)" in the deferred container$/ do |todo_description| - todo = @current_user.todos.find_by_description(todo_description) - todo.should_not be_nil - - xpath = "//div[@id='tickler']//div[@id='line_todo_#{todo.id}']" - - wait_for :timeout => 5 do - !selenium.is_element_present(xpath) - end -end - -Then /^I should see "([^"]*)" in the due next month container$/ do |todo_description| - todo = @current_user.todos.find_by_description(todo_description) - todo.should_not be_nil - - xpath = "//div[@id='due_after_this_month']//div[@id='line_todo_#{todo.id}']" - - wait_for :timeout => 5 do - selenium.is_element_present(xpath) - end -end - Then /^the selected project should be "([^"]*)"$/ do |content| # Works for mobile. TODO: make it work for both mobile and non-mobile field_labeled("Project").element.search(".//option[@selected = 'selected']").inner_html.should =~ /#{content}/ @@ -215,3 +128,44 @@ Then /^the selected context should be "([^"]*)"$/ do |content| # Works for mobile. TODO: make it work for both mobile and non-mobile field_labeled("Context").element.search(".//option[@selected = 'selected']").inner_html.should =~ /#{content}/ end + +Then /^I should see the page selector$/ do + page_selector_xpath = ".//a[@class='next_page']" + response.body.should have_xpath(page_selector_xpath) +end + +Then /^the page should be "([^"]*)"$/ do |page_number| + page_number_found = -1 + page_number_xpath = ".//span[@class='current']" + response.should have_xpath(page_number_xpath) do |node| + page_number_found = node.first.content.to_i + end + page_number_found.should == page_number.to_i +end + +Then /^the project field of the new todo form should contain "([^"]*)"$/ do |project_name| + xpath= "//form[@id='todo-form-new-action']/input[@id='todo_project_name']" + project_name.should == response.selenium.get_value("xpath=#{xpath}") +end + +Then /^the default context of the new todo form should be "([^"]*)"$/ do |context_name| + xpath= "//form[@id='todo-form-new-action']/input[@id='todo_context_name']" + context_name.should == response.selenium.get_value("xpath=#{xpath}") +end + +Then /^the tag field in the new todo form should be empty$/ do + xpath= "//form[@id='todo-form-new-action']/input[@id='todo_tag_list']" + assert response.selenium.get_value("xpath=#{xpath}").blank? +end + +Then /^the tag field in the new todo form should be "([^"]*)"$/ do |tag_list| + xpath= "//form[@id='todo-form-new-action']/input[@id='todo_tag_list']" + tag_list.should == response.selenium.get_value("xpath=#{xpath}") +end + +Then /^the tags of "([^"]*)" should be "([^"]*)"$/ do |todo_description, tag_list| + todo = @current_user.todos.find_by_description(todo_description) + todo.should_not be_nil + + todo.tag_list.should == tag_list +end \ No newline at end of file diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb index 05022302..dd1ef9b9 100644 --- a/features/step_definitions/user_steps.rb +++ b/features/step_definitions/user_steps.rb @@ -2,10 +2,44 @@ Given /^the following user records?$/ do |table| User.delete_all table.hashes.each do |hash| user = Factory(:user, hash) - user.create_preference + user.create_preference({:locale => 'en'}) end end +Given /^the following user records with hash algorithm$/ do |table| + User.delete_all + table.hashes.each do | hash | + password = hash[:password] + algorithm = hash[:algorithm] + hash.delete("algorithm") + + user = Factory(:user, hash) + + case algorithm + when 'bcrypt' + user.change_password( password, password ) + user.reload + BCrypt::Password.new(user.crypted_password).should == password + when 'sha1' + user.password = user.password_confirmation = nil + user.write_attribute :crypted_password, user.sha1(password) + user.save + user.reload + user.crypted_password.should == user.sha1(password) + else + raise "Unknown hashing algorithm: #{algorithm}" + end + + user.create_preference({:locale => 'en'}) + end +end + +When /^I change my password to "([^"]*)"$/ do |password| + Then 'I should be on the change password page' + %w{password password_confirmation}.each { |name| fill_in "user[#{name}]", :with => password } + click_button +end + Given "no users exists" do User.delete_all end diff --git a/features/support/hooks.rb b/features/support/hooks.rb new file mode 100644 index 00000000..f53087e8 --- /dev/null +++ b/features/support/hooks.rb @@ -0,0 +1,11 @@ +AfterStep('@pause') do + print "Press Return to continue..." + STDIN.getc +end + +Before('@clear_cookies') do + cookies = selenium.cookies + cookies.split(';').each do | cookie | + selenium.delete_cookie(cookie) + end +end diff --git a/features/support/paths.rb b/features/support/paths.rb index 3d195d23..1c06e6ee 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -7,12 +7,47 @@ module NavigationHelpers # def path_to(page_name) options = @mobile_interface ? {:format => :m} : {} + options = {:locale => @locale}.merge(options) if @locale @source_view = nil + case page_name when /the home\s?page/ @source_view = "todos" root_path(options) + + when /the done page/ + @source_view = "done" + done_overview_path(options) + when /the done actions page for context "([^"]*)"/i + @source_view = "done" + context = @current_user.contexts.find_by_name($1) + done_todos_context_path(context, options) + when /the done actions page for project "([^"]*)"/i + @source_view = "done" + project = @current_user.projects.find_by_name($1) + done_todos_project_path(project, options) + when /the done actions page for tag "([^"]*)"/i + @source_view = "done" + done_tag_path($1, options) + when /the done actions page/ + @source_view = "done" + done_todos_path(options) + when /the all done actions page for context "([^"]*)"/i + @source_view = "done" + context = @current_user.contexts.find_by_name($1) + all_done_todos_context_path(context, options) + when /the all done actions page for project "([^"]*)"/i + @source_view = "done" + project = @current_user.projects.find_by_name($1) + all_done_todos_project_path(project, options) + when /the all done actions page for tag "([^"]*)"/i + @source_view = "done" + all_done_tag_path($1, options) + when /the all done actions page/ + @source_view = "done" + all_done_todos_path(options) + when /the statistics page/ @source_view = "stats" stats_path(options) @@ -20,8 +55,15 @@ module NavigationHelpers signup_path(options) when /the login page/ login_path(options) + when /the logout page/ + logout_path(options) when /the notes page/ notes_path(options) + when /the calendar page/ + calendar_path(options) + when /the review page/ + @source_view = "review" + review_path(options) when /the contexts page/ @source_view = "contexts" contexts_path(options) @@ -35,6 +77,7 @@ module NavigationHelpers when /the integrations page/ integrations_path(options) when /the tickler page/ + @source_view = "deferred" tickler_path(options) when /the export page/ data_path(options) @@ -64,6 +107,8 @@ module NavigationHelpers when /the tag page for "([^"]*)"/i @source_view = "tag" tag_path($1, options) + when /the change password page/ + change_password_user_path @current_user # Add more mappings here. # Here is an example that pulls values out of the Regexp: diff --git a/features/support/world.rb b/features/support/world.rb index 899fb801..b379e29d 100644 --- a/features/support/world.rb +++ b/features/support/world.rb @@ -22,7 +22,7 @@ module TracksStepHelper !selenium.is_element_present("//form[@id='form_todo_#{todo.id}']") end end - + def format_date(date) # copy-and-past from ApplicationController::format_date return date ? date.in_time_zone(@current_user.prefs.time_zone).strftime("#{@current_user.prefs.date_format}") : '' @@ -46,14 +46,14 @@ module TracksStepHelper wait_for :timeout => 5 do selenium.is_element_present(edit_button) end - + selenium.click(edit_button, :wait_for => :ajax, :javascript_framework => :jquery) end def wait_for_ajax selenium.wait_for :wait_for => :ajax, :javascript_framework => :jquery end - + end World(TracksStepHelper) \ No newline at end of file diff --git a/features/tagging_todos.feature b/features/tagging_todos.feature index 2ab5a72e..e6d5ecaa 100644 --- a/features/tagging_todos.feature +++ b/features/tagging_todos.feature @@ -8,33 +8,71 @@ Feature: Tagging todos | login | password | is_admin | | testuser | secret | false | And I have logged in as "testuser" with password "secret" + And I have a context called "@pc" + And I have a project called "hacking tracks" - Scenario: I can edit a todo to add tags to that todo - Given this is a pending scenario + Scenario: If there are no todos with a tag, the tag page should show an empty message + When I go to the tag page for "starred" + Then I should see "Currently there are no incomplete actions with the tag 'starred'" - Scenario: I can add a new todo with tags - Given this is a pending scenario - - Scenario: I can show all todos tagged with a specific tag - Given this is a pending scenario - - Scenario: I can remove a tag from a todo from the tag view and the tag will be removed - Given this is a pending scenario + @selenium + Scenario: I can remove a tag from a todo from the tag view and the todo will be removed + Given I have a todo "fix tests" in context "@pc" with tags "now" + When I go to the tag page for "now" + Then I should see "fix tests" + When I edit the tags of "fix tests" to "later" + Then I should not see "fix tests" + @selenium Scenario: I can add a new todo from tag view with that tag and it will be added to the page - Given this is a pending scenario + When I go to the tag page for "tracks" + And I submit a new action with description "prepare release" and the tags "tracks, release" in the context "@pc" + Then I should see "prepare release" in the context container for "@pc" + @selenium Scenario: I can add a new todo from tag view with a different tag and it will not be added to the page - Given this is a pending scenario - - Scenario: I can change the context of a tagged todo in tag view and it will move the tag on the page - Given this is a pending scenario - - Scenario: I can defer a tagged todo in tag view and it will move the todo on the page to the deferred container - Given this is a pending scenario + When I go to the tag page for "tracks" + And I submit a new action with description "prepare release" and the tags "release, next" in the context "@pc" + Then I should not see "prepare release" + @selenium Scenario: I can move a tagged todo in tag view to a hidden project and it will move the todo on the page to the hidden container - Given this is a pending scenario + Given I have a hidden project called "secret" + When I go to the tag page for "tracks" + And I submit a new action with description "prepare release" to project "hacking tracks" with tags "release, tracks" in the context "@pc" + Then I should see "prepare release" in the context container for "@pc" + When I edit the project of "prepare release" to "secret" + Then I should not see "prepare release" in the context container for "@pc" + And I should see "prepare release" in the hidden container -Scenario: I can move a tagged todo in tag view to a hidden context and it will move the todo on the page to the hidden container - Given this is a pending scenario + @selenium + Scenario: I can move a tagged todo in tag view to a hidden context and it will move the todo on the page to the hidden container + Given I have a hidden context called "@secret" + When I go to the tag page for "tracks" + And I submit a new action with description "prepare release" and the tags "release, tracks" in the context "@pc" + Then I should see "prepare release" in the context container for "@pc" + When I edit the context of "prepare release" to "@secret" + Then I should not see "prepare release" in the context container for "@pc" + Then I should see "prepare release" in the hidden container + + @selenium + Scenario: Completing the last todo from the tag view will show the empty message + Given I have a todo "migrate old scripts" in context "@pc" with tags "starred" + When I go to the tag page for "starred" + Then I should see "migrate old scripts" in the context container for "@pc" + When I mark "migrate old scripts" as complete + Then I should not see the context container for "@pc" + And I should see "Currently there are no incomplete actions with the tag 'starred'" + + @selenium + Scenario: Setting default tags for a project will prefill new todo form for that project + When I go to the "hacking tracks" project + Then the tag field in the new todo form should be empty + And I edit the default tags to "tests" + Then the tag field in the new todo form should be "tests" + # also the tag field should be prefilled after reload + When I go to the "hacking tracks" project + Then the tag field in the new todo form should be "tests" + # and the tag field should be prefilled after submitting a new todo + When I submit a new action with description "are my tags prefilled" + Then the tags of "are my tags prefilled" should be "tests" \ No newline at end of file diff --git a/features/tickler.feature b/features/tickler.feature index 3c6462a1..446323be 100644 --- a/features/tickler.feature +++ b/features/tickler.feature @@ -10,23 +10,46 @@ Feature: Manage deferred todos And there exists a project "manage me" for user "testuser" And I have logged in as "testuser" with password "secret" - @selenium @wip + @selenium Scenario: I can add a deferred todo and it will show in the tickler # also adding the first deferred todo will hide the empty message - When I go to the tickler + Given I have a context called "test" + When I go to the tickler page Then I should see the empty tickler message - When I submit a deferred new action with description "a new next action" + When I submit a new deferred action with description "a new next action" Then I should see "a new next action" And I should not see the empty tickler message - Scenario: Editing the description of a todo updated the todo - Given this is a pending scenario + @selenium + Scenario: Editing the description of a todo in the tickler updated the todo + Given I have a deferred todo "not yet now" + When I go to the tickler page + Then I should see "not yet now" + When I edit the description of "not yet now" to "almost" + Then I should not see "not yet now" + And I should see "almost" + @selenium Scenario: Editing the context of a todo moves it to the new context - Given this is a pending scenario + Given I have a context called "A" + And I have a context called "B" + And I have a deferred todo "not yet now" in the context "A" + When I go to the tickler page + Then I should see "not yet now" in the context container for "A" + When I edit the context of "not yet now" to "B" + Then I should see "not yet now" in the context container for "B" + And I should not see "not yet now" in the context container for "A" + @selenium Scenario: Removing the show from date from a todo removes it from the tickler - Given this is a pending scenario + Given I have a deferred todo "not yet now" + When I go to the tickler page + Then I should see "not yet now" + When I remove the show from date from "not yet now" + Then I should not see "not yet now" + And I should see the empty tickler message + When I go to the home page + Then I should see "not yet now" Scenario: Opening the tickler page shows me all deferred todos Given I have a deferred todo "not yet now" @@ -34,3 +57,12 @@ Feature: Manage deferred todos When I go to the tickler page Then I should see "not yet now" And I should not see "now is a good time" + + @selenium + Scenario: I can mark an action complete from the tickler + Given I have a deferred todo "not yet now" + When I go to the tickler page + And I mark "not yet now" as complete + Then I should not see "not yet now" + When I go to the done page + Then I should see "not yet now" diff --git a/features/toggle_context_containers.feature b/features/toggle_context_containers.feature new file mode 100644 index 00000000..fc1bbe37 --- /dev/null +++ b/features/toggle_context_containers.feature @@ -0,0 +1,66 @@ +Feature: Toggle the context containers + In order to only see the todos relevant on this moment + As a Tracks user + I want to toggle the contexts so the todos in that context are not shown + + Background: + Given the following user record + | login | password | is_admin | + | testuser | secret | false | + And I have logged in as "testuser" with password "secret" + + @selenium @clear_cookies + Scenario: I can toggle a context container + Given I have the following contexts + | context | hide | + | @ipad | false | + | @home | false | + | @boss | false | + And I have a project "collapse those contexts" that has the following todos + | description | context | + | test 1 | @ipad | + | test 2 | @home | + | test 3 | @boss | + When I go to the home page + Then I should see "test 1" in the context container for "@ipad" + And I should see "test 2" in the context container for "@home" + And I should see "test 3" in the context container for "@boss" + When I collapse the context container of "@ipad" + Then I should not see "test 1" + And I should see "test 2" in the context container for "@home" + And I should see "test 3" in the context container for "@boss" + When I collapse the context container of "@home" + Then I should not see "test 1" + And I should not see "test 2" + And I should see "test 3" in the context container for "@boss" + When I collapse the context container of "@boss" + Then I should not see "test 1" + And I should not see "test 2" + And I should not see "test 3" + + @selenium @clear_cookies + Scenario: I can hide all collapsed containers + Given I have the following contexts + | context | hide | + | @ipad | false | + | @home | false | + | @boss | false | + And I have a project "collapse those contexts" that has the following todos + | description | context | + | test 1 | @ipad | + | test 2 | @home | + | test 3 | @boss | + When I go to the home page + Then I should see "test 1" in the context container for "@ipad" + And I should see "test 2" in the context container for "@home" + And I should see "test 3" in the context container for "@boss" + When I collapse the context container of "@home" + And I collapse the context container of "@boss" + And I collapse the context container of "@ipad" + Then I should not see "test 1" + And I should not see "test 2" + And I should not see "test 3" + When I toggle all collapsed context containers + Then I should not see the context container for "@home" + And I should not see the context container for "@boss" + And I should not see the context container for "@ipad" diff --git a/features/view_done.feature b/features/view_done.feature index 248d106f..4f9b1fee 100644 --- a/features/view_done.feature +++ b/features/view_done.feature @@ -7,9 +7,226 @@ Feature: Show done Given the following user record | login | password | is_admin | | testuser | secret | false | + And I have logged in as "testuser" with password "secret" + And I have a context called "@pc" + And I have a project called "test project" + And I have 1 completed todos in project "test project" in context "@pc" with tags "starred" - Scenario: Visit done page - Given I have logged in as "testuser" with password "secret" - And I have 1 completed todos with a note + Scenario: Visit done overview page When I go to the done page - Then I should see "Completed in the last 24 hours" + Then I should see "Last Completed Actions" + And I should see "Last Completed Projects" + And I should see "Last Completed Repeating Actions" + + Scenario Outline: Page with actions links to show all completed actions + When I go to the + Then I should see "Completed actions" + And I should see "Show all" + When I follow "Show all" + Then I should be on the + + Scenarios: + | page | next page | + | home page | done actions page | + | context page for "@pc" | done actions page for context "@pc" | + | "test project" project | done actions page for project "test project" | + | tag page for "starred" | done actions page for tag "starred" | + + Scenario Outline: I can see all todos completed in the last timeperiod + When I go to the + Then I should see "todo 1" + And I should see "Completed today" + And I should see "Completed in the rest of this week" + And I should see "Completed in the rest of this month" + + Scenarios: + | page | + | done actions page | + | done actions page for context "@pc" | + | done actions page for project "test project" | + | done actions page for tag "starred" | + + Scenario Outline: I can see all todos completed + When I go to the + And I should see "You can see all completed actions here" + When I follow "here" + Then I should be on the + + Scenarios: + | page | other page | + | done actions page | all done actions page | + | done actions page for project "test project" | all done actions page for project "test project" | + | done actions page for context "@pc" | all done actions page for context "@pc" | + | done actions page for tag "starred" | all done actions page for tag "starred" | + + Scenario Outline: I can browse all todos completed by page + Given I have 50 completed todos with a note in project "test project" in context "@pc" with tags "starred" + When I go to the + Then I should see the page selector + When I follow "2" + Then I should be on the + And the page should be "2" + + Scenarios: + | page | + | all done actions page | + | all done actions page for project "test project" | + | all done actions page for context "@pc" | + | all done actions page for tag "starred" | + + Scenario: The projects page shows a link to all completed projects + Given I have a completed project called "finished" + When I go to the projects page + Then I should see "finished" + And I should see "Show all" + When I follow "Show all" + Then I should be on the done projects page + And I should see "finished" + + Scenario: I can browse all completed projects by page + Given I have 40 completed projects + When I go to the projects page + Then I should see "10 / 40" + When I follow "Show all" + Then I should see the page selector + And I should see "40 (1-20)" + When I follow "2" + Then I should be on the done projects page + And the page should be "2" + + Scenario: The recurring todos page shows a link to all completed recurring todos + Given I have a completed repeat pattern "finished" + When I go to the recurring todos page + Then I should see "finished" + And I should see "Show all" + When I follow "Show all" + Then I should be on the done recurring todos page + And I should see "finished" + + Scenario: I can browse all completed recurring todos by page + Given I have 40 completed repeat patterns + When I go to the recurring todos page + And I follow "Show all" + Then I should see the page selector + And I should see "40 (1-20)" + When I follow "2" + Then I should be on the done recurring todos page + And the page should be "2" + + @selenium + Scenario: I can toggle a done recurring todo active from done page + Given I have a completed repeat pattern "test pattern" + When I go to the done recurring todos page + Then I should see "test pattern" + When I mark the pattern "test pattern" as active + Then I should not see "test pattern" in the completed recurring todos container + When I go to the recurring todos page + Then I should see "test pattern" in the active recurring todos container + + @selenium + Scenario: I can delete a recurring todo from the done page + Given I have a completed repeat pattern "test pattern" + When I go to the done recurring todos page + Then I should see "test pattern" + When I delete the pattern "test pattern" + Then I should not see "test pattern" in the completed recurring todos container + When I go to the recurring todos page + Then I should see "test pattern" in the active recurring todos container + + @selenium + Scenario Outline: I can toggle a todo active from the done pages + When I go to the + Then I should see "todo 1" + When I mark the complete todo "todo 1" active + Then I should not see "todo 1" + When I go to the + Then I should see "todo 1" + + Scenarios: + | page | next page | where | + | done actions page | home page | in the context container for "@pc" | + | all done actions page | home page | in the context container for "@pc" | + | done actions page for context "@pc" | context page for "@pc" | | + | done actions page for project "test project" | "test project" project | | + | done actions page for tag "starred" | home page | in the context container for "@pc" | + | all done actions page for context "@pc" | context page for "@pc" | | + | all done actions page for project "test project"| "test project" project | | + | all done actions page for tag "starred" | home page | in the context container for "@pc" | + + @selenium + Scenario Outline: I can toggle the star of a todo from the done pages + When I go to the + Then I should see a starred "todo 1" + When I unstar the action "todo 1" + Then I should see an unstarred "todo 1" + + Scenarios: + | page | + | done actions page | + | all done actions page | + | done actions page for context "@pc" | + | done actions page for project "test project" | + | done actions page for tag "starred" | + | all done actions page for context "@pc" | + | all done actions page for project "test project"| + | all done actions page for tag "starred" | + + @selenium + Scenario: I can edit a project to active from the project done page + Given I have a completed project called "completed project" + When I go to the done projects page + Then I should see "completed project" + When I edit the project state of "completed project" to "active" + Then I should not see "completed project" + When I go to the projects page + Then I should see "completed project" + + + Scenario Outline: All pages are internationalized + Given I set the locale to "" + When I go to the + Then I should not see "translation missing" + + Scenarios: + | page | locale | + | done actions page | en | + | all done actions page | en | + | done actions page for context "@pc" | en | + | done actions page for project "test project" | en | + | done actions page for tag "starred" | en | + | all done actions page for context "@pc" | en | + | all done actions page for project "test project"| en | + | all done actions page for tag "starred" | en | + | done actions page | nl | + | all done actions page | nl | + | done actions page for context "@pc" | nl | + | done actions page for project "test project" | nl | + | done actions page for tag "starred" | nl | + | all done actions page for context "@pc" | nl | + | all done actions page for project "test project"| nl | + | all done actions page for tag "starred" | nl | + | done actions page | de | + | all done actions page | de | + | done actions page for context "@pc" | de | + | done actions page for project "test project" | de | + | done actions page for tag "starred" | de | + | all done actions page for context "@pc" | de | + | all done actions page for project "test project"| de | + | all done actions page for tag "starred" | de | + | done actions page | es | + | all done actions page | es | + | done actions page for context "@pc" | es | + | done actions page for project "test project" | es | + | done actions page for tag "starred" | es | + | all done actions page for context "@pc" | es | + | all done actions page for project "test project"| es | + | all done actions page for tag "starred" | es | +# fr locale needs changes from preference branch +# | done actions page | fr | +# | all done actions page | fr | +# | done actions page for context "@pc" | fr | +# | done actions page for project "test project" | fr | +# | done actions page for tag "starred" | fr | +# | all done actions page for context "@pc" | fr | +# | all done actions page for project "test project"| fr | +# | all done actions page for tag "starred" | fr | diff --git a/lib/login_system.rb b/lib/login_system.rb index 4d4be7ca..8bec423a 100644 --- a/lib/login_system.rb +++ b/lib/login_system.rb @@ -188,7 +188,6 @@ module LoginSystem end def basic_auth_denied - response.headers["Status"] = "401 Unauthorized" response.headers["WWW-Authenticate"] = "Basic realm=\"'Tracks Login Required'\"" render :text => t('login.unsuccessful'), :status => 401 end diff --git a/lib/selenium_driver_manager.rb b/lib/selenium_driver_manager.rb deleted file mode 100644 index 5019ba3c..00000000 --- a/lib/selenium_driver_manager.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'singleton' -require 'selenium' - -class SeleniumDriverManager - include Singleton - - def running_selenium_driver - start - driver - end - - def start - return if running? - driver.start - @running = true - end - - def stop - return unless running? - driver.stop - @running = false - end - - def running? - @running - end - - protected - - def driver - @driver ||= Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", "http://localhost", 15000) - end - -end diff --git a/lib/tasks/reset_password.rake b/lib/tasks/reset_password.rake index d7b28f69..6cc61a60 100644 --- a/lib/tasks/reset_password.rake +++ b/lib/tasks/reset_password.rake @@ -1,8 +1,6 @@ namespace :tracks do desc 'Replace the password of USER with a new one.' task :password => :environment do - - Dependencies.load_paths.unshift(File.dirname(__FILE__) + "/../../vendor/gems/highline-1.5.0/lib") require "highline/import" user = User.find_by_login(ENV['USER']) diff --git a/lib/tracks/todo_list.rb b/lib/tracks/todo_list.rb index 58f4f9b0..b1a32229 100644 --- a/lib/tracks/todo_list.rb +++ b/lib/tracks/todo_list.rb @@ -25,7 +25,7 @@ module Tracks end def find_done_todos - self.todos.find_in_state(:all, :completed, :order => "todos.completed_at DESC", :limit => self.user.prefs.show_number_completed) + self.todos.completed.all(:order => "todos.completed_at DESC", :limit => self.user.prefs.show_number_completed) end def not_done_todo_count(opts={}) @@ -54,6 +54,6 @@ module Tracks def deferred_todo_count self.todos.count_in_state(:deferred) end - + end end diff --git a/public/404.html b/public/404.html index 0e184561..eff660b9 100644 --- a/public/404.html +++ b/public/404.html @@ -1,8 +1,30 @@ - - + + + + + + + The page you were looking for doesn't exist (404) + + + -

File not found

-

Change this error message for pages not found in public/404.html

+ +
+

The page you were looking for doesn't exist.

+

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

+
\ No newline at end of file diff --git a/vendor/rails/railties/html/422.html b/public/422.html similarity index 100% rename from vendor/rails/railties/html/422.html rename to public/422.html diff --git a/public/500.html b/public/500.html index a1001a00..ec3bbf02 100644 --- a/public/500.html +++ b/public/500.html @@ -1,8 +1,30 @@ - - + + + + + + + We're sorry, but something went wrong (500) + + + -

Application error (Apache)

-

Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html

+ +
+

We're sorry, but something went wrong.

+

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

+
- \ No newline at end of file + diff --git a/public/images/reviewed.png b/public/images/reviewed.png new file mode 100755 index 00000000..9c4495be Binary files /dev/null and b/public/images/reviewed.png differ diff --git a/public/javascripts/application.js b/public/javascripts/application.js index fd7af758..280bf6bf 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -12,7 +12,7 @@ var TracksForm = { $('#'+formId+' input:text:first').focus(); } toggleLink.parent().toggleClass('hide_form'); - }, + }, set_project_name: function (name) { $('input#todo_project_name').val(name); }, @@ -35,7 +35,7 @@ var TracksForm = { $('#project_name').html(name); }, set_tag_list: function (name) { - $('input#tag_list').val(name); + $('input#todo_tag_list').val(name); }, set_tag_list_for_multi_add: function (name) { $('#multi_tag_list').val(name); @@ -74,8 +74,15 @@ var TracksForm = { $(this).prev().val(''); }); + $("#new_todo_starred_link").click(function() { + $("#new_todo_starred").val($(this).children(".todo_star").toggleClass("starred").hasClass("starred")); + }); + /* submit todo form after entering new todo */ $("button#todo_new_action_submit").live('click', function (ev) { + if ($('input#predecessor_input').val() != "") + if (!confirm(i18n['todos.unresolved_dependency'])) + return false; if (TodoItems.askIfNewContextProvided('', this)) submit_with_ajax_and_block_element('form#todo-form-new-action', $(this)); return false; @@ -174,8 +181,13 @@ var TracksPages = { var flash = $('div#message_holder'); flash.html("

"+message+"

"); flash = $('h4#flash'); - flash.show(); - flash.fadeOut(fade_duration_in_sec*1000); + + fadein_duration = 1500; + fadeout_duration = 1500; + show_duration = fade_duration_in_sec*1000 - fadein_duration - fadeout_duration + if (show_duration < 0) + show_duration = 1000; + flash.fadeIn(fadein_duration).delay(show_duration).fadeOut(fadeout_duration); }, set_page_badge: function(count) { $('#badge_count').html(count); @@ -239,7 +251,8 @@ var TracksPages = { ProjectItems.setup_autocomplete_for_projects('input[name=project_name]'); ContextItems.setup_autocomplete_for_contexts('input[name=context_name]'); ContextItems.setup_autocomplete_for_contexts('input[id="project_default_context_name"]'); - TracksPages.setup_autocomplete_for_tag_list('input[name=tag_list]'); + TracksPages.setup_autocomplete_for_tag_list('input[name=tag_list]'); // todo edit form + TracksPages.setup_autocomplete_for_tag_list('input[name=todo_tag_list]'); // new todo form TracksPages.setup_autocomplete_for_tag_list('input[id="project_default_tags"]'); TodoItems.setup_autocomplete_for_predecessor(); }, @@ -292,6 +305,19 @@ var TracksPages = { $(".todo_notes").toggle(); }); + + /* Poor man's perspectives, allows to hide any context that is collapsed */ + $("#toggle-contexts-nav").click(function () { + /* Need to keep a single toggle across all contexts */ + $(this).toggleClass("context_visibility"); + if ($(this).hasClass("context_visibility")) { + $(".context_collapsed").hide(); /* Hide all collapsed contexts together*/ + } + else { + $(".context_collapsed").show(); + } + }); + /* fade flashes and alerts in automatically */ $(".alert").fadeOut(8000); } @@ -341,12 +367,16 @@ var TodoItemsContainer = { $(this).find('img').attr('src', imgSrc.replace('collapse', 'expand')); $.cookie(TodoItemsContainer.buildCookieName(this.parentNode.parentNode), true); toggle_target.slideUp(500); + // set parent class to 'context_collapsed' so we can hide/unhide all collapsed contexts + toggle_target.parent().addClass("context_collapsed"); } else { // show it imgSrc = $(this).find('img').attr('src'); $(this).find('img').attr('src', imgSrc.replace('expand', 'collapse')); $.cookie(TodoItemsContainer.buildCookieName(this.parentNode.parentNode), null); toggle_target.slideDown(500); + // remove class 'context_collapsed' from parent class + toggle_target.parent().removeClass("context_collapsed"); } return false; }); @@ -357,6 +387,7 @@ var TodoItemsContainer = { if (imgSrc) { $(this).find('.container_toggle img').attr('src', imgSrc.replace('collapse', 'expand')); $(this).find('.toggle_target').hide(); + $(this).find('.toggle_target').parent().addClass("context_collapsed"); } } }); @@ -616,7 +647,7 @@ var ProjectItems = { var UsersPage = { setup_behavior: function() { - /* delete button to delete a usedr from the list */ + /* delete button to delete a user from the list */ $('a.delete_user_button').live('click', function(evt){ var confirm_message = $(this).attr("x_confirm_message") if(confirm(confirm_message)){ @@ -628,6 +659,47 @@ var UsersPage = { } } +var PreferencesPage = { + get_date_format: function(tag_name) { + var value = $('input[name="prefs['+tag_name+']"]').val(); + var element = 'span[id="prefs.'+tag_name+'"]'; + var url = 'preferences/render_date_format'; + var param = "date_format="+encodeURIComponent( value ); + generic_get_script_for_list(element, url, param); + }, + setup_getter_for_date_format: function(tag_name) { + $('input[name="prefs['+tag_name+']"]').change(function() { + PreferencesPage.get_date_format(tag_name); + }); + }, + setup_behavior: function() { + $( "#tabs" ).tabs(); + + $( "button#prefs_submit" ).button(); + + $('input[name="user[auth_type]"]').change(function() { + var value = $('input[name="user[auth_type]"]:checked').val(); + $('#open_id')[0].style.display = value == 'open_id' ? 'block' : 'none' + $('#database')[0].style.display = value == 'database' ? 'block' : 'none' + }); + + $('input[name="date_picker1"]').change(function() { + var value = $('input[name="date_picker1"]:checked').val(); + $('input[name="prefs[date_format]"]').val(value); + PreferencesPage.get_date_format('date_format'); + }); + + $('input[name="date_picker2"]').change(function() { + var value = $('input[name="date_picker2"]:checked').val(); + $('input[name="prefs[title_date_format]"]').val(value); + PreferencesPage.get_date_format('title_date_format'); + }); + + PreferencesPage.setup_getter_for_date_format('date_format'); + PreferencesPage.setup_getter_for_date_format('title_date_format'); + } +} + var ProjectListPage = { update_state_count: function(state, count) { $('#'+state+'-projects-count').html(count); @@ -662,8 +734,8 @@ var ProjectListPage = { }, setup_behavior: function() { /* in-place edit of project name */ - $('h2#project_name').editable(ProjectListPage.save_project_name, { - style: 'padding:0px', + $('div#project_name').editable(ProjectListPage.save_project_name, { + style: 'padding: 0px; width=100%;', submit: i18n['common.ok'], cancel: i18n['common.cancel'] }); @@ -735,6 +807,8 @@ var ProjectListPage = { update: update_order }); }); + + $('#project_new #project_name').focus(); } } @@ -818,6 +892,8 @@ var ContextListPage = { update: update_order }) }); + + $('#context-form #context_name').focus(); } } @@ -898,7 +974,7 @@ var NotesPage = { /* update button when editing a note */ $("form.edit-note-form button.positive").live('click', function (ev) { - submit_with_ajax_and_block_element('form.edit-note-form', $(this)); + submit_with_ajax_and_block_element($(this).parents('form.edit-note-form'), $(this)); return false; }); } @@ -991,6 +1067,10 @@ function redirect_to(path) { window.location.href = path; } +function refresh_page() { + location.reload(true); +} + function setup_auto_refresh(interval){ field_touched = false; function refresh_page() { @@ -1208,12 +1288,20 @@ function enable_rich_interaction(){ } $(document).ready(function() { + + // fix for IE8. Without this checkboxes don't work AJAXy. See #1152 + if($.browser.msie && ($.browser.version.substring(0, 2) == "8.")) { + $('body').bind('change', function() { + return true; + }); + } + TracksPages.setup_nifty_corners(); TodoItemsContainer.setup_container_toggles(); /* enable page specific behavior */ - $([ 'IntegrationsPage', 'NotesPage', 'ProjectListPage', 'ContextListPage', + $([ 'PreferencesPage', 'IntegrationsPage', 'NotesPage', 'ProjectListPage', 'ContextListPage', 'FeedsPage', 'RecurringTodosPage', 'TodoItems', 'TracksPages', 'TracksForm', 'SearchPage', 'UsersPage' ]).each(function() { eval(this+'.setup_behavior();'); diff --git a/public/javascripts/i18n/jquery.ui.datepicker-es.js b/public/javascripts/i18n/jquery.ui.datepicker-es.js new file mode 100644 index 00000000..a02133de --- /dev/null +++ b/public/javascripts/i18n/jquery.ui.datepicker-es.js @@ -0,0 +1,23 @@ +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['es'] = { + closeText: 'Cerrar', + prevText: '<Ant', + nextText: 'Sig>', + currentText: 'Hoy', + monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', + 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], + monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', + 'Jul','Ago','Sep','Oct','Nov','Dic'], + dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['es']); +}); \ No newline at end of file diff --git a/public/javascripts/i18n/jquery.ui.datepicker-fr.js b/public/javascripts/i18n/jquery.ui.datepicker-fr.js new file mode 100644 index 00000000..134bda65 --- /dev/null +++ b/public/javascripts/i18n/jquery.ui.datepicker-fr.js @@ -0,0 +1,23 @@ +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au) and Stéphane Nahmani (sholby@sholby.net). */ +jQuery(function($){ + $.datepicker.regional['fr'] = { + closeText: 'Fermer', + prevText: '<Préc', + nextText: 'Suiv>', + currentText: 'Courant', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', + 'Jul','Aoû','Sep','Oct','Nov','Déc'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], + dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr']); +}); \ No newline at end of file diff --git a/public/javascripts/jquery-1.5.2.min.js b/public/javascripts/jquery-1.5.2.min.js deleted file mode 100644 index f78f96a1..00000000 --- a/public/javascripts/jquery-1.5.2.min.js +++ /dev/null @@ -1,16 +0,0 @@ -/*! - * jQuery JavaScript Library v1.5.2 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Mar 31 15:28:23 2011 -0400 - */ -(function(a,b){function ci(a){return d.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cf(a){if(!b_[a]){var b=d("<"+a+">").appendTo("body"),c=b.css("display");b.remove();if(c==="none"||c==="")c="block";b_[a]=c}return b_[a]}function ce(a,b){var c={};d.each(cd.concat.apply([],cd.slice(0,b)),function(){c[this]=a});return c}function b$(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function bZ(){try{return new a.XMLHttpRequest}catch(b){}}function bY(){d(a).unload(function(){for(var a in bW)bW[a](0,1)})}function bS(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var e=a.dataTypes,f={},g,h,i=e.length,j,k=e[0],l,m,n,o,p;for(g=1;g=0===c})}function P(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function H(a,b){return(a&&a!=="*"?a+".":"")+b.replace(t,"`").replace(u,"&")}function G(a){var b,c,e,f,g,h,i,j,k,l,m,n,o,p=[],q=[],s=d._data(this,"events");if(a.liveFired!==this&&s&&s.live&&!a.target.disabled&&(!a.button||a.type!=="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var t=s.live.slice(0);for(i=0;ic)break;a.currentTarget=f.elem,a.data=f.handleObj.data,a.handleObj=f.handleObj,o=f.handleObj.origHandler.apply(f.elem,arguments);if(o===!1||a.isPropagationStopped()){c=f.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function E(a,c,e){var f=d.extend({},e[0]);f.type=a,f.originalEvent={},f.liveFired=b,d.event.handle.call(c,f),f.isDefaultPrevented()&&e[0].preventDefault()}function y(){return!0}function x(){return!1}function i(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function h(a,c,e){if(e===b&&a.nodeType===1){e=a.getAttribute("data-"+c);if(typeof e==="string"){try{e=e==="true"?!0:e==="false"?!1:e==="null"?null:d.isNaN(e)?g.test(e)?d.parseJSON(e):e:parseFloat(e)}catch(f){}d.data(a,c,e)}else e=b}return e}var c=a.document,d=function(){function G(){if(!d.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(G,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=navigator.userAgent,w,x,y,z=Object.prototype.toString,A=Object.prototype.hasOwnProperty,B=Array.prototype.push,C=Array.prototype.slice,D=String.prototype.trim,E=Array.prototype.indexOf,F={};d.fn=d.prototype={constructor:d,init:function(a,e,f){var g,i,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!e&&c.body){this.context=c,this[0]=c.body,this.selector="body",this.length=1;return this}if(typeof a==="string"){g=h.exec(a);if(!g||!g[1]&&e)return!e||e.jquery?(e||f).find(a):this.constructor(e).find(a);if(g[1]){e=e instanceof d?e[0]:e,k=e?e.ownerDocument||e:c,j=m.exec(a),j?d.isPlainObject(e)?(a=[c.createElement(j[1])],d.fn.attr.call(a,e,!0)):a=[k.createElement(j[1])]:(j=d.buildFragment([g[1]],[k]),a=(j.cacheable?d.clone(j.fragment):j.fragment).childNodes);return d.merge(this,a)}i=c.getElementById(g[2]);if(i&&i.parentNode){if(i.id!==g[2])return f.find(a);this.length=1,this[0]=i}this.context=c,this.selector=a;return this}if(d.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return d.makeArray(a,this)},selector:"",jquery:"1.5.2",length:0,size:function(){return this.length},toArray:function(){return C.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();d.isArray(a)?B.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+")");return e},each:function(a,b){return d.each(this,a,b)},ready:function(a){d.bindReady(),x.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(C.apply(this,arguments),"slice",C.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:B,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;x.resolveWith(c,[d]),d.fn.trigger&&d(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!x){x=d._Deferred();if(c.readyState==="complete")return setTimeout(d.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",y,!1),a.addEventListener("load",d.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",y),a.attachEvent("onload",d.ready);var b=!1;try{b=a.frameElement==null}catch(e){}c.documentElement.doScroll&&b&&G()}}},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):F[z.call(a)]||"object"},isPlainObject:function(a){if(!a||d.type(a)!=="object"||a.nodeType||d.isWindow(a))return!1;if(a.constructor&&!A.call(a,"constructor")&&!A.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a){}return c===b||A.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(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return a.JSON&&a.JSON.parse?a.JSON.parse(b):(new Function("return "+b))();d.error("Invalid JSON: "+b)},parseXML:function(b,c,e){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);return c},noop:function(){},globalEval:function(a){if(a&&i.test(a)){var b=c.head||c.getElementsByTagName("head")[0]||c.documentElement,e=c.createElement("script");d.support.scriptEval()?e.appendChild(c.createTextNode(a)):e.text=a,b.insertBefore(e,b.firstChild),b.removeChild(e)}},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(;g1?f.call(arguments,0):c,--g||h.resolveWith(h,f.call(b,0))}}var b=arguments,c=0,e=b.length,g=e,h=e<=1&&a&&d.isFunction(a.promise)?a:d.Deferred();if(e>1){for(;c
a";var e=b.getElementsByTagName("*"),f=b.getElementsByTagName("a")[0],g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=b.getElementsByTagName("input")[0];if(e&&e.length&&f){d.support={leadingWhitespace:b.firstChild.nodeType===3,tbody:!b.getElementsByTagName("tbody").length,htmlSerialize:!!b.getElementsByTagName("link").length,style:/red/.test(f.getAttribute("style")),hrefNormalized:f.getAttribute("href")==="/a",opacity:/^0.55$/.test(f.style.opacity),cssFloat:!!f.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,deleteExpando:!0,optDisabled:!1,checkClone:!1,noCloneEvent:!0,noCloneChecked:!0,boxModel:null,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableHiddenOffsets:!0,reliableMarginRight:!0},i.checked=!0,d.support.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,d.support.optDisabled=!h.disabled;var j=null;d.support.scriptEval=function(){if(j===null){var b=c.documentElement,e=c.createElement("script"),f="script"+d.now();try{e.appendChild(c.createTextNode("window."+f+"=1;"))}catch(g){}b.insertBefore(e,b.firstChild),a[f]?(j=!0,delete a[f]):j=!1,b.removeChild(e)}return j};try{delete b.test}catch(k){d.support.deleteExpando=!1}!b.addEventListener&&b.attachEvent&&b.fireEvent&&(b.attachEvent("onclick",function l(){d.support.noCloneEvent=!1,b.detachEvent("onclick",l)}),b.cloneNode(!0).fireEvent("onclick")),b=c.createElement("div"),b.innerHTML="";var m=c.createDocumentFragment();m.appendChild(b.firstChild),d.support.checkClone=m.cloneNode(!0).cloneNode(!0).lastChild.checked,d(function(){var a=c.createElement("div"),b=c.getElementsByTagName("body")[0];if(b){a.style.width=a.style.paddingLeft="1px",b.appendChild(a),d.boxModel=d.support.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,d.support.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",d.support.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
";var e=a.getElementsByTagName("td");d.support.reliableHiddenOffsets=e[0].offsetHeight===0,e[0].style.display="",e[1].style.display="none",d.support.reliableHiddenOffsets=d.support.reliableHiddenOffsets&&e[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(a.style.width="1px",a.style.marginRight="0",d.support.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(a,null).marginRight,10)||0)===0),b.removeChild(a).style.display="none",a=e=null}});var n=function(a){var b=c.createElement("div");a="on"+a;if(!b.attachEvent)return!0;var d=a in b;d||(b.setAttribute(a,"return;"),d=typeof b[a]==="function");return d};d.support.submitBubbles=n("submit"),d.support.changeBubbles=n("change"),b=e=f=null}}();var g=/^(?:\{.*\}|\[.*\])$/;d.extend({cache:{},uuid:0,expando:"jQuery"+(d.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?d.cache[a[d.expando]]:a[d.expando];return!!a&&!i(a)},data:function(a,c,e,f){if(d.acceptData(a)){var g=d.expando,h=typeof c==="string",i,j=a.nodeType,k=j?d.cache:a,l=j?a[d.expando]:a[d.expando]&&d.expando;if((!l||f&&l&&!k[l][g])&&h&&e===b)return;l||(j?a[d.expando]=l=++d.uuid:l=d.expando),k[l]||(k[l]={},j||(k[l].toJSON=d.noop));if(typeof c==="object"||typeof c==="function")f?k[l][g]=d.extend(k[l][g],c):k[l]=d.extend(k[l],c);i=k[l],f&&(i[g]||(i[g]={}),i=i[g]),e!==b&&(i[c]=e);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,e){if(d.acceptData(b)){var f=d.expando,g=b.nodeType,h=g?d.cache:b,j=g?b[d.expando]:d.expando;if(!h[j])return;if(c){var k=e?h[j][f]:h[j];if(k){delete k[c];if(!i(k))return}}if(e){delete h[j][f];if(!i(h[j]))return}var l=h[j][f];d.support.deleteExpando||h!=a?delete h[j]:h[j]=null,l?(h[j]={},g||(h[j].toJSON=d.noop),h[j][f]=l):g&&(d.support.deleteExpando?delete b[d.expando]:b.removeAttribute?b.removeAttribute(d.expando):b[d.expando]=null)}},_data:function(a,b,c){return d.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=d.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),d.fn.extend({data:function(a,c){var e=null;if(typeof a==="undefined"){if(this.length){e=d.data(this[0]);if(this[0].nodeType===1){var f=this[0].attributes,g;for(var i=0,j=f.length;i-1)return!0;return!1},val:function(a){if(!arguments.length){var c=this[0];if(c){if(d.nodeName(c,"option")){var e=c.attributes.value;return!e||e.specified?c.value:c.text}if(d.nodeName(c,"select")){var f=c.selectedIndex,g=[],h=c.options,i=c.type==="select-one";if(f<0)return null;for(var j=i?f:0,k=i?f+1:h.length;j=0;else if(d.nodeName(this,"select")){var f=d.makeArray(e);d("option",this).each(function(){this.selected=d.inArray(d(this).val(),f)>=0}),f.length||(this.selectedIndex=-1)}else this.value=e}})}}),d.extend({attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,e,f){if(!a||a.nodeType===3||a.nodeType===8||a.nodeType===2)return b;if(f&&c in d.attrFn)return d(a)[c](e);var g=a.nodeType!==1||!d.isXMLDoc(a),h=e!==b;c=g&&d.props[c]||c;if(a.nodeType===1){var i=m.test(c);if(c==="selected"&&!d.support.optSelected){var j=a.parentNode;j&&(j.selectedIndex,j.parentNode&&j.parentNode.selectedIndex)}if((c in a||a[c]!==b)&&g&&!i){h&&(c==="type"&&n.test(a.nodeName)&&a.parentNode&&d.error("type property can't be changed"),e===null?a.nodeType===1&&a.removeAttribute(c):a[c]=e);if(d.nodeName(a,"form")&&a.getAttributeNode(c))return a.getAttributeNode(c).nodeValue;if(c==="tabIndex"){var k=a.getAttributeNode("tabIndex");return k&&k.specified?k.value:o.test(a.nodeName)||p.test(a.nodeName)&&a.href?0:b}return a[c]}if(!d.support.style&&g&&c==="style"){h&&(a.style.cssText=""+e);return a.style.cssText}h&&a.setAttribute(c,""+e);if(!a.attributes[c]&&(a.hasAttribute&&!a.hasAttribute(c)))return b;var l=!d.support.hrefNormalized&&g&&i?a.getAttribute(c,2):a.getAttribute(c);return l===null?b:l}h&&(a[c]=e);return a[c]}});var r=/\.(.*)$/,s=/^(?:textarea|input|select)$/i,t=/\./g,u=/ /g,v=/[^\w\s.|`]/g,w=function(a){return a.replace(v,"\\$&")};d.event={add:function(c,e,f,g){if(c.nodeType!==3&&c.nodeType!==8){try{d.isWindow(c)&&(c!==a&&!c.frameElement)&&(c=a)}catch(h){}if(f===!1)f=x;else if(!f)return;var i,j;f.handler&&(i=f,f=i.handler),f.guid||(f.guid=d.guid++);var k=d._data(c);if(!k)return;var l=k.events,m=k.handle;l||(k.events=l={}),m||(k.handle=m=function(a){return typeof d!=="undefined"&&d.event.triggered!==a.type?d.event.handle.apply(m.elem,arguments):b}),m.elem=c,e=e.split(" ");var n,o=0,p;while(n=e[o++]){j=i?d.extend({},i):{handler:f,data:g},n.indexOf(".")>-1?(p=n.split("."),n=p.shift(),j.namespace=p.slice(0).sort().join(".")):(p=[],j.namespace=""),j.type=n,j.guid||(j.guid=f.guid);var q=l[n],r=d.event.special[n]||{};if(!q){q=l[n]=[];if(!r.setup||r.setup.call(c,g,p,m)===!1)c.addEventListener?c.addEventListener(n,m,!1):c.attachEvent&&c.attachEvent("on"+n,m)}r.add&&(r.add.call(c,j),j.handler.guid||(j.handler.guid=f.guid)),q.push(j),d.event.global[n]=!0}c=null}},global:{},remove:function(a,c,e,f){if(a.nodeType!==3&&a.nodeType!==8){e===!1&&(e=x);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=d.hasData(a)&&d._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(e=c.handler,c=c.type);if(!c||typeof c==="string"&&c.charAt(0)==="."){c=c||"";for(h in t)d.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+d.map(m.slice(0).sort(),w).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!e){for(j=0;j=0&&(a.type=f=f.slice(0,-1),a.exclusive=!0),e||(a.stopPropagation(),d.event.global[f]&&d.each(d.cache,function(){var b=d.expando,e=this[b];e&&e.events&&e.events[f]&&d.event.trigger(a,c,e.handle.elem)}));if(!e||e.nodeType===3||e.nodeType===8)return b;a.result=b,a.target=e,c=d.makeArray(c),c.unshift(a)}a.currentTarget=e;var h=d._data(e,"handle");h&&h.apply(e,c);var i=e.parentNode||e.ownerDocument;try{e&&e.nodeName&&d.noData[e.nodeName.toLowerCase()]||e["on"+f]&&e["on"+f].apply(e,c)===!1&&(a.result=!1,a.preventDefault())}catch(j){}if(!a.isPropagationStopped()&&i)d.event.trigger(a,c,i,!0);else if(!a.isDefaultPrevented()){var k,l=a.target,m=f.replace(r,""),n=d.nodeName(l,"a")&&m==="click",o=d.event.special[m]||{};if((!o._default||o._default.call(e,a)===!1)&&!n&&!(l&&l.nodeName&&d.noData[l.nodeName.toLowerCase()])){try{l[m]&&(k=l["on"+m],k&&(l["on"+m]=null),d.event.triggered=a.type,l[m]())}catch(p){}k&&(l["on"+m]=k),d.event.triggered=b}}},handle:function(c){var e,f,g,h,i,j=[],k=d.makeArray(arguments);c=k[0]=d.event.fix(c||a.event),c.currentTarget=this,e=c.type.indexOf(".")<0&&!c.exclusive,e||(g=c.type.split("."),c.type=g.shift(),j=g.slice(0).sort(),h=new RegExp("(^|\\.)"+j.join("\\.(?:.*\\.)?")+"(\\.|$)")),c.namespace=c.namespace||j.join("."),i=d._data(this,"events"),f=(i||{})[c.type];if(i&&f){f=f.slice(0);for(var l=0,m=f.length;l-1?d.map(a.options,function(a){return a.selected}).join("-"):"":a.nodeName.toLowerCase()==="select"&&(c=a.selectedIndex);return c},D=function D(a){var c=a.target,e,f;if(s.test(c.nodeName)&&!c.readOnly){e=d._data(c,"_change_data"),f=C(c),(a.type!=="focusout"||c.type!=="radio")&&d._data(c,"_change_data",f);if(e===b||f===e)return;if(e!=null||f)a.type="change",a.liveFired=b,d.event.trigger(a,arguments[1],c)}};d.event.special.change={filters:{focusout:D,beforedeactivate:D,click:function(a){var b=a.target,c=b.type;(c==="radio"||c==="checkbox"||b.nodeName.toLowerCase()==="select")&&D.call(this,a)},keydown:function(a){var b=a.target,c=b.type;(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&D.call(this,a)},beforeactivate:function(a){var b=a.target;d._data(b,"_change_data",C(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in B)d.event.add(this,c+".specialChange",B[c]);return s.test(this.nodeName)},teardown:function(a){d.event.remove(this,".specialChange");return s.test(this.nodeName)}},B=d.event.special.change.filters,B.focus=B.beforeactivate}c.addEventListener&&d.each({focus:"focusin",blur:"focusout"},function(a,b){function f(a){var c=d.event.fix(a);c.type=b,c.originalEvent={},d.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var e=0;d.event.special[b]={setup:function(){e++===0&&c.addEventListener(a,f,!0)},teardown:function(){--e===0&&c.removeEventListener(a,f,!0)}}}),d.each(["bind","one"],function(a,c){d.fn[c]=function(a,e,f){if(typeof a==="object"){for(var g in a)this[c](g,e,a[g],f);return this}if(d.isFunction(e)||e===!1)f=e,e=b;var h=c==="one"?d.proxy(f,function(a){d(this).unbind(a,h);return f.apply(this,arguments)}):f;if(a==="unload"&&c!=="one")this.one(a,e,f);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},d.attrFn&&(d.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(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(){h=!1;return 0});var k=function(b,d,e,g){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!=="string")return e;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(f.call(n)==="[object Array]")if(u)if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&e.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&e.push(j[t]);else e.push.apply(e,n);else p(n,e);o&&(k(o,h,e,g),k.uniqueSort(e));return e};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]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return 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){a.parentNode&&a.parentNode.selectedIndex;return 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"text"===c&&(b===c||b===null)},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},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){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.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",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(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}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.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}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.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}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.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 v=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(var g=c;g0},closest:function(a,b){var c=[],e,f,g=this[0];if(d.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(e=0,f=a.length;e-1:d(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=N.test(a)?d(a,b||this.context):null;for(e=0,f=this.length;e-1:d.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b)break}}c=c.length>1?d.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a==="string")return d.inArray(this[0],a?d(a):this.parent().children());return d.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a==="string"?d(a,b):d.makeArray(a),e=d.merge(this.get(),c);return this.pushStack(P(c[0])||P(e[0])?e:d.unique(e))},andSelf:function(){return this.add(this.prevObject)}}),d.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return d.dir(a,"parentNode")},parentsUntil:function(a,b,c){return d.dir(a,"parentNode",c)},next:function(a){return d.nth(a,2,"nextSibling")},prev:function(a){return d.nth(a,2,"previousSibling")},nextAll:function(a){return d.dir(a,"nextSibling")},prevAll:function(a){return d.dir(a,"previousSibling")},nextUntil:function(a,b,c){return d.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return d.dir(a,"previousSibling",c)},siblings:function(a){return d.sibling(a.parentNode.firstChild,a)},children:function(a){return d.sibling(a.firstChild)},contents:function(a){return d.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:d.makeArray(a.childNodes)}},function(a,b){d.fn[a]=function(c,e){var f=d.map(this,b,c),g=M.call(arguments);I.test(a)||(e=c),e&&typeof e==="string"&&(f=d.filter(e,f)),f=this.length>1&&!O[a]?d.unique(f):f,(this.length>1||K.test(e))&&J.test(a)&&(f=f.reverse());return this.pushStack(f,a,g.join(","))}}),d.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?d.find.matchesSelector(b[0],a)?[b[0]]:[]:d.find.matches(a,b)},dir:function(a,c,e){var f=[],g=a[c];while(g&&g.nodeType!==9&&(e===b||g.nodeType!==1||!d(g).is(e)))g.nodeType===1&&f.push(g),g=g[c];return f},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 R=/ jQuery\d+="(?:\d+|null)"/g,S=/^\s+/,T=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,U=/<([\w:]+)/,V=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};Z.optgroup=Z.option,Z.tbody=Z.tfoot=Z.colgroup=Z.caption=Z.thead,Z.th=Z.td,d.support.htmlSerialize||(Z._default=[1,"div
","
"]),d.fn.extend({text:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.text(a.call(this,b,c.text()))});if(typeof a!=="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return d.text(this)},wrapAll:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapAll(a.call(this,b))});if(this[0]){var b=d(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){if(d.isFunction(a))return this.each(function(b){d(this).wrapInner(a.call(this,b))});return this.each(function(){var b=d(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){d(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){d.nodeName(this,"body")||d(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=d(arguments[0]);a.push.apply(a,this.toArray());return 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);a.push.apply(a,d(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,e;(e=this[c])!=null;c++)if(!a||d.filter(a,[e]).length)!b&&e.nodeType===1&&(d.cleanData(e.getElementsByTagName("*")),d.cleanData([e])),e.parentNode&&e.parentNode.removeChild(e);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&d.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return d.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(R,""):null;if(typeof a!=="string"||X.test(a)||!d.support.leadingWhitespace&&S.test(a)||Z[(U.exec(a)||["",""])[1].toLowerCase()])d.isFunction(a)?this.each(function(b){var c=d(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);else{a=a.replace(T,"<$1>");try{for(var c=0,e=this.length;c1&&l0?this.clone(!0):this).get();d(f[h])[b](j),e=e.concat(j)}return this.pushStack(e,a,f.selector)}}),d.extend({clone:function(a,b,c){var e=a.cloneNode(!0),f,g,h;if((!d.support.noCloneEvent||!d.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!d.isXMLDoc(a)){ba(a,e),f=bb(a),g=bb(e);for(h=0;f[h];++h)ba(f[h],g[h])}if(b){_(a,e);if(c){f=bb(a),g=bb(e);for(h=0;f[h];++h)_(f[h],g[h])}}return e},clean:function(a,b,e,f){b=b||c,typeof b.createElement==="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var g=[];for(var h=0,i;(i=a[h])!=null;h++){typeof i==="number"&&(i+="");if(!i)continue;if(typeof i!=="string"||W.test(i)){if(typeof i==="string"){i=i.replace(T,"<$1>");var j=(U.exec(i)||["",""])[1].toLowerCase(),k=Z[j]||Z._default,l=k[0],m=b.createElement("div");m.innerHTML=k[1]+i+k[2];while(l--)m=m.lastChild;if(!d.support.tbody){var n=V.test(i),o=j==="table"&&!n?m.firstChild&&m.firstChild.childNodes:k[1]===""&&!n?m.childNodes:[];for(var p=o.length-1;p>=0;--p)d.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!d.support.leadingWhitespace&&S.test(i)&&m.insertBefore(b.createTextNode(S.exec(i)[0]),m.firstChild),i=m.childNodes}}else i=b.createTextNode(i);i.nodeType?g.push(i):g=d.merge(g,i)}if(e)for(h=0;g[h];h++)!f||!d.nodeName(g[h],"script")||g[h].type&&g[h].type.toLowerCase()!=="text/javascript"?(g[h].nodeType===1&&g.splice.apply(g,[h+1,0].concat(d.makeArray(g[h].getElementsByTagName("script")))),e.appendChild(g[h])):f.push(g[h].parentNode?g[h].parentNode.removeChild(g[h]):g[h]);return g},cleanData:function(a){var b,c,e=d.cache,f=d.expando,g=d.event.special,h=d.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&d.noData[j.nodeName.toLowerCase()])continue;c=j[d.expando];if(c){b=e[c]&&e[c][f];if(b&&b.events){for(var k in b.events)g[k]?d.event.remove(j,k):d.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[d.expando]:j.removeAttribute&&j.removeAttribute(d.expando),delete e[c]}}}});var bd=/alpha\([^)]*\)/i,be=/opacity=([^)]*)/,bf=/-([a-z])/ig,bg=/([A-Z]|^ms)/g,bh=/^-?\d+(?:px)?$/i,bi=/^-?\d/,bj={position:"absolute",visibility:"hidden",display:"block"},bk=["Left","Right"],bl=["Top","Bottom"],bm,bn,bo,bp=function(a,b){return b.toUpperCase()};d.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return d.access(this,a,c,!0,function(a,c,e){return e!==b?d.style(a,c,e):d.css(a,c)})},d.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bm(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0},cssProps:{"float":d.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,e,f){if(a&&a.nodeType!==3&&a.nodeType!==8&&a.style){var g,h=d.camelCase(c),i=a.style,j=d.cssHooks[h];c=d.cssProps[h]||h;if(e===b){if(j&&"get"in j&&(g=j.get(a,!1,f))!==b)return g;return i[c]}if(typeof e==="number"&&isNaN(e)||e==null)return;typeof e==="number"&&!d.cssNumber[h]&&(e+="px");if(!j||!("set"in j)||(e=j.set(a,e))!==b)try{i[c]=e}catch(k){}}},css:function(a,c,e){var f,g=d.camelCase(c),h=d.cssHooks[g];c=d.cssProps[g]||g;if(h&&"get"in h&&(f=h.get(a,!0,e))!==b)return f;if(bm)return bm(a,c,g)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bf,bp)}}),d.curCSS=d.css,d.each(["height","width"],function(a,b){d.cssHooks[b]={get:function(a,c,e){var f;if(c){a.offsetWidth!==0?f=bq(a,b,e):d.swap(a,bj,function(){f=bq(a,b,e)});if(f<=0){f=bm(a,b,b),f==="0px"&&bo&&(f=bo(a,b,b));if(f!=null)return f===""||f==="auto"?"0px":f}if(f<0||f==null){f=a.style[b];return f===""||f==="auto"?"0px":f}return typeof f==="string"?f:f+"px"}},set:function(a,b){if(!bh.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),d.support.opacity||(d.cssHooks.opacity={get:function(a,b){return be.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style;c.zoom=1;var e=d.isNaN(b)?"":"alpha(opacity="+b*100+")",f=c.filter||"";c.filter=bd.test(f)?f.replace(bd,e):c.filter+" "+e}}),d(function(){d.support.reliableMarginRight||(d.cssHooks.marginRight={get:function(a,b){var c;d.swap(a,{display:"inline-block"},function(){b?c=bm(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bn=function(a,c,e){var f,g,h;e=e.replace(bg,"-$1").toLowerCase();if(!(g=a.ownerDocument.defaultView))return b;if(h=g.getComputedStyle(a,null))f=h.getPropertyValue(e),f===""&&!d.contains(a.ownerDocument.documentElement,a)&&(f=d.style(a,e));return f}),c.documentElement.currentStyle&&(bo=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bh.test(d)&&bi.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));return d===""?"auto":d}),bm=bn||bo,d.expr&&d.expr.filters&&(d.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!d.support.reliableHiddenOffsets&&(a.style.display||d.css(a,"display"))==="none"},d.expr.filters.visible=function(a){return!d.expr.filters.hidden(a)});var br=/%20/g,bs=/\[\]$/,bt=/\r?\n/g,bu=/#.*$/,bv=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bw=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bx=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,by=/^(?:GET|HEAD)$/,bz=/^\/\//,bA=/\?/,bB=/)<[^<]*)*<\/script>/gi,bC=/^(?:select|textarea)/i,bD=/\s+/,bE=/([?&])_=[^&]*/,bF=/(^|\-)([a-z])/g,bG=function(a,b,c){return b+c.toUpperCase()},bH=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bI=d.fn.load,bJ={},bK={},bL,bM;try{bL=c.location.href}catch(bN){bL=c.createElement("a"),bL.href="",bL=bL.href}bM=bH.exec(bL.toLowerCase())||[],d.fn.extend({load:function(a,c,e){if(typeof a!=="string"&&bI)return bI.apply(this,arguments);if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var g=a.slice(f,a.length);a=a.slice(0,f)}var h="GET";c&&(d.isFunction(c)?(e=c,c=b):typeof c==="object"&&(c=d.param(c,d.ajaxSettings.traditional),h="POST"));var i=this;d.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?d("
").append(c.replace(bB,"")).find(g):c)),e&&i.each(e,[c,b,a])}});return this},serialize:function(){return d.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?d.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bC.test(this.nodeName)||bw.test(this.type))}).map(function(a,b){var c=d(this).val();return c==null?null:d.isArray(c)?d.map(c,function(a,c){return{name:b.name,value:a.replace(bt,"\r\n")}}):{name:b.name,value:c.replace(bt,"\r\n")}}).get()}}),d.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){d.fn[b]=function(a){return this.bind(b,a)}}),d.each(["get","post"],function(a,c){d[c]=function(a,e,f,g){d.isFunction(e)&&(g=g||f,f=e,e=b);return d.ajax({type:c,url:a,data:e,success:f,dataType:g})}}),d.extend({getScript:function(a,c){return d.get(a,b,c,"script")},getJSON:function(a,b,c){return d.get(a,b,c,"json")},ajaxSetup:function(a,b){b?d.extend(!0,a,d.ajaxSettings,b):(b=a,a=d.extend(!0,d.ajaxSettings,b));for(var c in {context:1,url:1})c in b?a[c]=b[c]:c in d.ajaxSettings&&(a[c]=d.ajaxSettings[c]);return a},ajaxSettings:{url:bL,isLocal:bx.test(bM[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":d.parseJSON,"text xml":d.parseXML}},ajaxPrefilter:bO(bJ),ajaxTransport:bO(bK),ajax:function(a,c){function v(a,c,l,n){if(r!==2){r=2,p&&clearTimeout(p),o=b,m=n||"",u.readyState=a?4:0;var q,t,v,w=l?bR(e,u,l):b,x,y;if(a>=200&&a<300||a===304){if(e.ifModified){if(x=u.getResponseHeader("Last-Modified"))d.lastModified[k]=x;if(y=u.getResponseHeader("Etag"))d.etag[k]=y}if(a===304)c="notmodified",q=!0;else try{t=bS(e,w),c="success",q=!0}catch(z){c="parsererror",v=z}}else{v=c;if(!c||a)c="error",a<0&&(a=0)}u.status=a,u.statusText=c,q?h.resolveWith(f,[t,c,u]):h.rejectWith(f,[u,c,v]),u.statusCode(j),j=b,s&&g.trigger("ajax"+(q?"Success":"Error"),[u,e,q?t:v]),i.resolveWith(f,[u,c]),s&&(g.trigger("ajaxComplete",[u,e]),--d.active||d.event.trigger("ajaxStop"))}}typeof a==="object"&&(c=a,a=b),c=c||{};var e=d.ajaxSetup({},c),f=e.context||e,g=f!==e&&(f.nodeType||f instanceof d)?d(f):d.event,h=d.Deferred(),i=d._Deferred(),j=e.statusCode||{},k,l={},m,n,o,p,q,r=0,s,t,u={readyState:0,setRequestHeader:function(a,b){r||(l[a.toLowerCase().replace(bF,bG)]=b);return this},getAllResponseHeaders:function(){return r===2?m:null},getResponseHeader:function(a){var c;if(r===2){if(!n){n={};while(c=bv.exec(m))n[c[1].toLowerCase()]=c[2]}c=n[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){r||(e.mimeType=a);return this},abort:function(a){a=a||"abort",o&&o.abort(a),v(0,a);return this}};h.promise(u),u.success=u.done,u.error=u.fail,u.complete=i.done,u.statusCode=function(a){if(a){var b;if(r<2)for(b in a)j[b]=[j[b],a[b]];else b=a[u.status],u.then(b,b)}return this},e.url=((a||e.url)+"").replace(bu,"").replace(bz,bM[1]+"//"),e.dataTypes=d.trim(e.dataType||"*").toLowerCase().split(bD),e.crossDomain==null&&(q=bH.exec(e.url.toLowerCase()),e.crossDomain=q&&(q[1]!=bM[1]||q[2]!=bM[2]||(q[3]||(q[1]==="http:"?80:443))!=(bM[3]||(bM[1]==="http:"?80:443)))),e.data&&e.processData&&typeof e.data!=="string"&&(e.data=d.param(e.data,e.traditional)),bP(bJ,e,c,u);if(r===2)return!1;s=e.global,e.type=e.type.toUpperCase(),e.hasContent=!by.test(e.type),s&&d.active++===0&&d.event.trigger("ajaxStart");if(!e.hasContent){e.data&&(e.url+=(bA.test(e.url)?"&":"?")+e.data),k=e.url;if(e.cache===!1){var w=d.now(),x=e.url.replace(bE,"$1_="+w);e.url=x+(x===e.url?(bA.test(e.url)?"&":"?")+"_="+w:"")}}if(e.data&&e.hasContent&&e.contentType!==!1||c.contentType)l["Content-Type"]=e.contentType;e.ifModified&&(k=k||e.url,d.lastModified[k]&&(l["If-Modified-Since"]=d.lastModified[k]),d.etag[k]&&(l["If-None-Match"]=d.etag[k])),l.Accept=e.dataTypes[0]&&e.accepts[e.dataTypes[0]]?e.accepts[e.dataTypes[0]]+(e.dataTypes[0]!=="*"?", */*; q=0.01":""):e.accepts["*"];for(t in e.headers)u.setRequestHeader(t,e.headers[t]);if(e.beforeSend&&(e.beforeSend.call(f,u,e)===!1||r===2)){u.abort();return!1}for(t in {success:1,error:1,complete:1})u[t](e[t]);o=bP(bK,e,c,u);if(o){u.readyState=1,s&&g.trigger("ajaxSend",[u,e]),e.async&&e.timeout>0&&(p=setTimeout(function(){u.abort("timeout")},e.timeout));try{r=1,o.send(l,v)}catch(y){status<2?v(-1,y):d.error(y)}}else v(-1,"No Transport");return u},param:function(a,c){var e=[],f=function(a,b){b=d.isFunction(b)?b():b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=d.ajaxSettings.traditional);if(d.isArray(a)||a.jquery&&!d.isPlainObject(a))d.each(a,function(){f(this.name,this.value)});else for(var g in a)bQ(g,a[g],c,f);return e.join("&").replace(br,"+")}}),d.extend({active:0,lastModified:{},etag:{}});var bT=d.now(),bU=/(\=)\?(&|$)|\?\?/i;d.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return d.expando+"_"+bT++}}),d.ajaxPrefilter("json jsonp",function(b,c,e){var f=typeof b.data==="string";if(b.dataTypes[0]==="jsonp"||c.jsonpCallback||c.jsonp!=null||b.jsonp!==!1&&(bU.test(b.url)||f&&bU.test(b.data))){var g,h=b.jsonpCallback=d.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2",m=function(){a[h]=i,g&&d.isFunction(i)&&a[h](g[0])};b.jsonp!==!1&&(j=j.replace(bU,l),b.url===j&&(f&&(k=k.replace(bU,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},e.then(m,m),b.converters["script json"]=function(){g||d.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),d.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){d.globalEval(a);return a}}}),d.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),d.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var bV=d.now(),bW,bX;d.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&bZ()||b$()}:bZ,bX=d.ajaxSettings.xhr(),d.support.ajax=!!bX,d.support.cors=bX&&"withCredentials"in bX,bX=b,d.support.ajax&&d.ajaxTransport(function(a){if(!a.crossDomain||d.support.cors){var c;return{send:function(e,f){var g=a.xhr(),h,i;a.username?g.open(a.type,a.url,a.async,a.username,a.password):g.open(a.type,a.url,a.async);if(a.xhrFields)for(i in a.xhrFields)g[i]=a.xhrFields[i];a.mimeType&&g.overrideMimeType&&g.overrideMimeType(a.mimeType),!a.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(i in e)g.setRequestHeader(i,e[i])}catch(j){}g.send(a.hasContent&&a.data||null),c=function(e,i){var j,k,l,m,n;try{if(c&&(i||g.readyState===4)){c=b,h&&(g.onreadystatechange=d.noop,delete bW[h]);if(i)g.readyState!==4&&g.abort();else{j=g.status,l=g.getAllResponseHeaders(),m={},n=g.responseXML,n&&n.documentElement&&(m.xml=n),m.text=g.responseText;try{k=g.statusText}catch(o){k=""}j||!a.isLocal||a.crossDomain?j===1223&&(j=204):j=m.text?200:404}}}catch(p){i||f(-1,p)}m&&f(j,k,m,l)},a.async&&g.readyState!==4?(bW||(bW={},bY()),h=bV++,g.onreadystatechange=bW[h]=c):c()},abort:function(){c&&c(0,1)}}}});var b_={},ca=/^(?:toggle|show|hide)$/,cb=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cc,cd=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];d.fn.extend({show:function(a,b,c){var e,f;if(a||a===0)return this.animate(ce("show",3),a,b,c);for(var g=0,h=this.length;g=0;a--)c[a].elem===this&&(b&&c[a](!0),c.splice(a,1))}),b||this.dequeue();return this}}),d.each({slideDown:ce("show",1),slideUp:ce("hide",1),slideToggle:ce("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){d.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),d.extend({speed:function(a,b,c){var e=a&&typeof a==="object"?d.extend({},a):{complete:c||!c&&b||d.isFunction(a)&&a,duration:a,easing:c&&b||b&&!d.isFunction(b)&&b};e.duration=d.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in d.fx.speeds?d.fx.speeds[e.duration]:d.fx.speeds._default,e.old=e.complete,e.complete=function(){e.queue!==!1&&d(this).dequeue(),d.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig||(b.orig={})}}),d.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(d.fx.step[this.prop]||d.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=d.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return e.step(a)}var e=this,f=d.fx;this.startTime=d.now(),this.start=a,this.end=b,this.unit=c||this.unit||(d.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&d.timers.push(g)&&!cc&&(cc=setInterval(f.tick,f.interval))},show:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),d(this.elem).show()},hide:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=d.now(),c=!0;if(a||b>=this.options.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),this.options.curAnim[this.prop]=!0;for(var e in this.options.curAnim)this.options.curAnim[e]!==!0&&(c=!1);if(c){if(this.options.overflow!=null&&!d.support.shrinkWrapBlocks){var f=this.elem,g=this.options;d.each(["","X","Y"],function(a,b){f.style["overflow"+b]=g.overflow[a]})}this.options.hide&&d(this.elem).hide();if(this.options.hide||this.options.show)for(var h in this.options.curAnim)d.style(this.elem,h,this.options.orig[h]);this.options.complete.call(this.elem)}return!1}var i=b-this.startTime;this.state=i/this.options.duration;var j=this.options.specialEasing&&this.options.specialEasing[this.prop],k=this.options.easing||(d.easing.swing?"swing":"linear");this.pos=d.easing[j||k](this.state,i,0,1,this.options.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update();return!0}},d.extend(d.fx,{tick:function(){var a=d.timers;for(var b=0;b
";d.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),e=b.firstChild,f=e.firstChild,h=e.nextSibling.firstChild.firstChild,this.doesNotAddBorder=f.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,f.style.position="fixed",f.style.top="20px",this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15,f.style.position=f.style.top="",e.style.overflow="hidden",e.style.position="relative",this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),d.offset.initialize=d.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;d.offset.initialize(),d.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(d.css(a,"marginTop"))||0,c+=parseFloat(d.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var e=d.css(a,"position");e==="static"&&(a.style.position="relative");var f=d(a),g=f.offset(),h=d.css(a,"top"),i=d.css(a,"left"),j=(e==="absolute"||e==="fixed")&&d.inArray("auto",[h,i])>-1,k={},l={},m,n;j&&(l=f.position()),m=j?l.top:parseInt(h,10)||0,n=j?l.left:parseInt(i,10)||0,d.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):f.css(k)}},d.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),e=ch.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(d.css(a,"marginTop"))||0,c.left-=parseFloat(d.css(a,"marginLeft"))||0,e.top+=parseFloat(d.css(b[0],"borderTopWidth"))||0,e.left+=parseFloat(d.css(b[0],"borderLeftWidth"))||0;return{top:c.top-e.top,left:c.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&(!ch.test(a.nodeName)&&d.css(a,"position")==="static"))a=a.offsetParent;return a})}}),d.each(["Left","Top"],function(a,c){var e="scroll"+c;d.fn[e]=function(c){var f=this[0],g;if(!f)return null;if(c!==b)return this.each(function(){g=ci(this),g?g.scrollTo(a?d(g).scrollLeft():c,a?c:d(g).scrollTop()):this[e]=c});g=ci(f);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:d.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]}}),d.each(["Height","Width"],function(a,c){var e=c.toLowerCase();d.fn["inner"+c]=function(){return this[0]?parseFloat(d.css(this[0],e,"padding")):null},d.fn["outer"+c]=function(a){return this[0]?parseFloat(d.css(this[0],e,a?"margin":"border")):null},d.fn[e]=function(a){var f=this[0];if(!f)return a==null?null:this;if(d.isFunction(a))return this.each(function(b){var c=d(this);c[e](a.call(this,b,c[e]()))});if(d.isWindow(f)){var g=f.document.documentElement["client"+c];return f.document.compatMode==="CSS1Compat"&&g||f.document.body["client"+c]||g}if(f.nodeType===9)return Math.max(f.documentElement["client"+c],f.body["scroll"+c],f.documentElement["scroll"+c],f.body["offset"+c],f.documentElement["offset"+c]);if(a===b){var h=d.css(f,e),i=parseFloat(h);return d.isNaN(i)?h:i}return this.css(e,typeof a==="string"?a:a+"px")}}),a.jQuery=a.$=d})(window); \ No newline at end of file diff --git a/public/javascripts/jquery-1.6.2.min.js b/public/javascripts/jquery-1.6.2.min.js new file mode 100644 index 00000000..8cdc80eb --- /dev/null +++ b/public/javascripts/jquery-1.6.2.min.js @@ -0,0 +1,18 @@ +/*! + * jQuery JavaScript Library v1.6.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu Jun 30 14:16:56 2011 -0400 + */ +(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(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(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.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,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return 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 g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.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 g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i. +shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.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?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};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]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return 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){a.parentNode&&a.parentNode.selectedIndex;return 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){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(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}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.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}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.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}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.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 v=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(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[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 X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(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){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(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=f(arguments[0]);a.push.apply(a,this.toArray());return 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);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.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&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j +)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.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=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.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));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[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":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.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&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}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 h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/public/javascripts/jquery-ui-1.8.11.custom.min.js b/public/javascripts/jquery-ui-1.8.11.custom.min.js deleted file mode 100644 index f8709e0f..00000000 --- a/public/javascripts/jquery-ui-1.8.11.custom.min.js +++ /dev/null @@ -1,783 +0,0 @@ -/*! - * jQuery UI 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.11",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106, -NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this, -"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position"); -if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f, -"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h, -d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}}); -c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate); -if(this._mouseStarted){this._mouseStarted=false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); -;/* - * jQuery UI Position 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Position - */ -(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY, -left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+= -k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-= -m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left= -d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= -a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), -g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); -;/* - * jQuery UI Draggable 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Draggables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== -"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= -this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top- -this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions(); -d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis|| -this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&& -this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this== -a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]|| -0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0], -this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top- -(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(), -height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[(a.containment=="document"?0:d(window).scrollLeft())-this.offset.relative.left-this.offset.parent.left,(a.containment=="document"?0:d(window).scrollTop())-this.offset.relative.top-this.offset.parent.top,(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"? -document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"), -10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"), -10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&& -d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0], -this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.leftthis.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g= -this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])? -e:!(e-this.offset.click.left
').css({width:this.offsetWidth+ -"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity", -a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e=j&&f<=l||h>=j&&h<=l||fl)&&(e>= -i&&e<=k||g>=i&&g<=k||ek);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), -top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= -this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", -nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== -String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection(); -this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()}; -if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(), -d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset= -this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio: -this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize", -b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height; -f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing"); -this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top= -null}if(d=="nw"){b.top=a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidthb.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+ -this.size.height,k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b, -a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a, -c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize, -originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.11"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize= -b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width", -"height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})}; -if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height- -g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width, -height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d= -e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options, -d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper? -d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height= -a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&& -/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable"); -b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/ -(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery); -;/* - * jQuery UI Selectable 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), -selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, -c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting", -c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d= -this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable"); -this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]= -b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false; -d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left- -this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; -this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= -document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); -return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], -e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); -c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): -this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, -dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, -toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+jg&&b+la[this.floating?"width":"height"]?j:g0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); -if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), -this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h=0;b--){var c=this.items[b],e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left= -e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0]; -if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder); -c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length=== -1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-f)this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top< -this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(d.ui.contains(this.containers[e].element[0], -this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out", -g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"); -a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); -if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion", -function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a= -this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); -this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons(); -b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target); -a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ -c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options; -if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); -if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(), -e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight|| -e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false", -"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.11", -animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/); -f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide", -paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); -;/* - * jQuery UI Autocomplete 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.position.js - */ -(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){g= -false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!= -a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)}; -this.menu=d("
    ").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&& -a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); -d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&& -b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source= -this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length").data("item.autocomplete",b).append(d("").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, -"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery); -(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", --1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.attr("scrollTop"),c=this.element.height();if(b<0)this.element.attr("scrollTop",g+b);else b>=c&&this.element.attr("scrollTop",g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})}, -deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0); -e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e, -g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first")); -this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,f=d.primary&&d.secondary,e=[];if(d.primary||d.secondary){if(this.options.text)e.push("ui-button-text-icon"+(f?"s":d.primary?"-primary":"-secondary"));d.primary&&b.prepend("");d.secondary&&b.append("");if(!this.options.text){e.push(f?"ui-button-icons-only": -"ui-button-icon-only");this.hasTitle||b.attr("title",c)}}else e.push("ui-button-text-only");b.addClass(e.join(" "))}}});a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()}, -destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery); -;/* - * jQuery UI Dialog 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.button.js - * jquery.ui.draggable.js - * jquery.ui.mouse.js - * jquery.ui.position.js - * jquery.ui.resizable.js - */ -(function(c,j){var k={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},l={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&& -c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
    ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex", --1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
    ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role", -"button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id",e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose= -b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&& -a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0]){e=c(this).css("z-index"); -isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ); -d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===f[0]&&e.shiftKey){g.focus(1);return false}}}); -c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("
    ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("
    ").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(f, -h){h=c.isFunction(h)?{click:h,text:f}:h;f=c('').attr(h,true).unbind("click").click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&f.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g= -d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,originalSize:f.originalSize, -position:f.position,size:f.size}}a=a===j?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",f,b(h))},stop:function(f, -h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length=== -1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);if(g in k)e=true;if(g in -l)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):e.removeClass("ui-dialog-disabled"); -break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=this.options,b,d,e= -this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-b,0));this.uiDialog.is(":data(resizable)")&& -this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.11",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length=== -0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), -height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight); -b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a");if(!a.values)a.values=[this._valueMin(),this._valueMin()];if(a.values.length&&a.values.length!==2)a.values=[a.values[0],a.values[0]]}else this.range=d("
    ");this.range.appendTo(this.element).addClass("ui-slider-range");if(a.range==="min"||a.range==="max")this.range.addClass("ui-slider-range-"+a.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("").appendTo(this.element).addClass("ui-slider-handle"); -if(a.values&&a.values.length)for(;d(".ui-slider-handle",this.element).length").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){a.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(a.disabled)d(this).blur(); -else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),h,g,i;if(!b.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e= -false;if(!b._keySliding){b._keySliding=true;d(this).addClass("ui-state-active");h=b._start(c,f);if(h===false)return}break}i=b.options.step;h=b.options.values&&b.options.values.length?(g=b.values(f)):(g=b.value());switch(c.keyCode){case d.ui.keyCode.HOME:g=b._valueMin();break;case d.ui.keyCode.END:g=b._valueMax();break;case d.ui.keyCode.PAGE_UP:g=b._trimAlignValue(h+(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:g=b._trimAlignValue(h-(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(h=== -b._valueMax())return;g=b._trimAlignValue(h+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(h===b._valueMin())return;g=b._trimAlignValue(h-i);break}b._slide(c,f,g);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(b._keySliding){b._keySliding=false;b._stop(c,e);b._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"); -this._mouseDestroy();return this},_mouseCapture:function(b){var a=this.options,c,e,f,h,g;if(a.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:b.pageX,y:b.pageY});e=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(i){var j=Math.abs(c-h.values(i));if(e>j){e=j;f=d(this);g=i}});if(a.range===true&&this.values(1)===a.min){g+=1;f=d(this.handles[g])}if(this._start(b, -g)===false)return false;this._mouseSliding=true;h._handleIndex=g;f.addClass("ui-state-active").focus();a=f.offset();this._clickOffset=!d(b.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:b.pageX-a.left-f.width()/2,top:b.pageY-a.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(b,g,c);return this._animateOff=true},_mouseStart:function(){return true}, -_mouseDrag:function(b){var a=this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b,this._handleIndex,a);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(b){var a; -if(this.orientation==="horizontal"){a=this.elementSize.width;b=b.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{a=this.elementSize.height;b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}a=b/a;if(a>1)a=1;if(a<0)a=0;if(this.orientation==="vertical")a=1-a;b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+a*b)},_start:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value= -this.values(a);c.values=this.values()}return this._trigger("start",b,c)},_slide:function(b,a,c){var e;if(this.options.values&&this.options.values.length){e=this.values(a?0:1);if(this.options.values.length===2&&this.options.range===true&&(a===0&&c>e||a===1&&c1){this.options.values[b]=this._trimAlignValue(a);this._refreshValue();this._change(null,b)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;f=this._valueMax())return this._valueMax();var a=this.options.step>0?this.options.step:1,c=(b-this._valueMin())%a;alignValue=b-c;if(Math.abs(c)*2>=a)alignValue+=c>0?a:-a;return parseFloat(alignValue.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max}, -_refreshValue:function(){var b=this.options.range,a=this.options,c=this,e=!this._animateOff?a.animate:false,f,h={},g,i,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(k){f=(c.values(k)-c._valueMin())/(c._valueMax()-c._valueMin())*100;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](h,a.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(k===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},a.animate); -if(k===1)c.range[e?"animate":"css"]({width:f-g+"%"},{queue:false,duration:a.animate})}else{if(k===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},a.animate);if(k===1)c.range[e?"animate":"css"]({height:f-g+"%"},{queue:false,duration:a.animate})}g=f});else{i=this.value();j=this._valueMin();l=this._valueMax();f=l!==j?(i-j)/(l-j)*100:0;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](h,a.animate);if(b==="min"&&this.orientation==="horizontal")this.range.stop(1, -1)[e?"animate":"css"]({width:f+"%"},a.animate);if(b==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:a.animate});if(b==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},a.animate);if(b==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:a.animate})}}});d.extend(d.ui.slider,{version:"1.8.11"})})(jQuery); -;/* - * jQuery UI Tabs 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
    ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& -e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= -d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| -(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); -this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= -this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); -if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); -this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ -g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", -function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; -this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= --1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; -d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= -d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, -e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); -j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); -if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, -this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, -load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, -"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, -url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.11"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k')}function F(a,b){d.extend(a,b);for(var c in b)if(b[c]== -null||b[c]==A)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.11"}});var y=(new Date).getTime();d.extend(K.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){F(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase(); -f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('
    ')}}, -_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&& -b.append.remove();if(c){b.append=d(''+c+"");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('').addClass(this._triggerClass).html(f== -""?c:d("").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;gh){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a, -c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b), -true);this._updateDatepicker(b);this._updateAlternate(b);b.dpDiv.show()}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}F(a.settings,e||{}); -b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass); -this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup", -this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs, -function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null: -f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target); -if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a); -d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");F(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-= -document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim"); -var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst= -b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a));var e=a.dpDiv.find("iframe.ui-datepicker-cover");e.length&&e.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});a.dpDiv.find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){d(this).removeClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover"); -this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).addClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+ -this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&& -a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var f=a.yearshtml;setTimeout(function(){f===a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);f=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth(): -0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a), -"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"? -"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a= -d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a= -d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c== -"M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth= -b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker(); -this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0); -a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c? -c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=z+1-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}w=this._daylightSavingAdjust(new Date(c,j-1,l));if(w.getFullYear()!=c||w.getMonth()+1!=j||w.getDate()!=l)throw"Invalid date";return w},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y", -RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+112?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay= -a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(), -b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n= -this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&nn;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?''+n+"":f?"":''+n+"";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m,g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?''+r+"":f?"":''+r+"";j=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&&a.currentDay?u:b;j=!h?j:this.formatDate(j,r,this._getFormatConfig(a));h=!a.inline?'":"";e=e?'
    '+(c?h:"")+(this._isInRange(a,r)?'":"")+(c?"":h)+"
    ":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z= -this._get(a,"monthNames"),w=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),v=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var L=this._getDefaultDate(a),I="",D=0;D1)switch(E){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]- -1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='
    '+(/all|left/.test(t)&&D==0?c?f:n:"")+(/all|right/.test(t)&&D==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,D>0||E>0,z,w)+'
    ';var B=j?'":"";for(t=0;t<7;t++){var q= -(t+h)%7;B+="=5?' class="ui-datepicker-week-end"':"")+'>'+s[q]+""}x+=B+"";B=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,B);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;B=l?6:Math.ceil((t+B)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var O=0;O";var P=!j?"":'";for(t=0;t<7;t++){var G= -p?p.apply(a.input?a.input[0]:null,[q]):[true,""],C=q.getMonth()!=g,J=C&&!H||!G[0]||k&&qo;P+='";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+= -P+""}g++;if(g>11){g=0;m++}x+="
    '+this._get(a,"weekHeader")+"
    '+this._get(a,"calculateWeek")(q)+""+(C&&!v?" ":J?''+q.getDate()+"":''+q.getDate()+"")+"
    "+(l?""+(i[0]>0&&E==i[1]-1?'
    ':""):"");M+=x}I+=M}I+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
    ', -o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&& -l)?" ":""));a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";if(d.browser.mozilla)k+='";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
    ";return k},_adjustInstDate:function(a,b,c){var e= -a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a, -"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); -c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, -"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= -function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker, -[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.11";window["DP_jQuery_"+y]=d})(jQuery); -;/* - * jQuery UI Progressbar 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
    ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); -this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* -this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.11"})})(jQuery); -;/* - * jQuery UI Effects 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/ - */ -jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], -16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, -a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= -a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", -"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, -0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, -211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, -d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0]; -h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c, -a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.11",save:function(c,a){for(var b=0;b").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent", -border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c); -return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments); -else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c), -b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c, -a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c, -a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a== -e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ -e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); -;/* - * jQuery UI Effects Fade 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fade - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Fold 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * jquery.effects.core.js - */ -(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], -10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); -;/* - * jQuery UI Effects Highlight 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& -this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Pulsate 1.8.11 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * jquery.effects.core.js - */ -(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); -b.dequeue()})})}})(jQuery); -; \ No newline at end of file diff --git a/public/javascripts/jquery-ui-1.8.15.custom.min.js b/public/javascripts/jquery-ui-1.8.15.custom.min.js new file mode 100644 index 00000000..83de870c --- /dev/null +++ b/public/javascripts/jquery-ui-1.8.15.custom.min.js @@ -0,0 +1,790 @@ +/*! + * jQuery UI 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.15", +keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= +this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, +"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": +"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, +outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, +"tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& +a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= +false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); +;/* + * jQuery UI Position 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Position + */ +(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY, +left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+= +k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-= +m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left= +d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= +a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), +g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); +;/* + * jQuery UI Draggable 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== +"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= +this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options;this.helper= +this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}); +this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true}, +_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b= +false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration, +10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle|| +!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&& +a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent= +this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"), +10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"), +10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top, +(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!= +"hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"), +10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+ +this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&& +!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.leftg[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.topg[3])?h:!(h-this.offset.click.topg[2])?e:!(e-this.offset.click.left=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e=j&&f<=l||h>=j&&h<=l||fl)&&(e>= +i&&e<=k||g>=i&&g<=k||ek);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), +top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= +this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", +nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== +String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); +var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a= +false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"}); +this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff= +{width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis]; +if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false}, +_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f, +{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight: +Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(cb.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left= +null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+ +a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+ +c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]); +b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.15"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(), +10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top- +f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType? +e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a= +e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing, +step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= +e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset; +var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left: +a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top- +d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition, +f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, +display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b= +e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height= +d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); +;/* + * jQuery UI Selectable 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), +selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, +c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting", +c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d= +this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable"); +this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a=== +"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&& +!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, +left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; +this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= +document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); +return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], +e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); +c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): +this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, +dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, +toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+jg&&b+la[this.floating?"width":"height"]?j:g0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); +if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), +this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b= +this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f= +d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")|| +0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out", +a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- +f)this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- +this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this, +this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop", +a,this._uiHash());for(e=0;e li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"); +a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); +if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion", +function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a= +this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); +this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons(); +b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target); +a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ +c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options; +if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); +if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(), +e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight|| +e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false", +"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.15", +animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/); +f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide", +paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); +;/* + * jQuery UI Autocomplete 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.propAttr("readOnly"))){g= +false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!= +a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)}; +this.menu=d("
      ").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&& +a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); +d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&& +b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source= +this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length").data("item.autocomplete",b).append(d("").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, +"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery); +(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); +this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b, +this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| +this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| +this.first()?":last":":first"))},hasScroll:function(){return this.element.height()").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("");e.secondary&&a.append("");if(!this.options.text){d.push(f?"ui-button-icons-only": +"ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")=== +"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); +b.Widget.prototype.destroy.call(this)}})})(jQuery); +;/* + * jQuery UI Dialog 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */ +(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, +position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
      ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), +h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", +e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); +a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== +b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1; +d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== +f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("
      ").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a, +function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", +handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition, +originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize", +f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "): +[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f); +if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"): +e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a= +this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height- +b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.15",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "), +create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), +height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight); +b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(b.range==="min"||b.range==="max"?" ui-slider-range-"+b.range:""))}for(var j=c.length;j"); +this.handles=c.add(d(e.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle", +g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!a.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");i=a._start(g,l);if(i===false)return}break}m=a.options.step;i=a.options.values&&a.options.values.length? +(h=a.values(l)):(h=a.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(i+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(i-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===a._valueMax())return;h=a._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===a._valueMin())return;h=a._trimAlignValue(i- +m);break}a._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(g,k);a._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); +return this},_mouseCapture:function(a){var b=this.options,c,f,e,j,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(b.range===true&&this.values(1)===b.min){g+=1;e=d(this.handles[g])}if(this._start(a,g)===false)return false; +this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();b=e.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-e.width()/2,top:a.pageY-b.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b= +this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b= +this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b); +c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var f;if(this.options.values&&this.options.values.length){f=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>f||b===1&&c1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a= +this.options.range,b=this.options,c=this,f=!this._animateOff?b.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({width:e- +g+"%"},{queue:false,duration:b.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:b.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[f?"animate":"css"]({width:e+"%"}, +b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.15"})})(jQuery); +;/* + * jQuery UI Tabs 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
      ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
    • #{label}
    • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& +e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= +d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| +(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); +this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= +this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); +if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); +this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ +g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", +function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; +this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= +-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; +d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= +d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, +e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); +j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); +if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, +this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, +load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, +"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, +url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.15"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k'))}function N(a){return a.bind("mouseout", +function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); +b.addClass("ui-state-hover");b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.15"}});var B=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv}, +setDefaults:function(a){H(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g, +"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('
      '))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker", +function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b);b.settings.disabled&&this._disableDatepicker(a)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d(''+c+"");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c== +"focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('').addClass(this._triggerClass).html(f==""?c:d("").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker(): +d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;gh){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a, +b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.settings.disabled&&this._disableDatepicker(a);b.dpDiv.css("display","block")}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+= +1;this._dialogInput=d('');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/ +2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b= +d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e= +a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a, +"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f== +a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input", +a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=d.datepicker._get(b,"beforeShow");H(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos= +d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b, +c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing=true;d.effects&& +d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});a.dpDiv.find("."+ +this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&& +a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth(): +0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a), +"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst= +null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")}, +_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"): +0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e["selected"+(c=="M"? +"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a); +this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a, +"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b== +"")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=A+1-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y", +RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+112?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear; +b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a));if(c=this._get(a,"onSelect")){e=this._formatDate(a);c.apply(a.input?a.input[0]:null,[e,a])}},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()== +""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999, +9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&nn;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a)); +n=this._canAdjustMonth(a,-1,m,g)?''+n+"":f?"":''+n+"";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m, +g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?''+s+"":f?"":''+s+"";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&& +a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'":"";e=e?'
      '+(c?h:"")+(this._isInRange(a,s)?'":"")+(c?"":h)+"
      ":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),A=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='
      '+(/all|left/.test(t)&& +x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,A,v)+'
      ';var z=j?'":"";for(t=0;t<7;t++){var r=(t+h)%7;z+="=5?' class="ui-datepicker-week-end"':"")+'>'+q[r]+""}y+=z+"";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay, +z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q";var R=!j?"":'";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&ro;R+='";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+""}g++;if(g>11){g=0;m++}y+="
      '+this._get(a,"weekHeader")+"
      '+this._get(a,"calculateWeek")(r)+""+(F&&!D?" ":L?''+ +r.getDate()+"":''+r.getDate()+"")+"
      "+(l?""+(i[0]>0&&G==i[1]-1?'
      ':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'': +"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
      ',o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&&l)?" ":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b, +e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
      ";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+ +(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input? +a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c, +e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a, +"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this; +if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a== +"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.15";window["DP_jQuery_"+B]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
      ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.15"})})(jQuery); +;/* + * jQuery UI Effects 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})}; +f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this, +[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.15",save:function(c,a){for(var b=0;b").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}); +c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c, +a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments); +a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%", +"pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d* +((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/= +e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/= +e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.15 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/public/javascripts/jquery.blockUI.js b/public/javascripts/jquery.blockUI.js index fe1144a0..3c111d52 100644 --- a/public/javascripts/jquery.blockUI.js +++ b/public/javascripts/jquery.blockUI.js @@ -1,10 +1,10 @@ -/*! +/*! * jQuery blockUI plugin - * Version 2.36 (16-NOV-2010) + * Version 2.38 (29-MAR-2011) * @requires jQuery v1.2.3 or later * * Examples at: http://malsup.com/jquery/block/ - * Copyright (c) 2007-2008 M. Alsup + * Copyright (c) 2007-2010 M. Alsup * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html @@ -42,7 +42,7 @@ $.growlUI = function(title, message, timeout, onClose) { $.blockUI({ message: $m, fadeIn: 700, fadeOut: 1000, centerY: false, timeout: timeout, showOverlay: false, - onUnblock: onClose, + onUnblock: onClose, css: $.blockUI.defaults.growlCSS }); }; @@ -65,7 +65,7 @@ $.fn.unblock = function(opts) { }); }; -$.blockUI.version = 2.35; // 2nd generation blocking at no extra cost! +$.blockUI.version = 2.38; // 2nd generation blocking at no extra cost! // override these in your code to change the default behavior and style $.blockUI.defaults = { @@ -74,9 +74,9 @@ $.blockUI.defaults = { title: null, // title string; only used when theme == true draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) - + theme: false, // set to true to use with jQuery UI themes - + // styles for the message when blocking; if you wish to disable // these and use an external stylesheet then do this in your code: // $.blockUI.defaults.css = {}; @@ -92,7 +92,7 @@ $.blockUI.defaults = { backgroundColor:'#fff', cursor: 'wait' }, - + // minimal style set used when themes are used themedCSS: { width: '30%', @@ -123,7 +123,7 @@ $.blockUI.defaults = { '-moz-border-radius': '10px', 'border-radius': '10px' }, - + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w // (hat tip to Jorge H. N. de Vasconcelos) iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', @@ -167,7 +167,7 @@ $.blockUI.defaults = { // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) applyPlatformOpacityRules: true, - + // callback method invoked when fadeIn has completed and blocking message is visible onBlock: null, @@ -224,11 +224,14 @@ function install(el, opts) { // layer2 is the overlay layer which has opacity and a wait cursor (by default) // layer3 is the message content that is displayed while blocking - var lyr1 = ($.browser.msie || opts.forceIframe) + var lyr1 = ($.browser.msie || opts.forceIframe) ? $('') : $(''); - var lyr2 = $(''); - + + var lyr2 = opts.theme + ? $('') + : $(''); + var lyr3, s; if (opts.theme && full) { s = '