From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1QOo8E-0002lP-3v for garchives@archives.gentoo.org; Tue, 24 May 2011 09:42:34 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 166DB1C414; Tue, 24 May 2011 09:41:57 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id C0EF11C406 for ; Tue, 24 May 2011 09:41:55 +0000 (UTC) Received: from pelican.gentoo.org (unknown [66.219.59.40]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id DF25D1CC002 for ; Tue, 24 May 2011 09:41:54 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by pelican.gentoo.org (Postfix) with ESMTP id 4F8F08050C for ; Tue, 24 May 2011 09:41:54 +0000 (UTC) From: "Petteri Räty" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Petteri Räty" Message-ID: Subject: [gentoo-commits] proj/council-webapp:master commit in: site/config/environments/, site/app/views/taglibs/, site/db/, ... X-VCS-Repository: proj/council-webapp X-VCS-Files: site/Gemfile site/Gemfile.lock site/Rakefile site/app/controllers/application_controller.rb site/app/controllers/front_controller.rb site/app/controllers/users_controller.rb site/app/mailers/user_mailer.rb site/app/models/guest.rb site/app/models/user.rb site/app/views/front/index.dryml site/app/views/taglibs/application.dryml site/app/views/taglibs/themes/clean-sidemenu/clean-sidemenu.dryml site/app/views/taglibs/themes/clean/clean.dryml site/app/views/user_mailer/forgot_password.erb site/config.ru site/config/application.rb site/config/boot.rb site/config/environment.rb site/config/environments/development.rb site/config/environments/production.rb site/config/environments/test.rb site/config/hobo_routes.rb site/config/initializers/backtrace_silencers.rb site/config/initializers/dryml_taglibs.rb site/config/initializers/inflections.rb site/config/initializers/mime_types.rb site/config/initializers/secret_token.rb site/config/initializers/session_store.rb site/co nfig/locales/app.en.yml site/config/locales/hobo.en.yml site/config/routes.rb site/db/schema.rb site/lib/tasks/.gitkeep site/public/404.html site/public/422.html site/public/500.html site/public/favicon.ico site/public/hobothemes/clean-sidemenu/images/100-ACD3E6-DBE1E5-H.png site/public/hobothemes/clean-sidemenu/images/100-DBE1E5-FCFEF5-H.png site/public/hobothemes/clean-sidemenu/images/300-3B5F87-ACD3E6-H.png site/public/hobothemes/clean-sidemenu/images/spinner.gif site/public/hobothemes/clean-sidemenu/stylesheets/clean-sidemenu.css site/public/hobothemes/clean/images/101-3B5F87-ACD3E6.png site/public/hobothemes/clean/images/30-3E547A-242E42.png site/public/hobothemes/clean/images/30-DBE1E5-FCFEF5.png site/public/hobothemes/clean/images/300-ACD3E6-fff.png site/public/hobothemes/clean/images/50-ACD3E6-fff.png site/public/hobothemes/clean/images/fieldbg.gif site/public/hobothemes/clean/images/pencil.png site/public/hobothemes/clean/images/small_close.png site/public/hobotheme s/clean/images/spinner.gif site/public/hobothemes/clean/stylesheets/clean.css site/public/hobothemes/clean/stylesheets/rapid-ui.css site/public/images/rails.png site/public/javascripts/IE7.js site/public/javascripts/application.js site/public/javascripts/blank.gif site/public/javascripts/controls.js site/public/javascripts/dragdrop.js site/public/javascripts/dryml-support.js site/public/javascripts/effects.js site/public/javascripts/hobo-rapid.js site/public/javascripts/ie7-recalc.js site/public/javascripts/lowpro.js site/public/javascripts/prototype.js site/public/javascripts/rails.js site/public/robots.txt site/public/stylesheets/.gitkeep site/public/stylesheets/application.css site/public/stylesheets/hobo-rapid.css site/public/stylesheets/reset.css site/script/rails X-VCS-Directories: site/config/environments/ site/app/views/taglibs/ site/db/ site/app/views/user_mailer/ site/app/mailers/ site/ site/public/ site/config/ site/app/views/taglibs/themes/clean/ site/app/models/ site/public/images/ site/config/locales/ site/lib/tasks/ site/public/hobothemes/clean/images/ site/public/stylesheets/ site/app/views/taglibs/themes/clean-sidemenu/ site/public/javascripts/ site/app/views/front/ site/public/hobothemes/clean-sidemenu/stylesheets/ site/config/initializers/ site/app/controllers/ site/public/hobothemes/clean/stylesheets/ site/public/hobothemes/clean-sidemenu/images/ site/script/ X-VCS-Committer: betelgeuse X-VCS-Committer-Name: Petteri Räty X-VCS-Revision: d70b433c2d639c3e373dbb8a148b8f494d84a10e Date: Tue, 24 May 2011 09:41:54 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: 6c7ab33d1753c66e76f4a1fef45842fc commit: d70b433c2d639c3e373dbb8a148b8f494d84a10e Author: Joachim Filip Ignacy Bartosik gmail com= > AuthorDate: Mon May 9 11:03:04 2011 +0000 Commit: Petteri R=C3=A4ty gentoo org> CommitDate: Tue May 10 09:18:07 2011 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/council-webap= p.git;a=3Dcommit;h=3Dd70b433c A plain hobo application --- site/Gemfile | 5 + site/Gemfile.lock | 91 + site/Rakefile | 7 + site/app/controllers/application_controller.rb | 3 + site/app/controllers/front_controller.rb | 19 + site/app/controllers/users_controller.rb | 17 + site/app/mailers/user_mailer.rb | 10 + site/app/models/guest.rb | 7 + site/app/models/user.rb | 52 + site/app/views/front/index.dryml | 30 + site/app/views/taglibs/application.dryml | 9 + .../themes/clean-sidemenu/clean-sidemenu.dryml | 30 + site/app/views/taglibs/themes/clean/clean.dryml | 10 + site/app/views/user_mailer/forgot_password.erb | 10 + site/config.ru | 4 + site/config/application.rb | 45 + site/config/boot.rb | 13 + site/config/environment.rb | 5 + site/config/environments/development.rb | 26 + site/config/environments/production.rb | 49 + site/config/environments/test.rb | 35 + site/config/hobo_routes.rb | 29 + site/config/initializers/backtrace_silencers.rb | 7 + site/config/initializers/dryml_taglibs.rb | 1 + site/config/initializers/inflections.rb | 10 + site/config/initializers/mime_types.rb | 5 + site/config/initializers/secret_token.rb | 7 + site/config/initializers/session_store.rb | 8 + site/config/locales/app.en.yml | 25 + site/config/locales/hobo.en.yml | 194 + site/config/routes.rb | 62 + site/db/schema.rb | 31 + site/public/404.html | 26 + site/public/422.html | 26 + site/public/500.html | 26 + .../clean-sidemenu/images/100-ACD3E6-DBE1E5-H.png | Bin 0 -> 3191 byte= s .../clean-sidemenu/images/100-DBE1E5-FCFEF5-H.png | Bin 0 -> 3138 byte= s .../clean-sidemenu/images/300-3B5F87-ACD3E6-H.png | Bin 0 -> 3745 byte= s .../hobothemes/clean-sidemenu/images/spinner.gif | Bin 0 -> 1553 byte= s .../clean-sidemenu/stylesheets/clean-sidemenu.css | 81 + .../hobothemes/clean/images/101-3B5F87-ACD3E6.png | Bin 0 -> 225 bytes .../hobothemes/clean/images/30-3E547A-242E42.png | Bin 0 -> 150 bytes .../hobothemes/clean/images/30-DBE1E5-FCFEF5.png | Bin 0 -> 174 bytes .../hobothemes/clean/images/300-ACD3E6-fff.png | Bin 0 -> 446 bytes .../hobothemes/clean/images/50-ACD3E6-fff.png | Bin 0 -> 318 bytes site/public/hobothemes/clean/images/fieldbg.gif | Bin 0 -> 46 bytes site/public/hobothemes/clean/images/pencil.png | Bin 0 -> 450 bytes .../public/hobothemes/clean/images/small_close.png | Bin 0 -> 3261 byte= s site/public/hobothemes/clean/images/spinner.gif | Bin 0 -> 1553 byte= s site/public/hobothemes/clean/stylesheets/clean.css | 326 ++ .../hobothemes/clean/stylesheets/rapid-ui.css | 102 + site/public/images/rails.png | Bin 0 -> 6646 byte= s site/public/javascripts/IE7.js | 2 + site/public/javascripts/application.js | 2 + site/public/javascripts/blank.gif | Bin 0 -> 48 bytes site/public/javascripts/controls.js | 965 ++++ site/public/javascripts/dragdrop.js | 974 ++++ site/public/javascripts/dryml-support.js | 132 + site/public/javascripts/effects.js | 1123 ++++ site/public/javascripts/hobo-rapid.js | 1030 ++++ site/public/javascripts/ie7-recalc.js | 166 + site/public/javascripts/lowpro.js | 339 ++ site/public/javascripts/prototype.js | 6001 ++++++++++++++= ++++++ site/public/javascripts/rails.js | 175 + site/public/robots.txt | 5 + site/public/stylesheets/hobo-rapid.css | 94 + site/public/stylesheets/reset.css | 95 + site/script/rails | 6 + 68 files changed, 12552 insertions(+), 0 deletions(-) diff --git a/site/Gemfile b/site/Gemfile new file mode 100644 index 0000000..9897314 --- /dev/null +++ b/site/Gemfile @@ -0,0 +1,5 @@ +source 'http://rubygems.org' +gem 'rails', '3.0.3' +gem 'sqlite3-ruby', :require =3D> 'sqlite3' + +gem "hobo", ">=3D 1.3.0.pre28" diff --git a/site/Gemfile.lock b/site/Gemfile.lock new file mode 100644 index 0000000..11cd8dd --- /dev/null +++ b/site/Gemfile.lock @@ -0,0 +1,91 @@ +GEM + remote: http://rubygems.org/ + specs: + abstract (1.0.0) + actionmailer (3.0.3) + actionpack (=3D 3.0.3) + mail (~> 2.2.9) + actionpack (3.0.3) + activemodel (=3D 3.0.3) + activesupport (=3D 3.0.3) + builder (>=3D 2.1.2) + erubis (~> 2.6.6) + i18n (~> 0.4) + rack (~> 1.2.1) + rack-mount (~> 0.6.13) + rack-test (~> 0.5.6) + tzinfo (~> 0.3.23) + activemodel (3.0.3) + activesupport (=3D 3.0.3) + builder (>=3D 2.1.2) + i18n (~> 0.4) + activerecord (3.0.3) + activemodel (=3D 3.0.3) + activesupport (=3D 3.0.3) + arel (~> 2.0.2) + tzinfo (~> 0.3.23) + activeresource (3.0.3) + activemodel (=3D 3.0.3) + activesupport (=3D 3.0.3) + activesupport (3.0.3) + arel (2.0.9) + builder (3.0.0) + dryml (1.3.0.pre28) + actionpack (>=3D 3.0.0) + hobo_support (=3D 1.3.0.pre28) + erubis (2.6.6) + abstract (>=3D 1.0.0) + hobo (1.3.0.pre28) + dryml (=3D 1.3.0.pre28) + hobo_fields (=3D 1.3.0.pre28) + hobo_support (=3D 1.3.0.pre28) + rails (>=3D 3.0.0) + will_paginate (>=3D 3.0.pre) + hobo_fields (1.3.0.pre28) + hobo_support (=3D 1.3.0.pre28) + rails (>=3D 3.0.0) + hobo_support (1.3.0.pre28) + rails (>=3D 3.0.0) + i18n (0.5.0) + mail (2.2.15) + activesupport (>=3D 2.3.6) + i18n (>=3D 0.4.0) + mime-types (~> 1.16) + treetop (~> 1.4.8) + mime-types (1.16) + polyglot (0.3.1) + rack (1.2.2) + rack-mount (0.6.14) + rack (>=3D 1.0.0) + rack-test (0.5.7) + rack (>=3D 1.0) + rails (3.0.3) + actionmailer (=3D 3.0.3) + actionpack (=3D 3.0.3) + activerecord (=3D 3.0.3) + activeresource (=3D 3.0.3) + activesupport (=3D 3.0.3) + bundler (~> 1.0) + railties (=3D 3.0.3) + railties (3.0.3) + actionpack (=3D 3.0.3) + activesupport (=3D 3.0.3) + rake (>=3D 0.8.7) + thor (~> 0.14.4) + rake (0.8.7) + sqlite3 (1.3.3) + sqlite3-ruby (1.3.3) + sqlite3 (>=3D 1.3.3) + thor (0.14.6) + treetop (1.4.9) + polyglot (>=3D 0.3.1) + tzinfo (0.3.25) + will_paginate (3.0.pre2) + +PLATFORMS + ruby + +DEPENDENCIES + hobo (>=3D 1.3.0.pre28) + rails (=3D 3.0.3) + sqlite3-ruby diff --git a/site/Rakefile b/site/Rakefile new file mode 100644 index 0000000..25101e4 --- /dev/null +++ b/site/Rakefile @@ -0,0 +1,7 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be = available to Rake. + +require File.expand_path('../config/application', __FILE__) +require 'rake' + +Council::Application.load_tasks diff --git a/site/app/controllers/application_controller.rb b/site/app/co= ntrollers/application_controller.rb new file mode 100644 index 0000000..e8065d9 --- /dev/null +++ b/site/app/controllers/application_controller.rb @@ -0,0 +1,3 @@ +class ApplicationController < ActionController::Base + protect_from_forgery +end diff --git a/site/app/controllers/front_controller.rb b/site/app/controll= ers/front_controller.rb new file mode 100644 index 0000000..86e3201 --- /dev/null +++ b/site/app/controllers/front_controller.rb @@ -0,0 +1,19 @@ +class FrontController < ApplicationController + + hobo_controller + + def index; end + + def summary + if !current_user.administrator? + redirect_to user_login_path + end + end + + def search + if params[:query] + site_search(params[:query]) + end + end + +end diff --git a/site/app/controllers/users_controller.rb b/site/app/controll= ers/users_controller.rb new file mode 100644 index 0000000..651de7d --- /dev/null +++ b/site/app/controllers/users_controller.rb @@ -0,0 +1,17 @@ +class UsersController < ApplicationController + + hobo_user_controller + + auto_actions :all, :except =3D> [ :index, :new, :create ] + + def create + hobo_create do + if valid? + self.current_user =3D this + flash[:notice] =3D t("hobo.messages.you_are_site_admin", :defaul= t=3D>"You are now the site administrator") + redirect_to home_page + end + end + end + +end diff --git a/site/app/mailers/user_mailer.rb b/site/app/mailers/user_mail= er.rb new file mode 100644 index 0000000..dd96057 --- /dev/null +++ b/site/app/mailers/user_mailer.rb @@ -0,0 +1,10 @@ +class UserMailer < ActionMailer::Base + default :from =3D> "no-reply@#{host}" + + def forgot_password(user, key) + @user, @key =3D user, key + mail( :subject =3D> "#{app_name} -- forgotten password", + :to =3D> user.email_address ) + end + +end diff --git a/site/app/models/guest.rb b/site/app/models/guest.rb new file mode 100644 index 0000000..b7b3230 --- /dev/null +++ b/site/app/models/guest.rb @@ -0,0 +1,7 @@ +class Guest < Hobo::Model::Guest + + def administrator? + false + end + +end diff --git a/site/app/models/user.rb b/site/app/models/user.rb new file mode 100644 index 0000000..fc9bc9f --- /dev/null +++ b/site/app/models/user.rb @@ -0,0 +1,52 @@ +class User < ActiveRecord::Base + + hobo_user_model # Don't put anything above this + + fields do + name :string, :required, :unique + email_address :email_address, :login =3D> true + administrator :boolean, :default =3D> false + timestamps + end + + # --- Signup lifecycle --- # + + lifecycle do + + state :active, :default =3D> true + + create :signup, :available_to =3D> "Guest", + :params =3D> [:name, :email_address, :password, :password_con= firmation], + :become =3D> :active + + transition :request_password_reset, { :active =3D> :active }, :new_k= ey =3D> true do + UserMailer.forgot_password(self, lifecycle.key).deliver + end + + transition :reset_password, { :active =3D> :active }, :available_to = =3D> :key_holder, + :params =3D> [ :password, :password_confirmation ] + + end + + # --- Permissions --- # + + def create_permitted? + false + end + + def update_permitted? + acting_user.administrator? || + (acting_user =3D=3D self && only_changed?(:email_address, :crypted= _password, + :current_password, :password= , :password_confirmation)) + # Note: crypted_password has attr_protected so although it is permit= ted to change, it cannot be changed + # directly from a form submission. + end + + def destroy_permitted? + acting_user.administrator? + end + + def view_permitted?(field) + true + end +end diff --git a/site/app/views/front/index.dryml b/site/app/views/front/inde= x.dryml new file mode 100644 index 0000000..f07d85b --- /dev/null +++ b/site/app/views/front/index.dryml @@ -0,0 +1,30 @@ + + + + + +
+

Welcome to

+
+

Congratulations! Your Hobo Rails App is up and running

+
    +
  • To customise this page: edit app/views/front/index.dryml +
+ + <% if User.count =3D=3D 0 -%> +

There are no user accounts - p= lease provide the details of the site administrator

+
+ + + + <% end -%> + + +
+
+ +
+
+
+ +
diff --git a/site/app/views/taglibs/application.dryml b/site/app/views/ta= glibs/application.dryml new file mode 100644 index 0000000..2f08a8e --- /dev/null +++ b/site/app/views/taglibs/application.dryml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/site/app/views/taglibs/themes/clean-sidemenu/clean-sidemenu.= dryml b/site/app/views/taglibs/themes/clean-sidemenu/clean-sidemenu.dryml new file mode 100644 index 0000000..43204e2 --- /dev/null +++ b/site/app/views/taglibs/themes/clean-sidemenu/clean-sidemenu.dryml @@ -0,0 +1,30 @@ + + + + + + + + + + + + +

+ + + + + + + + +
+ + +
+
+
+ + + diff --git a/site/app/views/taglibs/themes/clean/clean.dryml b/site/app/v= iews/taglibs/themes/clean/clean.dryml new file mode 100644 index 0000000..4022808 --- /dev/null +++ b/site/app/views/taglibs/themes/clean/clean.dryml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/site/app/views/user_mailer/forgot_password.erb b/site/app/vi= ews/user_mailer/forgot_password.erb new file mode 100644 index 0000000..b4fe24f --- /dev/null +++ b/site/app/views/user_mailer/forgot_password.erb @@ -0,0 +1,10 @@ +<%=3D @user %>, + +If you have forgotten your password for <%=3D @app_name %>, you can choo= se +a new one by clicking on this link: + + <%=3D user_reset_password_url :id =3D> @user, :key =3D> @key %> + +Thank you, + +The <%=3D @app_name %> team. diff --git a/site/config.ru b/site/config.ru new file mode 100644 index 0000000..62e85e7 --- /dev/null +++ b/site/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Council::Application diff --git a/site/config/application.rb b/site/config/application.rb new file mode 100644 index 0000000..2b15039 --- /dev/null +++ b/site/config/application.rb @@ -0,0 +1,45 @@ +require File.expand_path('../boot', __FILE__) + +require 'rails/all' + +# If you have a Gemfile, require the gems listed there, including any ge= ms +# you've limited to :test, :development, or :production. +Bundler.require(:default, Rails.env) if defined?(Bundler) + +module Council + class Application < Rails::Application + =20 + config.hobo.dryml_only_templates =3D true + + # Settings in config/environments/* take precedence over those speci= fied here. + # Application configuration should go into files in config/initializ= ers + # -- all .rb files in that directory are automatically loaded. + + # Custom directories with classes and modules you want to be autoloa= dable. + # config.autoload_paths +=3D %W(#{config.root}/extras) + + # Only load the plugins named here, in the order given (default is a= lphabetical). + # :all can be used as a placeholder for all plugins not explicitly n= amed. + # config.plugins =3D [ :exception_notification, :ssl_requirement, :a= ll ] + + # Activate observers that should always be running. + # config.active_record.observers =3D :cacher, :garbage_collector, :f= orum_observer + + # Set Time.zone default to the specified zone and make Active Record= auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names= . Default is UTC. + # config.time_zone =3D 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales= /*.rb,yml are auto loaded. + # config.i18n.load_path +=3D Dir[Rails.root.join('my', 'locales', '*= .{rb,yml}').to_s] + # config.i18n.default_locale =3D :de + + # JavaScript files you want as :defaults (application.js is always i= ncluded). + # config.action_view.javascript_expansions[:defaults] =3D %w(jquery = rails) + + # Configure the default encoding used in templates for Ruby 1.9. + config.encoding =3D "utf-8" + + # Configure sensitive parameters which will be filtered from the log= file. + config.filter_parameters +=3D [:password] + end +end diff --git a/site/config/boot.rb b/site/config/boot.rb new file mode 100644 index 0000000..ab6cb37 --- /dev/null +++ b/site/config/boot.rb @@ -0,0 +1,13 @@ +require 'rubygems' + +# Set up gems listed in the Gemfile. +gemfile =3D File.expand_path('../../Gemfile', __FILE__) +begin + ENV['BUNDLE_GEMFILE'] =3D gemfile + require 'bundler' + Bundler.setup +rescue Bundler::GemNotFound =3D> e + STDERR.puts e.message + STDERR.puts "Try running `bundle install`." + exit! +end if File.exist?(gemfile) diff --git a/site/config/environment.rb b/site/config/environment.rb new file mode 100644 index 0000000..4bc0d55 --- /dev/null +++ b/site/config/environment.rb @@ -0,0 +1,5 @@ +# Load the rails application +require File.expand_path('../application', __FILE__) + +# Initialize the rails application +Council::Application.initialize! diff --git a/site/config/environments/development.rb b/site/config/enviro= nments/development.rb new file mode 100644 index 0000000..691e1b5 --- /dev/null +++ b/site/config/environments/development.rb @@ -0,0 +1,26 @@ +Council::Application.configure do + # Settings specified here will take precedence over those in config/ap= plication.rb + + # In the development environment your application's code is reloaded o= n + # every request. This slows down response time but is perfect for dev= elopment + # since you don't have to restart the webserver when you make code cha= nges. + config.cache_classes =3D false + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils =3D true + + # Show full error reports and disable caching + config.consider_all_requests_local =3D true + config.action_view.debug_rjs =3D true + config.action_controller.perform_caching =3D false + + # Don't care if the mailer can't send + config.action_mailer.raise_delivery_errors =3D false + + # Print deprecation notices to the Rails logger + config.active_support.deprecation =3D :log + + # Only use best-standards-support built into browsers + config.action_dispatch.best_standards_support =3D :builtin +end + diff --git a/site/config/environments/production.rb b/site/config/environ= ments/production.rb new file mode 100644 index 0000000..68f5e85 --- /dev/null +++ b/site/config/environments/production.rb @@ -0,0 +1,49 @@ +Council::Application.configure do + # Settings specified here will take precedence over those in config/ap= plication.rb + + # The production environment is meant for finished, "live" apps. + # Code is not reloaded between requests + config.cache_classes =3D true + + # Full error reports are disabled and caching is turned on + config.consider_all_requests_local =3D false + config.action_controller.perform_caching =3D true + + # Specifies the header that your server uses for sending files + config.action_dispatch.x_sendfile_header =3D "X-Sendfile" + + # For nginx: + # config.action_dispatch.x_sendfile_header =3D 'X-Accel-Redirect' + + # If you have no front-end server that supports something like X-Sendf= ile, + # just comment this out and Rails will serve the files + + # See everything in the log (default is :info) + # config.log_level =3D :debug + + # Use a different logger for distributed setups + # config.logger =3D SyslogLogger.new + + # Use a different cache store in production + # config.cache_store =3D :mem_cache_store + + # Disable Rails's static asset server + # In production, Apache or nginx will already do this + config.serve_static_assets =3D false + + # Enable serving of images, stylesheets, and javascripts from an asset= server + # config.action_controller.asset_host =3D "http://assets.example.com" + + # Disable delivery errors, bad email addresses will be ignored + # config.action_mailer.raise_delivery_errors =3D false + + # Enable threaded mode + # config.threadsafe! + + # Enable locale fallbacks for I18n (makes lookups for any locale fall = back to + # the I18n.default_locale when a translation can not be found) + config.i18n.fallbacks =3D true + + # Send deprecation notices to registered listeners + config.active_support.deprecation =3D :notify +end diff --git a/site/config/environments/test.rb b/site/config/environments/= test.rb new file mode 100644 index 0000000..c2fc237 --- /dev/null +++ b/site/config/environments/test.rb @@ -0,0 +1,35 @@ +Council::Application.configure do + # Settings specified here will take precedence over those in config/ap= plication.rb + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember tha= t + # your test database is "scratch space" for the test suite and is wipe= d + # and recreated between test runs. Don't rely on the data there! + config.cache_classes =3D true + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils =3D true + + # Show full error reports and disable caching + config.consider_all_requests_local =3D true + config.action_controller.perform_caching =3D false + + # Raise exceptions instead of rendering exception templates + config.action_dispatch.show_exceptions =3D false + + # Disable request forgery protection in test environment + config.action_controller.allow_forgery_protection =3D false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method =3D :test + + # Use SQL instead of Active Record's schema dumper when creating the t= est database. + # This is necessary if your schema can't be completely dumped by the s= chema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format =3D :sql + + # Print deprecation notices to the stderr + config.active_support.deprecation =3D :stderr +end diff --git a/site/config/hobo_routes.rb b/site/config/hobo_routes.rb new file mode 100644 index 0000000..dde7225 --- /dev/null +++ b/site/config/hobo_routes.rb @@ -0,0 +1,29 @@ +# This is an auto-generated file: don't edit! +# You can add your own routes in the config/routes.rb file +# which will override the routes in this file. + +Council::Application.routes.draw do + + + # Lifecycle routes for controller "users" + post 'users/signup(.:format)' =3D> 'users#do_signup', :as =3D> 'do_use= r_signup' + get 'users/signup(.:format)' =3D> 'users#signup', :as =3D> 'user_signu= p' + put 'users/:id/reset_password(.:format)' =3D> 'users#do_reset_password= ', :as =3D> 'do_user_reset_password' + get 'users/:id/reset_password(.:format)' =3D> 'users#reset_password', = :as =3D> 'user_reset_password' + + # Resource routes for controller "users" + get 'users/:id/edit(.:format)' =3D> 'users#edit', :as =3D> 'edit_user' + get 'users/:id(.:format)' =3D> 'users#show', :as =3D> 'user', :constra= ints =3D> { :id =3D> %r([^/.?]+) } + post 'users(.:format)' =3D> 'users#create', :as =3D> 'create_user' + put 'users/:id(.:format)' =3D> 'users#update', :as =3D> 'update_user',= :constraints =3D> { :id =3D> %r([^/.?]+) } + delete 'users/:id(.:format)' =3D> 'users#destroy', :as =3D> 'destroy_u= ser', :constraints =3D> { :id =3D> %r([^/.?]+) } + + # Show action routes for controller "users" + get 'users/:id/account(.:format)' =3D> 'users#account', :as =3D> 'user= _account' + + # User routes for controller "users" + match 'login(.:format)' =3D> 'users#login', :as =3D> 'user_login' + get 'logout(.:format)' =3D> 'users#logout', :as =3D> 'user_logout' + match 'forgot_password(.:format)' =3D> 'users#forgot_password', :as =3D= > 'user_forgot_password' + +end diff --git a/site/config/initializers/backtrace_silencers.rb b/site/confi= g/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/site/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but do= n't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =3D~ /my_noisy_libr= ary/ } + +# You can also remove all the silencers if you're trying to debug a prob= lem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/site/config/initializers/dryml_taglibs.rb b/site/config/init= ializers/dryml_taglibs.rb new file mode 100644 index 0000000..89b2d39 --- /dev/null +++ b/site/config/initializers/dryml_taglibs.rb @@ -0,0 +1 @@ +Dryml.precompile_taglibs if File.basename($0) !=3D "rake" && Rails.env.p= roduction? diff --git a/site/config/initializers/inflections.rb b/site/config/initia= lizers/inflections.rb new file mode 100644 index 0000000..9e8b013 --- /dev/null +++ b/site/config/initializers/inflections.rb @@ -0,0 +1,10 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format +# (all these examples are active by default): +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end diff --git a/site/config/initializers/mime_types.rb b/site/config/initial= izers/mime_types.rb new file mode 100644 index 0000000..72aca7e --- /dev/null +++ b/site/config/initializers/mime_types.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf +# Mime::Type.register_alias "text/html", :iphone diff --git a/site/config/initializers/secret_token.rb b/site/config/initi= alizers/secret_token.rb new file mode 100644 index 0000000..79ea814 --- /dev/null +++ b/site/config/initializers/secret_token.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key for verifying the integrity of signed cookies. +# 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. +Council::Application.config.secret_token =3D 'c1d15e022f0587a728fa354816= d19fcfe7781092dbde9e19e7da9cee986f09e3a4f067d1692fa05bb7ca1e1cf90fc2e8f9a= 2c4a74c8f3efcac6f3170978dfd20' diff --git a/site/config/initializers/session_store.rb b/site/config/init= ializers/session_store.rb new file mode 100644 index 0000000..3485dec --- /dev/null +++ b/site/config/initializers/session_store.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +Council::Application.config.session_store :cookie_store, :key =3D> '_Cou= ncil_session' + +# Use the database for sessions instead of the cookie-based default, +# which shouldn't be used to store highly confidential information +# (create the session table with "rails generate session_migration") +# Council::Application.config.session_store :active_record_store diff --git a/site/config/locales/app.en.yml b/site/config/locales/app.en.= yml new file mode 100644 index 0000000..26256ec --- /dev/null +++ b/site/config/locales/app.en.yml @@ -0,0 +1,25 @@ +# Even if you only support one language, you can use this file to custom= ise the names that appear in the UI +# e.g. + +en: + hello: "Hello world" + +# attributes: +# created_at: Created at +# updated_at: Updated at +# +# activerecord: +# models: +# user: +# one: User +# other: Users +# attributes: +# user: +# name: Name +# password: Password +# current_password: Current Password +# password_confirmation: Password Confirmation +# email_address: Email Address +# attribute_help: +# user: +# email_address: We will never share your address with third part= ies diff --git a/site/config/locales/hobo.en.yml b/site/config/locales/hobo.e= n.yml new file mode 100644 index 0000000..bff123f --- /dev/null +++ b/site/config/locales/hobo.en.yml @@ -0,0 +1,194 @@ +# Hobo internals translation file for English +en: + hobo: + # default hobo pages translations + index: + # if you uncomment the following you will loose the automatic sele= ction of dinamically pluralized nav-tabs + # if you need a different title you should implement a different w= ay to select the tab on your own + #title: "%{model} Index" + heading: "%{model} Index" + + new: + title: "New %{model}" + heading: "New %{model}" + + show: + title: "%{model}" + heading: "%{model} %{name}" + back_link: "Back" + edit_link: "Edit %{model}" + new_link: "New %{model}" + add_form_heading: "Add %{model}" + + edit: + title: "Edit %{model}" + heading: "Edit %{model}" + + index_for_owner: + title: "%{model} for" + # be aware that you will loose the automatic Your / J= om's + # default output for User models + # you better define the heading.* in the specific collection names= pace + #heading: + subheading: "For:" + + new_for_owner: + title: "New %{model} for" + heading: "New %{model}" + subheading: "For:" + + login: + title: "Login" + heading: "Login" + email_address: &email_address "E-mail" + name: "Name" + password: "Password" + remember_me: "Remember me" + login: "Login" + signup: "Signup" + forgot_password: &forgot_password "Forgotten password?" + + signup: + title: "Signup" + heading: "Signup new user" + + forgot_password: + title: *forgot_password + heading: *forgot_password + text: "Enter the e-mail address you used when you signed up for th= is site. + We will then send you an e-mail that you can use to generat= e a new password." + email_address: *email_address + send: "Send" + + forgot_password_sent: + title: "Forgotten password - E-mail sent" + heading: "Forgotten password - E-mail sent" + text: "An e-mail with instructions on how you generate a new passw= ord has been sent to %{email_address}. If you don't receive this e-mail p= lease check your spamfilter." + + account_disabled_page: + title: "Account disabled" + heading: "Account disabled" + text: "Your account is disabled at this time." + + account_page: + title: "Your Account" + heading: "Your Account" + new_password: "New Password" + confirm_new_password: "Confirm New Password" + + # default hobo action translation + # The action with added model variable are new, create, delete, save= , + # edit and back_to_parent + actions: + new: "New %{model}" + create: "Create %{model}" + previous: "Previous" + next: "Next" + add: "Add" + show_all: "Show all %{model}..." + delete: "Delete %{model}" + save: "Save %{model}" + cancel: "Cancel" + edit: "Edit %{model}" + back: "Back to" + back_to_parent: "Back to %{parent} %{name}" + send: "Send" + remove: "Remove" + signup: "Signup" + login: "Login" + logout: "Log out" + logged_in_as: "Logged in as %{name}" + account: "Account" + save_account: "Save Your Data" + + # default hobo message translation + messages: + create: + success: "The %{model} was created successfully" + error: "Couldn't create the %{model}.\n%{errors}" + creator: + error: "Couldn't do creator %{name}.\n%{errors}" + transition: + error: "Couldn't do transition %{name}.\n%{errors}" + update: + no_attribute_error: "No update specified in params" + success: "Changes to the %{model} were saved" + error: "There was a problem with that change.\n%{errors}" + destroy: + success: "The %{model} was deleted" + signup: + success: "Thanks for signing up!" + must_activate: "You must activate your account before you can lo= g in. Please check your email." + login: + success: "You have logged in." + error: "You did not provide a valid %{login} and Password!" + logout: "You have logged out." + reset_password: "Your password has been reset." + permission_denied: "Permission Denied" + not_found: "The page you requested cannot be found." + unauthenticated: "Couldn't authenticate you" + validate_password: "must be at least 6 characters long and must no= t consist solely of lowercase letters" + current_password_is_not_correct: "is not correct" + you_are_site_admin: "You are now the site administrator" + you_signed_up: "You have signed up" + no: "No %{model} available." + confirm: "Are you sure?" + + # default hobo collection translation + collection: + count: &collection_count + zero: &no_model "No %{model}" + one: "There is only one %{model} at the moment" + other: "There are already %{count} %{model}" + # you can use the following to completely override the collection = heading + # be aware that you will loose the automatic Your / J= om's + # default output for User models + # you better define the heading.* in the specific collection names= pace + #heading: + add_form_heading: "Add %{model}" + empty_message: "No records to display" + + # default hobo form translation + form: + new: + heading: "New %{model}" + error: + heading: "The following error occured:" + select_many: + prompt: "Add %{model}" + + # hobo support + support: + or: "or" + a: "a" + an: "an" + + table_plus: + search: "Search" + submit_label: "Go" + + live_search: + label: "Search" + results_label: "Search Results" + close_button: "close" + no_results: "Your search returned no matches." + + dev_user_changer: + guest: "Guest" + + admin: + subsite_name: "Admin" + invite_new_user: "Invite a new user" + + subsite: + back_link: "View Site" + + boolean_yes: "Yes" + boolean_no: "No" + password_hidden: "[password hidden]" + + in_place_editor: + click_to_edit: "(click to edit)" + + select_one_editor: + blank_message: *no_model diff --git a/site/config/routes.rb b/site/config/routes.rb new file mode 100644 index 0000000..e36d680 --- /dev/null +++ b/site/config/routes.rb @@ -0,0 +1,62 @@ +Council::Application.routes.draw do + root :to =3D> 'front#index' + + match 'search' =3D> 'front#search', :as =3D> 'site_search' + + # The priority is based upon order of creation: + # first created -> highest priority. + + # Sample of regular route: + # match 'products/:id' =3D> 'catalog#view' + # Keep in mind you can assign values other than :controller and :actio= n + + # Sample of named route: + # match 'products/:id/purchase' =3D> 'catalog#purchase', :as =3D> :p= urchase + # This route can be invoked with purchase_url(:id =3D> product.id) + + # Sample resource route (maps HTTP verbs to controller actions automat= ically): + # resources :products + + # Sample resource route with options: + # resources :products do + # member do + # get 'short' + # post 'toggle' + # end + # + # collection do + # get 'sold' + # end + # end + + # Sample resource route with sub-resources: + # resources :products do + # resources :comments, :sales + # resource :seller + # end + + # Sample resource route with more complex sub-resources + # resources :products do + # resources :comments + # resources :sales do + # get 'recent', :on =3D> :collection + # end + # end + + # Sample resource route within a namespace: + # namespace :admin do + # # Directs /admin/products/* to Admin::ProductsController + # # (app/controllers/admin/products_controller.rb) + # resources :products + # end + + # You can have the root of your site routed with "root" + # just remember to delete public/index.html. + # root :to =3D> "welcome#index" + + # See how all your routes lay out with "rake routes" + + # This is a legacy wild controller route that's not recommended for RE= STful applications. + # Note: This route will make all actions in every controller accessibl= e via GET requests. + # match ':controller(/:action(/:id(.:format)))' +end diff --git a/site/db/schema.rb b/site/db/schema.rb new file mode 100644 index 0000000..e4c4626 --- /dev/null +++ b/site/db/schema.rb @@ -0,0 +1,31 @@ +# This file is auto-generated from the current state of the database. In= stead +# of editing this file, please use the migrations feature of Active Reco= rd to +# incrementally modify your database, and then regenerate this schema de= finition. +# +# Note that this schema.rb definition is the authoritative source for yo= ur +# database schema. If you need to create the application database on ano= ther +# system, you should be using db:schema:load, not running all the migrat= ions +# from scratch. The latter is a flawed and unsustainable approach (the m= ore migrations +# you'll amass, the slower it'll run and the greater likelihood for issu= es). +# +# It's strongly recommended to check this file into your version control= system. + +ActiveRecord::Schema.define(:version =3D> 20110510091749) do + + create_table "users", :force =3D> true do |t| + t.string "crypted_password", :limit =3D> 40 + t.string "salt", :limit =3D> 40 + t.string "remember_token" + t.datetime "remember_token_expires_at" + t.string "name" + t.string "email_address" + t.boolean "administrator", :default =3D> = false + t.datetime "created_at" + t.datetime "updated_at" + t.string "state", :default =3D> = "active" + t.datetime "key_timestamp" + end + + add_index "users", ["state"], :name =3D> "index_users_on_state" + +end diff --git a/site/lib/tasks/.gitkeep b/site/lib/tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/site/public/404.html b/site/public/404.html new file mode 100644 index 0000000..9a48320 --- /dev/null +++ b/site/public/404.html @@ -0,0 +1,26 @@ + + + + The page you were looking for doesn't exist (404) + + + + + +
+

The page you were looking for doesn't exist.

+

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

+
+ + diff --git a/site/public/422.html b/site/public/422.html new file mode 100644 index 0000000..83660ab --- /dev/null +++ b/site/public/422.html @@ -0,0 +1,26 @@ + + + + The change you wanted was rejected (422) + + + + + +
+

The change you wanted was rejected.

+

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

+ + diff --git a/site/public/500.html b/site/public/500.html new file mode 100644 index 0000000..b80307f --- /dev/null +++ b/site/public/500.html @@ -0,0 +1,26 @@ + + + + We're sorry, but something went wrong (500) + + + + + +
+

We're sorry, but something went wrong.

+

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

+
+ + diff --git a/site/public/favicon.ico b/site/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/site/public/hobothemes/clean-sidemenu/images/100-ACD3E6-DBE1= E5-H.png b/site/public/hobothemes/clean-sidemenu/images/100-ACD3E6-DBE1E5= -H.png new file mode 100644 index 0000000..a952ba5 Binary files /dev/null and b/site/public/hobothemes/clean-sidemenu/images= /100-ACD3E6-DBE1E5-H.png differ diff --git a/site/public/hobothemes/clean-sidemenu/images/100-DBE1E5-FCFE= F5-H.png b/site/public/hobothemes/clean-sidemenu/images/100-DBE1E5-FCFEF5= -H.png new file mode 100644 index 0000000..4d8d779 Binary files /dev/null and b/site/public/hobothemes/clean-sidemenu/images= /100-DBE1E5-FCFEF5-H.png differ diff --git a/site/public/hobothemes/clean-sidemenu/images/300-3B5F87-ACD3= E6-H.png b/site/public/hobothemes/clean-sidemenu/images/300-3B5F87-ACD3E6= -H.png new file mode 100644 index 0000000..a054913 Binary files /dev/null and b/site/public/hobothemes/clean-sidemenu/images= /300-3B5F87-ACD3E6-H.png differ diff --git a/site/public/hobothemes/clean-sidemenu/images/spinner.gif b/s= ite/public/hobothemes/clean-sidemenu/images/spinner.gif new file mode 100644 index 0000000..6da716a Binary files /dev/null and b/site/public/hobothemes/clean-sidemenu/images= /spinner.gif differ diff --git a/site/public/hobothemes/clean-sidemenu/stylesheets/clean-side= menu.css b/site/public/hobothemes/clean-sidemenu/stylesheets/clean-sideme= nu.css new file mode 100644 index 0000000..381ee10 --- /dev/null +++ b/site/public/hobothemes/clean-sidemenu/stylesheets/clean-sidemenu.cs= s @@ -0,0 +1,81 @@ +@import url('/hobothemes/clean/stylesheets/clean.css'); +@import url('/hobothemes/clean/stylesheets/rapid-ui.css'); + +body { + width: 95%; + min-width: 800px; +} + +.page-header div.search { + margin-top: 0; + padding-left:50px; + padding-right:0 +} + +.page-header{ + margin-top: 6px; + background: none; +} + +.account-nav { + margin-top: 0; +} + +.page-header h1 { + padding: 20px 30px 20px 20px; +} + +.page-header h1 a { + color:#3B5F87 +} + +#container{ + width:100%; +} + +#main-nav-container{ + width: 20%; + background: #ACD3E6 url(../images/300-3B5F87-ACD3E6-H.png) repeat-y; + vertical-align:top; +} + +#content-container { + width: 80%; + background-color:#FCFFF5; + vertical-align:top; +} + +.section.with-flash { + background: none; + padding-top: 10px; +} + +.main-nav { + padding: 30px 0; +} + +.main-nav li { + text-align: right; + margin-right: 0; + list-style-type: none; +} + +.main-nav a { + background: none; + border-bottom: 1px dotted #FCFFF5; + display: block; + font-size: 14px; + font-weight: bold; + padding: 7px 20px; + color: #FCFFF5; +} + +.main-nav a:hover { + background: #DBE1E5 url(../images/100-ACD3E6-DBE1E5-H.png) repeat-y; + color:#3B5F87; +} + +.main-nav li.current a { + background: #FCFFF5 url(../images/100-DBE1E5-FCFEF5-H.png) repeat-y; + color: #242E42; +} diff --git a/site/public/hobothemes/clean/images/101-3B5F87-ACD3E6.png b/= site/public/hobothemes/clean/images/101-3B5F87-ACD3E6.png new file mode 100644 index 0000000..3072b06 Binary files /dev/null and b/site/public/hobothemes/clean/images/101-3B5F= 87-ACD3E6.png differ diff --git a/site/public/hobothemes/clean/images/30-3E547A-242E42.png b/s= ite/public/hobothemes/clean/images/30-3E547A-242E42.png new file mode 100644 index 0000000..e48e34f Binary files /dev/null and b/site/public/hobothemes/clean/images/30-3E547= A-242E42.png differ diff --git a/site/public/hobothemes/clean/images/30-DBE1E5-FCFEF5.png b/s= ite/public/hobothemes/clean/images/30-DBE1E5-FCFEF5.png new file mode 100644 index 0000000..6073aa0 Binary files /dev/null and b/site/public/hobothemes/clean/images/30-DBE1E= 5-FCFEF5.png differ diff --git a/site/public/hobothemes/clean/images/300-ACD3E6-fff.png b/sit= e/public/hobothemes/clean/images/300-ACD3E6-fff.png new file mode 100644 index 0000000..9997e23 Binary files /dev/null and b/site/public/hobothemes/clean/images/300-ACD3= E6-fff.png differ diff --git a/site/public/hobothemes/clean/images/50-ACD3E6-fff.png b/site= /public/hobothemes/clean/images/50-ACD3E6-fff.png new file mode 100644 index 0000000..d5c2c84 Binary files /dev/null and b/site/public/hobothemes/clean/images/50-ACD3E= 6-fff.png differ diff --git a/site/public/hobothemes/clean/images/fieldbg.gif b/site/publi= c/hobothemes/clean/images/fieldbg.gif new file mode 100644 index 0000000..026d52a Binary files /dev/null and b/site/public/hobothemes/clean/images/fieldbg.= gif differ diff --git a/site/public/hobothemes/clean/images/pencil.png b/site/public= /hobothemes/clean/images/pencil.png new file mode 100644 index 0000000..0bfecd5 Binary files /dev/null and b/site/public/hobothemes/clean/images/pencil.p= ng differ diff --git a/site/public/hobothemes/clean/images/small_close.png b/site/p= ublic/hobothemes/clean/images/small_close.png new file mode 100644 index 0000000..c32909e Binary files /dev/null and b/site/public/hobothemes/clean/images/small_cl= ose.png differ diff --git a/site/public/hobothemes/clean/images/spinner.gif b/site/publi= c/hobothemes/clean/images/spinner.gif new file mode 100644 index 0000000..6da716a Binary files /dev/null and b/site/public/hobothemes/clean/images/spinner.= gif differ diff --git a/site/public/hobothemes/clean/stylesheets/clean.css b/site/pu= blic/hobothemes/clean/stylesheets/clean.css new file mode 100644 index 0000000..df77106 --- /dev/null +++ b/site/public/hobothemes/clean/stylesheets/clean.css @@ -0,0 +1,326 @@ +body {color: #193440; background: url(../images/300-ACD3E6-fff.png) repe= at-x #fff; } +.page-header {color: white; background: url(../images/101-3B5F87-ACD3E6.= png) repeat-x #3F606E;} +.page-header .navigation.main-nav a { + background: url(../images/30-3E547A-242E42.png) repeat-x #242E42; +} +.page-header .navigation.main-nav li.current a { + color: #222; + background: url(../images/30-DBE1E5-FCFEF5.png) repeat-x #FCFEF5; + border-top: 1px solid white; + border-left: 1px solid white; + border-right: 1px solid white; +} +.page-header .navigation.main-nav a:hover {background: #193440;} +.section.content {background: #FCFFF5;} +.button {color: white; background: #5B8BA0;} +.button:hover {background-color: #193440;} +.add-to-collection {background: #E6E7DE;} +.aside { background: #E5E5E5;} + +/* Column Layout */ + +.section-group {display: table; width: 100%;} +.section-group-inner {display: table-row;} +.section-group-inner > * {display: table-cell; vertical-align: top;} +.aside {width: 210px;} /* works with % too */ +.aside { padding: 20px;} +/* ------ */ + + +body { + width: 960px; + margin: 0 auto 20px; + font: 12px "Lucida Grande", "Trebuchet MS", Arial, sans-serif; line-hei= ght: 18px; +} +h1, h2, h3 {font-weight: normal;} +h1 {margin: 20px 0 10px; font-size: 22px; line-height: 22px;} +h2 {margin: 15px 0 10px; font-size: 18px; line-height: 18px;} +h3 {margin: 10px 0 5px; font-size: 16px; line-height: 16px;} +h4 {margin: 10px 0 5px; font-size: 14px; line-height: 14px;} +h5 {margin: 10px 0 5px; font-size: 12px; line-height: 12px;} +h6 {margin: 10px 0 5px; font-size: 10px; line-height: 10px;} + +li {margin-left: 20px;} + +a { + border-bottom: 1px dotted #ccc; + color: #222; background: #fafafa; + text-decoration: none; +} +a:hover { + border-bottom: 1px dotted #aaa; + color: black; background: #f2f2f2; +} +h1 a, h2 a, h3 a {border: none; background: none;} + +pre, code { + font-family: "Courier New", Courier, monospace; +} + +input.text, input.string, input.email-address, input.password, input.sea= rch, input.integer, input.float, input.autocompleter, input.decimal, text= area { + border-top:1px solid #7c7c7c; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-bottom:1px solid #ddd; + background: #fff url(../images/fieldbg.gif) repeat-x top; + font-size: 1.1em; line-height: 1.3em; +} + +input.file_upload { + border: 1px dotted #666; +} + +.button { + padding: 6px 10px; + border: none; + width: auto; + font-size: 11px; font-weight: bold; + margin-top: 10px; +} +.button:hover {cursor: pointer;} +form .actions {_zoom: 1; overflow: hidden; font-size: 11px;} +form .actions input { margin: 0; } + +.flash { + margin: 0 40px 10px; padding: 10px 30px; border-width: 2px 0; + color: white; +} +.flash.notice {background: #4E6A8F;} +.flash.error {background: #BC1C3D;} +.section.with-flash { padding-top: 20px; } + +/* rails error message */ +.error-messages { + background: #BC1C3D; + border: 1px solid #900024; + padding: 15px 30px; + color: white; + margin-bottom: 20px; +} +.error-messages h2 { + color: white; margin-top: 0; padding-bottom: 0; font-size: 16px; +} +.error-messages li {margin-left: 20px; list-style: square;} + +.field-with-errors input, .field-with-errors textarea, .field-with-error= s select {border: 2px solid #BC1C3D;} + +#ajax-progress { + padding: 8px 20px 8px 40px; + border: 1px solid #444; + background: black url(../images/spinner.gif) no-repeat 10px 8px; + color: white; +} + +.field-list th {width: 120px; white-space: nowrap;} +.field-list td {width: auto;} +.field-list .input-help { color: #888;} + +.content-header, .content-body, .content-footer {margin: 0 45px 15px; pa= dding: 0;} +.content-header {padding: 5px 0;} +.content-body {padding: 15px 0;} +.content-footer {padding-bottom: 20px;} + +.page-header {margin-top: 25px; padding: 0 0 0;} +.page-header h1 { + margin: 0; padding: 20px 30px 30px; + font-family: "Arial Black", Tahoma, Arial, sans-serif; font-size: 36px;= letter-spacing: -1.5pt; +} +.page-header ul {zoom: 1; overflow: hidden;} +.page-header li {float: left; margin-left: 0; list-style: none;} + +.page-header .navigation a, +.page-header .navigation a:hover, +.page-header h1 a, +.page-header h1 a:hover + {border: none; color: white; background: none;} + +.page-header div.search { + float: right; + padding: 0 30px 8px 15px; + } +.page-header div.search label { + padding-right: 10px; + font: bold 9px Arial, sans-serif; text-transform: uppercase; letter-spa= cing: 1.0pt; +} +.page-header div.search input { + font-size: 10px; +} +#search-results-panel { + position: absolute; top: 35px; right: 25px; z-index: 50; + width: 350px; height: 500px; overflow: auto; + padding: 0 20px 20px; border: 1px solid #ddd; + color: black; background: #f2f2f2; +} +#search-results-panel .card.linkable a {color: black;} +#search-spinner {background:black;border:1px solid #666666;opacity:0.6;p= adding:2px;position:absolute;right:4px;top:6px;} + +.main-nav {padding: 0 30px;} +.main-nav li {margin-right: 10px;} +.page-header .main-nav a { + display: block; + padding: 5px 15px 7px; + font-size: 13px; font-weight: bold; +} + +.account-nav { + float:right; + margin: -22px 5px 0 0; + font-size: 11px; +} +.account-nav li { + float: left; + margin-left: 0; padding-left: 20px; + color: #ddd; + list-style: none; +} +.account-nav a {font-weight: bold;} +.account-nav a:hover {border-bottom: 1px dotted #ddd;} + +.user-account-page .change-password {width: 350px;} +.user-account-page .change-password th {width: 150px;} + +.page-footer {text-align: right; color: #ccc; padding: 5px; font-size: 1= 1px;} + +/* pagination nav, needs a more specific class on the wrapper */ +.content-body .nav {margin-bottom: 10px; font-size: 11px;} +.content-body .nav a {margin-right: 5px;} + +.login-page, .forgot-password-page {width: 470px; margin-top: 40px;} +.login-page .content-header {padding-bottom: 0;} +.login-page .field-list {width: 370px;} +.login-page form .actions {text-align: left; margin: 0; padding: 10px 0 = 10px 160px;} +.signup-page .field-list {width: 370px;} +.signup-page .content-body, .signup-page .content-header { margin-left: = 120px; margin-right: 120px;} +.login-page .field-list td, .signup-page .field-list td {width: auto;} +.login-page .field-list th, .signup-page .field-list th {width: 150px !i= mportant; width: 150px;} +.login-page .content-header { position: relative; } +.login-page .forgot-password {font-size: 11px; margin-left: 160px;} + +.edit-page .content-header {overflow: hidden; _zoom: 1;} +.edit-page .content-header h1 {float: left;} +.edit-page .content-header .delete-button {float: right; margin-top: 25p= x;} +form .actions {margin: 30px 0; width: 100%; text-align: center;} + +.show-page .content-header {position: relative; border-bottom: 1px dotte= d #888;} +.show-page .content-header h1, .new-in-collection-page .content-header h= 1 {margin-bottom: 2px; margin-right: 70px;} +.show-page .content-header a.edit-link {position: absolute; top: 30px; r= ight: 0;} +.aside-content .collection {padding-bottom: 10px;} + +.content-header .creation-details {font-size: 11px; line-height: 11px;} +.content-header .creator {margin-right: 15px;} +.content-header .created-at {color: #444;} + +.new-in-collection-page .content-header h2 {margin-top: 6px; font-size: = 14px;} +.new-in-collection-page .content-header h2, .new-in-collection-page .con= tent-header h2 a {color: #222;} + +.add-to-collection {padding: 20px 30px; margin-top: 20px;} +.collection-section .add-to-collection h3 {margin: 0 0 20px; padding: 0;= border-bottom: none;} +.add-to-collection form .submit-button {margin: 20px 130px;} +.add-to-collection .actions {text-align: left; margin-top: 0; margin-bot= tom: 0;} + +/* styling of generic elements */ +.creator {font-weight: bold;} +.card { + overflow: hidden; _zoom: 1; + margin: 10px 0; padding: 12px; border: 1px solid #e8e8e8; + background: #f5f5f5; + position: relative; +} +.card h4 {margin-top: 0;} +.card a {background: #f5f5f5;} +.card .creation-details { + display: block; color: #333; font-size: 11px; +} +.card .datetime {color: #666;} +.card .actions { position:absolute; right: 10px; top: 10px; } +div.ordering-handle { float: left; background: #ccc; color: white; margi= n-right: 5px; cursor: move; padding: 0 2px;} + +.card.content.with-owner { + padding: 0; margin: 10px 0 30px; border: none; + background: none; + font-size: 11px; +} +.card.content .creation-details { + float: left; width: 28%; + line-height: 14px; +} +.card.content .creation-details .created-at {display: block;} +.card.content.with-owner .content { + float: right; width: 72%; +} +ul.collection > li { margin-left: 0; list-style: none;} +.empty-collection-message {margin-top: 20px;} + +.new-link {margin-top: 20px;} + +.collection-section h3 { + padding: 15px 0; margin-bottom: 20px; border-bottom: 1px dotted #888; +} + +.table-plus .header {_zoom: 1; overflow: hidden;} +.table-plus .header a {float: left; margin-right: 20px;} +.table-plus div.search {float: right;} +.table-plus div.search span {color: #444;} +.table-plus div.search input.search {margin: 0 5px;} +.table-plus div.search .button {padding: 2px 4px;} + +.table-plus table {width: 100%; margin: 20px 0;} +.table-plus table th { + padding: 2px 10px; + color: white; background: #444; + font-weight: bold; font-size: 10px; +} +.table-plus table th a {color: white;} +.table-plus table td { + padding: 6px 10px; border-bottom: 1px solid #e2e2e2; color: #666; +} +.table-plus table td input.button, .collection .button {padding: 1px 3px= ; margin-left: 10px; margin-top: 0;} +.table-plus table td.controls {width: 100px;} +.table-plus .even {background: #f8f8f8;} +.table-plus a {background: none;} + +/* */ + +div.select-many {border-top: 1px dotted #999;} +div.select-many .items {margin-bottom: 10px;} +div.select-many .item { + overflow:hidden; _zoom: 1; font-weight: bold; + border-bottom: 1px dotted #999; padding: 5px 10px; /*margin: 5px 25px 5= px 0;*/ +} +div.select-many .item span { float: left; } +div.select-many .item .remove-item { float: right; } + +/* */ + +#search-results-panel { postition: relative; } +#search-results-panel .close-button { cursor: pointer; text-decoration: = underline; position: absolute; top: 3px; right: 6px;} + +/*******************************************************/ +/* these styles are for the generated front index page */ +/* you can delete them if you over-ride it */ + +.front-page .welcome-message { + padding: 10px 20px 20px; border: 1px solid #e8e8e8; + color: #222; + background: url(../images/50-ACD3E6-fff.png) repeat-x #fff; +} +.front-page .welcome-message h2 { + font-size: 18px; line-height: 27px; +} +.front-page ul.models li {margin-left: 0; list-style: none;} + +ul.input-many {list-style-type: none;} +ul.input-all {list-style-type: none;} + +ul.input-many > li { overflow:hidden; zoom:1;} +ul.input-many .input-many-item {float:left;} +ul.input-many div.buttons {float:left; margin-left:10px;} +li.input-many-template { display:none; } + +ul.check-many { list-style-type: none; margin-left: 0px;} +ul.check-many li input { vertical-align: -20%;} + +/* rapid-summary */ +table.app-summary { border: 1px solid; border-collapse: collapse; } +table.app-summary td { padding: 2px; border: 1px dotted #bbb; } +table.app-summary th { padding: 2px; border-bottom: 1px solid; backgroun= d: #acd3e6; } diff --git a/site/public/hobothemes/clean/stylesheets/rapid-ui.css b/site= /public/hobothemes/clean/stylesheets/rapid-ui.css new file mode 100644 index 0000000..f523d7f --- /dev/null +++ b/site/public/hobothemes/clean/stylesheets/rapid-ui.css @@ -0,0 +1,102 @@ +.hidden {display: none;} + +.in-place-textfield-bhv, .in-place-textarea-bhv, .in-place-html-textarea= -bhv { + border: 1px dotted #666; + padding: 0 3px; padding-right: 20px; + background-image: url(../images/pencil.png); + background-position: top right; + background-repeat: no-repeat; +} + +.inplaceeditor-form input, .inplaceeditor-form textarea, +table.new-record textarea, table.new-record input { + border: 1px dotted #666; + padding: 3px; width: 100%; +} +.inplaceeditor-form, .inplaceeditor-form input { + display: inline; +} + +/**** Admin ****/ + +.admin-banner { + background: #9d0018; border-top: 2px solid #7a0013; border-bottom: 2px = solid #7a0013; + padding: 2px 0; + margin: 10px 0; +} +.admin-banner p, .admin-banner span { + font: 12px "Lucida Grande", Arial, sans-serif; +} +.admin-banner p, .admin-banner div {margin-bottom: 0;} +.admin-banner a {color: white; text-decoration: none; padding: 1px 5px; = font-weight: bold;} +.admin-banner a:hover {color: #9d0018; background: white;} +.admin-banner .logged-in { + float: right; +} + +/********* everything below here came from hobo_rapid.css, needs looking= at ********/ + +/**** Default styling for Rapid ***/ + +#ajax-progress { + float: right; margin: 20px; + position: fixed; display: none; z-index: 10; +} + +/* Scriptaculous Autocompleter ---*/ + +div.completions-popup { + position:absolute; + width:250px; + background-color:white; + border:1px solid #888; + margin:0px; + padding:0px; +} +div.completions-popup ul { + list-style-type:none; + margin:0px; + padding:0px; +} +div.completions-popup ul li.selected { background-color: #ffb;} +div.completions-popup ul li { + list-style-type:none; + display:block; + margin:0; + padding:2px; + cursor:pointer; +} + + +.field-list {width:100%;} +.field-list td {vertical-align: middle;} +.field-list th {font-weight: bold;} +.field-list th, .field-list td {padding: 5px 0;} +.field-list th {padding-right: 10px;} + +.field-list td.field-label { + text-align: left; width: 1px; white-space: nowrap; vertical-align: t= op; + padding-top: 10px; padding-bottom: 10px; +} +.field-list textarea, .field-list input[type=3Dtext], .field-list input[= type=3Dpassword] { width: 99%; margin: 0; } + +/*input[type=3Dtext].wide { width: 100%; }*/ +textarea { height: 170px; } +textarea.wide { width: 100%; } +textarea.tall { height: 350px; } + +.field-list input.percentage {width: 25px; display: inline; margin-right= : 5px; padding: 1px 3px;} + +select.dev-user-changer { opacity: 0.3; } +select.dev-user-changer:hover { opacity: 1; } + +.part-wrapper { + display: inline; /* don't mess up layout when wrapping something */ +} + +optgroup.disabled-option { + color: #ccc; + height: 1em; +} + +input.nil-value { color:grey; } diff --git a/site/public/images/rails.png b/site/public/images/rails.png new file mode 100644 index 0000000..d5edc04 Binary files /dev/null and b/site/public/images/rails.png differ diff --git a/site/public/javascripts/IE7.js b/site/public/javascripts/IE7= .js new file mode 100644 index 0000000..5852494 --- /dev/null +++ b/site/public/javascripts/IE7.js @@ -0,0 +1,2 @@ +/* IE7/IE8.js - copyright 2004-2008, Dean Edwards */ +(function(){IE7=3D{toString:function(){return"IE7 version 2.0 (beta4)"}}= ;var k=3DIE7.appVersion=3Dnavigator.appVersion.match(/MSIE (\d\.\d)/)[1];= if(/ie7_off/.test(top.location.search)||k<5)return;var Q=3DbG();var C=3Dd= ocument.compatMode!=3D"CSS1Compat";var bm=3Ddocument.documentElement,v,s;= var bA=3D"!";var G=3D":link{ie7-link:link}:visited{ie7-link:visited}";var= cj=3D/^[\w\.]+[^:]*$/;function W(a,b){if(cj.test(a))a=3D(b||"")+a;return= a};function bn(a,b){a=3DW(a,b);return a.slice(0,a.lastIndexOf("/")+1)};v= ar bB=3Ddocument.scripts[document.scripts.length-1];var ck=3Dbn(bB.src);t= ry{var H=3Dnew ActiveXObject("Microsoft.XMLHTTP")}catch(e){}var X=3D{};fu= nction cl(a,b){try{a=3DW(a,b);if(!X[a]){H.open("GET",a,false);H.send();if= (H.status=3D=3D0||H.status=3D=3D200){X[a]=3DH.responseText}}}catch(e){}fi= nally{return X[a]||""}};if(k<5.5){undefined=3DQ();bA=3D"HTML:!";var cm=3D= /(g|gi)$/;var cn=3DString.prototype.replace;String.prototype.replace=3Dfu= nction(a,b){if(typeof b=3D=3D"function"){if(a&&a.constructor=3D=3DRegExp)= {var c=3Da;var d=3Dc.global;if(d=3D=3D null)d=3Dcm.test(c);if(d)c=3Dnew RegExp(c.source)}else{c=3Dnew RegExp(bb= (a))}var f,g=3Dthis,h=3D"";while(g&&(f=3Dc.exec(g))){h+=3Dg.slice(0,f.ind= ex)+b.apply(this,f);g=3Dg.slice(f.index+f[0].length);if(!d)break}return h= +g}return cn.apply(this,arguments)};Array.prototype.pop=3Dfunction(){if(t= his.length){var a=3Dthis[this.length-1];this.length--;return a}return und= efined};Array.prototype.push=3Dfunction(){for(var a=3D0;a":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*= \\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":bJ,'= "(\\\\.|[^"\\\\])*"':bJ,"\\s+":" "});function cB(a){return cA.exec(a)};fu= nction bI(c){return c.replace(cw,function(a,b){return bp[b-1]})};function= bJ(c){return"\x01"+bp.push(c.replace(cz,function(a,b){return eval("'\\u"= +"0000".slice(b.length)+b+"'")}).slice(1,-1).replace(cx,"\\'"))};function= cC(a){return cy.test(a)?bp[a.slice(1)-1]:a};var cD=3Dnew D({Width:"Heigh= t",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX= :"onY"});function A(a){return cD.exec(a)};var bK=3D[];function bq(a){cF(a= );w(window,"onresize",a)};function w(a,b,c){a.attachEvent(b ,c);bK.push(arguments)};function cE(a,b,c){try{a.detachEvent(b,c)}catch(= ignore){}};w(window,"onunload",function(){var a;while(a=3DbK.pop()){cE(a[= 0],a[1],a[2])}});function R(a,b,c){if(!a.elements)a.elements=3D{};if(c)a.= elements[b.uniqueID]=3Db;else delete a.elements[b.uniqueID];return c};w(w= indow,"onbeforeprint",function(){if(!IE7.CSS.print)new bw("print");IE7.CS= S.print.recalc()});var bL=3D/^\d+(px)?$/i;var J=3D/^\d+%$/;var E=3Dfuncti= on(a,b){if(bL.test(b))return parseInt(b);var c=3Da.style.left;var d=3Da.r= untimeStyle.left;a.runtimeStyle.left=3Da.currentStyle.left;a.style.left=3D= b||0;b=3Da.style.pixelLeft;a.style.left=3Dc;a.runtimeStyle.left=3Dd;retur= n b};var br=3D"ie7-";var bM=3Dz.extend({constructor:function(){this.fixes= =3D[];this.recalcs=3D[]},init:Q});var bs=3D[];function cF(a){bs.push(a)};= IE7.recalc=3Dfunction(){IE7.HTML.recalc();IE7.CSS.recalc();for(var a=3D0;= a1?2:0;var h=3DT.exec(f[g])||"if(0){";if(o){h+=3Di("if(e%1.nodeName!=3D= '!'){",m)}var p=3DS>1?bV:"";h+=3Di(p+bW,m);h+=3DArray(I(h,/\{/g).length+1= ).join("}");d+=3Dh}eval(i(bX,F)+T.unescape(d)+"return s?null:r}");be[a]=3D= _h}return be[a](b||document,c)};var bd=3Dk<6;var bO=3D/^(href|src)$/;var = bu=3D{"class":"className","for":"htmlFor"};IE7._5=3D1;IE7._e=3Dfunction(a= ,b){var c=3Da.all[b]||null;if(!c||c.id=3D=3Db)return c;for(var d=3D0;d+~,]|[^(]\+|^)([#= .:\[])/g,cH=3D/(^|,)([^\s>+~])/g,cI=3D/\s*([\s>+~(),]|^|$)\s*/g,bQ=3D/\s\= *\s/g;var bR=3DD.extend({constructor:function(a){this.base(a);this.sorter= =3Dnew D;this.sorter.add(/:not\([^)]*\)/,D.IGNORE);this.sorter.add(/([ >]= (\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4")},= ignoreCase:true,escape:function(a){return this.optimise(this.format(a))},= format:functi on(a){return a.replace(cI,"$1").replace(cH,"$1 $2").replace(cG,"$1*$2")}= ,optimise:function(a){return this.sorter.exec(a.replace(bQ,">* "))},unesc= ape:function(a){return bI(a)}});var bS=3D{"":"%1!=3Dnull","=3D":"%1=3D=3D= '%2'","~=3D":/(^| )%1( |$)/,"|=3D":/^%1(-|$)/,"^=3D":/^%1/,"$=3D":/%1$/,"= *=3D":/%1/};var bT=3D{"first-child":"!IE7._b(e%1)","link":"e%1.currentSty= le['ie7-link']=3D=3D'link'","visited":"e%1.currentStyle['ie7-link']=3D=3D= 'visited'"};var bv=3D"var p%2=3D0,i%2,e%2,n%2=3De%1.";var bU=3D"e%1.sourc= eIndex";var bV=3D"var g=3D"+bU+";if(!p[g]){p[g]=3D1;";var bW=3D"r[r.lengt= h]=3De%1;if(s)return e%1;";var bX=3D"var _h=3Dfunction(e0,s){IE7._5++;var= r=3D[],p=3D{},reg=3D[%1],d=3Ddocument;";var F;var m;var o;var x;var S;va= r be=3D{};var T=3Dnew bR({" (\\*|[\\w-]+)#([\\w-]+)":function(a,b,c){o=3D= false;var d=3D"var e%2=3DIE7._e(d,'%4');if(e%2&&";if(b!=3D"*")d+=3D"e%2.n= odeName=3D=3D'%3'&&";d+=3D"(e%1=3D=3Dd||e%1.contains(e%2))){";if(x)d+=3Di= ("i%1=3Dn%1.length;",x);return i(d,m++,m,b.toUpperCase(),c)}," (\\*|[\\w-= ]+)":function(a,b){S++;o=3Db=3D=3D"*";var c=3Dbv;c+=3D(o&&bd)?"all ":"getElementsByTagName('%3')";c+=3D";for(i%2=3D0;(e%2=3Dn%2[i%2]);i%2++= ){";return i(c,m++,x=3Dm,b.toUpperCase())},">(\\*|[\\w-]+)":function(a,b)= {var c=3Dx;o=3Db=3D=3D"*";var d=3Dbv;d+=3Dc?"children":"childNodes";if(!o= &&c)d+=3D".tags('%3')";d+=3D";for(i%2=3D0;(e%2=3Dn%2[i%2]);i%2++){";if(o)= {d+=3D"if(e%2.nodeType=3D=3D1){";o=3Dbd}else{if(!c)d+=3D"if(e%2.nodeName=3D= =3D'%3'){"}return i(d,m++,x=3Dm,b.toUpperCase())},"\\+(\\*|[\\w-]+)":func= tion(a,b){var c=3D"";if(o)c+=3D"if(e%1.nodeName!=3D'!'){";o=3Dfalse;c+=3D= "e%1=3DIE7._a(e%1);if(e%1";if(b!=3D"*")c+=3D"&&e%1.nodeName=3D=3D'%2'";c+= =3D"){";return i(c,m,b.toUpperCase())},"~(\\*|[\\w-]+)":function(a,b){var= c=3D"";if(o)c+=3D"if(e%1.nodeName!=3D'!'){";o=3Dfalse;S=3D2;c+=3D"while(= e%1=3De%1.nextSibling){if(e%1.ie7_adjacent=3D=3DIE7._5)break;if(";if(b=3D= =3D"*"){c+=3D"e%1.nodeType=3D=3D1";if(bd)c+=3D"&&e%1.nodeName!=3D'!'"}els= e c+=3D"e%1.nodeName=3D=3D'%2'";c+=3D"){e%1.ie7_adjacent=3DIE7._5;";retur= n i(c,m,b.toUpperCase())},"#([\\w-]+)":function(a,b){o=3Dfalse;var c=3D"i= f(e%1.id=3D=3D'%2'){";if(x)c+=3Di("i%1=3Dn%1.length;",x);return i(c,m,b)}= ,"\\.([\\w-]+ )":function(a,b){o=3Dfalse;F.push(new RegExp("(^|\\s)"+bb(b)+"(\\s|$)"))= ;return i("if(e%1.className&®[%2].test(e%1.className)){",m,F.length-1)= },"\\[([\\w-]+)\\s*([^=3D]?=3D)?\\s*([^\\]]*)\\]":function(a,b,c,d){var f= =3Dbu[b]||b;if(c){var g=3D"e%1.getAttribute('%2',2)";if(!bO.test(b)){g=3D= "e%1.%3||"+g}b=3Di("("+g+")",m,b,f)}else{b=3Di("IE7._f(e%1,'%2')",m,b)}va= r h=3DbS[c||""]||"0";if(h&&h.source){F.push(new RegExp(i(h.source,bb(T.un= escape(d)))));h=3D"reg[%2].test(%1)";d=3DF.length-1}return"if("+i(h,b,d)+= "){"},":+([\\w-]+)(\\(([^)]+)\\))?":function(a,b,c,d){b=3DbT[b];return"if= ("+(b?i(b,m,d||""):"0")+"){"}});var bY=3D/a(#[\w-]+)?(\.[\w-]+)?:(hover|a= ctive)/i;var bZ=3D/\s*\{\s*/,ca=3D/\s*\}\s*/,cb=3D/\s*\,\s*/;var cc=3D/(.= *)(:first-(line|letter))/;var y=3Ddocument.styleSheets;IE7.CSS=3Dnew(bM.e= xtend({parser:new bH,screen:"",print:"",styles:[],rules:[],pseudoClasses:= k<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var a=3D= [];for(var b in this)a.push(b);return a.join("|")}},init:function(){var a= =3D"^\x01$ ";var b=3D"\\[class=3D?[^\\]]*\\]";var c=3D[];if(this.pseudoClasses)c.pu= sh(this.pseudoClasses);var d=3Dthis.dynamicPseudoClasses.toString();if(d)= c.push(d);c=3Dc.join("|");var f=3Dk<7?["[>+~[(]|([:.])\\w+\\1"]:[b];if(c)= f.push(":("+c+")");this.UNKNOWN=3Dnew RegExp(f.join("|")||a,"i");var g=3D= k<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[b];var h=3Dg.concat();if(c)h.p= ush(":("+c+")");n.COMPLEX=3Dnew RegExp(h.join("|")||a,"ig");if(this.pseud= oClasses)g.push(":("+this.pseudoClasses+")");L.COMPLEX=3Dnew RegExp(g.joi= n("|")||a,"i");L.MATCH=3Dnew RegExp(d?"(.*):("+d+")(.*)":a,"i");this.crea= teStyleSheet();this.refresh()},addEventHandler:function(){w.apply(null,ar= guments)},addFix:function(a,b){this.parser.add(a,b)},addRecalc:function(c= ,d,f,g){d=3Dnew RegExp("([{;\\s])"+c+"\\s*:\\s*"+d+"[^;}]*");var h=3Dthis= .recalcs.length;if(g)g=3Dc+":"+g;this.addFix(d,function(a,b){return(g?b+g= :a)+";ie7-"+a.slice(1)+";ie7_recalc"+h+":1"});this.recalcs.push(arguments= );return h},apply:function(){this.getInlineStyles();new bw("screen");th is.trash()},createStyleSheet:function(){this.styleSheet=3Ddocument.creat= eStyleSheet();this.styleSheet.ie7=3Dtrue;this.styleSheet.owningElement.ie= 7=3Dtrue;this.styleSheet.cssText=3DG},getInlineStyles:function(){var a=3D= document.getElementsByTagName("style"),b;for(var c=3Da.length-1;(b=3Da[c]= );c--){if(!b.disabled&&!b.ie7){this.styles.push(b.innerHTML)}}},getText:f= unction(a,b){try{var c=3Da.cssText}catch(e){c=3D""}if(H)c=3Dcl(a.href,b)|= |c;return c},recalc:function(){this.screen.recalc();var a=3D/ie7_recalc\d= +/g;var b=3DG.match(/[{,]/g).length;var c=3Db+(this.screen.cssText.match(= /\{/g)||"").length;var d=3Dthis.styleSheet.rules,f;var g,h,p,t,q,j,u,l;fo= r(q=3Db;q0&&n= .CLASS.test(b)){b=3Db.replace(n.CLASS,"");d--}while(c>0&&n.TAG.test(b)){b= =3Db.replace(n.TAG,"$1*");c--}b+=3D"."+this.className;d=3DMath.min(d,2);c= =3DMath.min(c,2);var f=3D-10*d-c;if(f>0){b=3Db+","+n.MAP[f]+" "+b}return = b},remove:function(a){a.className=3Da.className.replace(this.MATCH,"$1")}= ,toString:functi on(){return i("%1 {%2}",this.selectorText,this.cssText)}},{CHILD:/>/g,CL= ASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",= TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body"= ,10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html = .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}= });var L=3Dn.extend({constructor:function(a,b,c,d,f){this.attach=3Db||"*"= ;this.dynamicPseudoClass=3DIE7.CSS.dynamicPseudoClasses[c];this.target=3D= d;this.base(a,f)},recalc:function(){var a=3DB(this.attach),b;for(var c=3D= 0;b=3Da[c];c++){var d=3Dthis.target?B(this.target,b):[b];if(d.length)this= .dynamicPseudoClass.apply(b,d,this)}}});var cd=3Dz.extend({constructor:fu= nction(a,b){this.name=3Da;this.apply=3Db;this.instances=3D{};IE7.CSS.dyna= micPseudoClasses[a]=3Dthis},register:function(a){var b=3Da[2];a.id=3Db.id= +a[0].uniqueID;if(!this.instances[a.id]){var c=3Da[1],d;for(d=3D0;d*:"+(b=3D=3D"marginTop"?"first= ":"last")+"-child",a,true);if(d&&d.currentStyle.styleFloat=3D=3D"none"&&I= E7.hasLayout(d)){collapseMargin(d,b);margin=3D_9(a,a.currentStyle[b]);chi= ldMargin=3D_ 9(d,d.currentStyle[b]);if(margin<0||childMargin<0){a.runtimeStyle[b]=3Dm= argin+childMargin}else{a.runtimeStyle[b]=3DMath.max(childMargin,margin)}d= .runtimeStyle[b]=3D"0px"}}};function _9(a,b){return b=3D=3D"auto"?0:E(a,b= )};var UNIT=3D/^[.\d][\w%]*$/,AUTO=3D/^(auto|0cm)$/;var applyWidth,applyH= eight;IE7.Layout.borderBox=3Dfunction(a){applyWidth(a);applyHeight(a)};va= r fixWidth=3Dfunction(g){applyWidth=3Dfunction(a){if(!J.test(a.currentSty= le.width))h(a);collapseMargins(a)};function h(a,b){if(!a.runtimeStyle.fix= edWidth){if(!b)b=3Da.currentStyle.width;a.runtimeStyle.fixedWidth=3D(UNIT= .test(b))?Math.max(0,q(a,b)):b;K(a,"width",a.runtimeStyle.fixedWidth)}};f= unction p(a){if(!bc(a)){var b=3Da.offsetParent;while(b&&!IE7.hasLayout(b)= )b=3Db.offsetParent}return(b||s).clientWidth};function t(a,b){if(J.test(b= ))return parseInt(parseFloat(b)/100*p(a));return E(a,b)};var q=3Dfunction= (a,b){var c=3Da.currentStyle["box-sizing"]=3D=3D"border-box";var d=3D0;if= (C&&!c)d+=3Dj(a)+u(a,"padding");else if(!C&&c)d-=3Dj(a)+u(a,"padding");re= turn t(a,b )+d};function j(a){return a.offsetWidth-a.clientWidth};function u(a,b){r= eturn t(a,a.currentStyle[b+"Left"])+t(a,a.currentStyle[b+"Right"])};G+=3D= "*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.min= Width=3Dfunction(a){if(a.currentStyle["min-width"]!=3Dnull){a.style.minWi= dth=3Da.currentStyle["min-width"]}if(R(arguments.callee,a,a.currentStyle.= minWidth!=3D"none")){layout.boxSizing(a);h(a);l(a)}};eval("IE7.Layout.max= Width=3D"+String(layout.minWidth).replace(/min/g,"max"));function l(a){va= r b=3Da.getBoundingClientRect();var c=3Db.right-b.left;if(a.currentStyle.= minWidth!=3D"none"&&c<=3Dq(a,a.currentStyle.minWidth)){a.runtimeStyle.wid= th=3Da.currentStyle.minWidth}else if(a.currentStyle.maxWidth!=3D"none"&&c= >=3Dq(a,a.currentStyle.maxWidth)){a.runtimeStyle.width=3Da.currentStyle.m= axWidth}else{a.runtimeStyle.width=3Da.runtimeStyle.fixedWidth}};function = r(a){if(R(r,a,/^(fixed|absolute)$/.test(a.currentStyle.position)&&bt(a,"l= eft")!=3D"auto"&&bt(a,"right")!=3D"auto"&&AUTO.test(bt(a,"width")))){N(a)= ;I E7.Layout.boxSizing(a)}};IE7.Layout.fixRight=3Dr;function N(a){var b=3Dt= (a,a.runtimeStyle._c||a.currentStyle.left);var c=3Dp(a)-t(a,a.currentStyl= e.right)-b-u(a,"margin");if(parseInt(a.runtimeStyle.width)=3D=3Dc)return;= a.runtimeStyle.width=3D"";if(bc(a)||g||a.offsetWidth=3D5.5&&k<7){IE7.CSS.addFix(/backgrou= nd(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(a,b,c,d,f){= d=3DcC(d);return bi.test(d)?"filter:"+i(bx,d,"crop")+";zoom:1;background"= +(b||"")+":"+(c||"")+"none"+(f||""):a});IE7.HTML.addRecalc("img,input",fu= nction(a){if(a.tagName=3D=3D"INPUT"&&a.type!=3D"image")return;by(a);w(a,"= onpropertychange",function(){if(!bj&&event.propertyName=3D=3D"src"&&a.src= .indexOf(bg)=3D=3D-1)by(a)})});var bj=3Dfalse;w(window,"onbeforeprint",fu= nction(){bj=3Dtrue;for(var a=3D0;a=3D7)retu= rn;IE7.CSS.addRecalc("position","fixed",_6,"absolute");IE7.CSS.addRecalc(= "background(-attachment)?","[^};]*fixed",_2);var $viewport=3DC?"body":"do= cumentElement";function _3(){if(v.currentStyle.backgroundAttachment!=3D"f= ixed"){if(v.currentStyle.backgroundImage=3D=3D"none"){v.runtimeStyle.back= groundRepeat=3D"no-repeat";v.runtimeStyle.backgroundImage=3D"url("+bg+")"= }v.runtimeStyle.backgroundAttachment=3D"fixed"}_3=3DQ};var _0=3DbN("img")= ;function _1(a){return a?bc(a)||_1(a.parentElement):false};function _d(a,= b,c){setTimeout("document.all."+a.uniqueID+".runtimeStyle.setExpression('= "+b+"','"+c+"')",0)};function _2(a){if(R(_2,a,a.currentStyle.backgroundAt= tachment=3D=3D"fixed"&&!a.contains(v))){_3();bgLeft(a);bgTop(a);_8(a)}};f= unction _8(a){_0.src=3Da.currentStyle.backgroundImage.slice(5,-2);var b=3D= a.canHa veChildren?a:a.parentElement;b.appendChild(_0);setOffsetLeft(a);setOffse= tTop(a);b.removeChild(_0)};function bgLeft(a){a.style.backgroundPositionX= =3Da.currentStyle.backgroundPositionX;if(!_1(a)){_d(a,"backgroundPosition= X","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)= ||0")}};eval(A(bgLeft));function setOffsetLeft(a){var b=3D_1(a)?"backgrou= ndPositionX":"offsetLeft";a.runtimeStyle[b]=3DgetOffsetLeft(a,a.style.bac= kgroundPositionX)-a.getBoundingClientRect().left-a.clientLeft+2};eval(A(s= etOffsetLeft));function getOffsetLeft(a,b){switch(b){case"left":case"top"= :return 0;case"right":case"bottom":return s.clientWidth-_0.offsetWidth;ca= se"center":return(s.clientWidth-_0.offsetWidth)/2;default:if(J.test(b)){r= eturn parseInt((s.clientWidth-_0.offsetWidth)*parseFloat(b)/100)}_0.style= .left=3Db;return _0.offsetLeft}};eval(A(getOffsetLeft));function _6(a){if= (R(_6,a,bc(a))){K(a,"position","absolute");K(a,"left",a.currentStyle.left= );K(a,"top",a.currentStyle.top);_3();IE7.Layout.f ixRight(a);_4(a)}};function _4(a,b){positionTop(a,b);positionLeft(a,b,tr= ue);if(!a.runtimeStyle.autoLeft&&a.currentStyle.marginLeft=3D=3D"auto"&&a= .currentStyle.right!=3D"auto"){var c=3Ds.clientWidth-getPixelWidth(a,a.cu= rrentStyle.right)-getPixelWidth(a,a.runtimeStyle._c)-a.clientWidth;if(a.c= urrentStyle.marginRight=3D=3D"auto")c=3DparseInt(c/2);if(_1(a.offsetParen= t))a.runtimeStyle.pixelLeft+=3Dc;else a.runtimeStyle.shiftLeft=3Dc}clipWi= dth(a);clipHeight(a)};function clipWidth(a){var b=3Da.runtimeStyle.fixWid= th;a.runtimeStyle.borderRightWidth=3D"";a.runtimeStyle.width=3Db?getPixel= Width(a,b):"";if(a.currentStyle.width!=3D"auto"){var c=3Da.getBoundingCli= entRect();var d=3Da.offsetWidth-s.clientWidth+c.left-2;if(d>=3D0){a.runti= meStyle.borderRightWidth=3D"0px";d=3DMath.max(E(a,a.currentStyle.width)-d= ,0);K(a,"width",d);return d}}};eval(A(clipWidth));function positionLeft(a= ,b){if(!b&&J.test(a.currentStyle.width)){a.runtimeStyle.fixWidth=3Da.curr= entStyle.width}if(a.runtimeStyle.fixWidth){a.runtimeStyle.width=3DgetPixe= lWidth(a ,a.runtimeStyle.fixWidth)}a.runtimeStyle.shiftLeft=3D0;a.runtimeStyle._c= =3Da.currentStyle.left;a.runtimeStyle.autoLeft=3Da.currentStyle.right!=3D= "auto"&&a.currentStyle.left=3D=3D"auto";a.runtimeStyle.left=3D"";a.runtim= eStyle.screenLeft=3DgetScreenLeft(a);a.runtimeStyle.pixelLeft=3Da.runtime= Style.screenLeft;if(!b&&!_1(a.offsetParent)){_d(a,"pixelLeft","runtimeSty= le.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft")}= };eval(A(positionLeft));function getScreenLeft(a){var b=3Da.offsetLeft,c=3D= 1;if(a.runtimeStyle.autoLeft){b=3Ds.clientWidth-a.offsetWidth-getPixelWid= th(a,a.currentStyle.right)}if(a.currentStyle.marginLeft!=3D"auto"){b-=3Dg= etPixelWidth(a,a.currentStyle.marginLeft)}while(a=3Da.offsetParent){if(a.= currentStyle.position!=3D"static")c=3D-1;b+=3Da.offsetLeft*c}return b};ev= al(A(getScreenLeft));function getPixelWidth(a,b){return J.test(b)?parseIn= t(parseFloat(b)/100*s.clientWidth):E(a,b)};eval(A(getPixelWidth));functio= n _g(){var a=3D_2.elements;for(var b in a)_8(a[b]);a=3D_6.elements;for(b = in a){ _4(a[b],true);_4(a[b],true)}_7=3D0};var _7;bq(function(){if(!_7)_7=3Dset= Timeout(_g,0)})};var bk=3D{backgroundColor:"transparent",backgroundImage:= "none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat= :null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftS= tyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomSty= le:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,margin= Right:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible"= ,function(a){if(a.parentNode.ie7_wrapped)return;if(IE7.Layout&&a.currentS= tyle["max-height"]!=3D"auto"){IE7.Layout.maxHeight(a)}if(a.currentStyle.m= arginLeft=3D=3D"auto")a.style.marginLeft=3D0;if(a.currentStyle.marginRigh= t=3D=3D"auto")a.style.marginRight=3D0;var b=3Ddocument.createElement(bA);= b.ie7_wrapped=3Da;for(var c in bk){b.style[c]=3Da.currentStyle[c];if(bk[c= ]!=3Dnull){a.runtimeStyle[c]=3Dbk[c]}}b.style.display=3D"block";b.style.p= osition=3D"relative";a.runtimeStyle.position=3D"absolute";a.parentNode.in= sert Before(b,a);b.appendChild(a)});function cf(){var f=3D"xx-small,x-small,s= mall,medium,large,x-large,xx-large".split(",");for(var g=3D0;g'); + this.iefix =3D $(this.update.id+'_iefix'); + } + if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); + }, + + fixIEOverlapping: function() { + Position.clone(this.update, this.iefix, {setTop:(!this.update.style.= height)}); + this.iefix.style.zIndex =3D 1; + this.update.style.zIndex =3D 2; + Element.show(this.iefix); + }, + + hide: function() { + this.stopIndicator(); + if(Element.getStyle(this.update, 'display')!=3D'none') this.options.= onHide(this.element, this.update); + if(this.iefix) Element.hide(this.iefix); + }, + + startIndicator: function() { + if(this.options.indicator) Element.show(this.options.indicator); + }, + + stopIndicator: function() { + if(this.options.indicator) Element.hide(this.options.indicator); + }, + + onKeyPress: function(event) { + if(this.active) + switch(event.keyCode) { + case Event.KEY_TAB: + case Event.KEY_RETURN: + this.selectEntry(); + Event.stop(event); + case Event.KEY_ESC: + this.hide(); + this.active =3D false; + Event.stop(event); + return; + case Event.KEY_LEFT: + case Event.KEY_RIGHT: + return; + case Event.KEY_UP: + this.markPrevious(); + this.render(); + Event.stop(event); + return; + case Event.KEY_DOWN: + this.markNext(); + this.render(); + Event.stop(event); + return; + } + else + if(event.keyCode=3D=3DEvent.KEY_TAB || event.keyCode=3D=3DEvent.K= EY_RETURN || + (Prototype.Browser.WebKit > 0 && event.keyCode =3D=3D 0)) retur= n; + + this.changed =3D true; + this.hasFocus =3D true; + + if(this.observer) clearTimeout(this.observer); + this.observer =3D + setTimeout(this.onObserverEvent.bind(this), this.options.frequen= cy*1000); + }, + + activate: function() { + this.changed =3D false; + this.hasFocus =3D true; + this.getUpdatedChoices(); + }, + + onHover: function(event) { + var element =3D Event.findElement(event, 'LI'); + if(this.index !=3D element.autocompleteIndex) + { + this.index =3D element.autocompleteIndex; + this.render(); + } + Event.stop(event); + }, + + onClick: function(event) { + var element =3D Event.findElement(event, 'LI'); + this.index =3D element.autocompleteIndex; + this.selectEntry(); + this.hide(); + }, + + onBlur: function(event) { + // needed to make click events working + setTimeout(this.hide.bind(this), 250); + this.hasFocus =3D false; + this.active =3D false; + }, + + render: function() { + if(this.entryCount > 0) { + for (var i =3D 0; i < this.entryCount; i++) + this.index=3D=3Di ? + Element.addClassName(this.getEntry(i),"selected") : + Element.removeClassName(this.getEntry(i),"selected"); + if(this.hasFocus) { + this.show(); + this.active =3D true; + } + } else { + this.active =3D false; + this.hide(); + } + }, + + markPrevious: function() { + if(this.index > 0) this.index--; + else this.index =3D this.entryCount-1; + this.getEntry(this.index).scrollIntoView(true); + }, + + markNext: function() { + if(this.index < this.entryCount-1) this.index++; + else this.index =3D 0; + this.getEntry(this.index).scrollIntoView(false); + }, + + getEntry: function(index) { + return this.update.firstChild.childNodes[index]; + }, + + getCurrentEntry: function() { + return this.getEntry(this.index); + }, + + selectEntry: function() { + this.active =3D false; + this.updateElement(this.getCurrentEntry()); + }, + + updateElement: function(selectedElement) { + if (this.options.updateElement) { + this.options.updateElement(selectedElement); + return; + } + var value =3D ''; + if (this.options.select) { + var nodes =3D $(selectedElement).select('.' + this.options.select)= || []; + if(nodes.length>0) value =3D Element.collectTextNodes(nodes[0], th= is.options.select); + } else + value =3D Element.collectTextNodesIgnoreClass(selectedElement, 'in= formal'); + + var bounds =3D this.getTokenBounds(); + if (bounds[0] !=3D -1) { + var newValue =3D this.element.value.substr(0, bounds[0]); + var whitespace =3D this.element.value.substr(bounds[0]).match(/^\s= +/); + if (whitespace) + newValue +=3D whitespace[0]; + this.element.value =3D newValue + value + this.element.value.subst= r(bounds[1]); + } else { + this.element.value =3D value; + } + this.oldElementValue =3D this.element.value; + this.element.focus(); + + if (this.options.afterUpdateElement) + this.options.afterUpdateElement(this.element, selectedElement); + }, + + updateChoices: function(choices) { + if(!this.changed && this.hasFocus) { + this.update.innerHTML =3D choices; + Element.cleanWhitespace(this.update); + Element.cleanWhitespace(this.update.down()); + + if(this.update.firstChild && this.update.down().childNodes) { + this.entryCount =3D + this.update.down().childNodes.length; + for (var i =3D 0; i < this.entryCount; i++) { + var entry =3D this.getEntry(i); + entry.autocompleteIndex =3D i; + this.addObservers(entry); + } + } else { + this.entryCount =3D 0; + } + + this.stopIndicator(); + this.index =3D 0; + + if(this.entryCount=3D=3D1 && this.options.autoSelect) { + this.selectEntry(); + this.hide(); + } else { + this.render(); + } + } + }, + + addObservers: function(element) { + Event.observe(element, "mouseover", this.onHover.bindAsEventListener= (this)); + Event.observe(element, "click", this.onClick.bindAsEventListener(thi= s)); + }, + + onObserverEvent: function() { + this.changed =3D false; + this.tokenBounds =3D null; + if(this.getToken().length>=3Dthis.options.minChars) { + this.getUpdatedChoices(); + } else { + this.active =3D false; + this.hide(); + } + this.oldElementValue =3D this.element.value; + }, + + getToken: function() { + var bounds =3D this.getTokenBounds(); + return this.element.value.substring(bounds[0], bounds[1]).strip(); + }, + + getTokenBounds: function() { + if (null !=3D this.tokenBounds) return this.tokenBounds; + var value =3D this.element.value; + if (value.strip().empty()) return [-1, 0]; + var diff =3D arguments.callee.getFirstDifferencePos(value, this.oldE= lementValue); + var offset =3D (diff =3D=3D this.oldElementValue.length ? 1 : 0); + var prevTokenPos =3D -1, nextTokenPos =3D value.length; + var tp; + for (var index =3D 0, l =3D this.options.tokens.length; index < l; += +index) { + tp =3D value.lastIndexOf(this.options.tokens[index], diff + offset= - 1); + if (tp > prevTokenPos) prevTokenPos =3D tp; + tp =3D value.indexOf(this.options.tokens[index], diff + offset); + if (-1 !=3D tp && tp < nextTokenPos) nextTokenPos =3D tp; + } + return (this.tokenBounds =3D [prevTokenPos + 1, nextTokenPos]); + } +}); + +Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos =3D fu= nction(newS, oldS) { + var boundary =3D Math.min(newS.length, oldS.length); + for (var index =3D 0; index < boundary; ++index) + if (newS[index] !=3D oldS[index]) + return index; + return boundary; +}; + +Ajax.Autocompleter =3D Class.create(Autocompleter.Base, { + initialize: function(element, update, url, options) { + this.baseInitialize(element, update, options); + this.options.asynchronous =3D true; + this.options.onComplete =3D this.onComplete.bind(this); + this.options.defaultParams =3D this.options.parameters || null; + this.url =3D url; + }, + + getUpdatedChoices: function() { + this.startIndicator(); + + var entry =3D encodeURIComponent(this.options.paramName) + '=3D' + + encodeURIComponent(this.getToken()); + + this.options.parameters =3D this.options.callback ? + this.options.callback(this.element, entry) : entry; + + if(this.options.defaultParams) + this.options.parameters +=3D '&' + this.options.defaultParams; + + new Ajax.Request(this.url, this.options); + }, + + onComplete: function(request) { + this.updateChoices(request.responseText); + } +}); + +// The local array autocompleter. Used when you'd prefer to +// inject an array of autocompletion options into the page, rather +// than sending out Ajax queries, which can be quite slow sometimes. +// +// The constructor takes four parameters. The first two are, as usual, +// the id of the monitored textbox, and id of the autocompletion menu. +// The third is the array you want to autocomplete from, and the fourth +// is the options block. +// +// Extra local autocompletion options: +// - choices - How many autocompletion choices to offer +// +// - partialSearch - If false, the autocompleter will match entered +// text only at the beginning of strings in the +// autocomplete array. Defaults to true, which will +// match text at the beginning of any *word* in the +// strings in the autocomplete array. If you want to +// search anywhere in the string, additionally set +// the option fullSearch to true (default: off). +// +// - fullSsearch - Search anywhere in autocomplete array strings. +// +// - partialChars - How many characters to enter before triggering +// a partial match (unlike minChars, which defines +// how many characters are required to do any match +// at all). Defaults to 2. +// +// - ignoreCase - Whether to ignore case when autocompleting. +// Defaults to true. +// +// It's possible to pass in a custom function as the 'selector' +// option, if you prefer to write your own autocompletion logic. +// In that case, the other options above will not apply unless +// you support them. + +Autocompleter.Local =3D Class.create(Autocompleter.Base, { + initialize: function(element, update, array, options) { + this.baseInitialize(element, update, options); + this.options.array =3D array; + }, + + getUpdatedChoices: function() { + this.updateChoices(this.options.selector(this)); + }, + + setOptions: function(options) { + this.options =3D Object.extend({ + choices: 10, + partialSearch: true, + partialChars: 2, + ignoreCase: true, + fullSearch: false, + selector: function(instance) { + var ret =3D []; // Beginning matches + var partial =3D []; // Inside matches + var entry =3D instance.getToken(); + var count =3D 0; + + for (var i =3D 0; i < instance.options.array.length && + ret.length < instance.options.choices ; i++) { + + var elem =3D instance.options.array[i]; + var foundPos =3D instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase()) : + elem.indexOf(entry); + + while (foundPos !=3D -1) { + if (foundPos =3D=3D 0 && elem.length !=3D entry.length) { + ret.push("
  • " + elem.substr(0, entry.length) + "= " + + elem.substr(entry.length) + "
  • "); + break; + } else if (entry.length >=3D instance.options.partialChars &= & + instance.options.partialSearch && foundPos !=3D -1) { + if (instance.options.fullSearch || /\s/.test(elem.substr(f= oundPos-1,1))) { + partial.push("
  • " + elem.substr(0, foundPos) + "" + + elem.substr(foundPos, entry.length) + "" + el= em.substr( + foundPos + entry.length) + "
  • "); + break; + } + } + + foundPos =3D instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos += 1) : + elem.indexOf(entry, foundPos + 1); + + } + } + if (partial.length) + ret =3D ret.concat(partial.slice(0, instance.options.choices -= ret.length)); + return "
      " + ret.join('') + "
    "; + } + }, options || { }); + } +}); + +// AJAX in-place editor and collection editor +// Full rewrite by Christophe Porteneuve (April 2007= ). + +// Use this if you notice weird scrolling problems on some browsers, +// the DOM might be a bit confused when this gets called so do this +// waits 1 ms (with setTimeout) until it does the activation +Field.scrollFreeActivate =3D function(field) { + setTimeout(function() { + Field.activate(field); + }, 1); +}; + +Ajax.InPlaceEditor =3D Class.create({ + initialize: function(element, url, options) { + this.url =3D url; + this.element =3D element =3D $(element); + this.prepareOptions(); + this._controls =3D { }; + arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION = LAYER!!! + Object.extend(this.options, options || { }); + if (!this.options.formId && this.element.id) { + this.options.formId =3D this.element.id + '-inplaceeditor'; + if ($(this.options.formId)) + this.options.formId =3D ''; + } + if (this.options.externalControl) + this.options.externalControl =3D $(this.options.externalControl); + if (!this.options.externalControl) + this.options.externalControlOnly =3D false; + this._originalBackground =3D this.element.getStyle('background-color= ') || 'transparent'; + this.element.title =3D this.options.clickToEditText; + this._boundCancelHandler =3D this.handleFormCancellation.bind(this); + this._boundComplete =3D (this.options.onComplete || Prototype.emptyF= unction).bind(this); + this._boundFailureHandler =3D this.handleAJAXFailure.bind(this); + this._boundSubmitHandler =3D this.handleFormSubmission.bind(this); + this._boundWrapperHandler =3D this.wrapUp.bind(this); + this.registerListeners(); + }, + checkForEscapeOrReturn: function(e) { + if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; + if (Event.KEY_ESC =3D=3D e.keyCode) + this.handleFormCancellation(e); + else if (Event.KEY_RETURN =3D=3D e.keyCode) + this.handleFormSubmission(e); + }, + createControl: function(mode, handler, extraClasses) { + var control =3D this.options[mode + 'Control']; + var text =3D this.options[mode + 'Text']; + if ('button' =3D=3D control) { + var btn =3D document.createElement('input'); + btn.type =3D 'submit'; + btn.value =3D text; + btn.className =3D 'editor_' + mode + '_button'; + if ('cancel' =3D=3D mode) + btn.onclick =3D this._boundCancelHandler; + this._form.appendChild(btn); + this._controls[mode] =3D btn; + } else if ('link' =3D=3D control) { + var link =3D document.createElement('a'); + link.href =3D '#'; + link.appendChild(document.createTextNode(text)); + link.onclick =3D 'cancel' =3D=3D mode ? this._boundCancelHandler := this._boundSubmitHandler; + link.className =3D 'editor_' + mode + '_link'; + if (extraClasses) + link.className +=3D ' ' + extraClasses; + this._form.appendChild(link); + this._controls[mode] =3D link; + } + }, + createEditField: function() { + var text =3D (this.options.loadTextURL ? this.options.loadingText : = this.getText()); + var fld; + if (1 >=3D this.options.rows && !/\r|\n/.test(this.getText())) { + fld =3D document.createElement('input'); + fld.type =3D 'text'; + var size =3D this.options.size || this.options.cols || 0; + if (0 < size) fld.size =3D size; + } else { + fld =3D document.createElement('textarea'); + fld.rows =3D (1 >=3D this.options.rows ? this.options.autoRows : t= his.options.rows); + fld.cols =3D this.options.cols || 40; + } + fld.name =3D this.options.paramName; + fld.value =3D text; // No HTML breaks conversion anymore + fld.className =3D 'editor_field'; + if (this.options.submitOnBlur) + fld.onblur =3D this._boundSubmitHandler; + this._controls.editor =3D fld; + if (this.options.loadTextURL) + this.loadExternalText(); + this._form.appendChild(this._controls.editor); + }, + createForm: function() { + var ipe =3D this; + function addText(mode, condition) { + var text =3D ipe.options['text' + mode + 'Controls']; + if (!text || condition =3D=3D=3D false) return; + ipe._form.appendChild(document.createTextNode(text)); + }; + this._form =3D $(document.createElement('form')); + this._form.id =3D this.options.formId; + this._form.addClassName(this.options.formClassName); + this._form.onsubmit =3D this._boundSubmitHandler; + this.createEditField(); + if ('textarea' =3D=3D this._controls.editor.tagName.toLowerCase()) + this._form.appendChild(document.createElement('br')); + if (this.options.onFormCustomization) + this.options.onFormCustomization(this, this._form); + addText('Before', this.options.okControl || this.options.cancelContr= ol); + this.createControl('ok', this._boundSubmitHandler); + addText('Between', this.options.okControl && this.options.cancelCont= rol); + this.createControl('cancel', this._boundCancelHandler, 'editor_cance= l'); + addText('After', this.options.okControl || this.options.cancelContro= l); + }, + destroy: function() { + if (this._oldInnerHTML) + this.element.innerHTML =3D this._oldInnerHTML; + this.leaveEditMode(); + this.unregisterListeners(); + }, + enterEditMode: function(e) { + if (this._saving || this._editing) return; + this._editing =3D true; + this.triggerCallback('onEnterEditMode'); + if (this.options.externalControl) + this.options.externalControl.hide(); + this.element.hide(); + this.createForm(); + this.element.parentNode.insertBefore(this._form, this.element); + if (!this.options.loadTextURL) + this.postProcessEditField(); + if (e) Event.stop(e); + }, + enterHover: function(e) { + if (this.options.hoverClassName) + this.element.addClassName(this.options.hoverClassName); + if (this._saving) return; + this.triggerCallback('onEnterHover'); + }, + getText: function() { + return this.element.innerHTML.unescapeHTML(); + }, + handleAJAXFailure: function(transport) { + this.triggerCallback('onFailure', transport); + if (this._oldInnerHTML) { + this.element.innerHTML =3D this._oldInnerHTML; + this._oldInnerHTML =3D null; + } + }, + handleFormCancellation: function(e) { + this.wrapUp(); + if (e) Event.stop(e); + }, + handleFormSubmission: function(e) { + var form =3D this._form; + var value =3D $F(this._controls.editor); + this.prepareSubmission(); + var params =3D this.options.callback(form, value) || ''; + if (Object.isString(params)) + params =3D params.toQueryParams(); + params.editorId =3D this.element.id; + if (this.options.htmlResponse) { + var options =3D Object.extend({ evalScripts: true }, this.options.= ajaxOptions); + Object.extend(options, { + parameters: params, + onComplete: this._boundWrapperHandler, + onFailure: this._boundFailureHandler + }); + new Ajax.Updater({ success: this.element }, this.url, options); + } else { + var options =3D Object.extend({ method: 'get' }, this.options.ajax= Options); + Object.extend(options, { + parameters: params, + onComplete: this._boundWrapperHandler, + onFailure: this._boundFailureHandler + }); + new Ajax.Request(this.url, options); + } + if (e) Event.stop(e); + }, + leaveEditMode: function() { + this.element.removeClassName(this.options.savingClassName); + this.removeForm(); + this.leaveHover(); + this.element.style.backgroundColor =3D this._originalBackground; + this.element.show(); + if (this.options.externalControl) + this.options.externalControl.show(); + this._saving =3D false; + this._editing =3D false; + this._oldInnerHTML =3D null; + this.triggerCallback('onLeaveEditMode'); + }, + leaveHover: function(e) { + if (this.options.hoverClassName) + this.element.removeClassName(this.options.hoverClassName); + if (this._saving) return; + this.triggerCallback('onLeaveHover'); + }, + loadExternalText: function() { + this._form.addClassName(this.options.loadingClassName); + this._controls.editor.disabled =3D true; + var options =3D Object.extend({ method: 'get' }, this.options.ajaxOp= tions); + Object.extend(options, { + parameters: 'editorId=3D' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + this._form.removeClassName(this.options.loadingClassName); + var text =3D transport.responseText; + if (this.options.stripLoadedTextTags) + text =3D text.stripTags(); + this._controls.editor.value =3D text; + this._controls.editor.disabled =3D false; + this.postProcessEditField(); + }.bind(this), + onFailure: this._boundFailureHandler + }); + new Ajax.Request(this.options.loadTextURL, options); + }, + postProcessEditField: function() { + var fpc =3D this.options.fieldPostCreation; + if (fpc) + $(this._controls.editor)['focus' =3D=3D fpc ? 'focus' : 'activate'= ](); + }, + prepareOptions: function() { + this.options =3D Object.clone(Ajax.InPlaceEditor.DefaultOptions); + Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); + [this._extraDefaultOptions].flatten().compact().each(function(defs) = { + Object.extend(this.options, defs); + }.bind(this)); + }, + prepareSubmission: function() { + this._saving =3D true; + this.removeForm(); + this.leaveHover(); + this.showSaving(); + }, + registerListeners: function() { + this._listeners =3D { }; + var listener; + $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { + listener =3D this[pair.value].bind(this); + this._listeners[pair.key] =3D listener; + if (!this.options.externalControlOnly) + this.element.observe(pair.key, listener); + if (this.options.externalControl) + this.options.externalControl.observe(pair.key, listener); + }.bind(this)); + }, + removeForm: function() { + if (!this._form) return; + this._form.remove(); + this._form =3D null; + this._controls =3D { }; + }, + showSaving: function() { + this._oldInnerHTML =3D this.element.innerHTML; + this.element.innerHTML =3D this.options.savingText; + this.element.addClassName(this.options.savingClassName); + this.element.style.backgroundColor =3D this._originalBackground; + this.element.show(); + }, + triggerCallback: function(cbName, arg) { + if ('function' =3D=3D typeof this.options[cbName]) { + this.options[cbName](this, arg); + } + }, + unregisterListeners: function() { + $H(this._listeners).each(function(pair) { + if (!this.options.externalControlOnly) + this.element.stopObserving(pair.key, pair.value); + if (this.options.externalControl) + this.options.externalControl.stopObserving(pair.key, pair.value)= ; + }.bind(this)); + }, + wrapUp: function(transport) { + this.leaveEditMode(); + // Can't use triggerCallback due to backward compatibility: requires + // binding + direct element + this._boundComplete(transport, this.element); + } +}); + +Object.extend(Ajax.InPlaceEditor.prototype, { + dispose: Ajax.InPlaceEditor.prototype.destroy +}); + +Ajax.InPlaceCollectionEditor =3D Class.create(Ajax.InPlaceEditor, { + initialize: function($super, element, url, options) { + this._extraDefaultOptions =3D Ajax.InPlaceCollectionEditor.DefaultOp= tions; + $super(element, url, options); + }, + + createEditField: function() { + var list =3D document.createElement('select'); + list.name =3D this.options.paramName; + list.size =3D 1; + this._controls.editor =3D list; + this._collection =3D this.options.collection || []; + if (this.options.loadCollectionURL) + this.loadCollection(); + else + this.checkForExternalText(); + this._form.appendChild(this._controls.editor); + }, + + loadCollection: function() { + this._form.addClassName(this.options.loadingClassName); + this.showLoadingText(this.options.loadingCollectionText); + var options =3D Object.extend({ method: 'get' }, this.options.ajaxOp= tions); + Object.extend(options, { + parameters: 'editorId=3D' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + var js =3D transport.responseText.strip(); + if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check + throw('Server returned an invalid collection representation.')= ; + this._collection =3D eval(js); + this.checkForExternalText(); + }.bind(this), + onFailure: this.onFailure + }); + new Ajax.Request(this.options.loadCollectionURL, options); + }, + + showLoadingText: function(text) { + this._controls.editor.disabled =3D true; + var tempOption =3D this._controls.editor.firstChild; + if (!tempOption) { + tempOption =3D document.createElement('option'); + tempOption.value =3D ''; + this._controls.editor.appendChild(tempOption); + tempOption.selected =3D true; + } + tempOption.update((text || '').stripScripts().stripTags()); + }, + + checkForExternalText: function() { + this._text =3D this.getText(); + if (this.options.loadTextURL) + this.loadExternalText(); + else + this.buildOptionList(); + }, + + loadExternalText: function() { + this.showLoadingText(this.options.loadingText); + var options =3D Object.extend({ method: 'get' }, this.options.ajaxOp= tions); + Object.extend(options, { + parameters: 'editorId=3D' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + this._text =3D transport.responseText.strip(); + this.buildOptionList(); + }.bind(this), + onFailure: this.onFailure + }); + new Ajax.Request(this.options.loadTextURL, options); + }, + + buildOptionList: function() { + this._form.removeClassName(this.options.loadingClassName); + this._collection =3D this._collection.map(function(entry) { + return 2 =3D=3D=3D entry.length ? entry : [entry, entry].flatten()= ; + }); + var marker =3D ('value' in this.options) ? this.options.value : this= ._text; + var textFound =3D this._collection.any(function(entry) { + return entry[0] =3D=3D marker; + }.bind(this)); + this._controls.editor.update(''); + var option; + this._collection.each(function(entry, index) { + option =3D document.createElement('option'); + option.value =3D entry[0]; + option.selected =3D textFound ? entry[0] =3D=3D marker : 0 =3D=3D = index; + option.appendChild(document.createTextNode(entry[1])); + this._controls.editor.appendChild(option); + }.bind(this)); + this._controls.editor.disabled =3D false; + Field.scrollFreeActivate(this._controls.editor); + } +}); + +//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** +//**** This only exists for a while, in order to let **** +//**** users adapt to the new API. Read up on the new **** +//**** API and convert your code to it ASAP! **** + +Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions =3D fu= nction(options) { + if (!options) return; + function fallback(name, expr) { + if (name in options || expr =3D=3D=3D undefined) return; + options[name] =3D expr; + }; + fallback('cancelControl', (options.cancelLink ? 'link' : (options.canc= elButton ? 'button' : + options.cancelLink =3D=3D options.cancelButton =3D=3D false ? false = : undefined))); + fallback('okControl', (options.okLink ? 'link' : (options.okButton ? '= button' : + options.okLink =3D=3D options.okButton =3D=3D false ? false : undefi= ned))); + fallback('highlightColor', options.highlightcolor); + fallback('highlightEndColor', options.highlightendcolor); +}; + +Object.extend(Ajax.InPlaceEditor, { + DefaultOptions: { + ajaxOptions: { }, + autoRows: 3, // Use when multi-line w= / rows =3D=3D 1 + cancelControl: 'link', // 'link'|'button'|false + cancelText: 'cancel', + clickToEditText: 'Click to edit', + externalControl: null, // id|elt + externalControlOnly: false, + fieldPostCreation: 'activate', // 'activate'|'focus'|fa= lse + formClassName: 'inplaceeditor-form', + formId: null, // id|elt + highlightColor: '#ffff99', + highlightEndColor: '#ffffff', + hoverClassName: '', + htmlResponse: true, + loadingClassName: 'inplaceeditor-loading', + loadingText: 'Loading...', + okControl: 'button', // 'link'|'button'|false + okText: 'ok', + paramName: 'value', + rows: 1, // If 1 and multi-line, = uses autoRows + savingClassName: 'inplaceeditor-saving', + savingText: 'Saving...', + size: 0, + stripLoadedTextTags: false, + submitOnBlur: false, + textAfterControls: '', + textBeforeControls: '', + textBetweenControls: '' + }, + DefaultCallbacks: { + callback: function(form) { + return Form.serialize(form); + }, + onComplete: function(transport, element) { + // For backward compatibility, this one is bound to the IPE, and p= asses + // the element directly. It was too often customized, so we don't= break it. + new Effect.Highlight(element, { + startcolor: this.options.highlightColor, keepBackgroundImage: tr= ue }); + }, + onEnterEditMode: null, + onEnterHover: function(ipe) { + ipe.element.style.backgroundColor =3D ipe.options.highlightColor; + if (ipe._effect) + ipe._effect.cancel(); + }, + onFailure: function(transport, ipe) { + alert('Error communication with the server: ' + transport.response= Text.stripTags()); + }, + onFormCustomization: null, // Takes the IPE and its generated form, = after editor, before controls. + onLeaveEditMode: null, + onLeaveHover: function(ipe) { + ipe._effect =3D new Effect.Highlight(ipe.element, { + startcolor: ipe.options.highlightColor, endcolor: ipe.options.hi= ghlightEndColor, + restorecolor: ipe._originalBackground, keepBackgroundImage: true + }); + } + }, + Listeners: { + click: 'enterEditMode', + keydown: 'checkForEscapeOrReturn', + mouseover: 'enterHover', + mouseout: 'leaveHover' + } +}); + +Ajax.InPlaceCollectionEditor.DefaultOptions =3D { + loadingCollectionText: 'Loading options...' +}; + +// Delayed observer, like Form.Element.Observer, +// but waits for delay after last key input +// Ideal for live-search fields + +Form.Element.DelayedObserver =3D Class.create({ + initialize: function(element, delay, callback) { + this.delay =3D delay || 0.5; + this.element =3D $(element); + this.callback =3D callback; + this.timer =3D null; + this.lastValue =3D $F(this.element); + Event.observe(this.element,'keyup',this.delayedListener.bindAsEventL= istener(this)); + }, + delayedListener: function(event) { + if(this.lastValue =3D=3D $F(this.element)) return; + if(this.timer) clearTimeout(this.timer); + this.timer =3D setTimeout(this.onTimerEvent.bind(this), this.delay *= 1000); + this.lastValue =3D $F(this.element); + }, + onTimerEvent: function() { + this.timer =3D null; + this.callback(this.element, $F(this.element)); + } +}); \ No newline at end of file diff --git a/site/public/javascripts/dragdrop.js b/site/public/javascript= s/dragdrop.js new file mode 100644 index 0000000..15c6dbc --- /dev/null +++ b/site/public/javascripts/dragdrop.js @@ -0,0 +1,974 @@ +// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://= mir.aculo.us) +// +// script.aculo.us is freely distributable under the terms of an MIT-sty= le license. +// For details, see the script.aculo.us web site: http://script.aculo.us= / + +if(Object.isUndefined(Effect)) + throw("dragdrop.js requires including script.aculo.us' effects.js libr= ary"); + +var Droppables =3D { + drops: [], + + remove: function(element) { + this.drops =3D this.drops.reject(function(d) { return d.element=3D=3D= $(element) }); + }, + + add: function(element) { + element =3D $(element); + var options =3D Object.extend({ + greedy: true, + hoverclass: null, + tree: false + }, arguments[1] || { }); + + // cache containers + if(options.containment) { + options._containers =3D []; + var containment =3D options.containment; + if(Object.isArray(containment)) { + containment.each( function(c) { options._containers.push($(c)) }= ); + } else { + options._containers.push($(containment)); + } + } + + if(options.accept) options.accept =3D [options.accept].flatten(); + + Element.makePositioned(element); // fix IE + options.element =3D element; + + this.drops.push(options); + }, + + findDeepestChild: function(drops) { + deepest =3D drops[0]; + + for (i =3D 1; i < drops.length; ++i) + if (Element.isParent(drops[i].element, deepest.element)) + deepest =3D drops[i]; + + return deepest; + }, + + isContained: function(element, drop) { + var containmentNode; + if(drop.tree) { + containmentNode =3D element.treeNode; + } else { + containmentNode =3D element.parentNode; + } + return drop._containers.detect(function(c) { return containmentNode = =3D=3D c }); + }, + + isAffected: function(point, element, drop) { + return ( + (drop.element!=3Delement) && + ((!drop._containers) || + this.isContained(element, drop)) && + ((!drop.accept) || + (Element.classNames(element).detect( + function(v) { return drop.accept.include(v) } ) )) && + Position.within(drop.element, point[0], point[1]) ); + }, + + deactivate: function(drop) { + if(drop.hoverclass) + Element.removeClassName(drop.element, drop.hoverclass); + this.last_active =3D null; + }, + + activate: function(drop) { + if(drop.hoverclass) + Element.addClassName(drop.element, drop.hoverclass); + this.last_active =3D drop; + }, + + show: function(point, element) { + if(!this.drops.length) return; + var drop, affected =3D []; + + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) + affected.push(drop); + }); + + if(affected.length>0) + drop =3D Droppables.findDeepestChild(affected); + + if(this.last_active && this.last_active !=3D drop) this.deactivate(t= his.last_active); + if (drop) { + Position.within(drop.element, point[0], point[1]); + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overla= p, drop.element)); + + if (drop !=3D this.last_active) Droppables.activate(drop); + } + }, + + fire: function(event, element) { + if(!this.last_active) return; + Position.prepare(); + + if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], = element, this.last_active)) + if (this.last_active.onDrop) { + this.last_active.onDrop(element, this.last_active.element, event= ); + return true; + } + }, + + reset: function() { + if(this.last_active) + this.deactivate(this.last_active); + } +}; + +var Draggables =3D { + drags: [], + observers: [], + + register: function(draggable) { + if(this.drags.length =3D=3D 0) { + this.eventMouseUp =3D this.endDrag.bindAsEventListener(this); + this.eventMouseMove =3D this.updateDrag.bindAsEventListener(this); + this.eventKeypress =3D this.keyPress.bindAsEventListener(this); + + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + Event.observe(document, "keypress", this.eventKeypress); + } + this.drags.push(draggable); + }, + + unregister: function(draggable) { + this.drags =3D this.drags.reject(function(d) { return d=3D=3Ddraggab= le }); + if(this.drags.length =3D=3D 0) { + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + Event.stopObserving(document, "keypress", this.eventKeypress); + } + }, + + activate: function(draggable) { + if(draggable.options.delay) { + this._timeout =3D setTimeout(function() { + Draggables._timeout =3D null; + window.focus(); + Draggables.activeDraggable =3D draggable; + }.bind(this), draggable.options.delay); + } else { + window.focus(); // allows keypress events if window isn't currentl= y focused, fails for Safari + this.activeDraggable =3D draggable; + } + }, + + deactivate: function() { + this.activeDraggable =3D null; + }, + + updateDrag: function(event) { + if(!this.activeDraggable) return; + var pointer =3D [Event.pointerX(event), Event.pointerY(event)]; + // Mozilla-based browsers fire successive mousemove events with + // the same coordinates, prevent needless redrawing (moz bug?) + if(this._lastPointer && (this._lastPointer.inspect() =3D=3D pointer.= inspect())) return; + this._lastPointer =3D pointer; + + this.activeDraggable.updateDrag(event, pointer); + }, + + endDrag: function(event) { + if(this._timeout) { + clearTimeout(this._timeout); + this._timeout =3D null; + } + if(!this.activeDraggable) return; + this._lastPointer =3D null; + this.activeDraggable.endDrag(event); + this.activeDraggable =3D null; + }, + + keyPress: function(event) { + if(this.activeDraggable) + this.activeDraggable.keyPress(event); + }, + + addObserver: function(observer) { + this.observers.push(observer); + this._cacheObserverCallbacks(); + }, + + removeObserver: function(element) { // element instead of observer fi= xes mem leaks + this.observers =3D this.observers.reject( function(o) { return o.ele= ment=3D=3Delement }); + this._cacheObserverCallbacks(); + }, + + notify: function(eventName, draggable, event) { // 'onStart', 'onEnd'= , 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); + if(draggable.options[eventName]) draggable.options[eventName](dragga= ble, event); + }, + + _cacheObserverCallbacks: function() { + ['onStart','onEnd','onDrag'].each( function(eventName) { + Draggables[eventName+'Count'] =3D Draggables.observers.select( + function(o) { return o[eventName]; } + ).length; + }); + } +}; + +/*----------------------------------------------------------------------= ----*/ + +var Draggable =3D Class.create({ + initialize: function(element) { + var defaults =3D { + handle: false, + reverteffect: function(element, top_offset, left_offset) { + var dur =3D Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offse= t^2))*0.02; + new Effect.Move(element, { x: -left_offset, y: -top_offset, dura= tion: dur, + queue: {scope:'_draggable', position:'end'} + }); + }, + endeffect: function(element) { + var toOpacity =3D Object.isNumber(element._opacity) ? element._o= pacity : 1.0; + new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacit= y, + queue: {scope:'_draggable', position:'end'}, + afterFinish: function(){ + Draggable._dragging[element] =3D false + } + }); + }, + zindex: 1000, + revert: false, + quiet: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + snap: false, // false, or xy or [x,y] or function(x,y){ return [x= ,y] } + delay: 0 + }; + + if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) + Object.extend(defaults, { + starteffect: function(element) { + element._opacity =3D Element.getOpacity(element); + Draggable._dragging[element] =3D true; + new Effect.Opacity(element, {duration:0.2, from:element._opaci= ty, to:0.7}); + } + }); + + var options =3D Object.extend(defaults, arguments[1] || { }); + + this.element =3D $(element); + + if(options.handle && Object.isString(options.handle)) + this.handle =3D this.element.down('.'+options.handle, 0); + + if(!this.handle) this.handle =3D $(options.handle); + if(!this.handle) this.handle =3D this.element; + + if(options.scroll && !options.scroll.scrollTo && !options.scroll.out= erHTML) { + options.scroll =3D $(options.scroll); + this._isScrollChild =3D Element.childOf(this.element, options.scro= ll); + } + + Element.makePositioned(this.element); // fix IE + + this.options =3D options; + this.dragging =3D false; + + this.eventMouseDown =3D this.initDrag.bindAsEventListener(this); + Event.observe(this.handle, "mousedown", this.eventMouseDown); + + Draggables.register(this); + }, + + destroy: function() { + Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + Draggables.unregister(this); + }, + + currentDelta: function() { + return([ + parseInt(Element.getStyle(this.element,'left') || '0'), + parseInt(Element.getStyle(this.element,'top') || '0')]); + }, + + initDrag: function(event) { + if(!Object.isUndefined(Draggable._dragging[this.element]) && + Draggable._dragging[this.element]) return; + if(Event.isLeftClick(event)) { + // abort on form elements, fixes a Firefox issue + var src =3D Event.element(event); + if((tag_name =3D src.tagName.toUpperCase()) && ( + tag_name=3D=3D'INPUT' || + tag_name=3D=3D'SELECT' || + tag_name=3D=3D'OPTION' || + tag_name=3D=3D'BUTTON' || + tag_name=3D=3D'TEXTAREA')) return; + + var pointer =3D [Event.pointerX(event), Event.pointerY(event)]; + var pos =3D this.element.cumulativeOffset(); + this.offset =3D [0,1].map( function(i) { return (pointer[i] - pos[= i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging =3D true; + if(!this.delta) + this.delta =3D this.currentDelta(); + + if(this.options.zindex) { + this.originalZ =3D parseInt(Element.getStyle(this.element,'z-index= ') || 0); + this.element.style.zIndex =3D this.options.zindex; + } + + if(this.options.ghosting) { + this._clone =3D this.element.cloneNode(true); + this._originallyAbsolute =3D (this.element.getStyle('position') =3D= =3D 'absolute'); + if (!this._originallyAbsolute) + Position.absolutize(this.element); + this.element.parentNode.insertBefore(this._clone, this.element); + } + + if(this.options.scroll) { + if (this.options.scroll =3D=3D window) { + var where =3D this._getWindowScroll(this.options.scroll); + this.originalScrollLeft =3D where.left; + this.originalScrollTop =3D where.top; + } else { + this.originalScrollLeft =3D this.options.scroll.scrollLeft; + this.originalScrollTop =3D this.options.scroll.scrollTop; + } + } + + Draggables.notify('onStart', this, event); + + if(this.options.starteffect) this.options.starteffect(this.element); + }, + + updateDrag: function(event, pointer) { + if(!this.dragging) this.startDrag(event); + + if(!this.options.quiet){ + Position.prepare(); + Droppables.show(pointer, this.element); + } + + Draggables.notify('onDrag', this, event); + + this.draw(pointer); + if(this.options.change) this.options.change(this); + + if(this.options.scroll) { + this.stopScrolling(); + + var p; + if (this.options.scroll =3D=3D window) { + with(this._getWindowScroll(this.options.scroll)) { p =3D [ left,= top, left+width, top+height ]; } + } else { + p =3D Position.page(this.options.scroll); + p[0] +=3D this.options.scroll.scrollLeft + Position.deltaX; + p[1] +=3D this.options.scroll.scrollTop + Position.deltaY; + p.push(p[0]+this.options.scroll.offsetWidth); + p.push(p[1]+this.options.scroll.offsetHeight); + } + var speed =3D [0,0]; + if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] =3D= pointer[0]-(p[0]+this.options.scrollSensitivity); + if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] =3D= pointer[1]-(p[1]+this.options.scrollSensitivity); + if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] =3D= pointer[0]-(p[2]-this.options.scrollSensitivity); + if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] =3D= pointer[1]-(p[3]-this.options.scrollSensitivity); + this.startScrolling(speed); + } + + // fix AppleWebKit rendering + if(Prototype.Browser.WebKit) window.scrollBy(0,0); + + Event.stop(event); + }, + + finishDrag: function(event, success) { + this.dragging =3D false; + + if(this.options.quiet){ + Position.prepare(); + var pointer =3D [Event.pointerX(event), Event.pointerY(event)]; + Droppables.show(pointer, this.element); + } + + if(this.options.ghosting) { + if (!this._originallyAbsolute) + Position.relativize(this.element); + delete this._originallyAbsolute; + Element.remove(this._clone); + this._clone =3D null; + } + + var dropped =3D false; + if(success) { + dropped =3D Droppables.fire(event, this.element); + if (!dropped) dropped =3D false; + } + if(dropped && this.options.onDropped) this.options.onDropped(this.el= ement); + Draggables.notify('onEnd', this, event); + + var revert =3D this.options.revert; + if(revert && Object.isFunction(revert)) revert =3D revert(this.eleme= nt); + + var d =3D this.currentDelta(); + if(revert && this.options.reverteffect) { + if (dropped =3D=3D 0 || revert !=3D 'failure') + this.options.reverteffect(this.element, + d[1]-this.delta[1], d[0]-this.delta[0]); + } else { + this.delta =3D d; + } + + if(this.options.zindex) + this.element.style.zIndex =3D this.originalZ; + + if(this.options.endeffect) + this.options.endeffect(this.element); + + Draggables.deactivate(this); + Droppables.reset(); + }, + + keyPress: function(event) { + if(event.keyCode!=3DEvent.KEY_ESC) return; + this.finishDrag(event, false); + Event.stop(event); + }, + + endDrag: function(event) { + if(!this.dragging) return; + this.stopScrolling(); + this.finishDrag(event, true); + Event.stop(event); + }, + + draw: function(point) { + var pos =3D this.element.cumulativeOffset(); + if(this.options.ghosting) { + var r =3D Position.realOffset(this.element); + pos[0] +=3D r[0] - Position.deltaX; pos[1] +=3D r[1] - Position.de= ltaY; + } + + var d =3D this.currentDelta(); + pos[0] -=3D d[0]; pos[1] -=3D d[1]; + + if(this.options.scroll && (this.options.scroll !=3D window && this._= isScrollChild)) { + pos[0] -=3D this.options.scroll.scrollLeft-this.originalScrollLeft= ; + pos[1] -=3D this.options.scroll.scrollTop-this.originalScrollTop; + } + + var p =3D [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) + }.bind(this)); + + if(this.options.snap) { + if(Object.isFunction(this.options.snap)) { + p =3D this.options.snap(p[0],p[1],this); + } else { + if(Object.isArray(this.options.snap)) { + p =3D p.map( function(v, i) { + return (v/this.options.snap[i]).round()*this.options.snap[i] }= .bind(this)); + } else { + p =3D p.map( function(v) { + return (v/this.options.snap).round()*this.options.snap }.bind(= this)); + } + }} + + var style =3D this.element.style; + if((!this.options.constraint) || (this.options.constraint=3D=3D'hori= zontal')) + style.left =3D p[0] + "px"; + if((!this.options.constraint) || (this.options.constraint=3D=3D'vert= ical')) + style.top =3D p[1] + "px"; + + if(style.visibility=3D=3D"hidden") style.visibility =3D ""; // fix g= ecko rendering + }, + + stopScrolling: function() { + if(this.scrollInterval) { + clearInterval(this.scrollInterval); + this.scrollInterval =3D null; + Draggables._lastScrollPointer =3D null; + } + }, + + startScrolling: function(speed) { + if(!(speed[0] || speed[1])) return; + this.scrollSpeed =3D [speed[0]*this.options.scrollSpeed,speed[1]*thi= s.options.scrollSpeed]; + this.lastScrolled =3D new Date(); + this.scrollInterval =3D setInterval(this.scroll.bind(this), 10); + }, + + scroll: function() { + var current =3D new Date(); + var delta =3D current - this.lastScrolled; + this.lastScrolled =3D current; + if(this.options.scroll =3D=3D window) { + with (this._getWindowScroll(this.options.scroll)) { + if (this.scrollSpeed[0] || this.scrollSpeed[1]) { + var d =3D delta / 1000; + this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], to= p + d*this.scrollSpeed[1] ); + } + } + } else { + this.options.scroll.scrollLeft +=3D this.scrollSpeed[0] * delta / = 1000; + this.options.scroll.scrollTop +=3D this.scrollSpeed[1] * delta / = 1000; + } + + Position.prepare(); + Droppables.show(Draggables._lastPointer, this.element); + Draggables.notify('onDrag', this); + if (this._isScrollChild) { + Draggables._lastScrollPointer =3D Draggables._lastScrollPointer ||= $A(Draggables._lastPointer); + Draggables._lastScrollPointer[0] +=3D this.scrollSpeed[0] * delta = / 1000; + Draggables._lastScrollPointer[1] +=3D this.scrollSpeed[1] * delta = / 1000; + if (Draggables._lastScrollPointer[0] < 0) + Draggables._lastScrollPointer[0] =3D 0; + if (Draggables._lastScrollPointer[1] < 0) + Draggables._lastScrollPointer[1] =3D 0; + this.draw(Draggables._lastScrollPointer); + } + + if(this.options.change) this.options.change(this); + }, + + _getWindowScroll: function(w) { + var T, L, W, H; + with (w.document) { + if (w.document.documentElement && documentElement.scrollTop) { + T =3D documentElement.scrollTop; + L =3D documentElement.scrollLeft; + } else if (w.document.body) { + T =3D body.scrollTop; + L =3D body.scrollLeft; + } + if (w.innerWidth) { + W =3D w.innerWidth; + H =3D w.innerHeight; + } else if (w.document.documentElement && documentElement.clientWid= th) { + W =3D documentElement.clientWidth; + H =3D documentElement.clientHeight; + } else { + W =3D body.offsetWidth; + H =3D body.offsetHeight; + } + } + return { top: T, left: L, width: W, height: H }; + } +}); + +Draggable._dragging =3D { }; + +/*----------------------------------------------------------------------= ----*/ + +var SortableObserver =3D Class.create({ + initialize: function(element, observer) { + this.element =3D $(element); + this.observer =3D observer; + this.lastValue =3D Sortable.serialize(this.element); + }, + + onStart: function() { + this.lastValue =3D Sortable.serialize(this.element); + }, + + onEnd: function() { + Sortable.unmark(); + if(this.lastValue !=3D Sortable.serialize(this.element)) + this.observer(this.element) + } +}); + +var Sortable =3D { + SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, + + sortables: { }, + + _findRootElement: function(element) { + while (element.tagName.toUpperCase() !=3D "BODY") { + if(element.id && Sortable.sortables[element.id]) return element; + element =3D element.parentNode; + } + }, + + options: function(element) { + element =3D Sortable._findRootElement($(element)); + if(!element) return; + return Sortable.sortables[element.id]; + }, + + destroy: function(element){ + element =3D $(element); + var s =3D Sortable.sortables[element.id]; + + if(s) { + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + + delete Sortable.sortables[s.element.id]; + } + }, + + create: function(element) { + element =3D $(element); + var options =3D Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag= : 'tagname' + dropOnEmpty: false, + tree: false, + treeTag: 'ul', + overlap: 'vertical', // one of 'vertical', 'horizontal' + constraint: 'vertical', // one of 'vertical', 'horizontal', false + containment: element, // also takes array of elements (or id's)= ; or false + handle: false, // or a CSS class + only: false, + delay: 0, + hoverclass: null, + ghosting: false, + quiet: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: this.SERIALIZE_RULE, + + // these take arrays of elements or ids and can be + // used for better initialization performance + elements: false, + handles: false, + + onChange: Prototype.emptyFunction, + onUpdate: Prototype.emptyFunction + }, arguments[1] || { }); + + // clear any old sortable with same element + this.destroy(element); + + // build options for the draggables + var options_for_draggable =3D { + revert: true, + quiet: options.quiet, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, + delay: options.delay, + ghosting: options.ghosting, + constraint: options.constraint, + handle: options.handle }; + + if(options.starteffect) + options_for_draggable.starteffect =3D options.starteffect; + + if(options.reverteffect) + options_for_draggable.reverteffect =3D options.reverteffect; + else + if(options.ghosting) options_for_draggable.reverteffect =3D functi= on(element) { + element.style.top =3D 0; + element.style.left =3D 0; + }; + + if(options.endeffect) + options_for_draggable.endeffect =3D options.endeffect; + + if(options.zindex) + options_for_draggable.zindex =3D options.zindex; + + // build options for the droppables + var options_for_droppable =3D { + overlap: options.overlap, + containment: options.containment, + tree: options.tree, + hoverclass: options.hoverclass, + onHover: Sortable.onHover + }; + + var options_for_tree =3D { + onHover: Sortable.onEmptyHover, + overlap: options.overlap, + containment: options.containment, + hoverclass: options.hoverclass + }; + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables =3D []; + options.droppables =3D []; + + // drop on empty handling + if(options.dropOnEmpty || options.tree) { + Droppables.add(element, options_for_tree); + options.droppables.push(element); + } + + (options.elements || this.findElements(element, options) || []).each= ( function(e,i) { + var handle =3D options.handles ? $(options.handles[i]) : + (options.handle ? $(e).select('.' + options.handle)[0] : e); + options.draggables.push( + new Draggable(e, Object.extend(options_for_draggable, { handle: = handle }))); + Droppables.add(e, options_for_droppable); + if(options.tree) e.treeNode =3D element; + options.droppables.push(e); + }); + + if(options.tree) { + (Sortable.findTreeElements(element, options) || []).each( function= (e) { + Droppables.add(e, options_for_tree); + e.treeNode =3D element; + options.droppables.push(e); + }); + } + + // keep reference + this.sortables[element.identify()] =3D options; + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdat= e)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.tag); + }, + + findTreeElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.treeTa= g); + }, + + onHover: function(element, dropon, overlap) { + if(Element.isParent(dropon, element)) return; + + if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) = { + return; + } else if(overlap>0.5) { + Sortable.mark(dropon, 'before'); + if(dropon.previousSibling !=3D element) { + var oldParentNode =3D element.parentNode; + element.style.visibility =3D "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, dropon); + if(dropon.parentNode!=3DoldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } else { + Sortable.mark(dropon, 'after'); + var nextElement =3D dropon.nextSibling || null; + if(nextElement !=3D element) { + var oldParentNode =3D element.parentNode; + element.style.visibility =3D "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, nextElement); + if(dropon.parentNode!=3DoldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } + }, + + onEmptyHover: function(element, dropon, overlap) { + var oldParentNode =3D element.parentNode; + var droponOptions =3D Sortable.options(dropon); + + if(!Element.isParent(dropon, element)) { + var index; + + var children =3D Sortable.findElements(dropon, {tag: droponOptions= .tag, only: droponOptions.only}); + var child =3D null; + + if(children) { + var offset =3D Element.offsetSize(dropon, droponOptions.overlap)= * (1.0 - overlap); + + for (index =3D 0; index < children.length; index +=3D 1) { + if (offset - Element.offsetSize (children[index], droponOption= s.overlap) >=3D 0) { + offset -=3D Element.offsetSize (children[index], droponOptio= ns.overlap); + } else if (offset - (Element.offsetSize (children[index], drop= onOptions.overlap) / 2) >=3D 0) { + child =3D index + 1 < children.length ? children[index + 1] = : null; + break; + } else { + child =3D children[index]; + break; + } + } + } + + dropon.insertBefore(element, child); + + Sortable.options(oldParentNode).onChange(element); + droponOptions.onChange(element); + } + }, + + unmark: function() { + if(Sortable._marker) Sortable._marker.hide(); + }, + + mark: function(dropon, position) { + // mark on ghosting only + var sortable =3D Sortable.options(dropon.parentNode); + if(sortable && !sortable.ghosting) return; + + if(!Sortable._marker) { + Sortable._marker =3D + ($('dropmarker') || Element.extend(document.createElement('DIV')= )). + hide().addClassName('dropmarker').setStyle({position:'absolute= '}); + document.getElementsByTagName("body").item(0).appendChild(Sortable= ._marker); + } + var offsets =3D dropon.cumulativeOffset(); + Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + = 'px'}); + + if(position=3D=3D'after') + if(sortable.overlap =3D=3D 'horizontal') + Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth)= + 'px'}); + else + Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight)= + 'px'}); + + Sortable._marker.show(); + }, + + _tree: function(element, options, parent) { + var children =3D Sortable.findElements(element, options) || []; + + for (var i =3D 0; i < children.length; ++i) { + var match =3D children[i].id.match(options.format); + + if (!match) continue; + + var child =3D { + id: encodeURIComponent(match ? match[1] : null), + element: element, + parent: parent, + children: [], + position: parent.children.length, + container: $(children[i]).down(options.treeTag) + }; + + /* Get the element containing the children and recurse over it */ + if (child.container) + this._tree(child.container, options, child); + + parent.children.push (child); + } + + return parent; + }, + + tree: function(element) { + element =3D $(element); + var sortableOptions =3D this.options(element); + var options =3D Object.extend({ + tag: sortableOptions.tag, + treeTag: sortableOptions.treeTag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format + }, arguments[1] || { }); + + var root =3D { + id: null, + parent: null, + children: [], + container: element, + position: 0 + }; + + return Sortable._tree(element, options, root); + }, + + /* Construct a [i] index for a particular node */ + _constructIndex: function(node) { + var index =3D ''; + do { + if (node.id) index =3D '[' + node.position + ']' + index; + } while ((node =3D node.parent) !=3D null); + return index; + }, + + sequence: function(element) { + element =3D $(element); + var options =3D Object.extend(this.options(element), arguments[1] ||= { }); + + return $(this.findElements(element, options) || []).map( function(it= em) { + return item.id.match(options.format) ? item.id.match(options.forma= t)[1] : ''; + }); + }, + + setSequence: function(element, new_sequence) { + element =3D $(element); + var options =3D Object.extend(this.options(element), arguments[2] ||= { }); + + var nodeMap =3D { }; + this.findElements(element, options).each( function(n) { + if (n.id.match(options.format)) + nodeMap[n.id.match(options.format)[1]] =3D [n, n.parentNode]= ; + n.parentNode.removeChild(n); + }); + + new_sequence.each(function(ident) { + var n =3D nodeMap[ident]; + if (n) { + n[1].appendChild(n[0]); + delete nodeMap[ident]; + } + }); + }, + + serialize: function(element) { + element =3D $(element); + var options =3D Object.extend(Sortable.options(element), arguments[1= ] || { }); + var name =3D encodeURIComponent( + (arguments[1] && arguments[1].name) ? arguments[1].name : element.= id); + + if (options.tree) { + return Sortable.tree(element, arguments[1]).children.map( function= (item) { + return [name + Sortable._constructIndex(item) + "[id]=3D" + + encodeURIComponent(item.id)].concat(item.children.map(ar= guments.callee)); + }).flatten().join('&'); + } else { + return Sortable.sequence(element, arguments[1]).map( function(item= ) { + return name + "[]=3D" + encodeURIComponent(item); + }).join('&'); + } + } +}; + +// Returns true if child is contained within element +Element.isParent =3D function(child, element) { + if (!child.parentNode || child =3D=3D element) return false; + if (child.parentNode =3D=3D element) return true; + return Element.isParent(child.parentNode, element); +}; + +Element.findChildren =3D function(element, only, recursive, tagName) { + if(!element.hasChildNodes()) return null; + tagName =3D tagName.toUpperCase(); + if(only) only =3D [only].flatten(); + var elements =3D []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName.toUpperCase()=3D=3DtagName && + (!only || (Element.classNames(e).detect(function(v) { return only.= include(v) })))) + elements.push(e); + if(recursive) { + var grandchildren =3D Element.findChildren(e, only, recursive, tag= Name); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : []); +}; + +Element.offsetSize =3D function (element, type) { + return element['offset' + ((type=3D=3D'vertical' || type=3D=3D'height'= ) ? 'Height' : 'Width')]; +}; \ No newline at end of file diff --git a/site/public/javascripts/dryml-support.js b/site/public/javas= cripts/dryml-support.js new file mode 100644 index 0000000..867db71 --- /dev/null +++ b/site/public/javascripts/dryml-support.js @@ -0,0 +1,132 @@ +Event.addBehavior({ + 'body:click' : function(event) { + if (event.shiftKey && event.altKey) { + Dryml.click(event) + Event.stop(event) + } + } +}) + + +var Dryml =3D { + + menu: null, + event: null, + + click: function(event) { + Dryml.event =3D event + Dryml.showSourceMenu(event.target) + }, + + showSourceMenu: function(element) { + var stack =3D Dryml.getSrcInfoStack(element) + Dryml.showMenu(stack) + }, + + getSrcInfoStack: function(element) { + var stack =3D $A() + while(element !=3D document.documentElement) { + var el =3D Dryml.findPrecedingDrymlInfo(element) + if (el =3D=3D null) { + element =3D element.parentNode + } else { + element =3D el + var info =3D Dryml.getDrymlInfo(element) + stack.push(info) + } + } + return stack + }, + + findPrecedingDrymlInfo: function(element) { + var ignoreCount =3D 0 + var el =3D element + while (el =3D el.previousSibling) { + if (Dryml.isDrymlInfo(el)) { + if (ignoreCount > 0) + ignoreCount -=3D 1; + else + return el + } else if (Dryml.isDrymlInfoClose(el)) { + ignoreCount +=3D 1 + } + } + return null + }, + + getDrymlInfo: function(el) { + var parts =3D el.nodeValue.sub(/^\[DRYML\|/, "").sub(/\[$/, "").= split("|") + return { kind: parts[0], tag: parts[1], line: parts[2], file: pa= rts[3] } + }, + + isDrymlInfo: function(el) { + return el.nodeType =3D=3D Node.COMMENT_NODE && el.nodeValue.matc= h(/^\[DRYML/) + }, + + isDrymlInfoClose: function(el) { + return el.nodeType =3D=3D Node.COMMENT_NODE && el.nodeValue =3D=3D= "]DRYML]" + }, + + showMenu: function(stack) { + Dryml.removeMenu() + + var style =3D $style({id: "dryml-menu-style"}, + "#dryml-src-menu { position: fixed; m= argin: 10px; padding: 10px; background: black; color: white; border: 1px = solid white; }\n", + "#dryml-src-menu a { color: white; text= -decoration: none; border: none; }\n", + "#dryml-src-menu td { padding: 2px 7px; = }\n", + "#dryml-src-menu a:hover { background: black;= color: white; text-decoration: none; border: none; }\n") + $$("head")[0].appendChild(style) + + var items =3D stack.map(Dryml.makeMenuItem) + + var closer =3D $a({href:"#"}, "[close]") + closer.onclick =3D Dryml.removeMenu + Dryml.menu =3D $div({id: "dryml-src-menu", + style: "position: fixed; margin: 10px; paddin= g: 10px; background: black; color: #cfc; border: 1px solid white;" + }, + closer, + $table(items)) + + document.body.appendChild(Dryml.menu) + Dryml.menu.style.top =3D "20px"//Dryml.event.clientY + "px" + Dryml.menu.style.left =3D "20px"//Dryml.event.clientX + "px" + }, + + editSourceFile: function(path, line) { + new Ajax.Request("/dryml/edit_source?file=3D" + path + "&line=3D= " + line) + }, + + + makeMenuItem: function(item) { + var text + switch (item.kind) { + case "call": + text =3D "<" + item.tag + ">" + break + case "param": + text =3D "<" + item.tag + ":>" + break + case "replace": + text =3D "<" + item.tag + ": replace>" + break + case "def": + text =3D "" + break + } + var a =3D $a({href:"#"}, text) + a.onclick =3D function() { Dryml.editSourceFile(item.file, item.= line); return false } + + var filename =3D item.file.sub("vendor/plugins", "").sub("app/vi= ews", "").sub(/^\/+/, "").sub(".dryml", "") + + return $tr($td({"class": "file"}, filename), $td(a)) + }, + + removeMenu: function() { + if (Dryml.menu) { + $("dryml-menu-style").remove() + Dryml.menu.remove() + Dryml.menu =3D null + } + } + +} diff --git a/site/public/javascripts/effects.js b/site/public/javascripts= /effects.js new file mode 100644 index 0000000..c81e6c7 --- /dev/null +++ b/site/public/javascripts/effects.js @@ -0,0 +1,1123 @@ +// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://= mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// script.aculo.us is freely distributable under the terms of an MIT-sty= le license. +// For details, see the script.aculo.us web site: http://script.aculo.us= / + +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor =3D function() { + var color =3D '#'; + if (this.slice(0,4) =3D=3D 'rgb(') { + var cols =3D this.slice(4,this.length-1).split(','); + var i=3D0; do { color +=3D parseInt(cols[i]).toColorPart() } while (= ++i<3); + } else { + if (this.slice(0,1) =3D=3D '#') { + if (this.length=3D=3D4) for(var i=3D1;i<4;i++) color +=3D (this.ch= arAt(i) + this.charAt(i)).toLowerCase(); + if (this.length=3D=3D7) color =3D this.toLowerCase(); + } + } + return (color.length=3D=3D7 ? color : (arguments[0] || this)); +}; + +/*----------------------------------------------------------------------= ----*/ + +Element.collectTextNodes =3D function(element) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType=3D=3D3 ? node.nodeValue : + (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); + }).flatten().join(''); +}; + +Element.collectTextNodesIgnoreClass =3D function(element, className) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType=3D=3D3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + Element.collectTextNodesIgnoreClass(node, className) : '')); + }).flatten().join(''); +}; + +Element.setContentZoom =3D function(element, percent) { + element =3D $(element); + element.setStyle({fontSize: (percent/100) + 'em'}); + if (Prototype.Browser.WebKit) window.scrollBy(0,0); + return element; +}; + +Element.getInlineOpacity =3D function(element){ + return $(element).style.opacity || ''; +}; + +Element.forceRerendering =3D function(element) { + try { + element =3D $(element); + var n =3D document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + +/*----------------------------------------------------------------------= ----*/ + +var Effect =3D { + _elementDoesNotExistError: { + name: 'ElementDoesNotExistError', + message: 'The specified DOM element does not exist, but is required = for this effect to operate' + }, + Transitions: { + linear: Prototype.K, + sinoidal: function(pos) { + return (-Math.cos(pos*Math.PI)/2) + .5; + }, + reverse: function(pos) { + return 1-pos; + }, + flicker: function(pos) { + var pos =3D ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4; + return pos > 1 ? 1 : pos; + }, + wobble: function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5; + }, + pulse: function(pos, pulses) { + return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5; + }, + spring: function(pos) { + return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); + }, + none: function(pos) { + return 0; + }, + full: function(pos) { + return 1; + } + }, + DefaultOptions: { + duration: 1.0, // seconds + fps: 100, // 100=3D assume 66fps max. + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' + }, + tagifyText: function(element) { + var tagifyStyle =3D 'position:relative'; + if (Prototype.Browser.IE) tagifyStyle +=3D ';zoom:1'; + + element =3D $(element); + $A(element.childNodes).each( function(child) { + if (child.nodeType=3D=3D3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + new Element('span', {style: tagifyStyle}).update( + character =3D=3D ' ' ? String.fromCharCode(160) : characte= r), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if (((typeof element =3D=3D 'object') || + Object.isFunction(element)) && + (element.length)) + elements =3D element; + else + elements =3D $(element).childNodes; + + var options =3D Object.extend({ + speed: 0.1, + delay: 0.0 + }, arguments[2] || { }); + var masterDelay =3D options.delay; + + $A(elements).each( function(element, index) { + new effect(element, Object.extend(options, { delay: index * option= s.speed + masterDelay })); + }); + }, + PAIRS: { + 'slide': ['SlideDown','SlideUp'], + 'blind': ['BlindDown','BlindUp'], + 'appear': ['Appear','Fade'] + }, + toggle: function(element, effect, options) { + element =3D $(element); + effect =3D (effect || 'appear').toLowerCase(); + + return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ]= (element, Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 = } + }, options || {})); + } +}; + +Effect.DefaultOptions.transition =3D Effect.Transitions.sinoidal; + +/* ------------- core effects ------------- */ + +Effect.ScopedQueue =3D Class.create(Enumerable, { + initialize: function() { + this.effects =3D []; + this.interval =3D null; + }, + _each: function(iterator) { + this.effects._each(iterator); + }, + add: function(effect) { + var timestamp =3D new Date().getTime(); + + var position =3D Object.isString(effect.options.queue) ? + effect.options.queue : effect.options.queue.position; + + switch(position) { + case 'front': + // move unstarted effects after this effect + this.effects.findAll(function(e){ return e.state=3D=3D'idle' }).= each( function(e) { + e.startOn +=3D effect.finishOn; + e.finishOn +=3D effect.finishOn; + }); + break; + case 'with-last': + timestamp =3D this.effects.pluck('startOn').max() || timestamp; + break; + case 'end': + // start effect after last queued effect has finished + timestamp =3D this.effects.pluck('finishOn').max() || timestamp; + break; + } + + effect.startOn +=3D timestamp; + effect.finishOn +=3D timestamp; + + if (!effect.options.queue.limit || (this.effects.length < effect.opt= ions.queue.limit)) + this.effects.push(effect); + + if (!this.interval) + this.interval =3D setInterval(this.loop.bind(this), 15); + }, + remove: function(effect) { + this.effects =3D this.effects.reject(function(e) { return e=3D=3Deff= ect }); + if (this.effects.length =3D=3D 0) { + clearInterval(this.interval); + this.interval =3D null; + } + }, + loop: function() { + var timePos =3D new Date().getTime(); + for(var i=3D0, len=3Dthis.effects.length;i=3D this.startOn) { + if (timePos >=3D this.finishOn) { + this.render(1.0); + this.cancel(); + this.event('beforeFinish'); + if (this.finish) this.finish(); + this.event('afterFinish'); + return; + } + var pos =3D (timePos - this.startOn) / this.totalTime, + frame =3D (pos * this.totalFrames).round(); + if (frame > this.currentFrame) { + this.render(pos); + this.currentFrame =3D frame; + } + } + }, + cancel: function() { + if (!this.options.sync) + Effect.Queues.get(Object.isString(this.options.queue) ? + 'global' : this.options.queue.scope).remove(this); + this.state =3D 'finished'; + }, + event: function(eventName) { + if (this.options[eventName + 'Internal']) this.options[eventName + '= Internal'](this); + if (this.options[eventName]) this.options[eventName](this); + }, + inspect: function() { + var data =3D $H(); + for(property in this) + if (!Object.isFunction(this[property])) data.set(property, this[pr= operty]); + return '#'; + } +}); + +Effect.Parallel =3D Class.create(Effect.Base, { + initialize: function(effects) { + this.effects =3D effects || []; + this.start(arguments[1]); + }, + update: function(position) { + this.effects.invoke('render', position); + }, + finish: function(position) { + this.effects.each( function(effect) { + effect.render(1.0); + effect.cancel(); + effect.event('beforeFinish'); + if (effect.finish) effect.finish(position); + effect.event('afterFinish'); + }); + } +}); + +Effect.Tween =3D Class.create(Effect.Base, { + initialize: function(object, from, to) { + object =3D Object.isString(object) ? $(object) : object; + var args =3D $A(arguments), method =3D args.last(), + options =3D args.length =3D=3D 5 ? args[3] : null; + this.method =3D Object.isFunction(method) ? method.bind(object) : + Object.isFunction(object[method]) ? object[method].bind(object) : + function(value) { object[method] =3D value }; + this.start(Object.extend({ from: from, to: to }, options || { })); + }, + update: function(position) { + this.method(position); + } +}); + +Effect.Event =3D Class.create(Effect.Base, { + initialize: function() { + this.start(Object.extend({ duration: 0 }, arguments[0] || { })); + }, + update: Prototype.emptyFunction +}); + +Effect.Opacity =3D Class.create(Effect.Base, { + initialize: function(element) { + this.element =3D $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + // make this work on IE on elements without 'layout' + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + var options =3D Object.extend({ + from: this.element.getOpacity() || 0.0, + to: 1.0 + }, arguments[1] || { }); + this.start(options); + }, + update: function(position) { + this.element.setOpacity(position); + } +}); + +Effect.Move =3D Class.create(Effect.Base, { + initialize: function(element) { + this.element =3D $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options =3D Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || { }); + this.start(options); + }, + setup: function() { + this.element.makePositioned(); + this.originalLeft =3D parseFloat(this.element.getStyle('left') || '0= '); + this.originalTop =3D parseFloat(this.element.getStyle('top') || '0= '); + if (this.options.mode =3D=3D 'absolute') { + this.options.x =3D this.options.x - this.originalLeft; + this.options.y =3D this.options.y - this.originalTop; + } + }, + update: function(position) { + this.element.setStyle({ + left: (this.options.x * position + this.originalLeft).round() + '= px', + top: (this.options.y * position + this.originalTop).round() + '= px' + }); + } +}); + +// for backwards compatibility +Effect.MoveBy =3D function(element, toTop, toLeft) { + return new Effect.Move(element, + Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); +}; + +Effect.Scale =3D Class.create(Effect.Base, { + initialize: function(element, percent) { + this.element =3D $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options =3D Object.extend({ + scaleX: true, + scaleY: true, + scaleContent: true, + scaleFromCenter: false, + scaleMode: 'box', // 'box' or 'contents' or { } with provid= ed values + scaleFrom: 100.0, + scaleTo: percent + }, arguments[2] || { }); + this.start(options); + }, + setup: function() { + this.restoreAfterFinish =3D this.options.restoreAfterFinish || false= ; + this.elementPositioning =3D this.element.getStyle('position'); + + this.originalStyle =3D { }; + ['top','left','width','height','fontSize'].each( function(k) { + this.originalStyle[k] =3D this.element.style[k]; + }.bind(this)); + + this.originalTop =3D this.element.offsetTop; + this.originalLeft =3D this.element.offsetLeft; + + var fontSize =3D this.element.getStyle('font-size') || '100%'; + ['em','px','%','pt'].each( function(fontSizeType) { + if (fontSize.indexOf(fontSizeType)>0) { + this.fontSize =3D parseFloat(fontSize); + this.fontSizeType =3D fontSizeType; + } + }.bind(this)); + + this.factor =3D (this.options.scaleTo - this.options.scaleFrom)/100; + + this.dims =3D null; + if (this.options.scaleMode=3D=3D'box') + this.dims =3D [this.element.offsetHeight, this.element.offsetWidth= ]; + if (/^content/.test(this.options.scaleMode)) + this.dims =3D [this.element.scrollHeight, this.element.scrollWidth= ]; + if (!this.dims) + this.dims =3D [this.options.scaleMode.originalHeight, + this.options.scaleMode.originalWidth]; + }, + update: function(position) { + var currentScale =3D (this.options.scaleFrom/100.0) + (this.factor *= position); + if (this.options.scaleContent && this.fontSize) + this.element.setStyle({fontSize: this.fontSize * currentScale + th= is.fontSizeType }); + this.setDimensions(this.dims[0] * currentScale, this.dims[1] * curre= ntScale); + }, + finish: function(position) { + if (this.restoreAfterFinish) this.element.setStyle(this.originalStyl= e); + }, + setDimensions: function(height, width) { + var d =3D { }; + if (this.options.scaleX) d.width =3D width.round() + 'px'; + if (this.options.scaleY) d.height =3D height.round() + 'px'; + if (this.options.scaleFromCenter) { + var topd =3D (height - this.dims[0])/2; + var leftd =3D (width - this.dims[1])/2; + if (this.elementPositioning =3D=3D 'absolute') { + if (this.options.scaleY) d.top =3D this.originalTop-topd + 'px'; + if (this.options.scaleX) d.left =3D this.originalLeft-leftd + 'p= x'; + } else { + if (this.options.scaleY) d.top =3D -topd + 'px'; + if (this.options.scaleX) d.left =3D -leftd + 'px'; + } + } + this.element.setStyle(d); + } +}); + +Effect.Highlight =3D Class.create(Effect.Base, { + initialize: function(element) { + this.element =3D $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options =3D Object.extend({ startcolor: '#ffff99' }, arguments[1= ] || { }); + this.start(options); + }, + setup: function() { + // Prevent executing on elements not in the layout flow + if (this.element.getStyle('display')=3D=3D'none') { this.cancel(); r= eturn; } + // Disable background image during the effect + this.oldStyle =3D { }; + if (!this.options.keepBackgroundImage) { + this.oldStyle.backgroundImage =3D this.element.getStyle('backgroun= d-image'); + this.element.setStyle({backgroundImage: 'none'}); + } + if (!this.options.endcolor) + this.options.endcolor =3D this.element.getStyle('background-color'= ).parseColor('#ffffff'); + if (!this.options.restorecolor) + this.options.restorecolor =3D this.element.getStyle('background-co= lor'); + // init color calculations + this._base =3D $R(0,2).map(function(i){ return parseInt(this.option= s.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); + this._delta =3D $R(0,2).map(function(i){ return parseInt(this.option= s.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); + }, + update: function(position) { + this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(= m,v,i){ + return m+((this._base[i]+(this._delta[i]*position)).round().toColo= rPart()); }.bind(this)) }); + }, + finish: function() { + this.element.setStyle(Object.extend(this.oldStyle, { + backgroundColor: this.options.restorecolor + })); + } +}); + +Effect.ScrollTo =3D function(element) { + var options =3D arguments[1] || { }, + scrollOffsets =3D document.viewport.getScrollOffsets(), + elementOffsets =3D $(element).cumulativeOffset(); + + if (options.offset) elementOffsets[1] +=3D options.offset; + + return new Effect.Tween(null, + scrollOffsets.top, + elementOffsets[1], + options, + function(p){ scrollTo(scrollOffsets.left, p.round()); } + ); +}; + +/* ------------- combination effects ------------- */ + +Effect.Fade =3D function(element) { + element =3D $(element); + var oldOpacity =3D element.getInlineOpacity(); + var options =3D Object.extend({ + from: element.getOpacity() || 1.0, + to: 0.0, + afterFinishInternal: function(effect) { + if (effect.options.to!=3D0) return; + effect.element.hide().setStyle({opacity: oldOpacity}); + } + }, arguments[1] || { }); + return new Effect.Opacity(element,options); +}; + +Effect.Appear =3D function(element) { + element =3D $(element); + var options =3D Object.extend({ + from: (element.getStyle('display') =3D=3D 'none' ? 0.0 : element.getOp= acity() || 0.0), + to: 1.0, + // force Safari to render floated elements properly + afterFinishInternal: function(effect) { + effect.element.forceRerendering(); + }, + beforeSetup: function(effect) { + effect.element.setOpacity(effect.options.from).show(); + }}, arguments[1] || { }); + return new Effect.Opacity(element,options); +}; + +Effect.Puff =3D function(element) { + element =3D $(element); + var oldStyle =3D { + opacity: element.getInlineOpacity(), + position: element.getStyle('position'), + top: element.style.top, + left: element.style.left, + width: element.style.width, + height: element.style.height + }; + return new Effect.Parallel( + [ new Effect.Scale(element, 200, + { sync: true, scaleFromCenter: true, scaleContent: true, restoreAf= terFinish: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], + Object.extend({ duration: 1.0, + beforeSetupInternal: function(effect) { + Position.absolutize(effect.effects[0].element); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().setStyle(oldStyle); } + }, arguments[1] || { }) + ); +}; + +Effect.BlindUp =3D function(element) { + element =3D $(element); + element.makeClipping(); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + restoreAfterFinish: true, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping(); + } + }, arguments[1] || { }) + ); +}; + +Effect.BlindDown =3D function(element) { + element =3D $(element); + var elementDimensions =3D element.getDimensions(); + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, + scaleFrom: 0, + scaleMode: {originalHeight: elementDimensions.height, originalWidth:= elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + } + }, arguments[1] || { })); +}; + +Effect.SwitchOff =3D function(element) { + element =3D $(element); + var oldOpacity =3D element.getInlineOpacity(); + return new Effect.Appear(element, Object.extend({ + duration: 0.4, + from: 0, + transition: Effect.Transitions.flicker, + afterFinishInternal: function(effect) { + new Effect.Scale(effect.element, 1, { + duration: 0.3, scaleFromCenter: true, + scaleX: false, scaleContent: false, restoreAfterFinish: true, + beforeSetup: function(effect) { + effect.element.makePositioned().makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().undoPositioned().setStyle= ({opacity: oldOpacity}); + } + }); + } + }, arguments[1] || { })); +}; + +Effect.DropOut =3D function(element) { + element =3D $(element); + var oldStyle =3D { + top: element.getStyle('top'), + left: element.getStyle('left'), + opacity: element.getInlineOpacity() }; + return new Effect.Parallel( + [ new Effect.Move(element, {x: 0, y: 100, sync: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 }) ], + Object.extend( + { duration: 0.5, + beforeSetup: function(effect) { + effect.effects[0].element.makePositioned(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().undoPositioned().setStyle(old= Style); + } + }, arguments[1] || { })); +}; + +Effect.Shake =3D function(element) { + element =3D $(element); + var options =3D Object.extend({ + distance: 20, + duration: 0.5 + }, arguments[1] || {}); + var distance =3D parseFloat(options.distance); + var split =3D parseFloat(options.duration) / 10.0; + var oldStyle =3D { + top: element.getStyle('top'), + left: element.getStyle('left') }; + return new Effect.Move(element, + { x: distance, y: 0, duration: split, afterFinishInternal: functi= on(effect) { + new Effect.Move(effect.element, + { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: f= unction(effect) { + new Effect.Move(effect.element, + { x: distance*2, y: 0, duration: split*2, afterFinishInternal: f= unction(effect) { + new Effect.Move(effect.element, + { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: f= unction(effect) { + new Effect.Move(effect.element, + { x: distance*2, y: 0, duration: split*2, afterFinishInternal: f= unction(effect) { + new Effect.Move(effect.element, + { x: -distance, y: 0, duration: split, afterFinishInternal: functi= on(effect) { + effect.element.undoPositioned().setStyle(oldStyle); + }}); }}); }}); }}); }}); }}); +}; + +Effect.SlideDown =3D function(element) { + element =3D $(element).cleanWhitespace(); + // SlideDown need to have the content of the element wrapped in a cont= ainer element with fixed height! + var oldInnerBottom =3D element.down().getStyle('bottom'); + var elementDimensions =3D element.getDimensions(); + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, + scaleFrom: window.opera ? 0 : 1, + scaleMode: {originalHeight: elementDimensions.height, originalWidth:= elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.down().makePositioned(); + if (window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, + afterUpdateInternal: function(effect) { + effect.element.down().setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping().undoPositioned(); + effect.element.down().undoPositioned().setStyle({bottom: oldInnerB= ottom}); } + }, arguments[1] || { }) + ); +}; + +Effect.SlideUp =3D function(element) { + element =3D $(element).cleanWhitespace(); + var oldInnerBottom =3D element.down().getStyle('bottom'); + var elementDimensions =3D element.getDimensions(); + return new Effect.Scale(element, window.opera ? 0 : 1, + Object.extend({ scaleContent: false, + scaleX: false, + scaleMode: 'box', + scaleFrom: 100, + scaleMode: {originalHeight: elementDimensions.height, originalWidth:= elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.down().makePositioned(); + if (window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping().show(); + }, + afterUpdateInternal: function(effect) { + effect.element.down().setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().undoPositioned(); + effect.element.down().undoPositioned().setStyle({bottom: oldInnerB= ottom}); + } + }, arguments[1] || { }) + ); +}; + +// Bug in opera makes the TD containing this element expand for a instan= ce after finish +Effect.Squish =3D function(element) { + return new Effect.Scale(element, window.opera ? 1 : 0, { + restoreAfterFinish: true, + beforeSetup: function(effect) { + effect.element.makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping(); + } + }); +}; + +Effect.Grow =3D function(element) { + element =3D $(element); + var options =3D Object.extend({ + direction: 'center', + moveTransition: Effect.Transitions.sinoidal, + scaleTransition: Effect.Transitions.sinoidal, + opacityTransition: Effect.Transitions.full + }, arguments[1] || { }); + var oldStyle =3D { + top: element.style.top, + left: element.style.left, + height: element.style.height, + width: element.style.width, + opacity: element.getInlineOpacity() }; + + var dims =3D element.getDimensions(); + var initialMoveX, initialMoveY; + var moveX, moveY; + + switch (options.direction) { + case 'top-left': + initialMoveX =3D initialMoveY =3D moveX =3D moveY =3D 0; + break; + case 'top-right': + initialMoveX =3D dims.width; + initialMoveY =3D moveY =3D 0; + moveX =3D -dims.width; + break; + case 'bottom-left': + initialMoveX =3D moveX =3D 0; + initialMoveY =3D dims.height; + moveY =3D -dims.height; + break; + case 'bottom-right': + initialMoveX =3D dims.width; + initialMoveY =3D dims.height; + moveX =3D -dims.width; + moveY =3D -dims.height; + break; + case 'center': + initialMoveX =3D dims.width / 2; + initialMoveY =3D dims.height / 2; + moveX =3D -dims.width / 2; + moveY =3D -dims.height / 2; + break; + } + + return new Effect.Move(element, { + x: initialMoveX, + y: initialMoveY, + duration: 0.01, + beforeSetup: function(effect) { + effect.element.hide().makeClipping().makePositioned(); + }, + afterFinishInternal: function(effect) { + new Effect.Parallel( + [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from= : 0.0, transition: options.opacityTransition }), + new Effect.Move(effect.element, { x: moveX, y: moveY, sync: tr= ue, transition: options.moveTransition }), + new Effect.Scale(effect.element, 100, { + scaleMode: { originalHeight: dims.height, originalWidth: dim= s.width }, + sync: true, scaleFrom: window.opera ? 1 : 0, transition: opt= ions.scaleTransition, restoreAfterFinish: true}) + ], Object.extend({ + beforeSetup: function(effect) { + effect.effects[0].element.setStyle({height: '0px'}).show(= ); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.undoClipping().undoPositioned()= .setStyle(oldStyle); + } + }, options) + ); + } + }); +}; + +Effect.Shrink =3D function(element) { + element =3D $(element); + var options =3D Object.extend({ + direction: 'center', + moveTransition: Effect.Transitions.sinoidal, + scaleTransition: Effect.Transitions.sinoidal, + opacityTransition: Effect.Transitions.none + }, arguments[1] || { }); + var oldStyle =3D { + top: element.style.top, + left: element.style.left, + height: element.style.height, + width: element.style.width, + opacity: element.getInlineOpacity() }; + + var dims =3D element.getDimensions(); + var moveX, moveY; + + switch (options.direction) { + case 'top-left': + moveX =3D moveY =3D 0; + break; + case 'top-right': + moveX =3D dims.width; + moveY =3D 0; + break; + case 'bottom-left': + moveX =3D 0; + moveY =3D dims.height; + break; + case 'bottom-right': + moveX =3D dims.width; + moveY =3D dims.height; + break; + case 'center': + moveX =3D dims.width / 2; + moveY =3D dims.height / 2; + break; + } + + return new Effect.Parallel( + [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, tran= sition: options.opacityTransition }), + new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, tran= sition: options.scaleTransition, restoreAfterFinish: true}), + new Effect.Move(element, { x: moveX, y: moveY, sync: true, transit= ion: options.moveTransition }) + ], Object.extend({ + beforeStartInternal: function(effect) { + effect.effects[0].element.makePositioned().makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().undoClipping().undoPositione= d().setStyle(oldStyle); } + }, options) + ); +}; + +Effect.Pulsate =3D function(element) { + element =3D $(element); + var options =3D arguments[1] || { }, + oldOpacity =3D element.getInlineOpacity(), + transition =3D options.transition || Effect.Transitions.linear, + reverser =3D function(pos){ + return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.= PI)/2) + .5); + }; + + return new Effect.Opacity(element, + Object.extend(Object.extend({ duration: 2.0, from: 0, + afterFinishInternal: function(effect) { effect.element.setStyle({o= pacity: oldOpacity}); } + }, options), {transition: reverser})); +}; + +Effect.Fold =3D function(element) { + element =3D $(element); + var oldStyle =3D { + top: element.style.top, + left: element.style.left, + width: element.style.width, + height: element.style.height }; + element.makeClipping(); + return new Effect.Scale(element, 5, Object.extend({ + scaleContent: false, + scaleX: false, + afterFinishInternal: function(effect) { + new Effect.Scale(element, 1, { + scaleContent: false, + scaleY: false, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().setStyle(oldStyle); + } }); + }}, arguments[1] || { })); +}; + +Effect.Morph =3D Class.create(Effect.Base, { + initialize: function(element) { + this.element =3D $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options =3D Object.extend({ + style: { } + }, arguments[1] || { }); + + if (!Object.isString(options.style)) this.style =3D $H(options.style= ); + else { + if (options.style.include(':')) + this.style =3D options.style.parseStyle(); + else { + this.element.addClassName(options.style); + this.style =3D $H(this.element.getStyles()); + this.element.removeClassName(options.style); + var css =3D this.element.getStyles(); + this.style =3D this.style.reject(function(style) { + return style.value =3D=3D css[style.key]; + }); + options.afterFinishInternal =3D function(effect) { + effect.element.addClassName(effect.options.style); + effect.transforms.each(function(transform) { + effect.element.style[transform.style] =3D ''; + }); + }; + } + } + this.start(options); + }, + + setup: function(){ + function parseColor(color){ + if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) c= olor =3D '#ffffff'; + color =3D color.parseColor(); + return $R(0,2).map(function(i){ + return parseInt( color.slice(i*2+1,i*2+3), 16 ); + }); + } + this.transforms =3D this.style.map(function(pair){ + var property =3D pair[0], value =3D pair[1], unit =3D null; + + if (value.parseColor('#zzzzzz') !=3D '#zzzzzz') { + value =3D value.parseColor(); + unit =3D 'color'; + } else if (property =3D=3D 'opacity') { + value =3D parseFloat(value); + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayou= t)) + this.element.setStyle({zoom: 1}); + } else if (Element.CSS_LENGTH.test(value)) { + var components =3D value.match(/^([\+\-]?[0-9\.]+)(.*)$/); + value =3D parseFloat(components[1]); + unit =3D (components.length =3D=3D 3) ? components[2] : null; + } + + var originalValue =3D this.element.getStyle(property); + return { + style: property.camelize(), + originalValue: unit=3D=3D'color' ? parseColor(originalValue) : p= arseFloat(originalValue || 0), + targetValue: unit=3D=3D'color' ? parseColor(value) : value, + unit: unit + }; + }.bind(this)).reject(function(transform){ + return ( + (transform.originalValue =3D=3D transform.targetValue) || + ( + transform.unit !=3D 'color' && + (isNaN(transform.originalValue) || isNaN(transform.targetValue= )) + ) + ); + }); + }, + update: function(position) { + var style =3D { }, transform, i =3D this.transforms.length; + while(i--) + style[(transform =3D this.transforms[i]).style] =3D + transform.unit=3D=3D'color' ? '#'+ + (Math.round(transform.originalValue[0]+ + (transform.targetValue[0]-transform.originalValue[0])*positi= on)).toColorPart() + + (Math.round(transform.originalValue[1]+ + (transform.targetValue[1]-transform.originalValue[1])*positi= on)).toColorPart() + + (Math.round(transform.originalValue[2]+ + (transform.targetValue[2]-transform.originalValue[2])*positi= on)).toColorPart() : + (transform.originalValue + + (transform.targetValue - transform.originalValue) * position).= toFixed(3) + + (transform.unit =3D=3D=3D null ? '' : transform.unit); + this.element.setStyle(style, true); + } +}); + +Effect.Transform =3D Class.create({ + initialize: function(tracks){ + this.tracks =3D []; + this.options =3D arguments[1] || { }; + this.addTracks(tracks); + }, + addTracks: function(tracks){ + tracks.each(function(track){ + track =3D $H(track); + var data =3D track.values().first(); + this.tracks.push($H({ + ids: track.keys().first(), + effect: Effect.Morph, + options: { style: data } + })); + }.bind(this)); + return this; + }, + play: function(){ + return new Effect.Parallel( + this.tracks.map(function(track){ + var ids =3D track.get('ids'), effect =3D track.get('effect'), op= tions =3D track.get('options'); + var elements =3D [$(ids) || $$(ids)].flatten(); + return elements.map(function(e){ return new effect(e, Object.ext= end({ sync:true }, options)) }); + }).flatten(), + this.options + ); + } +}); + +Element.CSS_PROPERTIES =3D $w( + 'backgroundColor backgroundPosition borderBottomColor borderBottomStyl= e ' + + 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + + 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + + 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + + 'fontSize fontWeight height left letterSpacing lineHeight ' + + 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight = '+ + 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + + 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + + 'right textIndent top width wordSpacing zIndex'); + +Element.CSS_LENGTH =3D /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))= |0$/; + +String.__parseStyleElement =3D document.createElement('div'); +String.prototype.parseStyle =3D function(){ + var style, styleRules =3D $H(); + if (Prototype.Browser.WebKit) + style =3D new Element('div',{style:this}).style; + else { + String.__parseStyleElement.innerHTML =3D '
    0) { + updates.each(function(id_or_el) { + var el =3D $(id_or_el) + if (el) { // ignore update of parts that do not exist + var partDomId =3D el.id + if (!hoboParts[partDomId]) { throw "Update of dom-id= that is not a part: " + partDomId } + params.push("render["+i+"][part_context]=3D" + encod= eURIComponent(hoboParts[partDomId])) + params.push("render["+i+"][id]=3D" + partDomId) + i +=3D 1 + } + }) + params.push("page_path=3D" + encodeURIComponent(hoboPagePath= )) + } + + if (resultUpdates) { + resultUpdates.each(function (resultUpdate) { + params.push("render["+i+"][id]=3D" + resultUpdate.id) + params.push("render["+i+"][result]=3D" + resultUpdate.re= sult) + if (resultUpdate.func) { + params.push("render["+i+"][function]=3D" + resultUpd= ate.func) + } + i +=3D 1 + }) + } + return params.join('&') + }, + + ajaxRequest: function(url_or_form, updates, options) { + options =3D Object.merge({ asynchronous:true, + evalScripts:true, + resetForm: false, + refocusForm: false, + message: "Saving..." + }, options) + if (typeof url_or_form =3D=3D "string") { + var url =3D url_or_form + var form =3D false + } else { + var form =3D url_or_form + var url =3D form.action + } + var params =3D [] + + if (typeof(formAuthToken) !=3D "undefined") { + params.push(formAuthToken.name + "=3D" + formAuthToken.value= ) + } + + updateParams =3D Hobo.ajaxUpdateParams(updates, options.resultUp= date) + if (updateParams !=3D "") { params.push(updateParams) } + + if (options.params) { + params.push(options.params) + delete options.params + } + + if (form) { + params.push(Form.serialize(form)) + } + + if (options.message !=3D false) Hobo.showSpinner(options.message= , options.spinnerNextTo) + + var complete =3D function() { + if (options.message !=3D false) Hobo.hideSpinner(); + if (options.onComplete) options.onComplete.apply(this, argum= ents) + if (form && options.refocusForm) Form.focusFirstElement(form= ) + Event.addBehavior.reload() + } + var success =3D function() { + if (options.onSuccess) options.onSuccess.apply(this, argumen= ts) + if (form && options.resetForm) form.reset(); + } + if (options.method && options.method.toLowerCase() =3D=3D "put")= { + delete options.method + params.push("_method=3DPUT") + } + + if (!options.onFailure) { + options.onFailure =3D function(response) { + alert(response.responseText) + } + } + + new Ajax.Request(url, Object.merge(options, { parameters: params= .join("&"), onComplete: complete, onSuccess: success })) + }, + + hide: function() { + for (i =3D 0; i < arguments.length; i++) { + if ($(arguments[i])) { + Element.addClassName(arguments[i], 'hidden') + } + } + }, + + show: function() { + for (i =3D 0; i < arguments.length; i++) { + if ($(arguments[i])) { + Element.removeClassName(arguments[i], 'hidden') + } + } + }, + + toggle: function() { + for (i =3D 0; i < arguments.length; i++) { + if ($(arguments[i])) { + if(Element.hasClassName(arguments[i], 'hidden')) { + Element.removeClassName(arguments[i], 'hidden') + } else { + Element.addClassName(arguments[i], 'hidden') + } + } + } + }, + + onFieldEditComplete: function(el, newValue) { + el =3D $(el) + var oldValue =3D Hobo.ipeOldValues[el.id] + delete Hobo.ipeOldValues[el.id] + + var blank =3D el.getAttribute("hobo-blank-message") + if (blank && newValue.strip().length =3D=3D 0) { + el.update(blank) + } else { + el.update(newValue) + } + + var modelId =3D Hobo.getModelId(el) + if (oldValue) { + $$(".model:" + modelId).each(function(e) { + if (e !=3D el && e.innerHTML =3D=3D oldValue) e.update(n= ewValue) + }) + } + }, + + _makeInPlaceEditor: function(el, options) { + var old + var updates =3D Hobo.updatesForElement(el) + var id =3D el.id + if (!id) { id =3D el.id =3D Hobo.uid() } + var updateParams =3D Hobo.ajaxUpdateParams(updates, [{id: id, + result: 'new= _field_value', + func: "Hobo.= onFieldEditComplete"}]) + var opts =3D {okButton: false, + cancelLink: false, + submitOnBlur: true, + evalScripts: true, + htmlResponse: false, + ajaxOptions: { method: "put" }, + onEnterHover: null, + onLeaveHover: null, + callback: function(form, val) { + old =3D val + el.setAttribute("hobo-edit-text", val) + return (Hobo.fieldSetParam(el, val) + "&" + upda= teParams) + }, + onFailure: function(_, resp) { + alert(resp.responseText); el.innerHTML =3D old + }, + onEnterEditMode: function() { + var blank_message =3D el.getAttribute("hobo-blan= k-message") + var editable_text =3D el.getAttribute("hobo-edit= -text") + if (editable_text) { + el.innerHTML =3D editable_text + } + if (el.innerHTML.gsub(" ", " ") =3D=3D blan= k_message) { + el.innerHTML =3D "" + } else { + Hobo.ipeOldValues[el.id] =3D el.innerHTML + } + } + } + Object.extend(opts, options) + return new Ajax.InPlaceEditor(el, Hobo.putUrl(el), opts) + }, + + + doSearch: function(el) { + el =3D $(el) + var spinner =3D $(el.getAttribute("search-spinner") || "search-s= pinner") + var search_results =3D $(el.getAttribute("search-results") || "s= earch-results") + var search_results_panel =3D $(el.getAttribute("search-results-p= anel") || "search-results-panel") + var url =3D el.getAttribute("search-url") || (urlBase + "/search= ") + + var clear =3D function() { Hobo.hide(search_results_panel); el.c= lear() } + + // Close window on [Escape] + Event.observe(el, 'keypress', function(ev) { + if (ev.keyCode =3D=3D 27) clear() + }); + + Event.observe(search_results_panel.down('.close-button'), 'click= ', clear) + + var value =3D $F(el) + if (Hobo.searchRequest) { Hobo.searchRequest.transport.abort() } + if (value.length >=3D 3) { + if (spinner) Hobo.show(spinner); + Hobo.searchRequest =3D new Ajax.Updater(search_results, + url, + { asynchronous:true, + evalScripts:true, + onSuccess:function(r= equest) { + if (spinner) Hob= o.hide(spinner) + if (search_resul= ts_panel) { + Hobo.show(se= arch_results_panel) + } + }, + method: "get", + parameters:"query=3D= " + value }); + } else { + Hobo.updateElement(search_results, '') + Hobo.hide(search_results_panel) + } + }, + + + putUrl: function(el) { + var spec =3D Hobo.modelSpecForElement(el) + return urlBase + "/" + Hobo.pluralise(spec.name) + "/" + spec.id= + "?_method=3DPUT" + }, + + + urlForId: function(id) { + var spec =3D Hobo.parseModelSpec(id) + var url =3D urlBase + "/" + Hobo.pluralise(spec.name) + if (spec.id) { url +=3D "/" + spec.id } + return url + }, + + + fieldSetParam: function(el, val) { + var spec =3D Hobo.modelSpecForElement(el) + var res =3D spec.name + '[' + spec.field + ']=3D' + encodeURICom= ponent(val) + if (typeof(formAuthToken) !=3D "undefined") { + res =3D res + "&" + formAuthToken.name + "=3D" + formAuthTok= en.value + } + return res + }, + + + fadeObjectElement: function(el) { + var fadeEl =3D Hobo.objectElementFor(el) + new Effect.Fade(fadeEl, { duration: 0.5, afterFinish: function (= ef) { + ef.element.remove() + } }); + Hobo.showEmptyMessageAfterLastRemove(fadeEl) + }, + + + removeButton: function(el, url, updates, options) { + if (options.fade =3D=3D null) { options.fade =3D true; } + if (options.confirm =3D=3D null) { options.confirm =3D "Are you = sure?"; } + + if (options.confirm =3D=3D false || confirm(options.confirm)) { + var objEl =3D Hobo.objectElementFor(el) + Hobo.showSpinner('Removing'); + function complete() { + if (options.fade) { Hobo.fadeObjectElement(objEl) } + Hobo.hideSpinner() + } + if (updates && updates.length > 0) { + new Hobo.ajaxRequest(url, updates, { method:'delete', me= ssage: "Removing...", onComplete: complete}); + } else { + var ajaxOptions =3D {asynchronous:true, evalScripts:true= , method:'delete', onComplete: complete} + if (typeof(formAuthToken) !=3D "undefined") { + ajaxOptions.parameters =3D formAuthToken.name + "=3D= " + formAuthToken.value + } + new Ajax.Request(url, ajaxOptions); + } + } + }, + + + ajaxUpdateField: function(element, field, value, updates) { + var objectElement =3D Hobo.objectElementFor(element) + var url =3D Hobo.putUrl(objectElement) + var spec =3D Hobo.modelSpecForElement(objectElement) + var params =3D spec.name + '[' + field + ']=3D' + encodeURICompo= nent(value) + new Hobo.ajaxRequest(url, updates, { method:'put', message: "Sav= ing...", params: params }); + }, + + + showEmptyMessageAfterLastRemove: function(el) { + var empty + var container =3D $(el.parentNode) + if (container.getElementsByTagName(el.nodeName).length =3D=3D 1 = && + (empty =3D container.next('.empty-collection-message'))) { + new Effect.Appear(empty, {delay:0.3}) + } + }, + + + getClassData: function(el, name) { + var match =3D el.className.match(new RegExp("(^| )" + name + "::= (\\S+)($| )")) + return match && match[2] + }, + + + getModelId: function(el) { + return Hobo.getClassData(el, 'model') + }, + + + modelSpecForElement: function(el) { + var id =3D Hobo.getModelId(el) + return id && Hobo.parseModelSpec(id) + }, + + + parseModelSpec: function(id) { + m =3D id.gsub('-', '_').match(/^([^:]+)(?::([^:]+)(?::([^:]+))?)= ?$/) + if (m) return { name: m[1], id: m[2], field: m[3] } + }, + + + objectElementFor: function(el) { + var m + while(el.getAttribute) { + id =3D Hobo.getModelId(el) + if (id) m =3D id.match(/^[^:]+:[^:]+$/); + if (m) break; + el =3D el.parentNode; + } + if (m) return el; + }, + + modelIdFor: function(el) { + var e =3D Hobo.objectElementFor(el) + return e && Hobo.getModelId(e) + }, + + + showSpinner: function(message, nextTo) { + clearTimeout(Hobo.spinnerTimer) + Hobo.spinnerHideAt =3D new Date().getTime() + Hobo.spinnerMinTim= e; + if (t =3D $('ajax-progress-text')) { + if (!message || message.length =3D=3D 0) { + t.hide() + } else { + Element.update(t, message); + t.show() + } + } + if (e =3D $('ajax-progress')) { + if (nextTo) { + var e_nextTo =3D $(nextTo); + var pos =3D e_nextTo.cumulativeOffset() + e.style.top =3D pos.top - e_nextTo.offsetHeight + "px" + e.style.left =3D (pos.left + e_nextTo.offsetWidth + 5) += "px" + } + e.style.display =3D "block"; + } + }, + + + hideSpinner: function() { + if (e =3D $('ajax-progress')) { + var remainingTime =3D Hobo.spinnerHideAt - new Date().getTim= e() + if (remainingTime <=3D 0) { + e.visualEffect('Fade') + } else { + Hobo.spinnerTimer =3D setTimeout(function () { e.visualE= ffect('Fade') }, remainingTime) + } + } + }, + + + updateElement: function(id, content) { + Element.update(id, content) + Element.fire($(id), "rapid:partupdated") + }, + + getStyle: function(el, styleProp) { + if (el.currentStyle) + var y =3D el.currentStyle[styleProp]; + else if (window.getComputedStyle) + var y =3D document.defaultView.getComputedStyle(el, null).ge= tPropertyValue(styleProp); + return y; + }, + + partFor: function(el) { + while (el) { + if (el.id && hoboParts[el.id]) { return el } + el =3D el.parentNode + } + return null + }, + + pluralise: function(s) { + return pluralisations[s] || s + "s" + }, + + addUrlParams: function(params, options) { + params =3D $H(window.location.search.toQueryParams()).merge(para= ms) + + if (options.remove) { + var remove =3D (options.remove instanceof Array) ? options.r= emove : [options.remove] + remove.each(function(k) { params.unset(k) }) + } + + return window.location.href.sub(/(\?.*|$)/, "?" + params.toQuery= String()) + }, + + + fixSectionGroup: function(e) { + rows =3D e.childElements().map(function(e, i) { + cells =3D e.childElements().map(function(e, i) { + return e.outerHTML.sub("$/i, "") + }).join('') + + var attrs =3D e.outerHTML.match(/]+)/)[1] + return "" + cells + "" + }).join("\n") + + var attrs =3D e.outerHTML.match(/]+)/)[1] + + var table=3D "" = + + rows + "
    " + e.outerHTML =3D table + }, + + makeHtmlEditor: function(textarea) { + // do nothing - plugins can overwrite this method + } + + +} + +Element.findContaining =3D function(el, tag) { + el =3D $(el) + tag =3D tag.toLowerCase() + e =3D el.parentNode + while (el) { + if (el.nodeName.toLowerCase() =3D=3D tag) { + return el; + } + e =3D el.parentNode + } + return null; +} + +Element.Methods.childWithClass =3D function(el, klass) { + var ret=3Dnull; + el.childElements().each(function(el2) { + if(ret=3D=3Dnull && el2.hasClassName(klass)) ret=3Del2; + }); + return ret; +} + +// Add an afterEnterEditMode hook to in-place-editor +origEnterEditMode =3D Ajax.InPlaceEditor.prototype.enterEditMode +Ajax.InPlaceEditor.prototype.enterEditMode =3D function(evt) { + origEnterEditMode.bind(this)(evt) + if (this.afterEnterEditMode) this.afterEnterEditMode() + return false +} + +// Fix Safari in-place-editor bug +Ajax.InPlaceEditor.prototype.removeForm =3D function() { + if (!this._form) return; + + if (this._form.parentNode) { try { Element.remove(this._form); } cat= ch (e) {}} + this._form =3D null; + this._controls =3D { }; +} + +// Silence errors from IE :-( +Field.scrollFreeActivate =3D function(field) { + setTimeout(function() { + try { + Field.activate(field); + } catch(e) {} + }, 1); +} + + +Element.Methods.$$ =3D function(e, css) { + return new Selector(css).findElements(e) +} + + +HoboBehavior =3D Class.create({ + + initialize: function(mainSelector, features) { + this.mainSelector =3D mainSelector + this.features =3D features + this.addEvents(mainSelector, features.events) + if (features.initialize) { + document.observe("dom:loaded", features.initialize); + } + }, + + addEvents: function(parentSelector, events) { + var self =3D this + + for (selector in events) { + fullSelector =3D parentSelector + ' ' + selector + var rhs =3D events[selector] + if (Object.isString(rhs)) { + this.addBehavior(fullSelector, this.features[rhs]) + } else { + this.addEvents(fullSelector, rhs) + } + } + + }, + + addBehavior: function(selector, handler) { + var self =3D this + behavior =3D {} + behavior[selector] =3D function(ev) { + self.features.element =3D this.up(self.mainSelector) + handler.call(self.features, ev, this) + } + Event.addBehavior(behavior) + } + +}) + + +HoboInputMany =3D { + + events: { + "> li > div.buttons": { + ".add-item:click": 'addOne', + ".remove-item:click": 'removeOne' + } + }, + + initialize: function(ev) { + /* the second clause should be sufficient, but it isn't in IE7. S= ee bug 603 */ + Element.select(ev.target, ".input-many-template input:hidden, .inp= ut-many-template select:hidden, .input-many-template textarea:hidden, .in= put-many-template button:hidden").each(function(input) { + if(!input.disabled) { + input.disabled =3D true; + input.addClassName("input_many_template_input"); + } + }); + + // disable all elements inside our template, and mark them so we c= an find them later. + Element.select(ev.target, ".input-many-template input:enabled, .in= put-many-template select:enabled, .input-many-template textarea:enabled, = .input-many-template button:enabled").each(function(input) { + input.disabled =3D true; + input.addClassName("input_many_template_input"); + }); + + Element.select(ev.target, ".sortable-input-many").each(function(el= ) { + HoboInputMany.createSortable.call(el); + }); + + /* need to reinitialize after every change */ + Event.addBehavior({".sortable-input-many:rapid:change": function(e= v) { + HoboInputMany.createSortable.call(this); + }}); + + document.observe("rapid:partupdated", HoboInputMany.initialize); + }, + + createSortable: function() { + Sortable.create(this.id, { + constraint: 'vertical', + handle: 'ordering-handle', + overlap: 'vertical', + scroll: 'window', + onUpdate: function(list) { + HoboInputMany.fixIndices.call(list); + } + }); + }, + + // given this=3D=3Dthe input-many, returns a lambda that updates the= name & id for an element + getNameUpdater: function(new_index) { + var name_prefix =3D Hobo.getClassData(this, 'input-many-prefix'); + var id_prefix =3D name_prefix.replace(/\[/g, "_").replace(/\]/g, "= "); + var name_re =3D RegExp("^" + RegExp.escape(name_prefix)+ "\[\-?[0-= 9]+\]"); + var name_sub =3D name_prefix + '[' + new_index.toString() + ']'; + var id_re =3D RegExp("^" + RegExp.escape(id_prefix)+ "_\-?[0-9]+")= ; + var id_sub =3D id_prefix + '_' + new_index.toString(); + var class_re =3D RegExp(RegExp.escape(name_prefix)+ "\[\-?[0-9]+\]= "); + var class_sub =3D name_sub; + + return function() { + if(this.name) { + this.name =3D this.name.replace(name_re, name_sub); + } + if (id_prefix=3D=3Dthis.id.slice(0, id_prefix.length)) { + this.id =3D this.id.replace(id_re, id_sub); + } else { + // silly rails. text_area_tag and text_field_tag use diff= erent conventions for the id. + if(name_prefix=3D=3Dthis.id.slice(0, name_prefix.length)) = { + this.id =3D this.id.replace(name_re, name_sub); + } /* else { + hjq.util.log("hjq.input_many.update_id: id_p= refix "+id_prefix+" didn't match input "+this.id); + } */ + } + if (class_re.test(this.className)) { + this.className =3D this.className.replace(class_re, class_= sub); + } + return this; + }; + }, + + // given this=3D=3Dan input-many item, get the submit index + getIndex: function() { + return Number(this.id.match(/_([-0-9]+)$/)[1]); + }, + + /* For some reason, select() and down() and all those useful functio= ns aren't working for us. Roll our own replacement. + + this: element to recurse on. + klass: class to filter on + f: function to invoke + */ + recurse_elements_with_class: function(klass,f ) { + if(klass=3D=3Dnull || this.hasClassName(klass)) { + f(this); + } + this.childElements().each(function(el2) {HoboInputMany.recurse_ele= ments_with_class.call(el2, klass, f);}); + }, + +/* fixes the indices on an input-many so they're in order. */ + fixIndices: function() { + var lis =3D this.immediateDescendants(); + var minimum =3D parseInt(Hobo.getClassData(this, 'minimum')); + /* first two lis are hidden/disabled on an input-many */ + for(var i=3D0; i=3D0 && ul.immediateDescendants().length>2= ) { + /* if(console) console.log("IE7 messed up again (bug 605)"); *= / + return; + } + + var template =3D ul.down("li.input-many-template"); + var clone =3D $(template.cloneNode(true)); + clone.removeClassName("input-many-template"); + // length-2 because ignore the template li and the empty li + var name_updater =3D this.getNameUpdater.call(ul, ul.childElements= ().length-2); + + function reenable_inputs(el) { + if(el.hasClassName("input_many_template_input")) { + el.disabled =3D false; + el.removeClassName("input_many_template_input"); + } + el.childElements().each(function(el2) { + if(!el2.hasClassName("input-many-template")) reenable_inpu= ts(el2); + }); + } + reenable_inputs(clone); + + // update id & name + HoboInputMany.recurse_elements_with_class.call(clone, null, functi= on(el) { + name_updater.call(el); + }); + + // do the add with anim + clone.setStyle("display", "none") + li.insert({after: clone}); + new Effect.BlindDown(clone, {duration: 0.3, afterFinish: function(= ef) { + Event.addBehavior.reload(); + + ul.fire("rapid:add", { element: clone }); + ul.fire("rapid:change", { element: clone }); + }}); + + // visibility + if(li.hasClassName("empty")) { + li.addClassName("hidden"); + li.childWithClass("empty-input").disabled =3D true; + } else { + // now that we've added an element after us, we should only ha= ve a '-' button + li.childWithClass("buttons").childWithClass("remove-item").rem= oveClassName("hidden"); + li.childWithClass("buttons").childWithClass("add-item").addCla= ssName("hidden"); + } + + return; + }, + + removeOne: function(ev, el) { + Event.stop(ev); + var that =3D this; + var ul =3D el.up('ul.input-many'), li =3D el.up('li.input-many-li'= ) + var minimum =3D parseInt(Hobo.getClassData(ul, 'minimum')); + + if(li.id.search(/_-1$/)>=3D0) { + /* if(console) console.log("IE7 messed up again (bug 605)"); *= / + return; + } + + if(ul.fire("rapid:remove", { element: li }).stopped) return; + + // rename everybody from me onwards + var i=3Dthis.getIndex.call(li) + var n=3Dli.next(); + for(; n; i+=3D1, n=3Dn.next()) { + var name_updater =3D this.getNameUpdater.call(ul, i); + HoboInputMany.recurse_elements_with_class.call(n, null, functi= on(el) {name_updater.call(el);}); + } + + // adjust +/- buttons on the button element as appropriate + var last=3Dul.childElements()[ul.childElements().length-1]; + if(last=3D=3Dli) { + last =3D last.previous(); + } + + if(last.hasClassName("empty")) { + last.removeClassName("hidden"); + HoboInputMany.recurse_elements_with_class.call(last, "empty-in= put", function(el) {el.disabled=3Dfalse;}); + } else { + // if we've reached the minimum, we don't want to add the '-' = button + if(ul.childElements().length-3 <=3D minimum||0) { + last.childWithClass("buttons").childWithClass("remove-item= ").addClassName("hidden"); + } else { + last.childWithClass("buttons").childWithClass("remove-item= ").removeClassName("hidden"); + } + last.childWithClass("buttons").childWithClass("add-item").remo= veClassName("hidden"); + } + + new Effect.BlindUp(li, { duration: 0.3, afterFinish: function (ef)= { + ul.fire("rapid:change") + li.remove() + } }); + + } + + + +} + +new HoboBehavior("ul.input-many", HoboInputMany); + + +SelectManyInput =3D Behavior.create({ + + initialize : function() { + // onchange doesn't bubble in IE6 so... + Event.observe(this.element.down('select'), 'change', this.addOne= .bind(this)) + }, + + addOne : function() { + var select =3D this.element.down('select') + var selected =3D select.options[select.selectedIndex] + if ($F(select) !=3D "") { + var newItem =3D $(DOM.Builder.fromHTML(this.element.down('.i= tem-proto').innerHTML.strip())) + this.element.down('.items').appendChild(newItem); + newItem.down('span').innerHTML =3D selected.innerHTML + this.itemAdded(newItem, selected) + var optgroup =3D new Element("optgroup", {alt:selected.value= , label:selected.text}) + optgroup.addClassName("disabled-option") + selected.replace(optgroup) + select.value =3D "" + Event.addBehavior.reload() + this.element.fire("rapid:add", { element: newItem }) + this.element.fire("rapid:change", { element: newItem }) + } + }, + + onclick : function(ev) { + var el =3D Event.element(ev); + if (el.match(".remove-item")) { this.removeOne(el.parentNode) } + }, + + removeOne : function(el) { + var element =3D this.element + new Effect.BlindUp(el, + { duration: 0.3, + afterFinish: function (ef) { + ef.element.remove() + element.fire("rapid:remove", { element:= el }) + element.fire("rapid:change", { element:= el }) + } } ) + var label =3D el.down('span').innerHTML + var optgroup =3D element.down("optgroup[label=3D"+label+"]") + var option =3D new Element("option", {value:optgroup.readAttribu= te("alt")}) + option.innerHTML =3D optgroup.readAttribute("label") + optgroup.replace(option) + }, + + itemAdded: function(item, option) { + this.hiddenField(item).value =3D option.value + }, + + hiddenField: function(item) { + return item.down('input[type=3Dhidden]') + //return item.getElementsByClassName("hidden-field")[0] + } + + +}) + +NameManyInput =3D Object.extend(SelectManyInput, { + addOne : function() { + var select =3D this.element.down('select') + var selected =3D select.options[select.selectedIndex] + if (selected.value !=3D "") { + var newItem =3D $(DOM.Builder.fromHTML(this.element.down('.i= tem-proto').innerHTML.strip())) + this.element.down('.items').appendChild(newItem); + newItem.down('span').innerHTML =3D selected.innerHTML + this.itemAdded(newItem, selected) + selected.disabled =3D true + select.value =3D "" + Event.addBehavior.reload() + } + } +}) + + +AutocompleteBehavior =3D Behavior.create({ + initialize : function() { + this.minChars =3D parseInt(Hobo.getClassData(this.element, "min= -chars")); + var match =3D this.element.className.match(/complete-on::([\= S]+)/) + var target =3D match[1].split('::') + var typedId =3D target[0] + var completer =3D target[1] + + var spec =3D Hobo.parseModelSpec(typedId) + var url =3D urlBase + "/" + Hobo.pluralise(spec.name) + "/compl= ete_" + completer + var parameters =3D spec.id ? "id=3D" + spec.id : "" + this.autocompleter =3D new Ajax.Autocompleter(this.element, + this.element.next('.completions-popup'), + url, + {paramName:'query', method:'get', parameters: parameters, mi= nChars: this.minChars, + afterUpdateElement: this.afterUpdateElement}); + }, + + onfocus: function() { + if(this.element.hasClassName("nil-value")) { + this.element.value =3D ''; + this.element.removeClassName("nil-value"); + } + if(this.minChars=3D=3D0) { + this.autocompleter.activate(); + } + }, + + afterUpdateElement: function(input, li) { + input.fire("rapid:autocomplete-assigned"); + } + +}) + + + +Event.addBehavior.reassignAfterAjax =3D true; +Event.addBehavior({ + + 'div.section-group' : function() { + if (Prototype.Browser.IE) Hobo.fixSectionGroup(this); + }, + + 'div.select-many.input' : SelectManyInput(), + + 'textarea.html' : function() { + Hobo.makeHtmlEditor(this) + }, + + 'form.filter-menu select:change': function(event) { + var paramName =3D this.getAttribute('name') + var params =3D {} + var remove =3D [ 'page' ] + if ($F(this) =3D=3D '') { + remove.push(paramName) + } else { + params[paramName] =3D $F(this) + } + location.href =3D Hobo.addUrlParams(params, {remove: remove}) + }, + + '.autocompleter' : AutocompleteBehavior(), + + '.string.in-place-edit, .datetime.in-place-edit, .date.in-place-edit= , .integer.in-place-edit, .float.in-place-edit, .decimal.in-place-edit' : + function (ev) { + + var ipe =3D Hobo._makeInPlaceEditor(this) + ipe.getText =3D function() { + return this.element.innerHTML.gsub(//, "\n").unes= capeHTML() + } + }, + + '.text.in-place-edit, .markdown.in-place-edit, .textile.in-place-edi= t' : function (ev) { + var ipe =3D Hobo._makeInPlaceEditor(this, {rows: 2}) + ipe.getText =3D function() { + return this.element.innerHTML.gsub(//, "\n").unesc= apeHTML() + } + }, + + ".html.in-place-edit" : function (ev) { + if (Hobo.makeInPlaceHtmlEditor) { + Hobo.makeInPlaceHtmlEditor(this) + } else { + var options =3D { + rows: 2, handleLineBreaks: false, okButton: true, cancel= Link: true, okText: "Save", submitOnBlur: false + } + var ipe =3D Hobo._makeInPlaceEditor(this, options) + ipe.getText =3D function() { + // Be careful! we're not calling unescapeHTML() here! + return this.element.innerHTML + } + } + }, + + "select.integer.editor" : function(e) { + var el =3D this + el.onchange =3D function() { + Hobo.ajaxSetFieldForElement(el, $F(el)) + } + }, + + "input.live-search[type=3Dsearch]" : function(e) { + var element =3D this + new Form.Element.Observer(element, 1.0, function() { Hobo.doSear= ch(element) }) + } + + +}); + +ElementSet =3D Class.create(Enumerable, { + + initialize: function(array) { + this.items =3D array + }, + + _each: function(fn) { + return this.items.each(fn) + }, + + selectChildren: function(selector) { + return new ElementSet(this.items.invoke('selectChildren', select= or).pluck('items').flatten()) + }, + + child: function(selector) { + return this.selectChildren(selector).first() + }, + + select: function(selector) { + return new ElementSet(this.items.invoke('select', selector).flat= ten()) + }, + + down: function(selector) { + for (var i =3D 0; i < this.items.length; i++) { + var match =3D this.items[i].down(selector) + if (match) return match + } + return null + }, + + size: function() { + return this.items.length + }, + + first: function() { + return this.items.first() + }, + + last: function() { + return this.items.last() + } + +}) + +Element.addMethods({ + selectChildren: function(element, selector) { + return new ElementSet(Selector.matchElements(element.childElemen= ts(), selector)) + } +}) diff --git a/site/public/javascripts/ie7-recalc.js b/site/public/javascri= pts/ie7-recalc.js new file mode 100644 index 0000000..91e6417 --- /dev/null +++ b/site/public/javascripts/ie7-recalc.js @@ -0,0 +1,166 @@ + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// ie7-recalc.js +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +(function() { + /* -------------------------------------------------------------------= -- + + This allows refreshing of IE7 style rules. If you modify the DOM + you can update IE7 by calling document.recalc(). + + This should be the LAST module included. + + --------------------------------------------------------------------- = */ + + if (!IE7.loaded) return; + + // remove all IE7 classes from an element + CLASSES =3D /\sie7_class\d+/g; + + IE7.CSS.extend({ + // store for elements that have style properties calculated + elements: {}, + handlers: [], + + // clear IE7 classes and styles + reset: function() { + this.removeEventHandlers(); + // reset IE7 classes here + var elements =3D this.elements; + for (var i in elements) elements[i].runtimeStyle.cssText =3D ""; + this.elements =3D {}; + // reset runtimeStyle here + var elements =3D IE7.Rule.elements; + for (var i in elements) { + with (elements[i]) className =3D className.replace(CLASSES, ""); + } + IE7.Rule.elements =3D {}; + }, + + reload: function() { + this.rules =3D []; + this.getInlineStyles(); + this.screen.load(); + if (this.print) this.print.load(); + this.refresh(); + this.trash(); + }, + + addRecalc: function(propertyName, test, handler, replacement) { + // call the ancestor method to add a wrapped recalc method + this.base(propertyName, test, function(element) { + // execute the original recalc method + handler(element); + // store a reference to this element so we can clear its style l= ater + IE7.CSS.elements[element.uniqueID] =3D element; + }, replacement); + }, + + recalc: function() { + // clear IE7 styles and classes + this.reset(); + // execute the ancestor method to perform recalculations + this.base(); + }, + + addEventHandler: function(element, type, handler) { + element.attachEvent(type, handler); + // store the handler so it can be detached later + this.handlers.push(arguments); + }, + + removeEventHandlers: function() { + var handler; + while (handler =3D this.handlers.pop()) { + handler[0].detachEvent(handler[1], handler[2]); + } + }, + + getInlineStyles: function() { + // load inline styles + var styleSheets =3D document.getElementsByTagName("style"), styleS= heet; + for (var i =3D styleSheets.length - 1; (styleSheet =3D styleSheets= [i]); i--) { + if (!styleSheet.disabled && !styleSheet.ie7) { + var cssText =3D styleSheet.cssText || styleSheet.innerHTML; + this.styles.push(cssText); + styleSheet.cssText =3D cssText; + } + } + }, + + trash: function() { + // trash the old style sheets + var styleSheets =3D document.styleSheets, styleSheet, i; + for (i =3D 0; i < styleSheets.length; i++) { + styleSheet =3D styleSheets[i]; + if (!styleSheet.ie7 && !styleSheet.cssText && styleSheet.cssText= !=3D '') { + styleSheet.cssText =3D styleSheet.cssText; + } + } + this.base(); + }, + + getText: function(styleSheet) { + return styleSheet.cssText || this.base(styleSheet); + } + }); + + // remove event handlers (they eat memory) + IE7.CSS.addEventHandler(window, "onunload", function() { + IE7.CSS.removeEventHandlers(); + }); + + // store all elements with an IE7 class assigned + IE7.Rule.elements =3D {}; + + IE7.Rule.prototype.extend({ + add: function(element) { + // execute the ancestor "add" method + this.base(element); + // store a reference to this element so we can clear its classes l= ater + IE7.Rule.elements[element.uniqueID] =3D element; + } + }); + + // store created pseudo elements + if (IE7.PseudoElement) { + IE7.PseudoElement.hash =3D {}; + + IE7.PseudoElement.prototype.extend({ + create: function(target) { + var key =3D this.selector + ":" + target.uniqueID; + if (!IE7.PseudoElement.hash[key]) { + IE7.PseudoElement.hash[key] =3D true; + this.base(target); + } + } + }); + } + + IE7.HTML.extend({ + elements: {}, + + addRecalc: function(selector, handler) { + // call the ancestor method to add a wrapped recalc method + this.base(selector, function(element) { + if (!this.elements[element.uniqueID]) { + // execute the original recalc method + handler(element); + // store a reference to this element so that + // it is not "fixed" again + this.elements[element.uniqueID] =3D element; + } + }); + } + }); + + // allow refreshing of IE7 fixes + document.recalc =3D function(reload) { + if (IE7.CSS.screen) { + if (reload) IE7.CSS.reload(); + IE7.recalc(); + } + }; + +})(); diff --git a/site/public/javascripts/lowpro.js b/site/public/javascripts/= lowpro.js new file mode 100644 index 0000000..67fbee1 --- /dev/null +++ b/site/public/javascripts/lowpro.js @@ -0,0 +1,339 @@ +LowPro =3D {}; +LowPro.Version =3D '0.5'; +LowPro.CompatibleWithPrototype =3D '1.6'; + +if (Prototype.Version.indexOf(LowPro.CompatibleWithPrototype) !=3D 0 && = window.console && window.console.warn) + console.warn("This version of Low Pro is tested with Prototype " + Low= Pro.CompatibleWithPrototype + + " it may not work as expected with this version (" + P= rototype.Version + ")"); + +if (!Element.addMethods) + Element.addMethods =3D function(o) { Object.extend(Element.Methods, o)= }; + +// Simple utility methods for working with the DOM +DOM =3D {}; + +// DOMBuilder for prototype +DOM.Builder =3D { + tagFunc : function(tag) { + return function() { + var attrs, children; + if (arguments.length>0) { + if (arguments[0].constructor =3D=3D Object) { + attrs =3D arguments[0]; + children =3D Array.prototype.slice.call(arguments, 1); + } else { + children =3D arguments; + }; + children =3D $A(children).flatten() + } + return DOM.Builder.create(tag, attrs, children); + }; + }, + create : function(tag, attrs, children) { + attrs =3D attrs || {}; children =3D children || []; tag =3D tag.toLowe= rCase(); + var el =3D new Element(tag, attrs); + + for (var i=3D0; i -1, + Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') =3D= =3D=3D -1, + MobileSafari: /Apple.*Mobile/.test(ua) + } + })(), + + BrowserFeatures: { + XPath: !!document.evaluate, + + SelectorsAPI: !!document.querySelector, + + ElementExtensions: (function() { + var constructor =3D window.Element || window.HTMLElement; + return !!(constructor && constructor.prototype); + })(), + SpecificElementExtensions: (function() { + if (typeof window.HTMLDivElement !=3D=3D 'undefined') + return true; + + var div =3D document.createElement('div'), + form =3D document.createElement('form'), + isSupported =3D false; + + if (div['__proto__'] && (div['__proto__'] !=3D=3D form['__proto__'= ])) { + isSupported =3D true; + } + + div =3D form =3D null; + + return isSupported; + })() + }, + + ScriptFragment: ']*>([\\S\\s]*?)<\/script>', + JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, + + emptyFunction: function() { }, + + K: function(x) { return x } +}; + +if (Prototype.Browser.MobileSafari) + Prototype.BrowserFeatures.SpecificElementExtensions =3D false; + + +var Abstract =3D { }; + + +var Try =3D { + these: function() { + var returnValue; + + for (var i =3D 0, length =3D arguments.length; i < length; i++) { + var lambda =3D arguments[i]; + try { + returnValue =3D lambda(); + break; + } catch (e) { } + } + + return returnValue; + } +}; + +/* Based on Alex Arnell's inheritance implementation. */ + +var Class =3D (function() { + + var IS_DONTENUM_BUGGY =3D (function(){ + for (var p in { toString: 1 }) { + if (p =3D=3D=3D 'toString') return false; + } + return true; + })(); + + function subclass() {}; + function create() { + var parent =3D null, properties =3D $A(arguments); + if (Object.isFunction(properties[0])) + parent =3D properties.shift(); + + function klass() { + this.initialize.apply(this, arguments); + } + + Object.extend(klass, Class.Methods); + klass.superclass =3D parent; + klass.subclasses =3D []; + + if (parent) { + subclass.prototype =3D parent.prototype; + klass.prototype =3D new subclass; + parent.subclasses.push(klass); + } + + for (var i =3D 0, length =3D properties.length; i < length; i++) + klass.addMethods(properties[i]); + + if (!klass.prototype.initialize) + klass.prototype.initialize =3D Prototype.emptyFunction; + + klass.prototype.constructor =3D klass; + return klass; + } + + function addMethods(source) { + var ancestor =3D this.superclass && this.superclass.prototype, + properties =3D Object.keys(source); + + if (IS_DONTENUM_BUGGY) { + if (source.toString !=3D Object.prototype.toString) + properties.push("toString"); + if (source.valueOf !=3D Object.prototype.valueOf) + properties.push("valueOf"); + } + + for (var i =3D 0, length =3D properties.length; i < length; i++) { + var property =3D properties[i], value =3D source[property]; + if (ancestor && Object.isFunction(value) && + value.argumentNames()[0] =3D=3D "$super") { + var method =3D value; + value =3D (function(m) { + return function() { return ancestor[m].apply(this, arguments);= }; + })(property).wrap(method); + + value.valueOf =3D method.valueOf.bind(method); + value.toString =3D method.toString.bind(method); + } + this.prototype[property] =3D value; + } + + return this; + } + + return { + create: create, + Methods: { + addMethods: addMethods + } + }; +})(); +(function() { + + var _toString =3D Object.prototype.toString, + NULL_TYPE =3D 'Null', + UNDEFINED_TYPE =3D 'Undefined', + BOOLEAN_TYPE =3D 'Boolean', + NUMBER_TYPE =3D 'Number', + STRING_TYPE =3D 'String', + OBJECT_TYPE =3D 'Object', + BOOLEAN_CLASS =3D '[object Boolean]', + NUMBER_CLASS =3D '[object Number]', + STRING_CLASS =3D '[object String]', + ARRAY_CLASS =3D '[object Array]', + NATIVE_JSON_STRINGIFY_SUPPORT =3D window.JSON && + typeof JSON.stringify =3D=3D=3D 'function' && + JSON.stringify(0) =3D=3D=3D '0' && + typeof JSON.stringify(Prototype.K) =3D=3D=3D 'undefined'; + + function Type(o) { + switch(o) { + case null: return NULL_TYPE; + case (void 0): return UNDEFINED_TYPE; + } + var type =3D typeof o; + switch(type) { + case 'boolean': return BOOLEAN_TYPE; + case 'number': return NUMBER_TYPE; + case 'string': return STRING_TYPE; + } + return OBJECT_TYPE; + } + + function extend(destination, source) { + for (var property in source) + destination[property] =3D source[property]; + return destination; + } + + function inspect(object) { + try { + if (isUndefined(object)) return 'undefined'; + if (object =3D=3D=3D null) return 'null'; + return object.inspect ? object.inspect() : String(object); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + } + + function toJSON(value) { + return Str('', { '': value }, []); + } + + function Str(key, holder, stack) { + var value =3D holder[key], + type =3D typeof value; + + if (Type(value) =3D=3D=3D OBJECT_TYPE && typeof value.toJSON =3D=3D=3D= 'function') { + value =3D value.toJSON(key); + } + + var _class =3D _toString.call(value); + + switch (_class) { + case NUMBER_CLASS: + case BOOLEAN_CLASS: + case STRING_CLASS: + value =3D value.valueOf(); + } + + switch (value) { + case null: return 'null'; + case true: return 'true'; + case false: return 'false'; + } + + type =3D typeof value; + switch (type) { + case 'string': + return value.inspect(true); + case 'number': + return isFinite(value) ? String(value) : 'null'; + case 'object': + + for (var i =3D 0, length =3D stack.length; i < length; i++) { + if (stack[i] =3D=3D=3D value) { throw new TypeError(); } + } + stack.push(value); + + var partial =3D []; + if (_class =3D=3D=3D ARRAY_CLASS) { + for (var i =3D 0, length =3D value.length; i < length; i++) { + var str =3D Str(i, value, stack); + partial.push(typeof str =3D=3D=3D 'undefined' ? 'null' : str= ); + } + partial =3D '[' + partial.join(',') + ']'; + } else { + var keys =3D Object.keys(value); + for (var i =3D 0, length =3D keys.length; i < length; i++) { + var key =3D keys[i], str =3D Str(key, value, stack); + if (typeof str !=3D=3D "undefined") { + partial.push(key.inspect(true)+ ':' + str); + } + } + partial =3D '{' + partial.join(',') + '}'; + } + stack.pop(); + return partial; + } + } + + function stringify(object) { + return JSON.stringify(object); + } + + function toQueryString(object) { + return $H(object).toQueryString(); + } + + function toHTML(object) { + return object && object.toHTML ? object.toHTML() : String.interpret(= object); + } + + function keys(object) { + if (Type(object) !=3D=3D OBJECT_TYPE) { throw new TypeError(); } + var results =3D []; + for (var property in object) { + if (object.hasOwnProperty(property)) { + results.push(property); + } + } + return results; + } + + function values(object) { + var results =3D []; + for (var property in object) + results.push(object[property]); + return results; + } + + function clone(object) { + return extend({ }, object); + } + + function isElement(object) { + return !!(object && object.nodeType =3D=3D 1); + } + + function isArray(object) { + return _toString.call(object) =3D=3D=3D ARRAY_CLASS; + } + + var hasNativeIsArray =3D (typeof Array.isArray =3D=3D 'function') + && Array.isArray([]) && !Array.isArray({}); + + if (hasNativeIsArray) { + isArray =3D Array.isArray; + } + + function isHash(object) { + return object instanceof Hash; + } + + function isFunction(object) { + return typeof object =3D=3D=3D "function"; + } + + function isString(object) { + return _toString.call(object) =3D=3D=3D STRING_CLASS; + } + + function isNumber(object) { + return _toString.call(object) =3D=3D=3D NUMBER_CLASS; + } + + function isUndefined(object) { + return typeof object =3D=3D=3D "undefined"; + } + + extend(Object, { + extend: extend, + inspect: inspect, + toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, + toQueryString: toQueryString, + toHTML: toHTML, + keys: Object.keys || keys, + values: values, + clone: clone, + isElement: isElement, + isArray: isArray, + isHash: isHash, + isFunction: isFunction, + isString: isString, + isNumber: isNumber, + isUndefined: isUndefined + }); +})(); +Object.extend(Function.prototype, (function() { + var slice =3D Array.prototype.slice; + + function update(array, args) { + var arrayLength =3D array.length, length =3D args.length; + while (length--) array[arrayLength + length] =3D args[length]; + return array; + } + + function merge(array, args) { + array =3D slice.call(array, 0); + return update(array, args); + } + + function argumentNames() { + var names =3D this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\= )/)[1] + .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') + .replace(/\s+/g, '').split(','); + return names.length =3D=3D 1 && !names[0] ? [] : names; + } + + function bind(context) { + if (arguments.length < 2 && Object.isUndefined(arguments[0])) return= this; + var __method =3D this, args =3D slice.call(arguments, 1); + return function() { + var a =3D merge(args, arguments); + return __method.apply(context, a); + } + } + + function bindAsEventListener(context) { + var __method =3D this, args =3D slice.call(arguments, 1); + return function(event) { + var a =3D update([event || window.event], args); + return __method.apply(context, a); + } + } + + function curry() { + if (!arguments.length) return this; + var __method =3D this, args =3D slice.call(arguments, 0); + return function() { + var a =3D merge(args, arguments); + return __method.apply(this, a); + } + } + + function delay(timeout) { + var __method =3D this, args =3D slice.call(arguments, 1); + timeout =3D timeout * 1000; + return window.setTimeout(function() { + return __method.apply(__method, args); + }, timeout); + } + + function defer() { + var args =3D update([0.01], arguments); + return this.delay.apply(this, args); + } + + function wrap(wrapper) { + var __method =3D this; + return function() { + var a =3D update([__method.bind(this)], arguments); + return wrapper.apply(this, a); + } + } + + function methodize() { + if (this._methodized) return this._methodized; + var __method =3D this; + return this._methodized =3D function() { + var a =3D update([this], arguments); + return __method.apply(null, a); + }; + } + + return { + argumentNames: argumentNames, + bind: bind, + bindAsEventListener: bindAsEventListener, + curry: curry, + delay: delay, + defer: defer, + wrap: wrap, + methodize: methodize + } +})()); + + + +(function(proto) { + + + function toISOString() { + return this.getUTCFullYear() + '-' + + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + + this.getUTCDate().toPaddedString(2) + 'T' + + this.getUTCHours().toPaddedString(2) + ':' + + this.getUTCMinutes().toPaddedString(2) + ':' + + this.getUTCSeconds().toPaddedString(2) + 'Z'; + } + + + function toJSON() { + return this.toISOString(); + } + + if (!proto.toISOString) proto.toISOString =3D toISOString; + if (!proto.toJSON) proto.toJSON =3D toJSON; + +})(Date.prototype); + + +RegExp.prototype.match =3D RegExp.prototype.test; + +RegExp.escape =3D function(str) { + return String(str).replace(/([.*+?^=3D!:${}()|[\]\/\\])/g, '\\$1'); +}; +var PeriodicalExecuter =3D Class.create({ + initialize: function(callback, frequency) { + this.callback =3D callback; + this.frequency =3D frequency; + this.currentlyExecuting =3D false; + + this.registerCallback(); + }, + + registerCallback: function() { + this.timer =3D setInterval(this.onTimerEvent.bind(this), this.freque= ncy * 1000); + }, + + execute: function() { + this.callback(this); + }, + + stop: function() { + if (!this.timer) return; + clearInterval(this.timer); + this.timer =3D null; + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting =3D true; + this.execute(); + this.currentlyExecuting =3D false; + } catch(e) { + this.currentlyExecuting =3D false; + throw e; + } + } + } +}); +Object.extend(String, { + interpret: function(value) { + return value =3D=3D null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, (function() { + var NATIVE_JSON_PARSE_SUPPORT =3D window.JSON && + typeof JSON.parse =3D=3D=3D 'function' && + JSON.parse('{"test": true}').test; + + function prepareReplacement(replacement) { + if (Object.isFunction(replacement)) return replacement; + var template =3D new Template(replacement); + return function(match) { return template.evaluate(match) }; + } + + function gsub(pattern, replacement) { + var result =3D '', source =3D this, match; + replacement =3D prepareReplacement(replacement); + + if (Object.isString(pattern)) + pattern =3D RegExp.escape(pattern); + + if (!(pattern.length || pattern.source)) { + replacement =3D replacement(''); + return replacement + source.split('').join(replacement) + replacem= ent; + } + + while (source.length > 0) { + if (match =3D source.match(pattern)) { + result +=3D source.slice(0, match.index); + result +=3D String.interpret(replacement(match)); + source =3D source.slice(match.index + match[0].length); + } else { + result +=3D source, source =3D ''; + } + } + return result; + } + + function sub(pattern, replacement, count) { + replacement =3D prepareReplacement(replacement); + count =3D Object.isUndefined(count) ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + } + + function scan(pattern, iterator) { + this.gsub(pattern, iterator); + return String(this); + } + + function truncate(length, truncation) { + length =3D length || 30; + truncation =3D Object.isUndefined(truncation) ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : String(th= is); + } + + function strip() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + } + + function stripTags() { + return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, = ''); + } + + function stripScripts() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '')= ; + } + + function extractScripts() { + var matchAll =3D new RegExp(Prototype.ScriptFragment, 'img'), + matchOne =3D new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + } + + function evalScripts() { + return this.extractScripts().map(function(script) { return eval(scri= pt) }); + } + + function escapeHTML() { + return this.replace(/&/g,'&').replace(//g,= '>'); + } + + function unescapeHTML() { + return this.stripTags().replace(/</g,'<').replace(/>/g,'>').re= place(/&/g,'&'); + } + + + function toQueryParams(separator) { + var match =3D this.strip().match(/([^?#]*)(#.*)?$/); + if (!match) return { }; + + return match[1].split(separator || '&').inject({ }, function(hash, p= air) { + if ((pair =3D pair.split('=3D'))[0]) { + var key =3D decodeURIComponent(pair.shift()), + value =3D pair.length > 1 ? pair.join('=3D') : pair[0]; + + if (value !=3D undefined) value =3D decodeURIComponent(value); + + if (key in hash) { + if (!Object.isArray(hash[key])) hash[key] =3D [hash[key]]; + hash[key].push(value); + } + else hash[key] =3D value; + } + return hash; + }); + } + + function toArray() { + return this.split(''); + } + + function succ() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + } + + function times(count) { + return count < 1 ? '' : new Array(count + 1).join(this); + } + + function camelize() { + return this.replace(/-+(.)?/g, function(match, chr) { + return chr ? chr.toUpperCase() : ''; + }); + } + + function capitalize() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(= ); + } + + function underscore() { + return this.replace(/::/g, '/') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .replace(/([a-z\d])([A-Z])/g, '$1_$2') + .replace(/-/g, '_') + .toLowerCase(); + } + + function dasherize() { + return this.replace(/_/g, '-'); + } + + function inspect(useDoubleQuotes) { + var escapedString =3D this.replace(/[\x00-\x1f\\]/g, function(charac= ter) { + if (character in String.specialChar) { + return String.specialChar[character]; + } + return '\\u00' + character.charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"')= + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + } + + function unfilterJSON(filter) { + return this.replace(filter || Prototype.JSONFilter, '$1'); + } + + function isJSON() { + var str =3D this; + if (str.blank()) return false; + str =3D str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); + str =3D str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?= :[eE][+\-]?\d+)?/g, ']'); + str =3D str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); + return (/^[\],:{}\s]*$/).test(str); + } + + function evalJSON(sanitize) { + var json =3D this.unfilterJSON(), + cx =3D /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200= f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + if (cx.test(json)) { + json =3D json.replace(cx, function (a) { + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)= ; + }); + } + try { + if (!sanitize || json.isJSON()) return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect())= ; + } + + function parseJSON() { + var json =3D this.unfilterJSON(); + return JSON.parse(json); + } + + function include(pattern) { + return this.indexOf(pattern) > -1; + } + + function startsWith(pattern) { + return this.lastIndexOf(pattern, 0) =3D=3D=3D 0; + } + + function endsWith(pattern) { + var d =3D this.length - pattern.length; + return d >=3D 0 && this.indexOf(pattern, d) =3D=3D=3D d; + } + + function empty() { + return this =3D=3D ''; + } + + function blank() { + return /^\s*$/.test(this); + } + + function interpolate(object, pattern) { + return new Template(this, pattern).evaluate(object); + } + + return { + gsub: gsub, + sub: sub, + scan: scan, + truncate: truncate, + strip: String.prototype.trim || strip, + stripTags: stripTags, + stripScripts: stripScripts, + extractScripts: extractScripts, + evalScripts: evalScripts, + escapeHTML: escapeHTML, + unescapeHTML: unescapeHTML, + toQueryParams: toQueryParams, + parseQuery: toQueryParams, + toArray: toArray, + succ: succ, + times: times, + camelize: camelize, + capitalize: capitalize, + underscore: underscore, + dasherize: dasherize, + inspect: inspect, + unfilterJSON: unfilterJSON, + isJSON: isJSON, + evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, + include: include, + startsWith: startsWith, + endsWith: endsWith, + empty: empty, + blank: blank, + interpolate: interpolate + }; +})()); + +var Template =3D Class.create({ + initialize: function(template, pattern) { + this.template =3D template.toString(); + this.pattern =3D pattern || Template.Pattern; + }, + + evaluate: function(object) { + if (object && Object.isFunction(object.toTemplateReplacements)) + object =3D object.toTemplateReplacements(); + + return this.template.gsub(this.pattern, function(match) { + if (object =3D=3D null) return (match[1] + ''); + + var before =3D match[1] || ''; + if (before =3D=3D '\\') return match[2]; + + var ctx =3D object, expr =3D match[3], + pattern =3D /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; + + match =3D pattern.exec(expr); + if (match =3D=3D null) return before; + + while (match !=3D null) { + var comp =3D match[1].startsWith('[') ? match[2].replace(/\\\\]/= g, ']') : match[1]; + ctx =3D ctx[comp]; + if (null =3D=3D ctx || '' =3D=3D match[3]) break; + expr =3D expr.substring('[' =3D=3D match[3] ? match[1].length : = match[0].length); + match =3D pattern.exec(expr); + } + + return before + String.interpret(ctx); + }); + } +}); +Template.Pattern =3D /(^|.|\r|\n)(#\{(.*?)\})/; + +var $break =3D { }; + +var Enumerable =3D (function() { + function each(iterator, context) { + var index =3D 0; + try { + this._each(function(value) { + iterator.call(context, value, index++); + }); + } catch (e) { + if (e !=3D $break) throw e; + } + return this; + } + + function eachSlice(number, iterator, context) { + var index =3D -number, slices =3D [], array =3D this.toArray(); + if (number < 1) return array; + while ((index +=3D number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.collect(iterator, context); + } + + function all(iterator, context) { + iterator =3D iterator || Prototype.K; + var result =3D true; + this.each(function(value, index) { + result =3D result && !!iterator.call(context, value, index); + if (!result) throw $break; + }); + return result; + } + + function any(iterator, context) { + iterator =3D iterator || Prototype.K; + var result =3D false; + this.each(function(value, index) { + if (result =3D !!iterator.call(context, value, index)) + throw $break; + }); + return result; + } + + function collect(iterator, context) { + iterator =3D iterator || Prototype.K; + var results =3D []; + this.each(function(value, index) { + results.push(iterator.call(context, value, index)); + }); + return results; + } + + function detect(iterator, context) { + var result; + this.each(function(value, index) { + if (iterator.call(context, value, index)) { + result =3D value; + throw $break; + } + }); + return result; + } + + function findAll(iterator, context) { + var results =3D []; + this.each(function(value, index) { + if (iterator.call(context, value, index)) + results.push(value); + }); + return results; + } + + function grep(filter, iterator, context) { + iterator =3D iterator || Prototype.K; + var results =3D []; + + if (Object.isString(filter)) + filter =3D new RegExp(RegExp.escape(filter)); + + this.each(function(value, index) { + if (filter.match(value)) + results.push(iterator.call(context, value, index)); + }); + return results; + } + + function include(object) { + if (Object.isFunction(this.indexOf)) + if (this.indexOf(object) !=3D -1) return true; + + var found =3D false; + this.each(function(value) { + if (value =3D=3D object) { + found =3D true; + throw $break; + } + }); + return found; + } + + function inGroupsOf(number, fillWith) { + fillWith =3D Object.isUndefined(fillWith) ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + } + + function inject(memo, iterator, context) { + this.each(function(value, index) { + memo =3D iterator.call(context, memo, value, index); + }); + return memo; + } + + function invoke(method) { + var args =3D $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + } + + function max(iterator, context) { + iterator =3D iterator || Prototype.K; + var result; + this.each(function(value, index) { + value =3D iterator.call(context, value, index); + if (result =3D=3D null || value >=3D result) + result =3D value; + }); + return result; + } + + function min(iterator, context) { + iterator =3D iterator || Prototype.K; + var result; + this.each(function(value, index) { + value =3D iterator.call(context, value, index); + if (result =3D=3D null || value < result) + result =3D value; + }); + return result; + } + + function partition(iterator, context) { + iterator =3D iterator || Prototype.K; + var trues =3D [], falses =3D []; + this.each(function(value, index) { + (iterator.call(context, value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + } + + function pluck(property) { + var results =3D []; + this.each(function(value) { + results.push(value[property]); + }); + return results; + } + + function reject(iterator, context) { + var results =3D []; + this.each(function(value, index) { + if (!iterator.call(context, value, index)) + results.push(value); + }); + return results; + } + + function sortBy(iterator, context) { + return this.map(function(value, index) { + return { + value: value, + criteria: iterator.call(context, value, index) + }; + }).sort(function(left, right) { + var a =3D left.criteria, b =3D right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + } + + function toArray() { + return this.map(); + } + + function zip() { + var iterator =3D Prototype.K, args =3D $A(arguments); + if (Object.isFunction(args.last())) + iterator =3D args.pop(); + + var collections =3D [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + } + + function size() { + return this.toArray().length; + } + + function inspect() { + return '#'; + } + + + + + + + + + + return { + each: each, + eachSlice: eachSlice, + all: all, + every: all, + any: any, + some: any, + collect: collect, + map: collect, + detect: detect, + findAll: findAll, + select: findAll, + filter: findAll, + grep: grep, + include: include, + member: include, + inGroupsOf: inGroupsOf, + inject: inject, + invoke: invoke, + max: max, + min: min, + partition: partition, + pluck: pluck, + reject: reject, + sortBy: sortBy, + toArray: toArray, + entries: toArray, + zip: zip, + size: size, + inspect: inspect, + find: detect + }; +})(); + +function $A(iterable) { + if (!iterable) return []; + if ('toArray' in Object(iterable)) return iterable.toArray(); + var length =3D iterable.length || 0, results =3D new Array(length); + while (length--) results[length] =3D iterable[length]; + return results; +} + + +function $w(string) { + if (!Object.isString(string)) return []; + string =3D string.strip(); + return string ? string.split(/\s+/) : []; +} + +Array.from =3D $A; + + +(function() { + var arrayProto =3D Array.prototype, + slice =3D arrayProto.slice, + _each =3D arrayProto.forEach; // use native browser JS 1.6 impleme= ntation if available + + function each(iterator) { + for (var i =3D 0, length =3D this.length; i < length; i++) + iterator(this[i]); + } + if (!_each) _each =3D each; + + function clear() { + this.length =3D 0; + return this; + } + + function first() { + return this[0]; + } + + function last() { + return this[this.length - 1]; + } + + function compact() { + return this.select(function(value) { + return value !=3D null; + }); + } + + function flatten() { + return this.inject([], function(array, value) { + if (Object.isArray(value)) + return array.concat(value.flatten()); + array.push(value); + return array; + }); + } + + function without() { + var values =3D slice.call(arguments, 0); + return this.select(function(value) { + return !values.include(value); + }); + } + + function reverse(inline) { + return (inline =3D=3D=3D false ? this.toArray() : this)._reverse(); + } + + function uniq(sorted) { + return this.inject([], function(array, value, index) { + if (0 =3D=3D index || (sorted ? array.last() !=3D value : !array.i= nclude(value))) + array.push(value); + return array; + }); + } + + function intersect(array) { + return this.uniq().findAll(function(item) { + return array.detect(function(value) { return item =3D=3D=3D value = }); + }); + } + + + function clone() { + return slice.call(this, 0); + } + + function size() { + return this.length; + } + + function inspect() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } + + function indexOf(item, i) { + i || (i =3D 0); + var length =3D this.length; + if (i < 0) i =3D length + i; + for (; i < length; i++) + if (this[i] =3D=3D=3D item) return i; + return -1; + } + + function lastIndexOf(item, i) { + i =3D isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; + var n =3D this.slice(0, i).reverse().indexOf(item); + return (n < 0) ? n : i - n - 1; + } + + function concat() { + var array =3D slice.call(this, 0), item; + for (var i =3D 0, length =3D arguments.length; i < length; i++) { + item =3D arguments[i]; + if (Object.isArray(item) && !('callee' in item)) { + for (var j =3D 0, arrayLength =3D item.length; j < arrayLength; = j++) + array.push(item[j]); + } else { + array.push(item); + } + } + return array; + } + + Object.extend(arrayProto, Enumerable); + + if (!arrayProto._reverse) + arrayProto._reverse =3D arrayProto.reverse; + + Object.extend(arrayProto, { + _each: _each, + clear: clear, + first: first, + last: last, + compact: compact, + flatten: flatten, + without: without, + reverse: reverse, + uniq: uniq, + intersect: intersect, + clone: clone, + toArray: clone, + size: size, + inspect: inspect + }); + + var CONCAT_ARGUMENTS_BUGGY =3D (function() { + return [].concat(arguments)[0][0] !=3D=3D 1; + })(1,2) + + if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat =3D concat; + + if (!arrayProto.indexOf) arrayProto.indexOf =3D indexOf; + if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf =3D lastIndexOf; +})(); +function $H(object) { + return new Hash(object); +}; + +var Hash =3D Class.create(Enumerable, (function() { + function initialize(object) { + this._object =3D Object.isHash(object) ? object.toObject() : Object.= clone(object); + } + + + function _each(iterator) { + for (var key in this._object) { + var value =3D this._object[key], pair =3D [key, value]; + pair.key =3D key; + pair.value =3D value; + iterator(pair); + } + } + + function set(key, value) { + return this._object[key] =3D value; + } + + function get(key) { + if (this._object[key] !=3D=3D Object.prototype[key]) + return this._object[key]; + } + + function unset(key) { + var value =3D this._object[key]; + delete this._object[key]; + return value; + } + + function toObject() { + return Object.clone(this._object); + } + + + + function keys() { + return this.pluck('key'); + } + + function values() { + return this.pluck('value'); + } + + function index(value) { + var match =3D this.detect(function(pair) { + return pair.value =3D=3D=3D value; + }); + return match && match.key; + } + + function merge(object) { + return this.clone().update(object); + } + + function update(object) { + return new Hash(object).inject(this, function(result, pair) { + result.set(pair.key, pair.value); + return result; + }); + } + + function toQueryPair(key, value) { + if (Object.isUndefined(value)) return key; + return key + '=3D' + encodeURIComponent(String.interpret(value)); + } + + function toQueryString() { + return this.inject([], function(results, pair) { + var key =3D encodeURIComponent(pair.key), values =3D pair.value; + + if (values && typeof values =3D=3D 'object') { + if (Object.isArray(values)) + return results.concat(values.map(toQueryPair.curry(key))); + } else results.push(toQueryPair(key, values)); + return results; + }).join('&'); + } + + function inspect() { + return '#'; + } + + function clone() { + return new Hash(this); + } + + return { + initialize: initialize, + _each: _each, + set: set, + get: get, + unset: unset, + toObject: toObject, + toTemplateReplacements: toObject, + keys: keys, + values: values, + index: index, + merge: merge, + update: update, + toQueryString: toQueryString, + inspect: inspect, + toJSON: toObject, + clone: clone + }; +})()); + +Hash.from =3D $H; +Object.extend(Number.prototype, (function() { + function toColorPart() { + return this.toPaddedString(2, 16); + } + + function succ() { + return this + 1; + } + + function times(iterator, context) { + $R(0, this, true).each(iterator, context); + return this; + } + + function toPaddedString(length, radix) { + var string =3D this.toString(radix || 10); + return '0'.times(length - string.length) + string; + } + + function abs() { + return Math.abs(this); + } + + function round() { + return Math.round(this); + } + + function ceil() { + return Math.ceil(this); + } + + function floor() { + return Math.floor(this); + } + + return { + toColorPart: toColorPart, + succ: succ, + times: times, + toPaddedString: toPaddedString, + abs: abs, + round: round, + ceil: ceil, + floor: floor + }; +})()); + +function $R(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var ObjectRange =3D Class.create(Enumerable, (function() { + function initialize(start, end, exclusive) { + this.start =3D start; + this.end =3D end; + this.exclusive =3D exclusive; + } + + function _each(iterator) { + var value =3D this.start; + while (this.include(value)) { + iterator(value); + value =3D value.succ(); + } + } + + function include(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <=3D this.end; + } + + return { + initialize: initialize, + _each: _each, + include: include + }; +})()); + + + +var Ajax =3D { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +}; + +Ajax.Responders =3D { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responder) { + if (!this.include(responder)) + this.responders.push(responder); + }, + + unregister: function(responder) { + this.responders =3D this.responders.without(responder); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (Object.isFunction(responder[callback])) { + try { + responder[callback].apply(responder, [request, transport, json= ]); + } catch (e) { } + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { Ajax.activeRequestCount++ }, + onComplete: function() { Ajax.activeRequestCount-- } +}); +Ajax.Base =3D Class.create({ + initialize: function(options) { + this.options =3D { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + encoding: 'UTF-8', + parameters: '', + evalJSON: true, + evalJS: true + }; + Object.extend(this.options, options || { }); + + this.options.method =3D this.options.method.toLowerCase(); + + if (Object.isString(this.options.parameters)) + this.options.parameters =3D this.options.parameters.toQueryParams(= ); + else if (Object.isHash(this.options.parameters)) + this.options.parameters =3D this.options.parameters.toObject(); + } +}); +Ajax.Request =3D Class.create(Ajax.Base, { + _complete: false, + + initialize: function($super, url, options) { + $super(options); + this.transport =3D Ajax.getTransport(); + this.request(url); + }, + + request: function(url) { + this.url =3D url; + this.method =3D this.options.method; + var params =3D Object.clone(this.options.parameters); + + if (!['get', 'post'].include(this.method)) { + params['_method'] =3D this.method; + this.method =3D 'post'; + } + + this.parameters =3D params; + + if (params =3D Object.toQueryString(params)) { + if (this.method =3D=3D 'get') + this.url +=3D (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params +=3D '&_=3D'; + } + + try { + var response =3D new Ajax.Response(this); + if (this.options.onCreate) this.options.onCreate(response); + Ajax.Responders.dispatch('onCreate', this, response); + + this.transport.open(this.method.toUpperCase(), this.url, + this.options.asynchronous); + + if (this.options.asynchronous) this.respondToReadyState.bind(this)= .defer(1); + + this.transport.onreadystatechange =3D this.onStateChange.bind(this= ); + this.setRequestHeaders(); + + this.body =3D this.method =3D=3D 'post' ? (this.options.postBody |= | params) : null; + this.transport.send(this.body); + + /* Force Firefox to handle ready state 4 for synchronous requests = */ + if (!this.options.asynchronous && this.transport.overrideMimeType) + this.onStateChange(); + + } + catch (e) { + this.dispatchException(e); + } + }, + + onStateChange: function() { + var readyState =3D this.transport.readyState; + if (readyState > 1 && !((readyState =3D=3D 4) && this._complete)) + this.respondToReadyState(this.transport.readyState); + }, + + setRequestHeaders: function() { + var headers =3D { + 'X-Requested-With': 'XMLHttpRequest', + 'X-Prototype-Version': Prototype.Version, + 'Accept': 'text/javascript, text/html, application/xml, text/xml, = */*' + }; + + if (this.method =3D=3D 'post') { + headers['Content-type'] =3D this.options.contentType + + (this.options.encoding ? '; charset=3D' + this.options.encoding = : ''); + + /* Force "Connection: close" for older Mozilla browsers to work + * around a bug where XMLHttpRequest sends an incorrect + * Content-length header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType && + (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] <= 2005) + headers['Connection'] =3D 'close'; + } + + if (typeof this.options.requestHeaders =3D=3D 'object') { + var extras =3D this.options.requestHeaders; + + if (Object.isFunction(extras.push)) + for (var i =3D 0, length =3D extras.length; i < length; i +=3D 2= ) + headers[extras[i]] =3D extras[i+1]; + else + $H(extras).each(function(pair) { headers[pair.key] =3D pair.valu= e }); + } + + for (var name in headers) + this.transport.setRequestHeader(name, headers[name]); + }, + + success: function() { + var status =3D this.getStatus(); + return !status || (status >=3D 200 && status < 300); + }, + + getStatus: function() { + try { + return this.transport.status || 0; + } catch (e) { return 0 } + }, + + respondToReadyState: function(readyState) { + var state =3D Ajax.Request.Events[readyState], response =3D new Ajax= .Response(this); + + if (state =3D=3D 'Complete') { + try { + this._complete =3D true; + (this.options['on' + response.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')= ] + || Prototype.emptyFunction)(response, response.headerJSON); + } catch (e) { + this.dispatchException(e); + } + + var contentType =3D response.getHeader('Content-type'); + if (this.options.evalJS =3D=3D 'force' + || (this.options.evalJS && this.isSameOrigin() && contentType + && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)= script(;.*)?\s*$/i))) + this.evalResponse(); + } + + try { + (this.options['on' + state] || Prototype.emptyFunction)(response, = response.headerJSON); + Ajax.Responders.dispatch('on' + state, this, response, response.he= aderJSON); + } catch (e) { + this.dispatchException(e); + } + + if (state =3D=3D 'Complete') { + this.transport.onreadystatechange =3D Prototype.emptyFunction; + } + }, + + isSameOrigin: function() { + var m =3D this.url.match(/^\s*https?:\/\/[^\/]*/); + return !m || (m[0] =3D=3D '#{protocol}//#{domain}#{port}'.interpolat= e({ + protocol: location.protocol, + domain: document.domain, + port: location.port ? ':' + location.port : '' + })); + }, + + getHeader: function(name) { + try { + return this.transport.getResponseHeader(name) || null; + } catch (e) { return null; } + }, + + evalResponse: function() { + try { + return eval((this.transport.responseText || '').unfilterJSON()); + } catch (e) { + this.dispatchException(e); + } + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exceptio= n); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Request.Events =3D + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + + + + + + + + +Ajax.Response =3D Class.create({ + initialize: function(request){ + this.request =3D request; + var transport =3D this.transport =3D request.transport, + readyState =3D this.readyState =3D transport.readyState; + + if ((readyState > 2 && !Prototype.Browser.IE) || readyState =3D=3D 4= ) { + this.status =3D this.getStatus(); + this.statusText =3D this.getStatusText(); + this.responseText =3D String.interpret(transport.responseText); + this.headerJSON =3D this._getHeaderJSON(); + } + + if (readyState =3D=3D 4) { + var xml =3D transport.responseXML; + this.responseXML =3D Object.isUndefined(xml) ? null : xml; + this.responseJSON =3D this._getResponseJSON(); + } + }, + + status: 0, + + statusText: '', + + getStatus: Ajax.Request.prototype.getStatus, + + getStatusText: function() { + try { + return this.transport.statusText || ''; + } catch (e) { return '' } + }, + + getHeader: Ajax.Request.prototype.getHeader, + + getAllHeaders: function() { + try { + return this.getAllResponseHeaders(); + } catch (e) { return null } + }, + + getResponseHeader: function(name) { + return this.transport.getResponseHeader(name); + }, + + getAllResponseHeaders: function() { + return this.transport.getAllResponseHeaders(); + }, + + _getHeaderJSON: function() { + var json =3D this.getHeader('X-JSON'); + if (!json) return null; + json =3D decodeURIComponent(escape(json)); + try { + return json.evalJSON(this.request.options.sanitizeJSON || + !this.request.isSameOrigin()); + } catch (e) { + this.request.dispatchException(e); + } + }, + + _getResponseJSON: function() { + var options =3D this.request.options; + if (!options.evalJSON || (options.evalJSON !=3D 'force' && + !(this.getHeader('Content-type') || '').include('application/json'= )) || + this.responseText.blank()) + return null; + try { + return this.responseText.evalJSON(options.sanitizeJSON || + !this.request.isSameOrigin()); + } catch (e) { + this.request.dispatchException(e); + } + } +}); + +Ajax.Updater =3D Class.create(Ajax.Request, { + initialize: function($super, container, url, options) { + this.container =3D { + success: (container.success || container), + failure: (container.failure || (container.success ? null : contain= er)) + }; + + options =3D Object.clone(options); + var onComplete =3D options.onComplete; + options.onComplete =3D (function(response, json) { + this.updateContent(response.responseText); + if (Object.isFunction(onComplete)) onComplete(response, json); + }).bind(this); + + $super(url, options); + }, + + updateContent: function(responseText) { + var receiver =3D this.container[this.success() ? 'success' : 'failur= e'], + options =3D this.options; + + if (!options.evalScripts) responseText =3D responseText.stripScripts= (); + + if (receiver =3D $(receiver)) { + if (options.insertion) { + if (Object.isString(options.insertion)) { + var insertion =3D { }; insertion[options.insertion] =3D respon= seText; + receiver.insert(insertion); + } + else options.insertion(receiver, responseText); + } + else receiver.update(responseText); + } + } +}); + +Ajax.PeriodicalUpdater =3D Class.create(Ajax.Base, { + initialize: function($super, container, url, options) { + $super(options); + this.onComplete =3D this.options.onComplete; + + this.frequency =3D (this.options.frequency || 2); + this.decay =3D (this.options.decay || 1); + + this.updater =3D { }; + this.container =3D container; + this.url =3D url; + + this.start(); + }, + + start: function() { + this.options.onComplete =3D this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.options.onComplete =3D undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(response) { + if (this.options.decay) { + this.decay =3D (response.responseText =3D=3D this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText =3D response.responseText; + } + this.timer =3D this.onTimerEvent.bind(this).delay(this.decay * this.= frequency); + }, + + onTimerEvent: function() { + this.updater =3D new Ajax.Updater(this.container, this.url, this.opt= ions); + } +}); + + +function $(element) { + if (arguments.length > 1) { + for (var i =3D 0, elements =3D [], length =3D arguments.length; i < = length; i++) + elements.push($(arguments[i])); + return elements; + } + if (Object.isString(element)) + element =3D document.getElementById(element); + return Element.extend(element); +} + +if (Prototype.BrowserFeatures.XPath) { + document._getElementsByXPath =3D function(expression, parentElement) { + var results =3D []; + var query =3D document.evaluate(expression, $(parentElement) || docu= ment, + null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i =3D 0, length =3D query.snapshotLength; i < length; i++) + results.push(Element.extend(query.snapshotItem(i))); + return results; + }; +} + +/*----------------------------------------------------------------------= ----*/ + +if (!Node) var Node =3D { }; + +if (!Node.ELEMENT_NODE) { + Object.extend(Node, { + ELEMENT_NODE: 1, + ATTRIBUTE_NODE: 2, + TEXT_NODE: 3, + CDATA_SECTION_NODE: 4, + ENTITY_REFERENCE_NODE: 5, + ENTITY_NODE: 6, + PROCESSING_INSTRUCTION_NODE: 7, + COMMENT_NODE: 8, + DOCUMENT_NODE: 9, + DOCUMENT_TYPE_NODE: 10, + DOCUMENT_FRAGMENT_NODE: 11, + NOTATION_NODE: 12 + }); +} + + + +(function(global) { + + var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX =3D (function(){ + try { + var el =3D document.createElement(''); + return el.tagName.toLowerCase() =3D=3D=3D 'input' && el.name =3D=3D= =3D 'x'; + } + catch(err) { + return false; + } + })(); + + var element =3D global.Element; + + global.Element =3D function(tagName, attributes) { + attributes =3D attributes || { }; + tagName =3D tagName.toLowerCase(); + var cache =3D Element.cache; + if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { + tagName =3D '<' + tagName + ' name=3D"' + attributes.name + '">'; + delete attributes.name; + return Element.writeAttribute(document.createElement(tagName), att= ributes); + } + if (!cache[tagName]) cache[tagName] =3D Element.extend(document.crea= teElement(tagName)); + return Element.writeAttribute(cache[tagName].cloneNode(false), attri= butes); + }; + + Object.extend(global.Element, element || { }); + if (element) global.Element.prototype =3D element.prototype; + +})(this); + +Element.idCounter =3D 1; +Element.cache =3D { }; + +function purgeElement(element) { + var uid =3D element._prototypeUID; + if (uid) { + Element.stopObserving(element); + element._prototypeUID =3D void 0; + delete Element.Storage[uid]; + } +} + +Element.Methods =3D { + visible: function(element) { + return $(element).style.display !=3D 'none'; + }, + + toggle: function(element) { + element =3D $(element); + Element[Element.visible(element) ? 'hide' : 'show'](element); + return element; + }, + + hide: function(element) { + element =3D $(element); + element.style.display =3D 'none'; + return element; + }, + + show: function(element) { + element =3D $(element); + element.style.display =3D ''; + return element; + }, + + remove: function(element) { + element =3D $(element); + element.parentNode.removeChild(element); + return element; + }, + + update: (function(){ + + var SELECT_ELEMENT_INNERHTML_BUGGY =3D (function(){ + var el =3D document.createElement("select"), + isBuggy =3D true; + el.innerHTML =3D ""; + if (el.options && el.options[0]) { + isBuggy =3D el.options[0].nodeName.toUpperCase() !=3D=3D "OPTION= "; + } + el =3D null; + return isBuggy; + })(); + + var TABLE_ELEMENT_INNERHTML_BUGGY =3D (function(){ + try { + var el =3D document.createElement("table"); + if (el && el.tBodies) { + el.innerHTML =3D "test"; + var isBuggy =3D typeof el.tBodies[0] =3D=3D "undefined"; + el =3D null; + return isBuggy; + } + } catch (e) { + return true; + } + })(); + + var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING =3D (function () { + var s =3D document.createElement("script"), + isBuggy =3D false; + try { + s.appendChild(document.createTextNode("")); + isBuggy =3D !s.firstChild || + s.firstChild && s.firstChild.nodeType !=3D=3D 3; + } catch (e) { + isBuggy =3D true; + } + s =3D null; + return isBuggy; + })(); + + function update(element, content) { + element =3D $(element); + + var descendants =3D element.getElementsByTagName('*'), + i =3D descendants.length; + while (i--) purgeElement(descendants[i]); + + if (content && content.toElement) + content =3D content.toElement(); + + if (Object.isElement(content)) + return element.update().insert(content); + + content =3D Object.toHTML(content); + + var tagName =3D element.tagName.toUpperCase(); + + if (tagName =3D=3D=3D 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_= APPENDING) { + element.text =3D content; + return element; + } + + if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGG= Y) { + if (tagName in Element._insertionTranslations.tags) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } + Element._getContentFromAnonymousElement(tagName, content.strip= Scripts()) + .each(function(node) { + element.appendChild(node) + }); + } + else { + element.innerHTML =3D content.stripScripts(); + } + } + else { + element.innerHTML =3D content.stripScripts(); + } + + content.evalScripts.bind(content).defer(); + return element; + } + + return update; + })(), + + replace: function(element, content) { + element =3D $(element); + if (content && content.toElement) content =3D content.toElement(); + else if (!Object.isElement(content)) { + content =3D Object.toHTML(content); + var range =3D element.ownerDocument.createRange(); + range.selectNode(element); + content.evalScripts.bind(content).defer(); + content =3D range.createContextualFragment(content.stripScripts())= ; + } + element.parentNode.replaceChild(content, element); + return element; + }, + + insert: function(element, insertions) { + element =3D $(element); + + if (Object.isString(insertions) || Object.isNumber(insertions) || + Object.isElement(insertions) || (insertions && (insertions.toEle= ment || insertions.toHTML))) + insertions =3D {bottom:insertions}; + + var content, insert, tagName, childNodes; + + for (var position in insertions) { + content =3D insertions[position]; + position =3D position.toLowerCase(); + insert =3D Element._insertionTranslations[position]; + + if (content && content.toElement) content =3D content.toElement(); + if (Object.isElement(content)) { + insert(element, content); + continue; + } + + content =3D Object.toHTML(content); + + tagName =3D ((position =3D=3D 'before' || position =3D=3D 'after') + ? element.parentNode : element).tagName.toUpperCase(); + + childNodes =3D Element._getContentFromAnonymousElement(tagName, co= ntent.stripScripts()); + + if (position =3D=3D 'top' || position =3D=3D 'after') childNodes.r= everse(); + childNodes.each(insert.curry(element)); + + content.evalScripts.bind(content).defer(); + } + + return element; + }, + + wrap: function(element, wrapper, attributes) { + element =3D $(element); + if (Object.isElement(wrapper)) + $(wrapper).writeAttribute(attributes || { }); + else if (Object.isString(wrapper)) wrapper =3D new Element(wrapper, = attributes); + else wrapper =3D new Element('div', wrapper); + if (element.parentNode) + element.parentNode.replaceChild(wrapper, element); + wrapper.appendChild(element); + return wrapper; + }, + + inspect: function(element) { + element =3D $(element); + var result =3D '<' + element.tagName.toLowerCase(); + $H({'id': 'id', 'className': 'class'}).each(function(pair) { + var property =3D pair.first(), + attribute =3D pair.last(), + value =3D (element[property] || '').toString(); + if (value) result +=3D ' ' + attribute + '=3D' + value.inspect(tru= e); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property, maximumLength) { + element =3D $(element); + maximumLength =3D maximumLength || -1; + var elements =3D []; + + while (element =3D element[property]) { + if (element.nodeType =3D=3D 1) + elements.push(Element.extend(element)); + if (elements.length =3D=3D maximumLength) + break; + } + + return elements; + }, + + ancestors: function(element) { + return Element.recursivelyCollect(element, 'parentNode'); + }, + + descendants: function(element) { + return Element.select(element, "*"); + }, + + firstDescendant: function(element) { + element =3D $(element).firstChild; + while (element && element.nodeType !=3D 1) element =3D element.nextS= ibling; + return $(element); + }, + + immediateDescendants: function(element) { + var results =3D [], child =3D $(element).firstChild; + while (child) { + if (child.nodeType =3D=3D=3D 1) { + results.push(Element.extend(child)); + } + child =3D child.nextSibling; + } + return results; + }, + + previousSiblings: function(element, maximumLength) { + return Element.recursivelyCollect(element, 'previousSibling'); + }, + + nextSiblings: function(element) { + return Element.recursivelyCollect(element, 'nextSibling'); + }, + + siblings: function(element) { + element =3D $(element); + return Element.previousSiblings(element).reverse() + .concat(Element.nextSiblings(element)); + }, + + match: function(element, selector) { + element =3D $(element); + if (Object.isString(selector)) + return Prototype.Selector.match(element, selector); + return selector.match(element); + }, + + up: function(element, expression, index) { + element =3D $(element); + if (arguments.length =3D=3D 1) return $(element.parentNode); + var ancestors =3D Element.ancestors(element); + return Object.isNumber(expression) ? ancestors[expression] : + Prototype.Selector.find(ancestors, expression, index); + }, + + down: function(element, expression, index) { + element =3D $(element); + if (arguments.length =3D=3D 1) return Element.firstDescendant(elemen= t); + return Object.isNumber(expression) ? Element.descendants(element)[ex= pression] : + Element.select(element, expression)[index || 0]; + }, + + previous: function(element, expression, index) { + element =3D $(element); + if (Object.isNumber(expression)) index =3D expression, expression =3D= false; + if (!Object.isNumber(index)) index =3D 0; + + if (expression) { + return Prototype.Selector.find(element.previousSiblings(), express= ion, index); + } else { + return element.recursivelyCollect("previousSibling", index + 1)[in= dex]; + } + }, + + next: function(element, expression, index) { + element =3D $(element); + if (Object.isNumber(expression)) index =3D expression, expression =3D= false; + if (!Object.isNumber(index)) index =3D 0; + + if (expression) { + return Prototype.Selector.find(element.nextSiblings(), expression,= index); + } else { + var maximumLength =3D Object.isNumber(index) ? index + 1 : 1; + return element.recursivelyCollect("nextSibling", index + 1)[index]= ; + } + }, + + + select: function(element) { + element =3D $(element); + var expressions =3D Array.prototype.slice.call(arguments, 1).join(',= '); + return Prototype.Selector.select(expressions, element); + }, + + adjacent: function(element) { + element =3D $(element); + var expressions =3D Array.prototype.slice.call(arguments, 1).join(',= '); + return Prototype.Selector.select(expressions, element.parentNode).wi= thout(element); + }, + + identify: function(element) { + element =3D $(element); + var id =3D Element.readAttribute(element, 'id'); + if (id) return id; + do { id =3D 'anonymous_element_' + Element.idCounter++ } while ($(id= )); + Element.writeAttribute(element, 'id', id); + return id; + }, + + readAttribute: function(element, name) { + element =3D $(element); + if (Prototype.Browser.IE) { + var t =3D Element._attributeTranslations.read; + if (t.values[name]) return t.values[name](element, name); + if (t.names[name]) name =3D t.names[name]; + if (name.include(':')) { + return (!element.attributes || !element.attributes[name]) ? null= : + element.attributes[name].value; + } + } + return element.getAttribute(name); + }, + + writeAttribute: function(element, name, value) { + element =3D $(element); + var attributes =3D { }, t =3D Element._attributeTranslations.write; + + if (typeof name =3D=3D 'object') attributes =3D name; + else attributes[name] =3D Object.isUndefined(value) ? true : value; + + for (var attr in attributes) { + name =3D t.names[attr] || attr; + value =3D attributes[attr]; + if (t.values[attr]) name =3D t.values[attr](element, value); + if (value =3D=3D=3D false || value =3D=3D=3D null) + element.removeAttribute(name); + else if (value =3D=3D=3D true) + element.setAttribute(name, name); + else element.setAttribute(name, value); + } + return element; + }, + + getHeight: function(element) { + return Element.getDimensions(element).height; + }, + + getWidth: function(element) { + return Element.getDimensions(element).width; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element =3D $(element))) return; + var elementClassName =3D element.className; + return (elementClassName.length > 0 && (elementClassName =3D=3D clas= sName || + new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassNam= e))); + }, + + addClassName: function(element, className) { + if (!(element =3D $(element))) return; + if (!Element.hasClassName(element, className)) + element.className +=3D (element.className ? ' ' : '') + className; + return element; + }, + + removeClassName: function(element, className) { + if (!(element =3D $(element))) return; + element.className =3D element.className.replace( + new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); + return element; + }, + + toggleClassName: function(element, className) { + if (!(element =3D $(element))) return; + return Element[Element.hasClassName(element, className) ? + 'removeClassName' : 'addClassName'](element, className); + }, + + cleanWhitespace: function(element) { + element =3D $(element); + var node =3D element.firstChild; + while (node) { + var nextNode =3D node.nextSibling; + if (node.nodeType =3D=3D 3 && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node =3D nextNode; + } + return element; + }, + + empty: function(element) { + return $(element).innerHTML.blank(); + }, + + descendantOf: function(element, ancestor) { + element =3D $(element), ancestor =3D $(ancestor); + + if (element.compareDocumentPosition) + return (element.compareDocumentPosition(ancestor) & 8) =3D=3D=3D 8= ; + + if (ancestor.contains) + return ancestor.contains(element) && ancestor !=3D=3D element; + + while (element =3D element.parentNode) + if (element =3D=3D ancestor) return true; + + return false; + }, + + scrollTo: function(element) { + element =3D $(element); + var pos =3D Element.cumulativeOffset(element); + window.scrollTo(pos[0], pos[1]); + return element; + }, + + getStyle: function(element, style) { + element =3D $(element); + style =3D style =3D=3D 'float' ? 'cssFloat' : style.camelize(); + var value =3D element.style[style]; + if (!value || value =3D=3D 'auto') { + var css =3D document.defaultView.getComputedStyle(element, null); + value =3D css ? css[style] : null; + } + if (style =3D=3D 'opacity') return value ? parseFloat(value) : 1.0; + return value =3D=3D 'auto' ? null : value; + }, + + getOpacity: function(element) { + return $(element).getStyle('opacity'); + }, + + setStyle: function(element, styles) { + element =3D $(element); + var elementStyle =3D element.style, match; + if (Object.isString(styles)) { + element.style.cssText +=3D ';' + styles; + return styles.include('opacity') ? + element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : = element; + } + for (var property in styles) + if (property =3D=3D 'opacity') element.setOpacity(styles[property]= ); + else + elementStyle[(property =3D=3D 'float' || property =3D=3D 'cssFlo= at') ? + (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 's= tyleFloat') : + property] =3D styles[property]; + + return element; + }, + + setOpacity: function(element, value) { + element =3D $(element); + element.style.opacity =3D (value =3D=3D 1 || value =3D=3D=3D '') ? '= ' : + (value < 0.00001) ? 0 : value; + return element; + }, + + makePositioned: function(element) { + element =3D $(element); + var pos =3D Element.getStyle(element, 'position'); + if (pos =3D=3D 'static' || !pos) { + element._madePositioned =3D true; + element.style.position =3D 'relative'; + if (Prototype.Browser.Opera) { + element.style.top =3D 0; + element.style.left =3D 0; + } + } + return element; + }, + + undoPositioned: function(element) { + element =3D $(element); + if (element._madePositioned) { + element._madePositioned =3D undefined; + element.style.position =3D + element.style.top =3D + element.style.left =3D + element.style.bottom =3D + element.style.right =3D ''; + } + return element; + }, + + makeClipping: function(element) { + element =3D $(element); + if (element._overflow) return element; + element._overflow =3D Element.getStyle(element, 'overflow') || 'auto= '; + if (element._overflow !=3D=3D 'hidden') + element.style.overflow =3D 'hidden'; + return element; + }, + + undoClipping: function(element) { + element =3D $(element); + if (!element._overflow) return element; + element.style.overflow =3D element._overflow =3D=3D 'auto' ? '' : el= ement._overflow; + element._overflow =3D null; + return element; + }, + + cumulativeOffset: function(element) { + var valueT =3D 0, valueL =3D 0; + if (element.parentNode) { + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + element =3D element.offsetParent; + } while (element); + } + return Element._returnOffset(valueL, valueT); + }, + + positionedOffset: function(element) { + var valueT =3D 0, valueL =3D 0; + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + element =3D element.offsetParent; + if (element) { + if (element.tagName.toUpperCase() =3D=3D 'BODY') break; + var p =3D Element.getStyle(element, 'position'); + if (p !=3D=3D 'static') break; + } + } while (element); + return Element._returnOffset(valueL, valueT); + }, + + absolutize: function(element) { + element =3D $(element); + if (Element.getStyle(element, 'position') =3D=3D 'absolute') return = element; + + var offsets =3D Element.positionedOffset(element), + top =3D offsets[1], + left =3D offsets[0], + width =3D element.clientWidth, + height =3D element.clientHeight; + + element._originalLeft =3D left - parseFloat(element.style.left ||= 0); + element._originalTop =3D top - parseFloat(element.style.top || 0= ); + element._originalWidth =3D element.style.width; + element._originalHeight =3D element.style.height; + + element.style.position =3D 'absolute'; + element.style.top =3D top + 'px'; + element.style.left =3D left + 'px'; + element.style.width =3D width + 'px'; + element.style.height =3D height + 'px'; + return element; + }, + + relativize: function(element) { + element =3D $(element); + if (Element.getStyle(element, 'position') =3D=3D 'relative') return = element; + + element.style.position =3D 'relative'; + var top =3D parseFloat(element.style.top || 0) - (element._origina= lTop || 0), + left =3D parseFloat(element.style.left || 0) - (element._origina= lLeft || 0); + + element.style.top =3D top + 'px'; + element.style.left =3D left + 'px'; + element.style.height =3D element._originalHeight; + element.style.width =3D element._originalWidth; + return element; + }, + + cumulativeScrollOffset: function(element) { + var valueT =3D 0, valueL =3D 0; + do { + valueT +=3D element.scrollTop || 0; + valueL +=3D element.scrollLeft || 0; + element =3D element.parentNode; + } while (element); + return Element._returnOffset(valueL, valueT); + }, + + getOffsetParent: function(element) { + if (element.offsetParent) return $(element.offsetParent); + if (element =3D=3D document.body) return $(element); + + while ((element =3D element.parentNode) && element !=3D document.bod= y) + if (Element.getStyle(element, 'position') !=3D 'static') + return $(element); + + return $(document.body); + }, + + viewportOffset: function(forElement) { + var valueT =3D 0, + valueL =3D 0, + element =3D forElement; + + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + + if (element.offsetParent =3D=3D document.body && + Element.getStyle(element, 'position') =3D=3D 'absolute') break; + + } while (element =3D element.offsetParent); + + element =3D forElement; + do { + if (!Prototype.Browser.Opera || (element.tagName && (element.tagNa= me.toUpperCase() =3D=3D 'BODY'))) { + valueT -=3D element.scrollTop || 0; + valueL -=3D element.scrollLeft || 0; + } + } while (element =3D element.parentNode); + + return Element._returnOffset(valueL, valueT); + }, + + clonePosition: function(element, source) { + var options =3D Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || { }); + + source =3D $(source); + var p =3D Element.viewportOffset(source), delta =3D [0, 0], parent =3D= null; + + element =3D $(element); + + if (Element.getStyle(element, 'position') =3D=3D 'absolute') { + parent =3D Element.getOffsetParent(element); + delta =3D Element.viewportOffset(parent); + } + + if (parent =3D=3D document.body) { + delta[0] -=3D document.body.offsetLeft; + delta[1] -=3D document.body.offsetTop; + } + + if (options.setLeft) element.style.left =3D (p[0] - delta[0] + op= tions.offsetLeft) + 'px'; + if (options.setTop) element.style.top =3D (p[1] - delta[1] + op= tions.offsetTop) + 'px'; + if (options.setWidth) element.style.width =3D source.offsetWidth + = 'px'; + if (options.setHeight) element.style.height =3D source.offsetHeight = + 'px'; + return element; + } +}; + +Object.extend(Element.Methods, { + getElementsBySelector: Element.Methods.select, + + childElements: Element.Methods.immediateDescendants +}); + +Element._attributeTranslations =3D { + write: { + names: { + className: 'class', + htmlFor: 'for' + }, + values: { } + } +}; + +if (Prototype.Browser.Opera) { + Element.Methods.getStyle =3D Element.Methods.getStyle.wrap( + function(proceed, element, style) { + switch (style) { + case 'left': case 'top': case 'right': case 'bottom': + if (proceed(element, 'position') =3D=3D=3D 'static') return nu= ll; + case 'height': case 'width': + if (!Element.visible(element)) return null; + + var dim =3D parseInt(proceed(element, style), 10); + + if (dim !=3D=3D element['offset' + style.capitalize()]) + return dim + 'px'; + + var properties; + if (style =3D=3D=3D 'height') { + properties =3D ['border-top-width', 'padding-top', + 'padding-bottom', 'border-bottom-width']; + } + else { + properties =3D ['border-left-width', 'padding-left', + 'padding-right', 'border-right-width']; + } + return properties.inject(dim, function(memo, property) { + var val =3D proceed(element, property); + return val =3D=3D=3D null ? memo : memo - parseInt(val, 10); + }) + 'px'; + default: return proceed(element, style); + } + } + ); + + Element.Methods.readAttribute =3D Element.Methods.readAttribute.wrap( + function(proceed, element, attribute) { + if (attribute =3D=3D=3D 'title') return element.title; + return proceed(element, attribute); + } + ); +} + +else if (Prototype.Browser.IE) { + Element.Methods.getOffsetParent =3D Element.Methods.getOffsetParent.wr= ap( + function(proceed, element) { + element =3D $(element); + if (!element.parentNode) return $(document.body); + var position =3D element.getStyle('position'); + if (position !=3D=3D 'static') return proceed(element); + element.setStyle({ position: 'relative' }); + var value =3D proceed(element); + element.setStyle({ position: position }); + return value; + } + ); + + $w('positionedOffset viewportOffset').each(function(method) { + Element.Methods[method] =3D Element.Methods[method].wrap( + function(proceed, element) { + element =3D $(element); + if (!element.parentNode) return Element._returnOffset(0, 0); + var position =3D element.getStyle('position'); + if (position !=3D=3D 'static') return proceed(element); + var offsetParent =3D element.getOffsetParent(); + if (offsetParent && offsetParent.getStyle('position') =3D=3D=3D = 'fixed') + offsetParent.setStyle({ zoom: 1 }); + element.setStyle({ position: 'relative' }); + var value =3D proceed(element); + element.setStyle({ position: position }); + return value; + } + ); + }); + + Element.Methods.getStyle =3D function(element, style) { + element =3D $(element); + style =3D (style =3D=3D 'float' || style =3D=3D 'cssFloat') ? 'style= Float' : style.camelize(); + var value =3D element.style[style]; + if (!value && element.currentStyle) value =3D element.currentStyle[s= tyle]; + + if (style =3D=3D 'opacity') { + if (value =3D (element.getStyle('filter') || '').match(/alpha\(opa= city=3D(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value =3D=3D 'auto') { + if ((style =3D=3D 'width' || style =3D=3D 'height') && (element.ge= tStyle('display') !=3D 'none')) + return element['offset' + style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity =3D function(element, value) { + function stripAlpha(filter){ + return filter.replace(/alpha\([^\)]*\)/gi,''); + } + element =3D $(element); + var currentStyle =3D element.currentStyle; + if ((currentStyle && !currentStyle.hasLayout) || + (!currentStyle && element.style.zoom =3D=3D 'normal')) + element.style.zoom =3D 1; + + var filter =3D element.getStyle('filter'), style =3D element.style; + if (value =3D=3D 1 || value =3D=3D=3D '') { + (filter =3D stripAlpha(filter)) ? + style.filter =3D filter : style.removeAttribute('filter'); + return element; + } else if (value < 0.00001) value =3D 0; + style.filter =3D stripAlpha(filter) + + 'alpha(opacity=3D' + (value * 100) + ')'; + return element; + }; + + Element._attributeTranslations =3D (function(){ + + var classProp =3D 'className', + forProp =3D 'for', + el =3D document.createElement('div'); + + el.setAttribute(classProp, 'x'); + + if (el.className !=3D=3D 'x') { + el.setAttribute('class', 'x'); + if (el.className =3D=3D=3D 'x') { + classProp =3D 'class'; + } + } + el =3D null; + + el =3D document.createElement('label'); + el.setAttribute(forProp, 'x'); + if (el.htmlFor !=3D=3D 'x') { + el.setAttribute('htmlFor', 'x'); + if (el.htmlFor =3D=3D=3D 'x') { + forProp =3D 'htmlFor'; + } + } + el =3D null; + + return { + read: { + names: { + 'class': classProp, + 'className': classProp, + 'for': forProp, + 'htmlFor': forProp + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute); + }, + _getAttr2: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _getAttrNode: function(element, attribute) { + var node =3D element.getAttributeNode(attribute); + return node ? node.value : ""; + }, + _getEv: (function(){ + + var el =3D document.createElement('div'), f; + el.onclick =3D Prototype.emptyFunction; + var value =3D el.getAttribute('onclick'); + + if (String(value).indexOf('{') > -1) { + f =3D function(element, attribute) { + attribute =3D element.getAttribute(attribute); + if (!attribute) return null; + attribute =3D attribute.toString(); + attribute =3D attribute.split('{')[1]; + attribute =3D attribute.split('}')[0]; + return attribute.strip(); + }; + } + else if (value =3D=3D=3D '') { + f =3D function(element, attribute) { + attribute =3D element.getAttribute(attribute); + if (!attribute) return null; + return attribute.strip(); + }; + } + el =3D null; + return f; + })(), + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null= ; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + return element.title; + } + } + } + } + })(); + + Element._attributeTranslations.write =3D { + names: Object.extend({ + cellpadding: 'cellPadding', + cellspacing: 'cellSpacing' + }, Element._attributeTranslations.read.names), + values: { + checked: function(element, value) { + element.checked =3D !!value; + }, + + style: function(element, value) { + element.style.cssText =3D value ? value : ''; + } + } + }; + + Element._attributeTranslations.has =3D {}; + + $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + + 'encType maxLength readOnly longDesc frameBorder').each(function(a= ttr) { + Element._attributeTranslations.write.names[attr.toLowerCase()] =3D a= ttr; + Element._attributeTranslations.has[attr.toLowerCase()] =3D attr; + }); + + (function(v) { + Object.extend(v, { + href: v._getAttr2, + src: v._getAttr2, + type: v._getAttr, + action: v._getAttrNode, + disabled: v._flag, + checked: v._flag, + readonly: v._flag, + multiple: v._flag, + onload: v._getEv, + onunload: v._getEv, + onclick: v._getEv, + ondblclick: v._getEv, + onmousedown: v._getEv, + onmouseup: v._getEv, + onmouseover: v._getEv, + onmousemove: v._getEv, + onmouseout: v._getEv, + onfocus: v._getEv, + onblur: v._getEv, + onkeypress: v._getEv, + onkeydown: v._getEv, + onkeyup: v._getEv, + onsubmit: v._getEv, + onreset: v._getEv, + onselect: v._getEv, + onchange: v._getEv + }); + })(Element._attributeTranslations.read.values); + + if (Prototype.BrowserFeatures.ElementExtensions) { + (function() { + function _descendants(element) { + var nodes =3D element.getElementsByTagName('*'), results =3D []; + for (var i =3D 0, node; node =3D nodes[i]; i++) + if (node.tagName !=3D=3D "!") // Filter out comment nodes. + results.push(node); + return results; + } + + Element.Methods.down =3D function(element, expression, index) { + element =3D $(element); + if (arguments.length =3D=3D 1) return element.firstDescendant(); + return Object.isNumber(expression) ? _descendants(element)[expre= ssion] : + Element.select(element, expression)[index || 0]; + } + })(); + } + +} + +else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgen= t)) { + Element.Methods.setOpacity =3D function(element, value) { + element =3D $(element); + element.style.opacity =3D (value =3D=3D 1) ? 0.999999 : + (value =3D=3D=3D '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +else if (Prototype.Browser.WebKit) { + Element.Methods.setOpacity =3D function(element, value) { + element =3D $(element); + element.style.opacity =3D (value =3D=3D 1 || value =3D=3D=3D '') ? '= ' : + (value < 0.00001) ? 0 : value; + + if (value =3D=3D 1) + if (element.tagName.toUpperCase() =3D=3D 'IMG' && element.width) { + element.width++; element.width--; + } else try { + var n =3D document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch (e) { } + + return element; + }; + + Element.Methods.cumulativeOffset =3D function(element) { + var valueT =3D 0, valueL =3D 0; + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + if (element.offsetParent =3D=3D document.body) + if (Element.getStyle(element, 'position') =3D=3D 'absolute') bre= ak; + + element =3D element.offsetParent; + } while (element); + + return Element._returnOffset(valueL, valueT); + }; +} + +if ('outerHTML' in document.documentElement) { + Element.Methods.replace =3D function(element, content) { + element =3D $(element); + + if (content && content.toElement) content =3D content.toElement(); + if (Object.isElement(content)) { + element.parentNode.replaceChild(content, element); + return element; + } + + content =3D Object.toHTML(content); + var parent =3D element.parentNode, tagName =3D parent.tagName.toUppe= rCase(); + + if (Element._insertionTranslations.tags[tagName]) { + var nextSibling =3D element.next(), + fragments =3D Element._getContentFromAnonymousElement(tagName,= content.stripScripts()); + parent.removeChild(element); + if (nextSibling) + fragments.each(function(node) { parent.insertBefore(node, nextSi= bling) }); + else + fragments.each(function(node) { parent.appendChild(node) }); + } + else element.outerHTML =3D content.stripScripts(); + + content.evalScripts.bind(content).defer(); + return element; + }; +} + +Element._returnOffset =3D function(l, t) { + var result =3D [l, t]; + result.left =3D l; + result.top =3D t; + return result; +}; + +Element._getContentFromAnonymousElement =3D function(tagName, html) { + var div =3D new Element('div'), + t =3D Element._insertionTranslations.tags[tagName]; + if (t) { + div.innerHTML =3D t[0] + html + t[1]; + for (var i =3D t[2]; i--; ) { + div =3D div.firstChild; + } + } + else { + div.innerHTML =3D html; + } + return $A(div.childNodes); +}; + +Element._insertionTranslations =3D { + before: function(element, node) { + element.parentNode.insertBefore(node, element); + }, + top: function(element, node) { + element.insertBefore(node, element.firstChild); + }, + bottom: function(element, node) { + element.appendChild(node); + }, + after: function(element, node) { + element.parentNode.insertBefore(node, element.nextSibling); + }, + tags: { + TABLE: ['', '
    ', 1], + TBODY: ['', '
    ', 2], + TR: ['', '
    ', 3], + TD: ['
    ', '
    ', 4], + SELECT: ['', 1] + } +}; + +(function() { + var tags =3D Element._insertionTranslations.tags; + Object.extend(tags, { + THEAD: tags.TBODY, + TFOOT: tags.TBODY, + TH: tags.TD + }); +})(); + +Element.Methods.Simulated =3D { + hasAttribute: function(element, attribute) { + attribute =3D Element._attributeTranslations.has[attribute] || attri= bute; + var node =3D $(element).getAttributeNode(attribute); + return !!(node && node.specified); + } +}; + +Element.Methods.ByTag =3D { }; + +Object.extend(Element, Element.Methods); + +(function(div) { + + if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) = { + window.HTMLElement =3D { }; + window.HTMLElement.prototype =3D div['__proto__']; + Prototype.BrowserFeatures.ElementExtensions =3D true; + } + + div =3D null; + +})(document.createElement('div')); + +Element.extend =3D (function() { + + function checkDeficiency(tagName) { + if (typeof window.Element !=3D 'undefined') { + var proto =3D window.Element.prototype; + if (proto) { + var id =3D '_' + (Math.random()+'').slice(2), + el =3D document.createElement(tagName); + proto[id] =3D 'x'; + var isBuggy =3D (el[id] !=3D=3D 'x'); + delete proto[id]; + el =3D null; + return isBuggy; + } + } + return false; + } + + function extendElementWith(element, methods) { + for (var property in methods) { + var value =3D methods[property]; + if (Object.isFunction(value) && !(property in element)) + element[property] =3D value.methodize(); + } + } + + var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY =3D checkDeficiency('object'); + + if (Prototype.BrowserFeatures.SpecificElementExtensions) { + if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { + return function(element) { + if (element && typeof element._extendedByPrototype =3D=3D 'undef= ined') { + var t =3D element.tagName; + if (t && (/^(?:object|applet|embed)$/i.test(t))) { + extendElementWith(element, Element.Methods); + extendElementWith(element, Element.Methods.Simulated); + extendElementWith(element, Element.Methods.ByTag[t.toUpperCa= se()]); + } + } + return element; + } + } + return Prototype.K; + } + + var Methods =3D { }, ByTag =3D Element.Methods.ByTag; + + var extend =3D Object.extend(function(element) { + if (!element || typeof element._extendedByPrototype !=3D 'undefined'= || + element.nodeType !=3D 1 || element =3D=3D window) return element= ; + + var methods =3D Object.clone(Methods), + tagName =3D element.tagName.toUpperCase(); + + if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); + + extendElementWith(element, methods); + + element._extendedByPrototype =3D Prototype.emptyFunction; + return element; + + }, { + refresh: function() { + if (!Prototype.BrowserFeatures.ElementExtensions) { + Object.extend(Methods, Element.Methods); + Object.extend(Methods, Element.Methods.Simulated); + } + } + }); + + extend.refresh(); + return extend; +})(); + +if (document.documentElement.hasAttribute) { + Element.hasAttribute =3D function(element, attribute) { + return element.hasAttribute(attribute); + }; +} +else { + Element.hasAttribute =3D Element.Methods.Simulated.hasAttribute; +} + +Element.addMethods =3D function(methods) { + var F =3D Prototype.BrowserFeatures, T =3D Element.Methods.ByTag; + + if (!methods) { + Object.extend(Form, Form.Methods); + Object.extend(Form.Element, Form.Element.Methods); + Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods) + }); + } + + if (arguments.length =3D=3D 2) { + var tagName =3D methods; + methods =3D arguments[1]; + } + + if (!tagName) Object.extend(Element.Methods, methods || { }); + else { + if (Object.isArray(tagName)) tagName.each(extend); + else extend(tagName); + } + + function extend(tagName) { + tagName =3D tagName.toUpperCase(); + if (!Element.Methods.ByTag[tagName]) + Element.Methods.ByTag[tagName] =3D { }; + Object.extend(Element.Methods.ByTag[tagName], methods); + } + + function copy(methods, destination, onlyIfAbsent) { + onlyIfAbsent =3D onlyIfAbsent || false; + for (var property in methods) { + var value =3D methods[property]; + if (!Object.isFunction(value)) continue; + if (!onlyIfAbsent || !(property in destination)) + destination[property] =3D value.methodize(); + } + } + + function findDOMClass(tagName) { + var klass; + var trans =3D { + "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", + "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList= ", + "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Headi= ng", + "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", + "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTIO= N": + "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD"= : + "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", = "TR": + "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": + "FrameSet", "IFRAME": "IFrame" + }; + if (trans[tagName]) klass =3D 'HTML' + trans[tagName] + 'Element'; + if (window[klass]) return window[klass]; + klass =3D 'HTML' + tagName + 'Element'; + if (window[klass]) return window[klass]; + klass =3D 'HTML' + tagName.capitalize() + 'Element'; + if (window[klass]) return window[klass]; + + var element =3D document.createElement(tagName), + proto =3D element['__proto__'] || element.constructor.prototype; + + element =3D null; + return proto; + } + + var elementPrototype =3D window.HTMLElement ? HTMLElement.prototype : + Element.prototype; + + if (F.ElementExtensions) { + copy(Element.Methods, elementPrototype); + copy(Element.Methods.Simulated, elementPrototype, true); + } + + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass =3D findDOMClass(tag); + if (Object.isUndefined(klass)) continue; + copy(T[tag], klass.prototype); + } + } + + Object.extend(Element, Element.Methods); + delete Element.ByTag; + + if (Element.extend.refresh) Element.extend.refresh(); + Element.cache =3D { }; +}; + + +document.viewport =3D { + + getDimensions: function() { + return { width: this.getWidth(), height: this.getHeight() }; + }, + + getScrollOffsets: function() { + return Element._returnOffset( + window.pageXOffset || document.documentElement.scrollLeft || docum= ent.body.scrollLeft, + window.pageYOffset || document.documentElement.scrollTop || docum= ent.body.scrollTop); + } +}; + +(function(viewport) { + var B =3D Prototype.Browser, doc =3D document, element, property =3D {= }; + + function getRootElement() { + if (B.WebKit && !doc.evaluate) + return document; + + if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) + return document.body; + + return document.documentElement; + } + + function define(D) { + if (!element) element =3D getRootElement(); + + property[D] =3D 'client' + D; + + viewport['get' + D] =3D function() { return element[property[D]] }; + return viewport['get' + D](); + } + + viewport.getWidth =3D define.curry('Width'); + + viewport.getHeight =3D define.curry('Height'); +})(document.viewport); + + +Element.Storage =3D { + UID: 1 +}; + +Element.addMethods({ + getStorage: function(element) { + if (!(element =3D $(element))) return; + + var uid; + if (element =3D=3D=3D window) { + uid =3D 0; + } else { + if (typeof element._prototypeUID =3D=3D=3D "undefined") + element._prototypeUID =3D Element.Storage.UID++; + uid =3D element._prototypeUID; + } + + if (!Element.Storage[uid]) + Element.Storage[uid] =3D $H(); + + return Element.Storage[uid]; + }, + + store: function(element, key, value) { + if (!(element =3D $(element))) return; + + if (arguments.length =3D=3D=3D 2) { + Element.getStorage(element).update(key); + } else { + Element.getStorage(element).set(key, value); + } + + return element; + }, + + retrieve: function(element, key, defaultValue) { + if (!(element =3D $(element))) return; + var hash =3D Element.getStorage(element), value =3D hash.get(key); + + if (Object.isUndefined(value)) { + hash.set(key, defaultValue); + value =3D defaultValue; + } + + return value; + }, + + clone: function(element, deep) { + if (!(element =3D $(element))) return; + var clone =3D element.cloneNode(deep); + clone._prototypeUID =3D void 0; + if (deep) { + var descendants =3D Element.select(clone, '*'), + i =3D descendants.length; + while (i--) { + descendants[i]._prototypeUID =3D void 0; + } + } + return Element.extend(clone); + }, + + purge: function(element) { + if (!(element =3D $(element))) return; + purgeElement(element); + + var descendants =3D element.getElementsByTagName('*'), + i =3D descendants.length; + + while (i--) purgeElement(descendants[i]); + + return null; + } +}); + +(function() { + + function toDecimal(pctString) { + var match =3D pctString.match(/^(\d+)%?$/i); + if (!match) return null; + return (Number(match[1]) / 100); + } + + function getPixelValue(value, property) { + if (Object.isElement(value)) { + element =3D value; + value =3D element.getStyle(property); + } + if (value =3D=3D=3D null) { + return null; + } + + if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { + return window.parseFloat(value); + } + + if (/\d/.test(value) && element.runtimeStyle) { + var style =3D element.style.left, rStyle =3D element.runtimeStyle.= left; + element.runtimeStyle.left =3D element.currentStyle.left; + element.style.left =3D value || 0; + value =3D element.style.pixelLeft; + element.style.left =3D style; + element.runtimeStyle.left =3D rStyle; + + return value; + } + + if (value.include('%')) { + var decimal =3D toDecimal(value); + var whole; + if (property.include('left') || property.include('right') || + property.include('width')) { + whole =3D $(element.parentNode).measure('width'); + } else if (property.include('top') || property.include('bottom') |= | + property.include('height')) { + whole =3D $(element.parentNode).measure('height'); + } + + return whole * decimal; + } + + return 0; + } + + function toCSSPixels(number) { + if (Object.isString(number) && number.endsWith('px')) { + return number; + } + return number + 'px'; + } + + function isDisplayed(element) { + var originalElement =3D element; + while (element && element.parentNode) { + var display =3D element.getStyle('display'); + if (display =3D=3D=3D 'none') { + return false; + } + element =3D $(element.parentNode); + } + return true; + } + + var hasLayout =3D Prototype.K; + if ('currentStyle' in document.documentElement) { + hasLayout =3D function(element) { + if (!element.currentStyle.hasLayout) { + element.style.zoom =3D 1; + } + return element; + }; + } + + function cssNameFor(key) { + if (key.include('border')) key =3D key + '-width'; + return key.camelize(); + } + + Element.Layout =3D Class.create(Hash, { + initialize: function($super, element, preCompute) { + $super(); + this.element =3D $(element); + + Element.Layout.PROPERTIES.each( function(property) { + this._set(property, null); + }, this); + + if (preCompute) { + this._preComputing =3D true; + this._begin(); + Element.Layout.PROPERTIES.each( this._compute, this ); + this._end(); + this._preComputing =3D false; + } + }, + + _set: function(property, value) { + return Hash.prototype.set.call(this, property, value); + }, + + set: function(property, value) { + throw "Properties of Element.Layout are read-only."; + }, + + get: function($super, property) { + var value =3D $super(property); + return value =3D=3D=3D null ? this._compute(property) : value; + }, + + _begin: function() { + if (this._prepared) return; + + var element =3D this.element; + if (isDisplayed(element)) { + this._prepared =3D true; + return; + } + + var originalStyles =3D { + position: element.style.position || '', + width: element.style.width || '', + visibility: element.style.visibility || '', + display: element.style.display || '' + }; + + element.store('prototype_original_styles', originalStyles); + + var position =3D element.getStyle('position'), + width =3D element.getStyle('width'); + + element.setStyle({ + position: 'absolute', + visibility: 'hidden', + display: 'block' + }); + + var positionedWidth =3D element.getStyle('width'); + + var newWidth; + if (width && (positionedWidth =3D=3D=3D width)) { + newWidth =3D getPixelValue(width); + } else if (width && (position =3D=3D=3D 'absolute' || position =3D= =3D=3D 'fixed')) { + newWidth =3D getPixelValue(width); + } else { + var parent =3D element.parentNode, pLayout =3D $(parent).getLayo= ut(); + + newWidth =3D pLayout.get('width') - + this.get('margin-left') - + this.get('border-left') - + this.get('padding-left') - + this.get('padding-right') - + this.get('border-right') - + this.get('margin-right'); + } + + element.setStyle({ width: newWidth + 'px' }); + + this._prepared =3D true; + }, + + _end: function() { + var element =3D this.element; + var originalStyles =3D element.retrieve('prototype_original_styles= '); + element.store('prototype_original_styles', null); + element.setStyle(originalStyles); + this._prepared =3D false; + }, + + _compute: function(property) { + var COMPUTATIONS =3D Element.Layout.COMPUTATIONS; + if (!(property in COMPUTATIONS)) { + throw "Property not found."; + } + return this._set(property, COMPUTATIONS[property].call(this, this.= element)); + }, + + toObject: function() { + var args =3D $A(arguments); + var keys =3D (args.length =3D=3D=3D 0) ? Element.Layout.PROPERTIES= : + args.join(' ').split(' '); + var obj =3D {}; + keys.each( function(key) { + if (!Element.Layout.PROPERTIES.include(key)) return; + var value =3D this.get(key); + if (value !=3D null) obj[key] =3D value; + }, this); + return obj; + }, + + toHash: function() { + var obj =3D this.toObject.apply(this, arguments); + return new Hash(obj); + }, + + toCSS: function() { + var args =3D $A(arguments); + var keys =3D (args.length =3D=3D=3D 0) ? Element.Layout.PROPERTIES= : + args.join(' ').split(' '); + var css =3D {}; + + keys.each( function(key) { + if (!Element.Layout.PROPERTIES.include(key)) return; + if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; + + var value =3D this.get(key); + if (value !=3D null) css[cssNameFor(key)] =3D value + 'px'; + }, this); + return css; + }, + + inspect: function() { + return "#"; + } + }); + + Object.extend(Element.Layout, { + PROPERTIES: $w('height width top left right bottom border-left borde= r-right border-top border-bottom padding-left padding-right padding-top p= adding-bottom margin-top margin-bottom margin-left margin-right padding-b= ox-width padding-box-height border-box-width border-box-height margin-box= -width margin-box-height'), + + COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margi= n-box-width margin-box-height border-box-width border-box-height'), + + COMPUTATIONS: { + 'height': function(element) { + if (!this._preComputing) this._begin(); + + var bHeight =3D this.get('border-box-height'); + if (bHeight <=3D 0) return 0; + + var bTop =3D this.get('border-top'), + bBottom =3D this.get('border-bottom'); + + var pTop =3D this.get('padding-top'), + pBottom =3D this.get('padding-bottom'); + + if (!this._preComputing) this._end(); + + return bHeight - bTop - bBottom - pTop - pBottom; + }, + + 'width': function(element) { + if (!this._preComputing) this._begin(); + + var bWidth =3D this.get('border-box-width'); + if (bWidth <=3D 0) return 0; + + var bLeft =3D this.get('border-left'), + bRight =3D this.get('border-right'); + + var pLeft =3D this.get('padding-left'), + pRight =3D this.get('padding-right'); + + if (!this._preComputing) this._end(); + + return bWidth - bLeft - bRight - pLeft - pRight; + }, + + 'padding-box-height': function(element) { + var height =3D this.get('height'), + pTop =3D this.get('padding-top'), + pBottom =3D this.get('padding-bottom'); + + return height + pTop + pBottom; + }, + + 'padding-box-width': function(element) { + var width =3D this.get('width'), + pLeft =3D this.get('padding-left'), + pRight =3D this.get('padding-right'); + + return width + pLeft + pRight; + }, + + 'border-box-height': function(element) { + return element.offsetHeight; + }, + + 'border-box-width': function(element) { + return element.offsetWidth; + }, + + 'margin-box-height': function(element) { + var bHeight =3D this.get('border-box-height'), + mTop =3D this.get('margin-top'), + mBottom =3D this.get('margin-bottom'); + + if (bHeight <=3D 0) return 0; + + return bHeight + mTop + mBottom; + }, + + 'margin-box-width': function(element) { + var bWidth =3D this.get('border-box-width'), + mLeft =3D this.get('margin-left'), + mRight =3D this.get('margin-right'); + + if (bWidth <=3D 0) return 0; + + return bWidth + mLeft + mRight; + }, + + 'top': function(element) { + var offset =3D element.positionedOffset(); + return offset.top; + }, + + 'bottom': function(element) { + var offset =3D element.positionedOffset(), + parent =3D element.getOffsetParent(), + pHeight =3D parent.measure('height'); + + var mHeight =3D this.get('border-box-height'); + + return pHeight - mHeight - offset.top; + }, + + 'left': function(element) { + var offset =3D element.positionedOffset(); + return offset.left; + }, + + 'right': function(element) { + var offset =3D element.positionedOffset(), + parent =3D element.getOffsetParent(), + pWidth =3D parent.measure('width'); + + var mWidth =3D this.get('border-box-width'); + + return pWidth - mWidth - offset.left; + }, + + 'padding-top': function(element) { + return getPixelValue(element, 'paddingTop'); + }, + + 'padding-bottom': function(element) { + return getPixelValue(element, 'paddingBottom'); + }, + + 'padding-left': function(element) { + return getPixelValue(element, 'paddingLeft'); + }, + + 'padding-right': function(element) { + return getPixelValue(element, 'paddingRight'); + }, + + 'border-top': function(element) { + return Object.isNumber(element.clientTop) ? element.clientTop : + getPixelValue(element, 'borderTopWidth'); + }, + + 'border-bottom': function(element) { + return Object.isNumber(element.clientBottom) ? element.clientBot= tom : + getPixelValue(element, 'borderBottomWidth'); + }, + + 'border-left': function(element) { + return Object.isNumber(element.clientLeft) ? element.clientLeft = : + getPixelValue(element, 'borderLeftWidth'); + }, + + 'border-right': function(element) { + return Object.isNumber(element.clientRight) ? element.clientRigh= t : + getPixelValue(element, 'borderRightWidth'); + }, + + 'margin-top': function(element) { + return getPixelValue(element, 'marginTop'); + }, + + 'margin-bottom': function(element) { + return getPixelValue(element, 'marginBottom'); + }, + + 'margin-left': function(element) { + return getPixelValue(element, 'marginLeft'); + }, + + 'margin-right': function(element) { + return getPixelValue(element, 'marginRight'); + } + } + }); + + if ('getBoundingClientRect' in document.documentElement) { + Object.extend(Element.Layout.COMPUTATIONS, { + 'right': function(element) { + var parent =3D hasLayout(element.getOffsetParent()); + var rect =3D element.getBoundingClientRect(), + pRect =3D parent.getBoundingClientRect(); + + return (pRect.right - rect.right).round(); + }, + + 'bottom': function(element) { + var parent =3D hasLayout(element.getOffsetParent()); + var rect =3D element.getBoundingClientRect(), + pRect =3D parent.getBoundingClientRect(); + + return (pRect.bottom - rect.bottom).round(); + } + }); + } + + Element.Offset =3D Class.create({ + initialize: function(left, top) { + this.left =3D left.round(); + this.top =3D top.round(); + + this[0] =3D this.left; + this[1] =3D this.top; + }, + + relativeTo: function(offset) { + return new Element.Offset( + this.left - offset.left, + this.top - offset.top + ); + }, + + inspect: function() { + return "#".interpolate(t= his); + }, + + toString: function() { + return "[#{left}, #{top}]".interpolate(this); + }, + + toArray: function() { + return [this.left, this.top]; + } + }); + + function getLayout(element, preCompute) { + return new Element.Layout(element, preCompute); + } + + function measure(element, property) { + return $(element).getLayout().get(property); + } + + function getDimensions(element) { + var layout =3D $(element).getLayout(); + return { + width: layout.get('width'), + height: layout.get('height') + }; + } + + function getOffsetParent(element) { + if (isDetached(element)) return $(document.body); + + var isInline =3D (Element.getStyle(element, 'display') =3D=3D=3D 'in= line'); + if (!isInline && element.offsetParent) return $(element.offsetParent= ); + if (element =3D=3D=3D document.body) return $(element); + + while ((element =3D element.parentNode) && element !=3D=3D document.= body) { + if (Element.getStyle(element, 'position') !=3D=3D 'static') { + return (element.nodeName =3D=3D=3D 'HTML') ? $(document.body) : = $(element); + } + } + + return $(document.body); + } + + + function cumulativeOffset(element) { + var valueT =3D 0, valueL =3D 0; + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + element =3D element.offsetParent; + } while (element); + return new Element.Offset(valueL, valueT); + } + + function positionedOffset(element) { + var layout =3D element.getLayout(); + + var valueT =3D 0, valueL =3D 0; + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + element =3D element.offsetParent; + if (element) { + if (isBody(element)) break; + var p =3D Element.getStyle(element, 'position'); + if (p !=3D=3D 'static') break; + } + } while (element); + + valueL -=3D layout.get('margin-top'); + valueT -=3D layout.get('margin-left'); + + return new Element.Offset(valueL, valueT); + } + + function cumulativeScrollOffset(element) { + var valueT =3D 0, valueL =3D 0; + do { + valueT +=3D element.scrollTop || 0; + valueL +=3D element.scrollLeft || 0; + element =3D element.parentNode; + } while (element); + return new Element.Offset(valueL, valueT); + } + + function viewportOffset(forElement) { + var valueT =3D 0, valueL =3D 0, docBody =3D document.body; + + var element =3D forElement; + do { + valueT +=3D element.offsetTop || 0; + valueL +=3D element.offsetLeft || 0; + if (element.offsetParent =3D=3D docBody && + Element.getStyle(element, 'position') =3D=3D 'absolute') break; + } while (element =3D element.offsetParent); + + element =3D forElement; + do { + if (element !=3D docBody) { + valueT -=3D element.scrollTop || 0; + valueL -=3D element.scrollLeft || 0; + } + } while (element =3D element.parentNode); + return new Element.Offset(valueL, valueT); + } + + function absolutize(element) { + element =3D $(element); + + if (Element.getStyle(element, 'position') =3D=3D=3D 'absolute') { + return element; + } + + var offsetParent =3D getOffsetParent(element); + var eOffset =3D element.viewportOffset(), + pOffset =3D offsetParent.viewportOffset(); + + var offset =3D eOffset.relativeTo(pOffset); + var layout =3D element.getLayout(); + + element.store('prototype_absolutize_original_styles', { + left: element.getStyle('left'), + top: element.getStyle('top'), + width: element.getStyle('width'), + height: element.getStyle('height') + }); + + element.setStyle({ + position: 'absolute', + top: offset.top + 'px', + left: offset.left + 'px', + width: layout.get('width') + 'px', + height: layout.get('height') + 'px' + }); + + return element; + } + + function relativize(element) { + element =3D $(element); + if (Element.getStyle(element, 'position') =3D=3D=3D 'relative') { + return element; + } + + var originalStyles =3D + element.retrieve('prototype_absolutize_original_styles'); + + if (originalStyles) element.setStyle(originalStyles); + return element; + } + + Element.addMethods({ + getLayout: getLayout, + measure: measure, + getDimensions: getDimensions, + getOffsetParent: getOffsetParent, + cumulativeOffset: cumulativeOffset, + positionedOffset: positionedOffset, + cumulativeScrollOffset: cumulativeScrollOffset, + viewportOffset: viewportOffset, + absolutize: absolutize, + relativize: relativize + }); + + function isBody(element) { + return element.nodeName.toUpperCase() =3D=3D=3D 'BODY'; + } + + function isDetached(element) { + return element !=3D=3D document.body && + !Element.descendantOf(element, document.body); + } + + if ('getBoundingClientRect' in document.documentElement) { + Element.addMethods({ + viewportOffset: function(element) { + element =3D $(element); + if (isDetached(element)) return new Element.Offset(0, 0); + + var rect =3D element.getBoundingClientRect(), + docEl =3D document.documentElement; + return new Element.Offset(rect.left - docEl.clientLeft, + rect.top - docEl.clientTop); + }, + + positionedOffset: function(element) { + element =3D $(element); + var parent =3D element.getOffsetParent(); + if (isDetached(element)) return new Element.Offset(0, 0); + + if (element.offsetParent && + element.offsetParent.nodeName.toUpperCase() =3D=3D=3D 'HTML') { + return positionedOffset(element); + } + + var eOffset =3D element.viewportOffset(), + pOffset =3D isBody(parent) ? viewportOffset(parent) : + parent.viewportOffset(); + var retOffset =3D eOffset.relativeTo(pOffset); + + var layout =3D element.getLayout(); + var top =3D retOffset.top - layout.get('margin-top'); + var left =3D retOffset.left - layout.get('margin-left'); + + return new Element.Offset(left, top); + } + }); + } +})(); +window.$$ =3D function() { + var expression =3D $A(arguments).join(', '); + return Prototype.Selector.select(expression, document); +}; + +Prototype.Selector =3D (function() { + + function select() { + throw new Error('Method "Prototype.Selector.select" must be defined.= '); + } + + function match() { + throw new Error('Method "Prototype.Selector.match" must be defined.'= ); + } + + function find(elements, expression, index) { + index =3D index || 0; + var match =3D Prototype.Selector.match, length =3D elements.length, = matchIndex =3D 0, i; + + for (i =3D 0; i < length; i++) { + if (match(elements[i], expression) && index =3D=3D matchIndex++) { + return Element.extend(elements[i]); + } + } + } + + function extendElements(elements) { + for (var i =3D 0, length =3D elements.length; i < length; i++) { + Element.extend(elements[i]); + } + return elements; + } + + + var K =3D Prototype.K; + + return { + select: select, + match: match, + find: find, + extendElements: (Element.extend =3D=3D=3D K) ? K : extendElements, + extendElement: Element.extend + }; +})(); +Prototype._original_property =3D window.Sizzle; +/*! + * Sizzle CSS Selector Engine - v1.0 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker =3D /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'= "]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)= /g, + done =3D 0, + toString =3D Object.prototype.toString, + hasDuplicate =3D false, + baseHasDuplicate =3D true; + +[0, 0].sort(function(){ + baseHasDuplicate =3D false; + return 0; +}); + +var Sizzle =3D function(selector, context, results, seed) { + results =3D results || []; + var origContext =3D context =3D context || document; + + if ( context.nodeType !=3D=3D 1 && context.nodeType !=3D=3D 9 ) { + return []; + } + + if ( !selector || typeof selector !=3D=3D "string" ) { + return results; + } + + var parts =3D [], m, set, checkSet, check, mode, extra, prune =3D true,= contextXML =3D isXML(context), + soFar =3D selector; + + while ( (chunker.exec(""), m =3D chunker.exec(soFar)) !=3D=3D null ) { + soFar =3D m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra =3D m[3]; + break; + } + } + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + if ( parts.length =3D=3D=3D 2 && Expr.relative[ parts[0] ] ) { + set =3D posProcess( parts[0] + parts[1], context ); + } else { + set =3D Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector =3D parts.shift(); + + if ( Expr.relative[ selector ] ) + selector +=3D parts.shift(); + + set =3D posProcess( selector, set ); + } + } + } else { + if ( !seed && parts.length > 1 && context.nodeType =3D=3D=3D 9 && !con= textXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.leng= th - 1]) ) { + var ret =3D Sizzle.find( parts.shift(), context, contextXML ); + context =3D ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.se= t[0]; + } + + if ( context ) { + var ret =3D seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length =3D=3D=3D 1 && (parts[0] =3D=3D= =3D "~" || parts[0] =3D=3D=3D "+") && context.parentNode ? context.parent= Node : context, contextXML ); + set =3D ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; + + if ( parts.length > 0 ) { + checkSet =3D makeArray(set); + } else { + prune =3D false; + } + + while ( parts.length ) { + var cur =3D parts.pop(), pop =3D cur; + + if ( !Expr.relative[ cur ] ) { + cur =3D ""; + } else { + pop =3D parts.pop(); + } + + if ( pop =3D=3D null ) { + pop =3D context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + } else { + checkSet =3D parts =3D []; + } + } + + if ( !checkSet ) { + checkSet =3D set; + } + + if ( !checkSet ) { + throw "Syntax error, unrecognized expression: " + (cur || selector); + } + + if ( toString.call(checkSet) =3D=3D=3D "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + } else if ( context && context.nodeType =3D=3D=3D 1 ) { + for ( var i =3D 0; checkSet[i] !=3D null; i++ ) { + if ( checkSet[i] && (checkSet[i] =3D=3D=3D true || checkSet[i].nodeT= ype =3D=3D=3D 1 && contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + } else { + for ( var i =3D 0; checkSet[i] !=3D null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType =3D=3D=3D 1 ) { + results.push( set[i] ); + } + } + } + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort =3D function(results){ + if ( sortOrder ) { + hasDuplicate =3D baseHasDuplicate; + results.sort(sortOrder); + + if ( hasDuplicate ) { + for ( var i =3D 1; i < results.length; i++ ) { + if ( results[i] =3D=3D=3D results[i-1] ) { + results.splice(i--, 1); + } + } + } + } + + return results; +}; + +Sizzle.matches =3D function(expr, set){ + return Sizzle(expr, null, null, set); +}; + +Sizzle.find =3D function(expr, context, isXML){ + var set, match; + + if ( !expr ) { + return []; + } + + for ( var i =3D 0, l =3D Expr.order.length; i < l; i++ ) { + var type =3D Expr.order[i], match; + + if ( (match =3D Expr.leftMatch[ type ].exec( expr )) ) { + var left =3D match[1]; + match.splice(1,1); + + if ( left.substr( left.length - 1 ) !=3D=3D "\\" ) { + match[1] =3D (match[1] || "").replace(/\\/g, ""); + set =3D Expr.find[ type ]( match, context, isXML ); + if ( set !=3D null ) { + expr =3D expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set =3D context.getElementsByTagName("*"); + } + + return {set: set, expr: expr}; +}; + +Sizzle.filter =3D function(expr, set, inplace, not){ + var old =3D expr, result =3D [], curLoop =3D set, match, anyFound, + isXMLFilter =3D set && set[0] && isXML(set[0]); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match =3D Expr.match[ type ].exec( expr )) !=3D null ) { + var filter =3D Expr.filter[ type ], found, item; + anyFound =3D false; + + if ( curLoop =3D=3D result ) { + result =3D []; + } + + if ( Expr.preFilter[ type ] ) { + match =3D Expr.preFilter[ type ]( match, curLoop, inplace, result, = not, isXMLFilter ); + + if ( !match ) { + anyFound =3D found =3D true; + } else if ( match =3D=3D=3D true ) { + continue; + } + } + + if ( match ) { + for ( var i =3D 0; (item =3D curLoop[i]) !=3D null; i++ ) { + if ( item ) { + found =3D filter( item, match, i, curLoop ); + var pass =3D not ^ !!found; + + if ( inplace && found !=3D null ) { + if ( pass ) { + anyFound =3D true; + } else { + curLoop[i] =3D false; + } + } else if ( pass ) { + result.push( item ); + anyFound =3D true; + } + } + } + } + + if ( found !=3D=3D undefined ) { + if ( !inplace ) { + curLoop =3D result; + } + + expr =3D expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + if ( expr =3D=3D old ) { + if ( anyFound =3D=3D null ) { + throw "Syntax error, unrecognized expression: " + expr; + } else { + break; + } + } + + old =3D expr; + } + + return curLoop; +}; + +var Expr =3D Sizzle.selectors =3D { + order: [ "ID", "NAME", "TAG" ], + match: { + ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, + NAME: /\[name=3D['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=3D)\s*(['"]*)(.*?)= \3|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=3D[^-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2= \(\)]*)+)\2\))?/ + }, + leftMatch: {}, + attrMap: { + "class": "className", + "for": "htmlFor" + }, + attrHandle: { + href: function(elem){ + return elem.getAttribute("href"); + } + }, + relative: { + "+": function(checkSet, part, isXML){ + var isPartStr =3D typeof part =3D=3D=3D "string", + isTag =3D isPartStr && !/\W/.test(part), + isPartStrNotTag =3D isPartStr && !isTag; + + if ( isTag && !isXML ) { + part =3D part.toUpperCase(); + } + + for ( var i =3D 0, l =3D checkSet.length, elem; i < l; i++ ) { + if ( (elem =3D checkSet[i]) ) { + while ( (elem =3D elem.previousSibling) && elem.nodeType !=3D=3D 1 = ) {} + + checkSet[i] =3D isPartStrNotTag || elem && elem.nodeName =3D=3D=3D = part ? + elem || false : + elem =3D=3D=3D part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + ">": function(checkSet, part, isXML){ + var isPartStr =3D typeof part =3D=3D=3D "string"; + + if ( isPartStr && !/\W/.test(part) ) { + part =3D isXML ? part : part.toUpperCase(); + + for ( var i =3D 0, l =3D checkSet.length; i < l; i++ ) { + var elem =3D checkSet[i]; + if ( elem ) { + var parent =3D elem.parentNode; + checkSet[i] =3D parent.nodeName =3D=3D=3D part ? parent : false; + } + } + } else { + for ( var i =3D 0, l =3D checkSet.length; i < l; i++ ) { + var elem =3D checkSet[i]; + if ( elem ) { + checkSet[i] =3D isPartStr ? + elem.parentNode : + elem.parentNode =3D=3D=3D part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + "": function(checkSet, part, isXML){ + var doneName =3D done++, checkFn =3D dirCheck; + + if ( !/\W/.test(part) ) { + var nodeCheck =3D part =3D isXML ? part : part.toUpperCase(); + checkFn =3D dirNodeCheck; + } + + checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); + }, + "~": function(checkSet, part, isXML){ + var doneName =3D done++, checkFn =3D dirCheck; + + if ( typeof part =3D=3D=3D "string" && !/\W/.test(part) ) { + var nodeCheck =3D part =3D isXML ? part : part.toUpperCase(); + checkFn =3D dirNodeCheck; + } + + checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML= ); + } + }, + find: { + ID: function(match, context, isXML){ + if ( typeof context.getElementById !=3D=3D "undefined" && !isXML ) { + var m =3D context.getElementById(match[1]); + return m ? [m] : []; + } + }, + NAME: function(match, context, isXML){ + if ( typeof context.getElementsByName !=3D=3D "undefined" ) { + var ret =3D [], results =3D context.getElementsByName(match[1]); + + for ( var i =3D 0, l =3D results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") =3D=3D=3D match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length =3D=3D=3D 0 ? null : ret; + } + }, + TAG: function(match, context){ + return context.getElementsByTagName(match[1]); + } + }, + preFilter: { + CLASS: function(match, curLoop, inplace, result, not, isXML){ + match =3D " " + match[1].replace(/\\/g, "") + " "; + + if ( isXML ) { + return match; + } + + for ( var i =3D 0, elem; (elem =3D curLoop[i]) !=3D null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(= match) >=3D 0) ) { + if ( !inplace ) + result.push( elem ); + } else if ( inplace ) { + curLoop[i] =3D false; + } + } + } + + return false; + }, + ID: function(match){ + return match[1].replace(/\\/g, ""); + }, + TAG: function(match, curLoop){ + for ( var i =3D 0; curLoop[i] =3D=3D=3D false; i++ ){} + return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperC= ase(); + }, + CHILD: function(match){ + if ( match[1] =3D=3D "nth" ) { + var test =3D /(-?)(\d*)n((?:\+|-)?\d*)/.exec( + match[2] =3D=3D "even" && "2n" || match[2] =3D=3D "odd" && "2n+1" |= | + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + match[2] =3D (test[1] + (test[2] || 1)) - 0; + match[3] =3D test[3] - 0; + } + + match[0] =3D done++; + + return match; + }, + ATTR: function(match, curLoop, inplace, result, not, isXML){ + var name =3D match[1].replace(/\\/g, ""); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] =3D Expr.attrMap[name]; + } + + if ( match[2] =3D=3D=3D "~=3D" ) { + match[4] =3D " " + match[4] + " "; + } + + return match; + }, + PSEUDO: function(match, curLoop, inplace, result, not){ + if ( match[1] =3D=3D=3D "not" ) { + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match= [3]) ) { + match[3] =3D Sizzle(match[3], null, null, curLoop); + } else { + var ret =3D Sizzle.filter(match[3], curLoop, inplace, true ^ not); + if ( !inplace ) { + result.push.apply( result, ret ); + } + return false; + } + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test(= match[0] ) ) { + return true; + } + + return match; + }, + POS: function(match){ + match.unshift( true ); + return match; + } + }, + filters: { + enabled: function(elem){ + return elem.disabled =3D=3D=3D false && elem.type !=3D=3D "hidden"; + }, + disabled: function(elem){ + return elem.disabled =3D=3D=3D true; + }, + checked: function(elem){ + return elem.checked =3D=3D=3D true; + }, + selected: function(elem){ + elem.parentNode.selectedIndex; + return elem.selected =3D=3D=3D true; + }, + parent: function(elem){ + return !!elem.firstChild; + }, + empty: function(elem){ + return !elem.firstChild; + }, + has: function(elem, i, match){ + return !!Sizzle( match[3], elem ).length; + }, + header: function(elem){ + return /h\d/i.test( elem.nodeName ); + }, + text: function(elem){ + return "text" =3D=3D=3D elem.type; + }, + radio: function(elem){ + return "radio" =3D=3D=3D elem.type; + }, + checkbox: function(elem){ + return "checkbox" =3D=3D=3D elem.type; + }, + file: function(elem){ + return "file" =3D=3D=3D elem.type; + }, + password: function(elem){ + return "password" =3D=3D=3D elem.type; + }, + submit: function(elem){ + return "submit" =3D=3D=3D elem.type; + }, + image: function(elem){ + return "image" =3D=3D=3D elem.type; + }, + reset: function(elem){ + return "reset" =3D=3D=3D elem.type; + }, + button: function(elem){ + return "button" =3D=3D=3D elem.type || elem.nodeName.toUpperCase() =3D= =3D=3D "BUTTON"; + }, + input: function(elem){ + return /input|select|textarea|button/i.test(elem.nodeName); + } + }, + setFilters: { + first: function(elem, i){ + return i =3D=3D=3D 0; + }, + last: function(elem, i, match, array){ + return i =3D=3D=3D array.length - 1; + }, + even: function(elem, i){ + return i % 2 =3D=3D=3D 0; + }, + odd: function(elem, i){ + return i % 2 =3D=3D=3D 1; + }, + lt: function(elem, i, match){ + return i < match[3] - 0; + }, + gt: function(elem, i, match){ + return i > match[3] - 0; + }, + nth: function(elem, i, match){ + return match[3] - 0 =3D=3D i; + }, + eq: function(elem, i, match){ + return match[3] - 0 =3D=3D i; + } + }, + filter: { + PSEUDO: function(elem, match, i, array){ + var name =3D match[1], filter =3D Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } else if ( name =3D=3D=3D "contains" ) { + return (elem.textContent || elem.innerText || "").indexOf(match[3]) = >=3D 0; + } else if ( name =3D=3D=3D "not" ) { + var not =3D match[3]; + + for ( var i =3D 0, l =3D not.length; i < l; i++ ) { + if ( not[i] =3D=3D=3D elem ) { + return false; + } + } + + return true; + } + }, + CHILD: function(elem, match){ + var type =3D match[1], node =3D elem; + switch (type) { + case 'only': + case 'first': + while ( (node =3D node.previousSibling) ) { + if ( node.nodeType =3D=3D=3D 1 ) return false; + } + if ( type =3D=3D 'first') return true; + node =3D elem; + case 'last': + while ( (node =3D node.nextSibling) ) { + if ( node.nodeType =3D=3D=3D 1 ) return false; + } + return true; + case 'nth': + var first =3D match[2], last =3D match[3]; + + if ( first =3D=3D 1 && last =3D=3D 0 ) { + return true; + } + + var doneName =3D match[0], + parent =3D elem.parentNode; + + if ( parent && (parent.sizcache !=3D=3D doneName || !elem.nodeIndex= ) ) { + var count =3D 0; + for ( node =3D parent.firstChild; node; node =3D node.nextSibling = ) { + if ( node.nodeType =3D=3D=3D 1 ) { + node.nodeIndex =3D ++count; + } + } + parent.sizcache =3D doneName; + } + + var diff =3D elem.nodeIndex - last; + if ( first =3D=3D 0 ) { + return diff =3D=3D 0; + } else { + return ( diff % first =3D=3D 0 && diff / first >=3D 0 ); + } + } + }, + ID: function(elem, match){ + return elem.nodeType =3D=3D=3D 1 && elem.getAttribute("id") =3D=3D=3D= match; + }, + TAG: function(elem, match){ + return (match =3D=3D=3D "*" && elem.nodeType =3D=3D=3D 1) || elem.nod= eName =3D=3D=3D match; + }, + CLASS: function(elem, match){ + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + ATTR: function(elem, match){ + var name =3D match[1], + result =3D Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] !=3D null ? + elem[ name ] : + elem.getAttribute( name ), + value =3D result + "", + type =3D match[2], + check =3D match[4]; + + return result =3D=3D null ? + type =3D=3D=3D "!=3D" : + type =3D=3D=3D "=3D" ? + value =3D=3D=3D check : + type =3D=3D=3D "*=3D" ? + value.indexOf(check) >=3D 0 : + type =3D=3D=3D "~=3D" ? + (" " + value + " ").indexOf(check) >=3D 0 : + !check ? + value && result !=3D=3D false : + type =3D=3D=3D "!=3D" ? + value !=3D check : + type =3D=3D=3D "^=3D" ? + value.indexOf(check) =3D=3D=3D 0 : + type =3D=3D=3D "$=3D" ? + value.substr(value.length - check.length) =3D=3D=3D check : + type =3D=3D=3D "|=3D" ? + value =3D=3D=3D check || value.substr(0, check.length + 1) =3D=3D=3D= check + "-" : + false; + }, + POS: function(elem, match, i, array){ + var name =3D match[2], filter =3D Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS =3D Expr.match.POS; + +for ( var type in Expr.match ) { + Expr.match[ type ] =3D new RegExp( Expr.match[ type ].source + /(?![^\[= ]*\])(?![^\(]*\))/.source ); + Expr.leftMatch[ type ] =3D new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr= .match[ type ].source ); +} + +var makeArray =3D function(array, results) { + array =3D Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 ); + +} catch(e){ + makeArray =3D function(array, results) { + var ret =3D results || []; + + if ( toString.call(array) =3D=3D=3D "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + } else { + if ( typeof array.length =3D=3D=3D "number" ) { + for ( var i =3D 0, l =3D array.length; i < l; i++ ) { + ret.push( array[i] ); + } + } else { + for ( var i =3D 0; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder =3D function( a, b ) { + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + if ( a =3D=3D b ) { + hasDuplicate =3D true; + } + return 0; + } + + var ret =3D a.compareDocumentPosition(b) & 4 ? -1 : a =3D=3D=3D b ? 0 = : 1; + if ( ret =3D=3D=3D 0 ) { + hasDuplicate =3D true; + } + return ret; + }; +} else if ( "sourceIndex" in document.documentElement ) { + sortOrder =3D function( a, b ) { + if ( !a.sourceIndex || !b.sourceIndex ) { + if ( a =3D=3D b ) { + hasDuplicate =3D true; + } + return 0; + } + + var ret =3D a.sourceIndex - b.sourceIndex; + if ( ret =3D=3D=3D 0 ) { + hasDuplicate =3D true; + } + return ret; + }; +} else if ( document.createRange ) { + sortOrder =3D function( a, b ) { + if ( !a.ownerDocument || !b.ownerDocument ) { + if ( a =3D=3D b ) { + hasDuplicate =3D true; + } + return 0; + } + + var aRange =3D a.ownerDocument.createRange(), bRange =3D b.ownerDocume= nt.createRange(); + aRange.setStart(a, 0); + aRange.setEnd(a, 0); + bRange.setStart(b, 0); + bRange.setEnd(b, 0); + var ret =3D aRange.compareBoundaryPoints(Range.START_TO_END, bRange); + if ( ret =3D=3D=3D 0 ) { + hasDuplicate =3D true; + } + return ret; + }; +} + +(function(){ + var form =3D document.createElement("div"), + id =3D "script" + (new Date).getTime(); + form.innerHTML =3D ""; + + var root =3D document.documentElement; + root.insertBefore( form, root.firstChild ); + + if ( !!document.getElementById( id ) ) { + Expr.find.ID =3D function(match, context, isXML){ + if ( typeof context.getElementById !=3D=3D "undefined" && !isXML ) { + var m =3D context.getElementById(match[1]); + return m ? m.id =3D=3D=3D match[1] || typeof m.getAttributeNode !=3D= =3D "undefined" && m.getAttributeNode("id").nodeValue =3D=3D=3D match[1] = ? [m] : undefined : []; + } + }; + + Expr.filter.ID =3D function(elem, match){ + var node =3D typeof elem.getAttributeNode !=3D=3D "undefined" && elem= .getAttributeNode("id"); + return elem.nodeType =3D=3D=3D 1 && node && node.nodeValue =3D=3D=3D = match; + }; + } + + root.removeChild( form ); + root =3D form =3D null; // release memory in IE +})(); + +(function(){ + + var div =3D document.createElement("div"); + div.appendChild( document.createComment("") ); + + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG =3D function(match, context){ + var results =3D context.getElementsByTagName(match[1]); + + if ( match[1] =3D=3D=3D "*" ) { + var tmp =3D []; + + for ( var i =3D 0; results[i]; i++ ) { + if ( results[i].nodeType =3D=3D=3D 1 ) { + tmp.push( results[i] ); + } + } + + results =3D tmp; + } + + return results; + }; + } + + div.innerHTML =3D ""; + if ( div.firstChild && typeof div.firstChild.getAttribute !=3D=3D "unde= fined" && + div.firstChild.getAttribute("href") !=3D=3D "#" ) { + Expr.attrHandle.href =3D function(elem){ + return elem.getAttribute("href", 2); + }; + } + + div =3D null; // release memory in IE +})(); + +if ( document.querySelectorAll ) (function(){ + var oldSizzle =3D Sizzle, div =3D document.createElement("div"); + div.innerHTML =3D "

    "; + + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length =3D=3D= =3D 0 ) { + return; + } + + Sizzle =3D function(query, context, extra, seed){ + context =3D context || document; + + if ( !seed && context.nodeType =3D=3D=3D 9 && !isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] =3D oldSizzle[ prop ]; + } + + div =3D null; // release memory in IE +})(); + +if ( document.getElementsByClassName && document.documentElement.getElem= entsByClassName ) (function(){ + var div =3D document.createElement("div"); + div.innerHTML =3D "
    "; + + if ( div.getElementsByClassName("e").length =3D=3D=3D 0 ) + return; + + div.lastChild.className =3D "e"; + + if ( div.getElementsByClassName("e").length =3D=3D=3D 1 ) + return; + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS =3D function(match, context, isXML) { + if ( typeof context.getElementsByClassName !=3D=3D "undefined" && !isX= ML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div =3D null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) = { + var sibDir =3D dir =3D=3D "previousSibling" && !isXML; + for ( var i =3D 0, l =3D checkSet.length; i < l; i++ ) { + var elem =3D checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType =3D=3D=3D 1 ){ + elem.sizcache =3D doneName; + elem.sizset =3D i; + } + elem =3D elem[dir]; + var match =3D false; + + while ( elem ) { + if ( elem.sizcache =3D=3D=3D doneName ) { + match =3D checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType =3D=3D=3D 1 && !isXML ){ + elem.sizcache =3D doneName; + elem.sizset =3D i; + } + + if ( elem.nodeName =3D=3D=3D cur ) { + match =3D elem; + break; + } + + elem =3D elem[dir]; + } + + checkSet[i] =3D match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + var sibDir =3D dir =3D=3D "previousSibling" && !isXML; + for ( var i =3D 0, l =3D checkSet.length; i < l; i++ ) { + var elem =3D checkSet[i]; + if ( elem ) { + if ( sibDir && elem.nodeType =3D=3D=3D 1 ) { + elem.sizcache =3D doneName; + elem.sizset =3D i; + } + elem =3D elem[dir]; + var match =3D false; + + while ( elem ) { + if ( elem.sizcache =3D=3D=3D doneName ) { + match =3D checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType =3D=3D=3D 1 ) { + if ( !isXML ) { + elem.sizcache =3D doneName; + elem.sizset =3D i; + } + if ( typeof cur !=3D=3D "string" ) { + if ( elem =3D=3D=3D cur ) { + match =3D true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match =3D elem; + break; + } + } + + elem =3D elem[dir]; + } + + checkSet[i] =3D match; + } + } +} + +var contains =3D document.compareDocumentPosition ? function(a, b){ + return a.compareDocumentPosition(b) & 16; +} : function(a, b){ + return a !=3D=3D b && (a.contains ? a.contains(b) : true); +}; + +var isXML =3D function(elem){ + return elem.nodeType =3D=3D=3D 9 && elem.documentElement.nodeName !=3D=3D= "HTML" || + !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !=3D= =3D "HTML"; +}; + +var posProcess =3D function(selector, context){ + var tmpSet =3D [], later =3D "", match, + root =3D context.nodeType ? [context] : context; + + while ( (match =3D Expr.match.PSEUDO.exec( selector )) ) { + later +=3D match[0]; + selector =3D selector.replace( Expr.match.PSEUDO, "" ); + } + + selector =3D Expr.relative[selector] ? selector + "*" : selector; + + for ( var i =3D 0, l =3D root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + + +window.Sizzle =3D Sizzle; + +})(); + +;(function(engine) { + var extendElements =3D Prototype.Selector.extendElements; + + function select(selector, scope) { + return extendElements(engine(selector, scope || document)); + } + + function match(element, selector) { + return engine.matches(selector, [element]).length =3D=3D 1; + } + + Prototype.Selector.engine =3D engine; + Prototype.Selector.select =3D select; + Prototype.Selector.match =3D match; +})(Sizzle); + +window.Sizzle =3D Prototype._original_property; +delete Prototype._original_property; + +var Form =3D { + reset: function(form) { + form =3D $(form); + form.reset(); + return form; + }, + + serializeElements: function(elements, options) { + if (typeof options !=3D 'object') options =3D { hash: !!options }; + else if (Object.isUndefined(options.hash)) options.hash =3D true; + var key, value, submitted =3D false, submit =3D options.submit; + + var data =3D elements.inject({ }, function(result, element) { + if (!element.disabled && element.name) { + key =3D element.name; value =3D $(element).getValue(); + if (value !=3D null && element.type !=3D 'file' && (element.type= !=3D 'submit' || (!submitted && + submit !=3D=3D false && (!submit || key =3D=3D submit) && (s= ubmitted =3D true)))) { + if (key in result) { + if (!Object.isArray(result[key])) result[key] =3D [result[ke= y]]; + result[key].push(value); + } + else result[key] =3D value; + } + } + return result; + }); + + return options.hash ? data : Object.toQueryString(data); + } +}; + +Form.Methods =3D { + serialize: function(form, options) { + return Form.serializeElements(Form.getElements(form), options); + }, + + getElements: function(form) { + var elements =3D $(form).getElementsByTagName('*'), + element, + arr =3D [ ], + serializers =3D Form.Element.Serializers; + for (var i =3D 0; element =3D elements[i]; i++) { + arr.push(element); + } + return arr.inject([], function(elements, child) { + if (serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + }) + }, + + getInputs: function(form, typeName, name) { + form =3D $(form); + var inputs =3D form.getElementsByTagName('input'); + + if (!typeName && !name) return $A(inputs).map(Element.extend); + + for (var i =3D 0, matchingInputs =3D [], length =3D inputs.length; i= < length; i++) { + var input =3D inputs[i]; + if ((typeName && input.type !=3D typeName) || (name && input.name = !=3D name)) + continue; + matchingInputs.push(Element.extend(input)); + } + + return matchingInputs; + }, + + disable: function(form) { + form =3D $(form); + Form.getElements(form).invoke('disable'); + return form; + }, + + enable: function(form) { + form =3D $(form); + Form.getElements(form).invoke('enable'); + return form; + }, + + findFirstElement: function(form) { + var elements =3D $(form).getElements().findAll(function(element) { + return 'hidden' !=3D element.type && !element.disabled; + }); + var firstByIndex =3D elements.findAll(function(element) { + return element.hasAttribute('tabIndex') && element.tabIndex >=3D 0= ; + }).sortBy(function(element) { return element.tabIndex }).first(); + + return firstByIndex ? firstByIndex : elements.find(function(element)= { + return /^(?:input|select|textarea)$/i.test(element.tagName); + }); + }, + + focusFirstElement: function(form) { + form =3D $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form =3D $(form), options =3D Object.clone(options || { }); + + var params =3D options.parameters, action =3D form.readAttribute('ac= tion') || ''; + if (action.blank()) action =3D window.location.href; + options.parameters =3D form.serialize(true); + + if (params) { + if (Object.isString(params)) params =3D params.toQueryParams(); + Object.extend(options.parameters, params); + } + + if (form.hasAttribute('method') && !options.method) + options.method =3D form.method; + + return new Ajax.Request(action, options); + } +}; + +/*----------------------------------------------------------------------= ----*/ + + +Form.Element =3D { + focus: function(element) { + $(element).focus(); + return element; + }, + + select: function(element) { + $(element).select(); + return element; + } +}; + +Form.Element.Methods =3D { + + serialize: function(element) { + element =3D $(element); + if (!element.disabled && element.name) { + var value =3D element.getValue(); + if (value !=3D undefined) { + var pair =3D { }; + pair[element.name] =3D value; + return Object.toQueryString(pair); + } + } + return ''; + }, + + getValue: function(element) { + element =3D $(element); + var method =3D element.tagName.toLowerCase(); + return Form.Element.Serializers[method](element); + }, + + setValue: function(element, value) { + element =3D $(element); + var method =3D element.tagName.toLowerCase(); + Form.Element.Serializers[method](element, value); + return element; + }, + + clear: function(element) { + $(element).value =3D ''; + return element; + }, + + present: function(element) { + return $(element).value !=3D ''; + }, + + activate: function(element) { + element =3D $(element); + try { + element.focus(); + if (element.select && (element.tagName.toLowerCase() !=3D 'input' = || + !(/^(?:button|reset|submit)$/i.test(element.type)))) + element.select(); + } catch (e) { } + return element; + }, + + disable: function(element) { + element =3D $(element); + element.disabled =3D true; + return element; + }, + + enable: function(element) { + element =3D $(element); + element.disabled =3D false; + return element; + } +}; + +/*----------------------------------------------------------------------= ----*/ + +var Field =3D Form.Element; + +var $F =3D Form.Element.Methods.getValue; + +/*----------------------------------------------------------------------= ----*/ + +Form.Element.Serializers =3D { + input: function(element, value) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element, value); + default: + return Form.Element.Serializers.textarea(element, value); + } + }, + + inputSelector: function(element, value) { + if (Object.isUndefined(value)) return element.checked ? element.valu= e : null; + else element.checked =3D !!value; + }, + + textarea: function(element, value) { + if (Object.isUndefined(value)) return element.value; + else element.value =3D value; + }, + + select: function(element, value) { + if (Object.isUndefined(value)) + return this[element.type =3D=3D 'select-one' ? + 'selectOne' : 'selectMany'](element); + else { + var opt, currentValue, single =3D !Object.isArray(value); + for (var i =3D 0, length =3D element.length; i < length; i++) { + opt =3D element.options[i]; + currentValue =3D this.optionValue(opt); + if (single) { + if (currentValue =3D=3D value) { + opt.selected =3D true; + return; + } + } + else opt.selected =3D value.include(currentValue); + } + } + }, + + selectOne: function(element) { + var index =3D element.selectedIndex; + return index >=3D 0 ? this.optionValue(element.options[index]) : nul= l; + }, + + selectMany: function(element) { + var values, length =3D element.length; + if (!length) return null; + + for (var i =3D 0, values =3D []; i < length; i++) { + var opt =3D element.options[i]; + if (opt.selected) values.push(this.optionValue(opt)); + } + return values; + }, + + optionValue: function(opt) { + return Element.extend(opt).hasAttribute('value') ? opt.value : opt.t= ext; + } +}; + +/*----------------------------------------------------------------------= ----*/ + + +Abstract.TimedObserver =3D Class.create(PeriodicalExecuter, { + initialize: function($super, element, frequency, callback) { + $super(callback, frequency); + this.element =3D $(element); + this.lastValue =3D this.getValue(); + }, + + execute: function() { + var value =3D this.getValue(); + if (Object.isString(this.lastValue) && Object.isString(value) ? + this.lastValue !=3D value : String(this.lastValue) !=3D String(v= alue)) { + this.callback(this.element, value); + this.lastValue =3D value; + } + } +}); + +Form.Element.Observer =3D Class.create(Abstract.TimedObserver, { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer =3D Class.create(Abstract.TimedObserver, { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*----------------------------------------------------------------------= ----*/ + +Abstract.EventObserver =3D Class.create({ + initialize: function(element, callback) { + this.element =3D $(element); + this.callback =3D callback; + + this.lastValue =3D this.getValue(); + if (this.element.tagName.toLowerCase() =3D=3D 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value =3D this.getValue(); + if (this.lastValue !=3D value) { + this.callback(this.element, value); + this.lastValue =3D value; + } + }, + + registerFormCallbacks: function() { + Form.getElements(this.element).each(this.registerCallback, this); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)= ); + break; + default: + Event.observe(element, 'change', this.onElementEvent.bind(this= )); + break; + } + } + } +}); + +Form.Element.EventObserver =3D Class.create(Abstract.EventObserver, { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver =3D Class.create(Abstract.EventObserver, { + getValue: function() { + return Form.serialize(this.element); + } +}); +(function() { + + var Event =3D { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + KEY_INSERT: 45, + + cache: {} + }; + + var docEl =3D document.documentElement; + var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED =3D 'onmouseenter' in docEl + && 'onmouseleave' in docEl; + + var _isButton; + if (Prototype.Browser.IE) { + var buttonMap =3D { 0: 1, 1: 4, 2: 2 }; + _isButton =3D function(event, code) { + return event.button =3D=3D=3D buttonMap[code]; + }; + } else if (Prototype.Browser.WebKit) { + _isButton =3D function(event, code) { + switch (code) { + case 0: return event.which =3D=3D 1 && !event.metaKey; + case 1: return event.which =3D=3D 1 && event.metaKey; + default: return false; + } + }; + } else { + _isButton =3D function(event, code) { + return event.which ? (event.which =3D=3D=3D code + 1) : (event.but= ton =3D=3D=3D code); + }; + } + + function isLeftClick(event) { return _isButton(event, 0) } + + function isMiddleClick(event) { return _isButton(event, 1) } + + function isRightClick(event) { return _isButton(event, 2) } + + function element(event) { + event =3D Event.extend(event); + + var node =3D event.target, type =3D event.type, + currentTarget =3D event.currentTarget; + + if (currentTarget && currentTarget.tagName) { + if (type =3D=3D=3D 'load' || type =3D=3D=3D 'error' || + (type =3D=3D=3D 'click' && currentTarget.tagName.toLowerCase() =3D= =3D=3D 'input' + && currentTarget.type =3D=3D=3D 'radio')) + node =3D currentTarget; + } + + if (node.nodeType =3D=3D Node.TEXT_NODE) + node =3D node.parentNode; + + return Element.extend(node); + } + + function findElement(event, expression) { + var element =3D Event.element(event); + if (!expression) return element; + while (element) { + if (Object.isElement(element) && Prototype.Selector.match(element,= expression)) { + return Element.extend(element); + } + element =3D element.parentNode; + } + } + + function pointer(event) { + return { x: pointerX(event), y: pointerY(event) }; + } + + function pointerX(event) { + var docElement =3D document.documentElement, + body =3D document.body || { scrollLeft: 0 }; + + return event.pageX || (event.clientX + + (docElement.scrollLeft || body.scrollLeft) - + (docElement.clientLeft || 0)); + } + + function pointerY(event) { + var docElement =3D document.documentElement, + body =3D document.body || { scrollTop: 0 }; + + return event.pageY || (event.clientY + + (docElement.scrollTop || body.scrollTop) - + (docElement.clientTop || 0)); + } + + + function stop(event) { + Event.extend(event); + event.preventDefault(); + event.stopPropagation(); + + event.stopped =3D true; + } + + Event.Methods =3D { + isLeftClick: isLeftClick, + isMiddleClick: isMiddleClick, + isRightClick: isRightClick, + + element: element, + findElement: findElement, + + pointer: pointer, + pointerX: pointerX, + pointerY: pointerY, + + stop: stop + }; + + + var methods =3D Object.keys(Event.Methods).inject({ }, function(m, nam= e) { + m[name] =3D Event.Methods[name].methodize(); + return m; + }); + + if (Prototype.Browser.IE) { + function _relatedTarget(event) { + var element; + switch (event.type) { + case 'mouseover': element =3D event.fromElement; break; + case 'mouseout': element =3D event.toElement; break; + default: return null; + } + return Element.extend(element); + } + + Object.extend(methods, { + stopPropagation: function() { this.cancelBubble =3D true }, + preventDefault: function() { this.returnValue =3D false }, + inspect: function() { return '[object Event]' } + }); + + Event.extend =3D function(event, element) { + if (!event) return false; + if (event._extendedByPrototype) return event; + + event._extendedByPrototype =3D Prototype.emptyFunction; + var pointer =3D Event.pointer(event); + + Object.extend(event, { + target: event.srcElement || element, + relatedTarget: _relatedTarget(event), + pageX: pointer.x, + pageY: pointer.y + }); + + return Object.extend(event, methods); + }; + } else { + Event.prototype =3D window.Event.prototype || document.createEvent('= HTMLEvents').__proto__; + Object.extend(Event.prototype, methods); + Event.extend =3D Prototype.K; + } + + function _createResponder(element, eventName, handler) { + var registry =3D Element.retrieve(element, 'prototype_event_registry= '); + + if (Object.isUndefined(registry)) { + CACHE.push(element); + registry =3D Element.retrieve(element, 'prototype_event_registry',= $H()); + } + + var respondersForEvent =3D registry.get(eventName); + if (Object.isUndefined(respondersForEvent)) { + respondersForEvent =3D []; + registry.set(eventName, respondersForEvent); + } + + if (respondersForEvent.pluck('handler').include(handler)) return fal= se; + + var responder; + if (eventName.include(":")) { + responder =3D function(event) { + if (Object.isUndefined(event.eventName)) + return false; + + if (event.eventName !=3D=3D eventName) + return false; + + Event.extend(event, element); + handler.call(element, event); + }; + } else { + if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && + (eventName =3D=3D=3D "mouseenter" || eventName =3D=3D=3D "mousele= ave")) { + if (eventName =3D=3D=3D "mouseenter" || eventName =3D=3D=3D "mou= seleave") { + responder =3D function(event) { + Event.extend(event, element); + + var parent =3D event.relatedTarget; + while (parent && parent !=3D=3D element) { + try { parent =3D parent.parentNode; } + catch(e) { parent =3D element; } + } + + if (parent =3D=3D=3D element) return; + + handler.call(element, event); + }; + } + } else { + responder =3D function(event) { + Event.extend(event, element); + handler.call(element, event); + }; + } + } + + responder.handler =3D handler; + respondersForEvent.push(responder); + return responder; + } + + function _destroyCache() { + for (var i =3D 0, length =3D CACHE.length; i < length; i++) { + Event.stopObserving(CACHE[i]); + CACHE[i] =3D null; + } + } + + var CACHE =3D []; + + if (Prototype.Browser.IE) + window.attachEvent('onunload', _destroyCache); + + if (Prototype.Browser.WebKit) + window.addEventListener('unload', Prototype.emptyFunction, false); + + + var _getDOMEventName =3D Prototype.K, + translations =3D { mouseenter: "mouseover", mouseleave: "mouseout"= }; + + if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { + _getDOMEventName =3D function(eventName) { + return (translations[eventName] || eventName); + }; + } + + function observe(element, eventName, handler) { + element =3D $(element); + + var responder =3D _createResponder(element, eventName, handler); + + if (!responder) return element; + + if (eventName.include(':')) { + if (element.addEventListener) + element.addEventListener("dataavailable", responder, false); + else { + element.attachEvent("ondataavailable", responder); + element.attachEvent("onfilterchange", responder); + } + } else { + var actualEventName =3D _getDOMEventName(eventName); + + if (element.addEventListener) + element.addEventListener(actualEventName, responder, false); + else + element.attachEvent("on" + actualEventName, responder); + } + + return element; + } + + function stopObserving(element, eventName, handler) { + element =3D $(element); + + var registry =3D Element.retrieve(element, 'prototype_event_registry= '); + if (!registry) return element; + + if (!eventName) { + registry.each( function(pair) { + var eventName =3D pair.key; + stopObserving(element, eventName); + }); + return element; + } + + var responders =3D registry.get(eventName); + if (!responders) return element; + + if (!handler) { + responders.each(function(r) { + stopObserving(element, eventName, r.handler); + }); + return element; + } + + var responder =3D responders.find( function(r) { return r.handler =3D= =3D=3D handler; }); + if (!responder) return element; + + if (eventName.include(':')) { + if (element.removeEventListener) + element.removeEventListener("dataavailable", responder, false); + else { + element.detachEvent("ondataavailable", responder); + element.detachEvent("onfilterchange", responder); + } + } else { + var actualEventName =3D _getDOMEventName(eventName); + if (element.removeEventListener) + element.removeEventListener(actualEventName, responder, false); + else + element.detachEvent('on' + actualEventName, responder); + } + + registry.set(eventName, responders.without(responder)); + + return element; + } + + function fire(element, eventName, memo, bubble) { + element =3D $(element); + + if (Object.isUndefined(bubble)) + bubble =3D true; + + if (element =3D=3D document && document.createEvent && !element.disp= atchEvent) + element =3D document.documentElement; + + var event; + if (document.createEvent) { + event =3D document.createEvent('HTMLEvents'); + event.initEvent('dataavailable', true, true); + } else { + event =3D document.createEventObject(); + event.eventType =3D bubble ? 'ondataavailable' : 'onfilterchange'; + } + + event.eventName =3D eventName; + event.memo =3D memo || { }; + + if (document.createEvent) + element.dispatchEvent(event); + else + element.fireEvent(event.eventType, event); + + return Event.extend(event); + } + + Event.Handler =3D Class.create({ + initialize: function(element, eventName, selector, callback) { + this.element =3D $(element); + this.eventName =3D eventName; + this.selector =3D selector; + this.callback =3D callback; + this.handler =3D this.handleEvent.bind(this); + }, + + start: function() { + Event.observe(this.element, this.eventName, this.handler); + return this; + }, + + stop: function() { + Event.stopObserving(this.element, this.eventName, this.handler); + return this; + }, + + handleEvent: function(event) { + var element =3D event.findElement(this.selector); + if (element) this.callback.call(this.element, event, element); + } + }); + + function on(element, eventName, selector, callback) { + element =3D $(element); + if (Object.isFunction(selector) && Object.isUndefined(callback)) { + callback =3D selector, selector =3D null; + } + + return new Event.Handler(element, eventName, selector, callback).sta= rt(); + } + + Object.extend(Event, Event.Methods); + + Object.extend(Event, { + fire: fire, + observe: observe, + stopObserving: stopObserving, + on: on + }); + + Element.addMethods({ + fire: fire, + + observe: observe, + + stopObserving: stopObserving, + + on: on + }); + + Object.extend(document, { + fire: fire.methodize(), + + observe: observe.methodize(), + + stopObserving: stopObserving.methodize(), + + on: on.methodize(), + + loaded: false + }); + + if (window.Event) Object.extend(window.Event, Event); + else window.Event =3D Event; +})(); + +(function() { + /* Support for the DOMContentLoaded event is based on work by Dan Webb= , + Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ + + var timer; + + function fireContentLoadedEvent() { + if (document.loaded) return; + if (timer) window.clearTimeout(timer); + document.loaded =3D true; + document.fire('dom:loaded'); + } + + function checkReadyState() { + if (document.readyState =3D=3D=3D 'complete') { + document.stopObserving('readystatechange', checkReadyState); + fireContentLoadedEvent(); + } + } + + function pollDoScroll() { + try { document.documentElement.doScroll('left'); } + catch(e) { + timer =3D pollDoScroll.defer(); + return; + } + fireContentLoadedEvent(); + } + + if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', fireContentLoadedEvent= , false); + } else { + document.observe('readystatechange', checkReadyState); + if (window =3D=3D top) + timer =3D pollDoScroll.defer(); + } + + Event.observe(window, 'load', fireContentLoadedEvent); +})(); + +Element.addMethods(); + +/*------------------------------- DEPRECATED ---------------------------= ----*/ + +Hash.toQueryString =3D Object.toQueryString; + +var Toggle =3D { display: Element.toggle }; + +Element.Methods.childOf =3D Element.Methods.descendantOf; + +var Insertion =3D { + Before: function(element, content) { + return Element.insert(element, {before:content}); + }, + + Top: function(element, content) { + return Element.insert(element, {top:content}); + }, + + Bottom: function(element, content) { + return Element.insert(element, {bottom:content}); + }, + + After: function(element, content) { + return Element.insert(element, {after:content}); + } +}; + +var $continue =3D new Error('"throw $continue" is deprecated, use "retur= n" instead'); + +var Position =3D { + includeScrollOffsets: false, + + prepare: function() { + this.deltaX =3D window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY =3D window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp =3D x; + this.ycomp =3D y; + this.offset =3D Element.cumulativeOffset(element); + + return (y >=3D this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >=3D this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache =3D Element.cumulativeScrollOffset(element); + + this.xcomp =3D x + offsetcache[0] - this.deltaX; + this.ycomp =3D y + offsetcache[1] - this.deltaY; + this.offset =3D Element.cumulativeOffset(element); + + return (this.ycomp >=3D this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >=3D this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + overlap: function(mode, element) { + if (!mode) return 0; + if (mode =3D=3D 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode =3D=3D 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + + cumulativeOffset: Element.Methods.cumulativeOffset, + + positionedOffset: Element.Methods.positionedOffset, + + absolutize: function(element) { + Position.prepare(); + return Element.absolutize(element); + }, + + relativize: function(element) { + Position.prepare(); + return Element.relativize(element); + }, + + realOffset: Element.Methods.cumulativeScrollOffset, + + offsetParent: Element.Methods.getOffsetParent, + + page: Element.Methods.viewportOffset, + + clone: function(source, target, options) { + options =3D options || { }; + return Element.clonePosition(target, source, options); + } +}; + +/*----------------------------------------------------------------------= ----*/ + +if (!document.getElementsByClassName) document.getElementsByClassName =3D= function(instanceMethods){ + function iter(name) { + return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' = " + name + " ')]"; + } + + instanceMethods.getElementsByClassName =3D Prototype.BrowserFeatures.X= Path ? + function(element, className) { + className =3D className.toString().strip(); + var cond =3D /\s/.test(className) ? $w(className).map(iter).join('')= : iter(className); + return cond ? document._getElementsByXPath('.//*' + cond, element) := []; + } : function(element, className) { + className =3D className.toString().strip(); + var elements =3D [], classNames =3D (/\s/.test(className) ? $w(class= Name) : null); + if (!classNames && !className) return elements; + + var nodes =3D $(element).getElementsByTagName('*'); + className =3D ' ' + className + ' '; + + for (var i =3D 0, child, cn; child =3D nodes[i]; i++) { + if (child.className && (cn =3D ' ' + child.className + ' ') && (cn= .include(className) || + (classNames && classNames.all(function(name) { + return !name.toString().blank() && cn.include(' ' + name + '= '); + })))) + elements.push(Element.extend(child)); + } + return elements; + }; + + return function(className, parentElement) { + return $(parentElement || document.body).getElementsByClassName(clas= sName); + }; +}(Element.Methods); + +/*----------------------------------------------------------------------= ----*/ + +Element.ClassNames =3D Class.create(); +Element.ClassNames.prototype =3D { + initialize: function(element) { + this.element =3D $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className =3D className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set($A(this).concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set($A(this).without(classNameToRemove).join(' ')); + }, + + toString: function() { + return $A(this).join(' '); + } +}; + +Object.extend(Element.ClassNames.prototype, Enumerable); + +/*----------------------------------------------------------------------= ----*/ + +(function() { + window.Selector =3D Class.create({ + initialize: function(expression) { + this.expression =3D expression.strip(); + }, + + findElements: function(rootElement) { + return Prototype.Selector.select(this.expression, rootElement); + }, + + match: function(element) { + return Prototype.Selector.match(element, this.expression); + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } + }); + + Object.extend(Selector, { + matchElements: function(elements, expression) { + var match =3D Prototype.Selector.match, + results =3D []; + + for (var i =3D 0, length =3D elements.length; i < length; i++) { + var element =3D elements[i]; + if (match(element, expression)) { + results.push(Element.extend(element)); + } + } + return results; + }, + + findElement: function(elements, expression, index) { + index =3D index || 0; + var matchIndex =3D 0, element; + for (var i =3D 0, length =3D elements.length; i < length; i++) { + element =3D elements[i]; + if (Prototype.Selector.match(element, expression) && index =3D=3D= =3D matchIndex++) { + return Element.extend(element); + } + } + }, + + findChildElements: function(element, expressions) { + var selector =3D expressions.toArray().join(', '); + return Prototype.Selector.select(selector, element || document); + } + }); +})(); diff --git a/site/public/javascripts/rails.js b/site/public/javascripts/r= ails.js new file mode 100644 index 0000000..4283ed8 --- /dev/null +++ b/site/public/javascripts/rails.js @@ -0,0 +1,175 @@ +(function() { + // Technique from Juriy Zaytsev + // http://thinkweb2.com/projects/prototype/detecting-event-support-wit= hout-browser-sniffing/ + function isEventSupported(eventName) { + var el =3D document.createElement('div'); + eventName =3D 'on' + eventName; + var isSupported =3D (eventName in el); + if (!isSupported) { + el.setAttribute(eventName, 'return;'); + isSupported =3D typeof el[eventName] =3D=3D 'function'; + } + el =3D null; + return isSupported; + } + + function isForm(element) { + return Object.isElement(element) && element.nodeName.toUpperCase() =3D= =3D 'FORM' + } + + function isInput(element) { + if (Object.isElement(element)) { + var name =3D element.nodeName.toUpperCase() + return name =3D=3D 'INPUT' || name =3D=3D 'SELECT' || name =3D=3D = 'TEXTAREA' + } + else return false + } + + var submitBubbles =3D isEventSupported('submit'), + changeBubbles =3D isEventSupported('change') + + if (!submitBubbles || !changeBubbles) { + // augment the Event.Handler class to observe custom events when nee= ded + Event.Handler.prototype.initialize =3D Event.Handler.prototype.initi= alize.wrap( + function(init, element, eventName, selector, callback) { + init(element, eventName, selector, callback) + // is the handler being attached to an element that doesn't supp= ort this event? + if ( (!submitBubbles && this.eventName =3D=3D 'submit' && !isFor= m(this.element)) || + (!changeBubbles && this.eventName =3D=3D 'change' && !isInp= ut(this.element)) ) { + // "submit" =3D> "emulated:submit" + this.eventName =3D 'emulated:' + this.eventName + } + } + ) + } + + if (!submitBubbles) { + // discover forms on the page by observing focus events which always= bubble + document.on('focusin', 'form', function(focusEvent, form) { + // special handler for the real "submit" event (one-time operation= ) + if (!form.retrieve('emulated:submit')) { + form.on('submit', function(submitEvent) { + var emulated =3D form.fire('emulated:submit', submitEvent, tru= e) + // if custom event received preventDefault, cancel the real on= e too + if (emulated.returnValue =3D=3D=3D false) submitEvent.preventD= efault() + }) + form.store('emulated:submit', true) + } + }) + } + + if (!changeBubbles) { + // discover form inputs on the page + document.on('focusin', 'input, select, texarea', function(focusEvent= , input) { + // special handler for real "change" events + if (!input.retrieve('emulated:change')) { + input.on('change', function(changeEvent) { + input.fire('emulated:change', changeEvent, true) + }) + input.store('emulated:change', true) + } + }) + } + + function handleRemote(element) { + var method, url, params; + + var event =3D element.fire("ajax:before"); + if (event.stopped) return false; + + if (element.tagName.toLowerCase() =3D=3D=3D 'form') { + method =3D element.readAttribute('method') || 'post'; + url =3D element.readAttribute('action'); + params =3D element.serialize(); + } else { + method =3D element.readAttribute('data-method') || 'get'; + url =3D element.readAttribute('href'); + params =3D {}; + } + + new Ajax.Request(url, { + method: method, + parameters: params, + evalScripts: true, + + onComplete: function(request) { element.fire("ajax:complete", r= equest); }, + onSuccess: function(request) { element.fire("ajax:success", r= equest); }, + onFailure: function(request) { element.fire("ajax:failure", r= equest); } + }); + + element.fire("ajax:after"); + } + + function handleMethod(element) { + var method =3D element.readAttribute('data-method'), + url =3D element.readAttribute('href'), + csrf_param =3D $$('meta[name=3Dcsrf-param]')[0], + csrf_token =3D $$('meta[name=3Dcsrf-token]')[0]; + + var form =3D new Element('form', { method: "POST", action: url, styl= e: "display: none;" }); + element.parentNode.insert(form); + + if (method !=3D=3D 'post') { + var field =3D new Element('input', { type: 'hidden', name: '_metho= d', value: method }); + form.insert(field); + } + + if (csrf_param) { + var param =3D csrf_param.readAttribute('content'), + token =3D csrf_token.readAttribute('content'), + field =3D new Element('input', { type: 'hidden', name: param, = value: token }); + form.insert(field); + } + + form.submit(); + } + + + document.on("click", "*[data-confirm]", function(event, element) { + var message =3D element.readAttribute('data-confirm'); + if (!confirm(message)) event.stop(); + }); + + document.on("click", "a[data-remote]", function(event, element) { + if (event.stopped) return; + handleRemote(element); + event.stop(); + }); + + document.on("click", "a[data-method]", function(event, element) { + if (event.stopped) return; + handleMethod(element); + event.stop(); + }); + + document.on("submit", function(event) { + var element =3D event.findElement(), + message =3D element.readAttribute('data-confirm'); + if (message && !confirm(message)) { + event.stop(); + return false; + } + + var inputs =3D element.select("input[type=3Dsubmit][data-disable-wit= h]"); + inputs.each(function(input) { + input.disabled =3D true; + input.writeAttribute('data-original-value', input.value); + input.value =3D input.readAttribute('data-disable-with'); + }); + + var element =3D event.findElement("form[data-remote]"); + if (element) { + handleRemote(element); + event.stop(); + } + }); + + document.on("ajax:after", "form", function(event, element) { + var inputs =3D element.select("input[type=3Dsubmit][disabled=3Dtrue]= [data-disable-with]"); + inputs.each(function(input) { + input.value =3D input.readAttribute('data-original-value'); + input.removeAttribute('data-original-value'); + input.disabled =3D false; + }); + }); +})(); diff --git a/site/public/robots.txt b/site/public/robots.txt new file mode 100644 index 0000000..085187f --- /dev/null +++ b/site/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/wc/norobots.html for documentation on how= to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-Agent: * +# Disallow: / diff --git a/site/public/stylesheets/.gitkeep b/site/public/stylesheets/.= gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/site/public/stylesheets/application.css b/site/public/styles= heets/application.css new file mode 100644 index 0000000..e69de29 diff --git a/site/public/stylesheets/hobo-rapid.css b/site/public/stylesh= eets/hobo-rapid.css new file mode 100644 index 0000000..e00c028 --- /dev/null +++ b/site/public/stylesheets/hobo-rapid.css @@ -0,0 +1,94 @@ +/**** Default styling for Rapid ****/ + +#ajax_progress { + color: gray; + float: right; + margin: 20px; + position: fixed; + background: white; + font-family: tahoma, sans-serif; + display: none; + z-index: 10; +} + +#ajax_progress div { + margin: 10px; + padding: 3px; +/* padding-top: -15px;*/ +} + +#ajax_progress img { + padding-left: 6px; + vertical-align: middle; +} + + +/* Scriptaculous Autocompleter ---*/ + +div.completions_popup { + position:absolute; + width:250px; + background-color:white; + border:1px solid #888; + margin:0px; + padding:0px; + z-index:100; +} +div.completions_popup ul { + list-style-type:none; + margin:0px; + padding:0px; +} +div.completions_popup ul li.selected { background-color: #ffb;} +div.completions_popup ul li { + list-style-type:none; + display:block; + margin:0; + padding:2px; + cursor:pointer; +} + + +.field_list { width:95%; } +.field_list td { padding: 5px; vertical-align: middle; } +.field_list td.field_label { + text-align: left; width: 1px; white-space: nowrap; vertical-align: t= op; + padding-top: 10px; padding-bottom: 10px; +} +.field_list input[type=3Dtext] { width: 100%; } +.field_list input, .field_list textarea { margin: -2px 0 0 0; } +.field_list textarea { width: 100%; margin: 0; } +/* +td span.in_place_textfield_bhv, td span.in_place_textarea_bhv, td span.i= n_place_html_textarea_bhv { + display: block; border: 1px solid #ddd; + padding: 4px; background: #fafafa; +} +*/ +table.login-table, table.login-table td {border: none;} +.login_table td.field_label { vertical-align: middle; } +/*table.login-table input {font-size: 16px; color: black;}*/ + +input[type=3Dtext].wide { width: 100%; } +textarea { height: 200px; } +textarea.wide { width: 100%; } +textarea.tall { height: 350px; } + +.field_list input.percentage {width: 25px; display: inline; margin-right= : 5px; padding: 1px 3px;} + +/* rails error message */ +.error_messages { + font-family: "Lucida Grande", arial, sans-serif; + background: #9d0018; + border: 1px solid #7a0013; + padding: 20px; + color: white; + margin-bottom: 20px; +} +.error_messages h2 { + text-transform: none; + letter-spacing: normal; + color: white; +} +.error_messages li { + margin-left: 20px; +} diff --git a/site/public/stylesheets/reset.css b/site/public/stylesheets/= reset.css new file mode 100644 index 0000000..68651b9 --- /dev/null +++ b/site/public/stylesheets/reset.css @@ -0,0 +1,95 @@ +/******** Reset default browser CSS styles. *********/ +/* Based on Blueprint */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, +del, dfn, font, img, ins, kbd, q, s, samp, +small, strike, sub, sup, tt, var, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +code { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + vertical-align: baseline; +} + +em { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +strong { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +/* Remember to define focus styles! */ +:focus { + outline: 0; +} +body { + line-height: 1; + color: black; + background: white; +} + +/* Tables still need 'cellspacing=3D"0"' in the markup. */ +table { + border-collapse: separate; + border-spacing: 0; +} +caption, th, td { + text-align: left; + font-weight: normal; +} + +/* Remove possible quote marks (") from ,
    . */ +blockquote:before, blockquote:after, +q:before, q:after { + content: ""; +} +blockquote, q { + quotes: "" ""; +} + +body { + font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif; + font-size: 12px; +} +h1,h2,h3,h4,h5,h6 { font-weight: bold; } +h1 { font-size: 36px;} +h2 { font-size: 28px;} +h3 { font-size: 18px;} +h4 { font-size: 14px;} +h5 { font-size: 12px;} +h6 { font-size: 10px;} diff --git a/site/script/rails b/site/script/rails new file mode 100755 index 0000000..b97de07 --- /dev/null +++ b/site/script/rails @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby18 +# This command will automatically be run when you run "rails" with Rails= 3 gems installed from the root of your application. + +APP_PATH =3D File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands'