whimsical-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sam Ruby <ru...@apache.org>
Subject [whimsy.git] [4/50] Commit 6fe655a: Initial import
Date Fri, 04 Dec 2015 19:09:51 GMT
Commit 6fe655ac1ea0d49143f0b41dd500b33371e109f5:
    Initial import
    git-svn-id: https://svn.apache.org/repos/infra/infrastructure/trunk/projects/whimsy@819329 90ea9780-b833-de11-8433-001ec94261de


Branch: refs/heads/master
Author: Sam Ruby <rubys@apache.org>
Committer: Sam Ruby <rubys@apache.org>
Pusher: rubys <rubys@apache.org>

------------------------------------------------------------
www/board/agenda.cgi                                         | ++++++++ 
www/board/draft-minutes.cgi                                  | +++++++++++++ 
www/board/publish_minutes.cgi                                | +++++++++++++++ 
www/board/subscriptions.cgi                                  | +++++++++++ 
www/fundraising/invoice.cgi                                  | +++++++++++++++ 
www/fundraising/sponsorship.cgi                              | +++++++++++ 
www/incubator/moderators.cgi                                 | +++++++++ 
www/incubator/podlings/by-age.cgi                            | ++++++++ 
www/index.html                                               | ++++++++ ---
www/infra/mlreq.cgi                                          | ++++++++++++ 
www/jquery-min.js                                            | + 
www/jquery.tablesorter.pager.js                              | ++++++++++++ 
www/members/subscriptions.cgi                                | ++++++++++ 
www/members/watch.cgi                                        | ++++++++ 
www/new-account-request-queue.cgi                            | ++++ 
www/roster/committee.cgi                                     | +++++++++++++++ 
www/roster/committer.cgi                                     | +++++++++++ 
www/secretary/workbench/ccla.erb                             | +++++++++++++ 
www/secretary/workbench/file.cgi                             | ++++++++++++++ 
www/secretary/workbench/grant.erb                            | +++++++++++++ 
www/secretary/workbench/icla.erb                             | ++++++++ 
www/secretary/workbench/index.html                           | ++++++++++ 
www/secretary/workbench/jquery-1.2.6.min.js                  | ++++++++ 
www/secretary/workbench/jquery-1.7.2.min.js                  | ++++ 
www/secretary/workbench/local_paths.rb                       | +++++++++ 
www/secretary/workbench/local_paths.yml                      | ++++++ 
www/secretary/workbench/mem.erb                              | +++++++++++++++ 
www/secretary/workbench/nda.erb                              | +++++++++++++ 
www/secretary/workbench/spinner.gif                          |  
www/secretary/workbench/worklist.cgi                         | +++++++++++++++ 
www/secretary/workbench/worklist.css                         | ++++++++++++ 
www/secretary/workbench/worklist.js                          | +++++++++++++++ 
www/technology.html                                          | ++++++++++++ 
www/treasurer/expenses.cgi                                   | +++++++++++++ 
www/treasurer/index.cgi                                      | +++++++++ 
www/treasurer/statements.cgi                                 | + 
www/voter/jquery.min.js                                      | ++++ 
www/whimsy.svg                                               | +++++++++++++++ 
------------------------------------------------------------
6344 changes: 6321 additions, 23 deletions.
------------------------------------------------------------


diff --git a/www/board/agenda.cgi b/www/board/agenda.cgi
new file mode 100755
index 0000000..ac65f77
--- /dev/null
+++ b/www/board/agenda.cgi
@@ -0,0 +1,1024 @@
+#!/usr/bin/ruby1.9.1
+require 'ostruct'
+require 'wunderbar'
+require 'yaml'
+require 'fileutils'
+require 'time'
+require '/var/tools/asf'
+
+ENV['HOME'] = ENV['DOCUMENT_ROOT']
+SVN_FOUNDATION_BOARD = ASF::SVN['private/foundation/board']
+MINUTES_WORK = '/var/tools/data'
+
+DIRECTORS = {
+  'rbowen'      => 'rb',
+  'cutting'     => 'dc',
+  'bdelacretaz' => 'bd',
+  'fielding'    => 'rf',
+  'rgardler'    => 'rg',
+  'jim'         => 'jj',
+  'brett'       => 'bp',
+  'rubys'       => 'sr',
+  'gstein'      => 'gs'
+}
+
+user = ASF::Person.new($USER)
+director = DIRECTORS[$USER]
+secretary = %w(clr rubys).include? $USER
+
+unless secretary or director or user.asf_member? or ASF.pmc_chairs.include? user
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+agenda = {}
+
+class << agenda
+  def order
+    @order ||= []
+  end
+
+  def filename
+    if ENV['REQUEST_URI'] =~ /\/agenda.*\/(\d\d\d\d[-_]\d\d[-_]\d\d)\//
+      date = $1.gsub('-','_').untaint
+    elsif ENV['REQUEST_URI'] =~ /\/agenda.*\/(\d\d\d\d[-_]\d\d)\//
+      date = $1.gsub('-','_').untaint + '_*'
+    elsif ENV['REQUEST_URI'] =~ /\/agenda.*\/(\d\d)\//
+      date = '*_' + $1.gsub('-','_').untaint + '_*'
+    elsif ENV['REQUEST_URI'] =~ /\/agenda.*\/(\d\d[-_]\d\d)\//
+      date = '*_' + $1.gsub('-','_').untaint
+    else
+      date = '*'
+    end
+
+    Dir["#{SVN_FOUNDATION_BOARD}/board_agenda_#{date}*.txt"].sort.last.untaint
+  end
+
+  def yaml
+    MINUTES_WORK + '/' + File.basename(filename).
+      sub('_agenda_','_minutes_').sub('.txt','.yml')
+  end
+
+  def save(report)
+    order << report.attach unless order.include? report.attach
+    self[report.attach] = report
+  end
+
+  def notes
+    @notes ||= (File.exist?(yaml) ? YAML.load_file(yaml) : {})
+  end
+
+  def at(index)
+    self[order[index]]
+  end
+end
+
+load_agenda = Proc.new do
+  agenda.clear
+  agenda.order.clear
+
+  file = File.read(agenda.filename)
+
+  # Front Matter
+  file.scan(/^ ([12]\.) (.*?)\n+(.*?)(?=\n [23]\.)/m).each do \
+    |attach, title, text|
+    next unless title =~ /Call/
+    report = agenda[attach] || OpenStruct.new
+    report.attach = attach
+    report.title = title
+    report.text = text
+    agenda.save report
+  end
+
+  # Minutes
+  file.split(/^ 3. Minutes from previous meetings/,2).last.
+         split(/^ 4. Executive Officer Reports/,2).first.scan(/
+    \s{4}([A-Z])\.         # section
+    \sThe.meeting.of(.*?)  # title
+    \[\s(?:.*?):\s*?(.*?)  # approved | TABLED
+    \s*comments:(.*?)\n    # comments
+    \s{8,9}\]\n
+  /mx).each do |section,title,approved,comments|
+    title,text = title.strip.split("\n",2)
+    attach = '3' + section
+    report = agenda[attach] || OpenStruct.new
+    report.attach = attach
+    report.title = title
+    report.text = text
+    report.approved = approved.strip.gsub(/\s+/,' ')
+    report.comments = comments
+    agenda.save report
+  end
+
+  # Executive Officer Reports
+  file.split(/^ 4. Executive Officer Reports/,2).last.
+         split(/^ 5. Additional Officer Reports/,2).first.scan(/
+    \s{4}([A-Z])\.          # section
+    \s([^\[]+?)             # title
+    \s\[([^\]]+?)\]         # owner
+    (.*?)                   # text
+    (?=\n\s{4}[A-Z]\.\s|\z) # next section
+  /mx).each do |section,title,owner,text|
+    attach = '4' + section
+    report = agenda[attach] || OpenStruct.new
+    report.attach = attach
+    report.author = owner.split('/').first.strip
+    report.shepherd = owner.split('/').last.strip
+    report.title = title
+    text.gsub!(/\n\n\s+\[.*\]\s*$/m) {|comments|
+      report.comments = comments
+      "\n\n"
+    }
+    report.text = text
+    agenda.save report
+  end
+
+  # Additional Officer Reports and Committee Reports (part I)
+  file.scan(/
+    -{41}\n                        # separator
+    Attachment\s\s?(\w+):\s(.*?)\n # Attachment, Title
+    .(.*?)\n                       # report
+    (?=-{41,}\n(?:End|Attach))     # separator
+  /mx).each do |attach,title,text|
+    title.sub! /^Report from the VP of /, ''
+    title.sub! /^Report from the /, ''
+    title.sub! /^Status report for the /, ''
+    title.sub! /^Apache /, ''
+    title.sub! /\sTeam$/, ''
+    title.sub! /\sCommittee$/, ''
+    title.sub! /\sProject$/, ''
+
+    report = agenda[attach] || OpenStruct.new
+    report.attach = attach
+    report.title = title
+    report.text  = text
+    agenda.save report
+  end
+
+  # Additional Officer Reports and Committee Reports (part II)
+  file.scan(/
+    \[([^\n]+)\]\n\n                  # owners
+    \s{7}See\sAttachment\s\s?(\w+)\s+ # attach
+    \[\sapproved:\s*?(.*?)            # approved
+    \s*comments:(.*?)\n\s{9}\]        # comments
+  /mx).each do |owners,attach,approved,comments|
+    report = agenda[attach] || OpenStruct.new
+
+    if owners.include? '/'
+      report.author, report.shepherd = owners.gsub(%r{\s*/\s*} ,'/').split('/',2)
+    else
+      report.author = report.shepherd = owners
+    end
+
+    report.attach = attach
+    report.approved = approved.gsub(/\s+/,' ').strip
+    report.comments = comments.gsub Regexp.new("^#{' '*9}"), ''
+    agenda.save report
+  end
+
+  # Special Orders
+  file.split(/^ 7. Special Orders/,2).last.
+         split(/^ 8. Discussion Items/,2).first.scan(/
+    \s{4}([A-Z])\.          # section
+    \s(.*?)\n               # title
+    (.*?)                   # text
+    (?=\n\s{4}[A-Z]\.\s|\z) # next section
+  /mx).each do |section,title,text|
+    attach = '7' + section
+    report = agenda[attach] || OpenStruct.new
+    report.attach = attach
+    text.sub!(/\n {7}\[ comments:(.*?)\n {9}\]\n/m) {report.comments = $1; ''}
+    report.text = "#{title}\n#{text}"
+
+    if secretary
+      directors = agenda.notes['Roll Call'].to_s.split(/\n\s*\n/)[1]
+      directors ||= agenda['2.'].text.split(/\n\s*\n/)[1]
+
+      report.text += "\n---\n"
+
+      if (section[-1].ord + Time.new.month) % 2 == 0
+        report.text += 'Roll call'
+      else
+        directors = directors.split("\n").reverse.join("\n")
+        report.text += 'Reverse roll call'
+      end
+      report.text += " vote on the matter of #{title}:\n\n#{directors}"
+    end
+
+    title.sub! /^Resolution to /, ''
+    title.sub! /\sthe\s/, ' '
+    title.sub! /\sApache\s/, ' '
+    title.sub! /\sCommittee\s/, ' '
+    title.sub! /\sProject\s/, ' '
+    title.sub! /\sProject$/, ''
+    title.sub! /\sPMC$/, ''
+
+    report.title = title
+    agenda.save report
+  end
+
+  # Back Matter
+  file.scan(/^((?: [89]| 9|1\d)\.) (.*?)\n(.*?)(?=\n[ 1]\d\.|\n===)/m).each do\
+    |attach, title, text|
+    report = agenda[attach.strip] || OpenStruct.new
+
+    if !text.empty? and title =~ /Action Items/
+      i = ('a'.ord-1).chr
+      text.gsub!(/\n        Update:\n/) {|line| "#{line.chomp} [#{i.succ!}]\n" }
+    end
+
+    report.attach = attach.strip
+    report.title = title
+    report.text = text
+    agenda.save report
+  end
+
+  agenda.order.each do |attach|
+    report = agenda[attach]
+    min = 5
+    min = 9 if attach =~ /3\w/
+    min = 0 if attach =~ /(8|9|1\d)\./ and report.text.to_s.empty?
+
+    report.title ||= "Missing #{attach}"
+    report.link = report.title.gsub(/\W/,'_').gsub(/_+/,'_')
+
+    report.status = 
+      if agenda.notes[report.title]
+        'reviewed'
+      elsif report.text.to_s.strip.empty? and min>0
+        if report.title =~ /THERE IS NO/
+          'reviewed'
+        else
+          'missing'
+        end
+      elsif report.approved.to_s.strip.split(/(?:,\s*|\s+)/).size < min
+        if report.attach =~ /7\w|\d\./ and report.approved.to_s.empty?
+          'ready4meet'
+        elsif director and
+          !report.approved.to_s.split(/[ ,]+/).include? director and
+          report.attach !~ /4\w/
+          'ready4me'
+        else
+          'ready'
+        end
+      elsif report.comments.to_s.strip.size > 0
+        'commented'
+      else
+        'reviewed'
+      end
+  end
+end
+
+class String
+  def asciize
+    if match /[^\x00-\x7F]/
+      # digraphs.  May be culturally sensitive
+      gsub! /\u00df/, 'ss'
+      gsub! /\u00e4|a\u0308/, 'ae'
+      gsub! /\u00e5|a\u030a/, 'aa'
+      gsub! /\u00e6/, 'ae'
+      gsub! /\u00f1|n\u0303/, 'ny'
+      gsub! /\u00f6|o\u0308/, 'oe'
+      gsub! /\u00fc|u\u0308/, 'ue'
+
+      # latin 1
+      gsub! /[\u00e0-\u00e5]/, 'a'
+      gsub! /\u00e7/, 'c'
+      gsub! /[\u00e8-\u00eb]/, 'e'
+      gsub! /[\u00ec-\u00ef]/, 'i'
+      gsub! /[\u00f2-\u00f6]|\u00f8/, 'o'
+      gsub! /[\u00f9-\u00fc]/, 'u'
+      gsub! /[\u00fd\u00ff]/, 'y'
+
+      # Latin Extended-A
+      gsub! /[\u0100-\u0105]/, 'a'
+      gsub! /[\u0106-\u010d]/, 'c'
+      gsub! /[\u010e-\u0111]/, 'd'
+      gsub! /[\u0112-\u011b]/, 'e'
+      gsub! /[\u011c-\u0123]/, 'g'
+      gsub! /[\u0124-\u0127]/, 'h'
+      gsub! /[\u0128-\u0131]/, 'i'
+      gsub! /[\u0132-\u0133]/, 'ij'
+      gsub! /[\u0134-\u0135]/, 'j'
+      gsub! /[\u0136-\u0138]/, 'k'
+      gsub! /[\u0139-\u0142]/, 'l'
+      gsub! /[\u0143-\u014b]/, 'n'
+      gsub! /[\u014C-\u0151]/, 'o'
+      gsub! /[\u0152-\u0153]/, 'oe'
+      gsub! /[\u0154-\u0159]/, 'r'
+      gsub! /[\u015a-\u0162]/, 's'
+      gsub! /[\u0162-\u0167]/, 't'
+      gsub! /[\u0168-\u0173]/, 'u'
+      gsub! /[\u0174-\u0175]/, 'w'
+      gsub! /[\u0176-\u0178]/, 'y'
+      gsub! /[\u0179-\u017e]/, 'z'
+
+      # denormalized diacritics
+      gsub! /[\u0300-\u036f]/, ''
+    end
+
+    self
+  end
+end
+
+# pattern looking for URIs in text
+uri_in_text = /(^|[\s.:;?\-\]<\(])
+               (https?:\/\/[-\w;\/?:@&=+$.!~*'()%,#]+[\w\/])
+               (?=$|[\s.:,?\-\[\]&\)])/x
+
+_html do
+  begin
+    load_agenda.call 
+  rescue
+    agenda.clear # load will be run again with traceback captured below
+  end
+
+  link = ENV['REQUEST_URI'][/\/agenda.*\/(.*)/,1]
+  attach, report = agenda.find {|attach,report| report.link == link}
+
+  _head do
+
+    if attach
+      _title 'ASF Board Agenda - ' + report.title
+    elsif agenda.filename
+      _title 'ASF Board Agenda - ' + File.basename(agenda.filename).
+       split('.').first.sub(/^[\D]+/,'').gsub('_','-')
+    end
+
+    _style %{
+      #notice, ._stdout {color: green; text-align: center}
+      ._stderr {color: red; text-align: center}
+      ._stdin {text-align: center}
+      footer {text-align: center}
+      footer ul {list-style-type: none; padding: 0}
+      a {color: #000}
+      .shell {border: 1px solid black;  border-radius: 1em; margin: 0 25%}
+
+      /* row colors */
+      .missing    {background-color: #F55}
+      .ready4meet {background-color: #F70}
+      .ready4me   {background-color: #F20}
+      .ready      {background-color: #F90}
+      .reviewed   {background-color: #9F9}
+      .commented  {background-color: #FF0}
+
+      /* sidebar */
+      .side {float: right} 
+      .side ul {margin: 0}
+      .side li {list-style: none}
+
+      /* next/back links */
+      .backlink {float: left}
+      .nextlink {float: right}
+      .backlink:before {content: "<< "}
+      .nextlink:after  {content: " >>"}
+
+      /* action items */
+      .ai {background-color: yellow}
+
+      /* make the header an eye catcher */
+      h1, h2.subtitle {
+        line-height: 2em;
+        text-align: center;
+        text-transform: capitalize;
+        clear: both
+      }
+
+      /* center the table */
+      table {
+        margin-left: auto;
+        margin-right: auto
+      }
+
+      /* table borders */
+      table, td, th {
+        border-color: #600;
+        border-style: solid;
+        border-width: 1px;
+      }
+
+      table {
+        border-spacing: 0;
+        border-collapse: collapse;
+      }
+
+      td, th {
+        margin: 0;
+        padding: 4px;
+      }
+
+      td:first-child {
+        text-align: center
+      }
+
+      tr {
+        background-color: #FFC;
+      }
+
+      tr.new {
+        background-color: yellow
+      }
+
+      .buttons {
+        margin-top: 1em;
+        text-align: center
+      }
+
+      .buttons div, .buttons form {
+        display: inline
+      }
+
+      form label {
+        display: block; margin-top: 0.5em
+      }
+
+      pre {
+        padding-left: 2em;
+        margin: 0;
+      }
+
+      pre#approved {
+        padding: 10px;
+      }
+
+      input[type=submit] {
+        border-radius: 1em;
+        background-color: #FFC;
+      }
+
+      .uptodate {
+        background-color: #7cfc00 !important
+      }
+
+      .stale {
+        background-color: #dc143c !important
+      }
+    }
+
+    if ENV['REQUEST_URI'] =~ /\/notes$/
+      _script src: '/jquery.min.js'
+    end
+  end
+
+  _body? do
+    load_agenda.call if agenda.empty?
+
+    if attach
+
+      ############################################################ 
+      #               Individual agenda item page                #
+      ############################################################ 
+
+      # previous and next links
+      index = agenda.order.index(attach)
+      if index > 0
+        _a.backlink agenda.at(index-1).title,
+           href: agenda.at(index-1).link, accesskey: '-'
+      end
+      if index < agenda.order.length-1
+        _a.nextlink agenda.at(index+1).title,
+           href: agenda.at(index+1).link, accesskey: '+'
+      end
+
+      # process update requests
+      if secretary and _.post?
+        if @title
+          if @notes.to_s.empty?
+            agenda.notes.delete @title
+          else
+            agenda.notes[@title] = @notes.gsub(/\r/,'').sub(/\A\s*\n/,'')
+          end
+
+          # safety first: verify data before write, and backup every change
+          if File.exist? agenda.yaml
+            # blows up on Ruby 1.8.7: YAML.load(YAML.dump({'boom'=>"\n x\ny"}))
+            YAML.load(YAML.dump(agenda.notes))
+
+            # make a timestamped copy of the original
+            backup = agenda.yaml.sub(/^(.*\/)?/, '\1backup/') + '-' +
+              File.stat(agenda.yaml).mtime.utc.iso8601.gsub(/\W/,'_')
+            FileUtils.mkdir_p File.dirname(backup)
+            FileUtils.cp agenda.yaml, backup
+          end
+
+          File.open(agenda.yaml, 'w') {|file| YAML.dump(agenda.notes, file)}
+          _p.notice! 'Report was successfully updated'
+        end
+      end
+
+      _h1 report.title, class: report.status
+
+      # sidebar
+      _div.side do
+        _ul do
+          _li {_a 'Agenda', href: '.'}
+          _li {_a 'Roll Call', href: agenda['2.'].link}
+          _li {_a 'Minutes', href: agenda['3A'].link}
+          _li {_a 'Executive Officer', href: agenda['4A'].link}
+          _li {_a 'Additional Officer', href: agenda['1'].link}
+          _li {_a 'Committee Reports', href: agenda['A'].link}
+          _li {_a 'Special Orders', href: agenda['7A'].link} rescue nil
+          _li {_a 'Discussion Items', href: agenda['8.'].link}
+          _li {_a 'Action Items', href: agenda['9.'].link}
+          if agenda.notes.empty?
+            _li {_a 'Pre-approvals', href: 'preapps'}
+          else
+            _li {_a 'Notes', href: 'notes'}
+          end
+        end
+      end
+
+      # Form with mostly readonly/hidden fields
+      _form method: 'post' do
+        _input.title! name: 'title', value: report.title,
+         type: 'hidden'
+
+        _p do
+          _label 'Attach', for: 'attach'
+          _input.attach! name: 'attach', value: attach,
+            readonly: 'readonly'
+        end
+
+        _p do
+          _label 'Author', for: 'author'
+          _input.author! name: 'author', value: report.author,
+            readonly: 'readonly'
+        end
+
+        _p do
+          _label 'Shepherd', for: 'shepherd'
+          _input.shepherd! name: 'shepherd', 
+            value: report.shepherd, readonly: 'readonly'
+        end
+        
+        unless report.approved.to_s.empty?
+          _label 'Approved by', for: 'approved'
+          _pre.approved! report.approved
+        end
+
+        _label 'Text', for: 'text'
+        _pre.text! do
+          text = CGI.escapeHTML(report.text.to_s).
+            gsub(/^    Guests( |:)/, '    <a href="https://svn.apache.org/repos/private/foundation/members.txt">Guests</a>\1').
+            gsub(/(board_minutes_\d+_\d+_\d+)/, '<a href="https://svn.apache.org/repos/private/foundation/board/\1.txt">\1</a>').
+            gsub(/\n---\n/, "\n<hr />\n").
+            gsub(/\n+\z/, "\n").
+            gsub(/\A\n/, "")
+
+          # make links in text active
+          text.gsub!(uri_in_text) do
+            pre, link = $1, $2
+            "#{pre}<a href=\"#{link.gsub("&amp;amp;", "&amp;")}\">#{link}</a>"
+          end
+          text.gsub! /(\s)(s\.apache\.org\/\w+)/, '\1<a href="http://\2">\2</a>'
+
+          # validate name/email addresses in resolutions
+          if report.attach =~ /7\w/ and text =~/^\s+[-*].*@/
+            text.gsub! /^\s*[-*].*?&lt;(\w+)@(\.\.\.|apache\.org)&gt;/ do |line|
+              person = ASF::Person.new($1)
+              if person.icla
+                # link to the roster information for this committer
+                line.sub! /(&lt;)(\w+)(@.*?)(&)/, 
+                  '\1<a href="/roster/committer/\2">\2\3</a>\4'
+
+                # match is defined as having a subset of tokens in any order
+                icla = person.icla.name.split(' ').map(&:asciize)
+                resolution = line[/[-*]\s+(.*?)\s&/,1].split(' ').map(&:asciize)
+                unless (icla-resolution).empty? or (resolution-icla).empty?
+		  ldap = person.public_name.split(' ').map(&:asciize)
+
+                  unless (ldap-resolution).empty? or (resolution-ldap).empty?
+                    line.sub! /([-*]\s+)(.*)(\s+&lt;)/, 
+                     '\1<span title="name doesn\'t match ICLA" ' +
+                     'class="commented">\2</span>\3'
+		  end
+                end
+              else
+                line.sub! /(&lt;)(\w+)(@)/, 
+                  '\1<span class="missing">\2</span>\3'
+              end
+
+              if person.asf_member?
+                # have members show up in bold
+                line.sub! /([-*]\s+)(.*?)(\s+&)/, 
+                  '\1<strong title="ASF member">\2</strong>\3'
+              end
+              line
+            end
+          end
+
+          if report.title =~ /Change (.*?) Chair/
+            pmc = $1
+            committee = ASF::Committee.find(pmc)
+            text.sub! "Apache #{pmc}", 
+              "<a href='/roster/committee/#{committee.name}'>Apache #{pmc}</a>"
+            committee.members.each do |person|
+              simple_name = person.public_name.sub(/ .* /,' ')
+              if person.asf_member?
+                sub = Proc.new do |name|
+                  "<a href='/roster/committer/#{person.id}' title='ASF Member'><strong>#{name}</strong></a>"
+                 end
+              else
+                sub = Proc.new do |name|
+                  "<a href='/roster/committer/#{person.id}'>#{name}</a>"
+                end
+              end
+              begin
+                text.sub! person.public_name, &sub
+                text.sub! simple_name, &sub if simple_name != person.public_name
+              rescue
+              end
+            end
+          end
+
+          if report.title == 'Incubator'
+            text.sub! /^---+ Detailed Reports ---+/, '------'
+            text.gsub! /\n+\n---+\n+(\w.*?)( \(|\n)/ do |match|
+              name = $1
+              file = name.gsub(/\W/,'_').untaint
+              if File.exist? "/var/www/board/minutes/#{file}.html"
+                match.sub(name, "<a href='/board/minutes/#{file}.html'>#{name}</a>")
+              else
+                match.sub(name, "<b>#{name}</b>")
+              end
+            end
+            text.gsub! /\n+\n---+\n/, "\n\n<hr/>\n"
+          end
+
+          _{text.untaint}
+        end
+
+        unless report.comments.to_s.empty?
+          _label 'Comments', for: 'comments'
+          text = CGI.escapeHTML(report.comments).gsub(uri_in_text) do
+            pre, link = $1, $2
+            "#{pre}<a href=\"#{link.gsub("&amp;amp;", "&amp;")}\">#{link}</a>"
+          end
+          _pre.comments! do
+            _{text.untaint}
+          end
+        end
+
+        # notes (editable by secretary only, for everybody else static)
+        if secretary
+          _p do
+            _label 'Notes', for: 'notes'
+            notes = agenda.notes[report.title]
+            if ['Roll Call', 'Discussion Items', 
+                'Review Outstanding Action Items'].include? report.title
+              notes ||= report.text.gsub(/ \(expected.*?\)/, '')
+            end
+            _textarea.notes! notes.to_s.sub(/\A\s*\n/,'').gsub(/^\s+\n/, "\n"), 
+              name: 'notes',
+              cols: 80, rows: [20, notes.to_s.split("\n").length+2].max
+          end
+          _input type: :submit, value: 'Update'
+          
+          # Buttons for common notes
+          if agenda.notes[report.title].to_s.empty?
+            if report.attach =~ /3\w/
+              _input type: 'submit', value: 'Approve', onclick:
+                "document.getElementById('notes').value='approved'"
+            end
+            if report.attach =~ /7\w/
+              _input type: 'submit', value: 'Unanimous', onclick:
+                "document.getElementById('notes').value='unanimous'"
+              _input type: 'submit', value: 'Tabled', onclick:
+                "document.getElementById('notes').value='tabled'"
+            end
+            if report.text.to_s.strip.empty? and not report.shepherd.to_s.empty?
+              _input type: 'submit', value: "AI:#{report.shepherd}",
+                 onclick: "document.getElementById('notes').value=" +
+                "'@#{report.shepherd} to pursue a report for #{report.title}'"
+            end
+            if ['1.','13.'].include? report.attach
+              _input type: 'submit', value: 'Timestamp', onclick:
+                "document.getElementById('notes').value=" +
+                "new Date().toLocaleTimeString()." +
+                "split(':').slice(0,2).join(':')"
+            end
+          end
+        elsif not agenda.notes[report.title].to_s.empty?
+          _label 'Secretary Notes', for: 'notes'
+          _pre.notes! do
+            _{CGI.escapeHTML(agenda.notes[report.title]).
+              gsub(/^\s*(@\w+ .*)/, '<span class="ai">\1</span>').
+              gsub(/\n+\z/, "\n").
+              gsub(/\A\n/, "").untaint}
+          end
+        end
+      end
+
+      # Misc links: Roster and Prior Reports
+      if report.attach =~ /^(4[A-Z]|\d+|[A-Z][A-Z]?)$/
+        _p do
+          title = report.title
+          title = 'stdcxx' if title == 'C++ Standard Library'
+          unless report.attach =~ /^4[A-Z]$/
+            _a 'Roster', href: "/roster/committee/#{CGI.escape title}"
+          end
+          _a 'Prior Reports', href: "/board/minutes/#{title.gsub(/\W/,'_')}"
+        end
+      end
+
+      # previous and next links
+      index = agenda.order.index(attach)
+      if index > 0
+        _a.backlink agenda.at(index-1).title,
+           href: agenda.at(index-1).link, accesskey: '-'
+      end
+      if index < agenda.order.length-1
+        _a.nextlink agenda.at(index+1).title,
+           href: agenda.at(index+1).link, accesskey: '+'
+      end
+
+    elsif secretary and ENV['REQUEST_URI'] =~ /\/calendar_summary$/
+
+      ############################################################ 
+      #                      Calendar Entry                      #
+      ############################################################ 
+
+      text = []
+      date =  Date.parse(agenda.filename[/(\d+_\d+_\d+)/,1].gsub('_','-'))
+      text << "- [#{date.strftime("%d %B %Y")}]" +
+        "(../records/minutes/#{date.strftime("%Y")}/" +
+        "board_minutes_#{date.strftime("%Y_%m_%d")}.txt)"
+      text << ''
+      agenda.order.each do |attach|
+        next unless attach =~ /7[A-Z]/
+        text << "    * #{agenda[attach].title.
+          gsub(/(.{1,76})(\s+|$)/, "\\1\n      ").strip}"
+      end
+      _h2 do
+        _ 'To be added to'
+        _a 'calendar.mdtext', href:
+'https://svn.apache.org/repos/asf/infrastructure/site/trunk/content/foundation/board/calendar.mdtext'
+        _ ':'
+      end
+      _form action: '../../publish_minutes', method: 'post' do
+        _textarea text.join("\n"), name: 'summary',
+          cols: 80, rows: text.length+2
+        _p
+        _input name: 'message', size: 48,
+          value: "Publish #{date.strftime("%d %B %Y")} minutes"
+        _button 'Commit', type: 'submit'
+      end
+
+    elsif ENV['REQUEST_URI'] =~ /\/preapps$/
+
+      ############################################################ 
+      #                       Pre-approvals                      #
+      ############################################################ 
+
+      _h1 'Pre-approvals'
+
+      all_approvals = agenda.
+        select {|key,value| key =~ /^([A-Z]+|[0-9]+|3[A-Z])$/}.
+        map { |key,report| report.approved.to_s.strip.split(/[, ]+/) }
+
+      _h2.subtitle 'By Number of Approvals'
+
+      _table do
+        _tr do
+          _th 'reports'
+          _th 'approvals'
+        end
+
+        reports = all_approvals.map(&:length).group_by(&:to_i)
+
+        reports.sort.each do |length, count|
+          _tr align: 'center' do
+            _td count.length
+            _td length
+          end
+        end
+      end
+
+      _h2.subtitle 'By Director'
+
+      _table do
+        _tr do
+          _th 'count'
+          _th 'initials'
+          _th 'name'
+        end
+
+        approvers = all_approvals.flatten.group_by(&:to_s).
+          map { |name, approvals| [approvals.length,name]}
+
+        approvers.sort.each do |count, name|
+          person = ASF::Person.find(DIRECTORS.invert[name])
+          _tr align: 'center' do
+            _td count
+            _td name
+            if person.icla?
+              _td align: 'left' do
+                _a person.public_name, href: "/roster/committer/#{person.id}"
+              end
+            else
+              _td {_em 'unknown'}
+            end
+          end
+        end
+      end
+
+      _footer do
+        _ul do
+          _li {_a 'Agenda', href: '.'}
+          _li {_a 'Comments', href: 'comments'}
+          _li {_a 'Notes', href: 'notes'} unless agenda.notes.empty?
+        end
+      end
+
+    elsif ENV['REQUEST_URI'] =~ /\/comments$/
+
+      ############################################################ 
+      #                     Report Comments                      #
+      ############################################################ 
+
+      _h1 'Report Comments'
+
+      # full details
+      agenda.order.map {|attach| agenda[attach]}.each do |report|
+        next if report.comments.to_s.strip.empty?
+        _h2 do
+          _a report.title, href: report.link
+        end
+        _pre do
+          text = CGI.escapeHTML(report.comments.sub(/\A\n+/,''))
+
+          # make links in text active
+          text.gsub!(uri_in_text) do
+            pre, link = $1, $2
+            "#{pre}<a href=\"#{link.gsub("&amp;amp;", "&amp;")}\">#{link}</a>"
+          end
+          text.gsub! /(\s)(s\.apache\.org\/\w+)/, '\1<a href="http://\2">\2</a>'
+
+          _{text}
+        end
+      end
+
+    elsif ENV['REQUEST_URI'] =~ /\/notes$/
+
+      ############################################################ 
+      #                   Aggregate notes page                   #
+      ############################################################ 
+
+      _h1 'Meeting Notes'
+      _a 'View/hide details', onclick: "toggleReport()"
+
+      # full details
+      _div.report! do
+        agenda.order.map {|attach| agenda[attach]}.each do |report|
+          next if agenda.notes[report.title].to_s.empty?
+          _h2 do
+            _a report.title, href: report.link
+          end
+          _pre do
+            _{CGI.escapeHTML(agenda.notes[report.title]).
+              gsub(/^\s*@(\w+ .*)/, '<span class="ai">AI: \1</span>').
+              gsub(/\n+\z/, "\n").
+              gsub(/\A\n/, "").untaint}
+            end
+        end
+      end
+
+      _div.buttons do
+        link = "/board/draft-minutes/#{agenda.filename[/(\d[\d_]+)/,1]}"
+        if File.exist? agenda.filename.sub('_agenda_','_minutes_')
+          _form action: link do
+            _button 'Show minutes', type: 'submit'
+          end
+          if secretary
+            _form action: 'calendar_summary' do
+              _button 'Publish Minutes', type: 'submit'
+            end
+          end
+        else
+          _form action: link do
+            _button 'Draft minutes', type: 'submit'
+          end
+        end
+      end
+
+      _ul do
+        _li {_a 'Pre-approvals', href: 'preapps'}
+        _li {_a 'Comments', href: 'comments'}
+      end
+ 
+      # List of action items (generated dynamically from the full list)
+      _div.ais!
+      _script! %{
+        $('#ais').toggle();
+
+        function toggleReport() {
+          if ($('#ais').children().length == 0) {
+            var ais = $('.ai');
+            var ul = $('<ul></ul>');
+            for (var i=0; i < ais.length; i++) {
+              ul.append($('<li></li>').text($(ais[i]).text().
+                replace(/^AI: /, '')));
+            }
+
+            $('#ais').append($('<h2>Action Items</h2>'));
+            $('#ais').append(ul);
+          }
+
+          $('#report').toggle();
+          $('#ais').toggle();
+        }
+      }
+
+    else
+
+      ############################################################ 
+      #                    Overall index page                   #
+      ############################################################ 
+
+      # If requested, reload agenda from svn
+      if secretary and _.post?
+        if @svnup
+          Dir.chdir SVN_FOUNDATION_BOARD do
+            _div.shell do
+              _.system 'svn up'
+            end
+          end
+
+          load_agenda.call
+        end
+      end
+
+      # Header
+      _h1 do
+        meeting = File.basename(agenda.filename)
+        _a "ASF Board Agenda #{meeting[/(\d[\d_]+)/,1].gsub('_','-')}",
+          href: "https://svn.apache.org/repos/private/foundation/board/#{meeting}"
+      end
+
+      # Index of reports
+      _table_ do
+        _tr do
+          _th 'Attach'
+          _th 'Tittle'
+          _th 'Author'
+          _th 'Shepherd'
+        end
+        agenda.order.each do |attach|
+          report = agenda[attach]
+          _tr_ class: report.status do
+            _td attach
+            _td do
+              _a report.title, href: report.link
+            end
+            _td report.author
+            _td report.shepherd
+          end
+        end
+      end
+
+      # Miscellaneous buttons: Draft minutes, Update agenda
+      _div.buttons do
+        unless agenda.notes.empty?
+          link = "/board/draft-minutes/#{agenda.filename[/(\d[\d_]+)/,1]}"
+          if File.exist? agenda.filename.sub('_agenda_','_minutes_')
+            _form action: link do
+              _button 'Show minutes', type: 'submit'
+            end
+            if secretary
+              _form action: 'calendar_summary' do
+                _button 'Publish minutes', type: 'submit'
+              end
+            end
+          else
+            _form action: link do
+              _button 'Draft minutes', type: 'submit'
+            end
+          end
+        end
+
+        if secretary
+          _form.buttons method: 'post' do
+            _button 'Update agenda', type: 'submit', name: 'svnup'
+          end
+        end
+      end
+
+      # Other Board Meeting Agendas
+      agendas = Dir["#{SVN_FOUNDATION_BOARD}/board_agenda_*.txt"]
+      agendas.delete agenda.filename
+      if agendas.length > 0
+        _footer_ do
+          _h2 'Other Board Meeting Agendas'
+          _ul do
+            agendas.sort.reverse.each do |agenda|
+              link = agenda[/(\d[\d_]+)/,1] + '/'
+              link = '../' + link if ENV['REQUEST_URI'] =~ /\d\//
+              _li! {_a File.basename(agenda), href: link}
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/www/board/draft-minutes.cgi b/www/board/draft-minutes.cgi
new file mode 100755
index 0000000..62884ad
--- /dev/null
+++ b/www/board/draft-minutes.cgi
@@ -0,0 +1,390 @@
+#!/usr/bin/ruby1.9.1
+require 'yaml'
+require 'wunderbar'
+require 'shellwords'
+require 'date'
+require '/var/tools/asf'
+
+ENV['HOME'] = ENV['DOCUMENT_ROOT']
+SVN_FOUNDATION_BOARD = ASF::SVN['private/foundation/board']
+MINUTES_WORK = '/var/tools/data'
+
+secretary = %w(clr rubys).include? $USER
+
+user = ASF::Person.new($USER)
+unless secretary or user.asf_member? or ASF.pmc_chairs.include?  user
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+request = ENV['REQUEST_URI'].split('?').first
+
+if request =~ /\/draft-minutes.*\/(\d\d\d\d[-_]\d\d[-_]\d\d)(\/|$)/
+  date = $1.gsub('-','_')
+elsif request =~ /\/draft-minutes.*\/(\d\d\d\d[-_]\d\d)(\/|$)/
+  date = $1.gsub('-','_') + '_*'
+elsif request =~ /\/draft-minutes.*\/(\d\d)(\/|$)/
+  date = '*_' + $1.gsub('-','_') + '_*'
+elsif request =~ /\/draft-minutes.*\/(\d\d[-_]\d\d)(\/|$)/
+  date = '*_' + $1.gsub('-','_')
+else
+  date = '*'
+end
+
+agenda_txt = Dir["#{SVN_FOUNDATION_BOARD}/board_agenda_#{date.untaint}*.txt"].
+  sort.last.untaint
+minutes_yaml = MINUTES_WORK + '/' + File.basename(agenda_txt).
+  sub('_agenda_','_minutes_').sub('.txt','.yml')
+
+minutes = File.read(agenda_txt)
+$notes = YAML.load_file(minutes_yaml) rescue {}
+
+def notes(index)
+  index = index.strip
+  index.sub! /^Report from the VP of /, ''
+  index.sub! /^Report from the /, ''
+  index.sub! /^Status report for the /, ''
+  index.sub! /^Resolution to /, ''
+  index.sub! /^Apache /, ''
+  index.sub! /\sTeam$/, ''
+  index.sub! /\sCommittee$/, ''
+  index.sub! /\sthe\s/, ' '
+  index.sub! /\sApache\s/, ' '
+  index.sub! /\sCommittee\s/, ' '
+  index.sub! /\sProject$/, ''
+  index.sub! /\sPMC$/, ''
+  index.sub! /\sProject\s/, ' '
+
+  $notes[index]
+end
+
+class String
+  def mreplace regexp, &block
+    matches = []
+    offset = 0
+    while self[offset..-1] =~ regexp
+      matches << [offset, $~]
+      offset += $~.end($~.size - 1)
+    end
+    raise 'unmatched' if matches.empty?
+
+    matches.reverse.each do |offset, match|
+      slice = self[offset...-1]
+      send = (1...match.size).map {|i| slice[match.begin(i)...match.end(i)]}
+      if send.length == 1
+        recv = block.call(send.first)
+        self[offset+match.begin(1)...offset+match.end(1)] = recv
+      else
+        recv = block.call(*send)
+        next unless recv
+        (1...match.size).map {|i| [match.begin(i), match.end(i), i-1]}.sort.
+          reverse.each do |start, fin, i|
+          self[offset+start...offset+fin] = recv[i]
+        end
+      end
+    end
+    self
+  end
+
+  def word_wrap(text, line_width=80)
+    text.split("\n").collect do |line|
+      line.length > line_width ?  line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
+    end * "\n"
+  end
+
+  def reflow(indent, len)
+    gsub!(/@(\w)/) {"AI: " + $1.upcase} # action items
+    strip.split(/\n\s+\n/).map {|line|
+      line.gsub!(/\s+/, ' ')
+      line.strip!
+      word_wrap(line, len).gsub(/^/, ' '*indent)
+    }.join("\n")
+  end
+end
+
+minutes.mreplace(/\n\s1.\sCall\sto\sorder\n+(.*?:)\n\n
+                 ((?:^\s{12}[^\n]*\n)+\n)
+                 (.*?)\n\n\s2.\sRoll\sCall/mx) do |meeting, number, backup|
+  start = notes('Call to order') || '??:??'
+  meeting.gsub! "is scheduled", "was scheduled"
+  meeting.gsub! "will begin as", "began at"
+  meeting.gsub! "soon thereafter that", "#{start} when"
+  meeting.gsub! "quorum is", "quorum was"
+  meeting.gsub! "will be", "was"
+  meeting.gsub! /:\z/, "."
+  backup.gsub! "will be", "was"
+  [meeting.reflow(4,64), '', backup.reflow(4, 68)]
+end
+
+minutes.mreplace(/\n\s2.\sRoll\sCall\n\n
+                 (.*?)\n\n+\s3.\sMinutes
+                 /mx) do |rollcall|
+  if notes('Roll Call')
+    notes('Roll Call').gsub(/\r\n/,"\n").gsub(/\n*\Z/,'')
+  else
+    rollcall.gsub(/ \(expected.*?\)/, '')
+  end
+end
+
+minutes.mreplace(/\n\s3.\sMinutes\sfrom\sprevious\smeetings\n\n
+                 (.*?\n\n)
+                 \s4.\sExecutive\sOfficer\sReports
+                 /mx) do |prior_minutes|
+  prior_minutes.mreplace(/\n\s+(\w)\.\sThe\smeeting\sof\s(.*?)\n.*?\n
+                         (\s{7}\[.*?\])\n\n
+                 /mx) do |attach, title, pub_minutes|
+    notes = notes(title)
+    if notes and !notes.empty?
+      notes = 'Approved by General Consent.' if notes == 'approved'
+      [attach, title, notes.reflow(7,62)]
+    else
+      [attach, title, '       Tabled.']
+    end
+  end
+end
+
+minutes.mreplace(/\n\s4.\sExecutive\sOfficer\sReports\n
+                 (\n.*?\n\n)
+                 \s5.\sAdditional\sOfficer\sReports
+                 /mx) do |reports|
+  reports.mreplace(/\n\s\s\s\s(\w)\.\s(.*?)\[.*?\](.*?)
+                 ()(?:\n+\s\s\s\s\w\.|\n\n\z)
+                 /mx) do |section, title, report, comments|
+    notes = notes(title)
+    if notes and !notes.empty?
+      [section, title, report, "\n\n" + notes.reflow(7,62)]
+    elsif report.strip.empty?
+      [section, title, report, "\n\n       No report was submitted."]
+    else
+      [section, title, report, ""]
+    end
+  end
+end
+
+minutes.mreplace(/\n\s5.\sAdditional\sOfficer\sReports\n
+                 (\n.*?\n\n)
+                 \s7.\sSpecial\sOrders
+                 /mx) do |reports|
+  reports.mreplace(/
+    \n\s\s\s\s\s?(\w+)\.\s([^\n]*?)   # section, title
+    \[([^\n]+)\]\n\n                  # owners
+    \s{7}See\s\s?Attachment\s\s?(\w+) # attach
+    (\s+\[\sapproved:\s*?.*?          # approved
+    \s*comments:.*?\n\s{9}\])         # comments
+  /mx) do |section, title, owners, attach, comments|
+    notes = notes(title.sub('VP of','').strip)
+    if notes and !notes.empty?
+      comments = "\n\n" + notes.to_s.reflow(7,62)
+    else
+      comments = ''
+    end
+    [section, title, owners, attach, comments]
+  end
+end
+
+minutes.mreplace(/\n\s7.\sSpecial\sOrders\n
+                 (.*?)
+                 \n\s8.\sDiscussion\sItems
+                 /mx) do |reports|
+  break if reports.empty?
+  reports.mreplace(/\n\s\s\s\s(\w)\.(.*?)\n(.*?)()(?:\n\s*\n\s\s\s\s\w\.|\n\z)
+                 /mx) do |section, title, order, comments|
+    order.sub! /\n       \[.*?\n         +\]\n/m, ''
+    notes = notes(title.strip)
+    if !notes or notes.empty? or notes.strip == 'tabled'
+      notes = "was tabled."
+    elsif notes == 'unanimous'
+      notes = "was approved by Unanimous Vote of the directors present."
+    end
+    notes = "Special Order 7#{section}, #{title}, " + notes
+    order += "\n" unless order =~ /\n\Z/
+    [section, title, order, "\n" + notes.reflow(7,62) + "\n"]
+  end
+end
+
+minutes.mreplace(/
+  ^((?:\s[89]|\s9|1\d)\.)\s
+  (.*?)\n
+  (.*?)
+  (?=\n[\s1]\d\.|\n===)
+/mx) do |attach, title, comments|
+  notes = notes(title)
+
+  if notes and !notes.empty?
+    if title =~ /Action Items/
+      comments = notes.gsub(/\r\n/,"\n").gsub(/^/,'    ')
+    elsif title =~ /Discussion Items/
+      comments = notes.gsub(/^/,'    ')+ "\n"
+    elsif title == 'Adjournment'
+      if notes =~ /1[01]:\d\d/
+        comments = "\n    Adjourned at #{notes} a.m. (Pacific)\n"
+      elsif notes =~ /\d\d:\d\d/
+        comments = "\n    Adjourned at #{notes} p.m. (Pacific)\n"
+      else
+        comments += "\n" + comments
+      end
+    else
+      comments += "\n" + notes.to_s.reflow(4,68) + "\n"
+    end
+  elsif title == 'Adjournment'
+    comments = "\n    Adjourned at ??:?? a.m. (Pacific)\n"
+  end
+  [attach, title, comments]
+end
+
+missing = minutes.scan(/^Attachment (\w\w?):.*\s*\n---/).flatten
+missing.each do |attach|
+  minutes.sub! /^(\s+)See Attachment #{attach}$/, '\1No report was submitted.'
+end
+
+minutes.sub! 'Minutes (in Subversion) are found under the URL:',
+  'Published minutes can be found at:'
+
+minutes.sub! 'https://svn.apache.org/repos/private/foundation/board/',
+  'http://www.apache.org/foundation/board/calendar.html'
+
+minutes[/^() 5. Additional Officer Reports/,1] =
+  "    Executive officer reports approved as submitted by General Consent.\n\n"
+
+minutes[/^() 6. Committee Reports/,1] =
+  "    Additional officer reports approved as submitted by General Consent.\n\n"
+
+minutes[/^() 7. Special Orders/,1] =
+  "    Committee reports approved as submitted by General Consent.\n\n"
+
+minutes.sub! 'Meeting Agenda', 'Meeting Minutes'
+minutes.sub! /^End of agenda/, 'End of minutes'
+
+minutes.gsub! /^\s*<private>.*?<\/private>\s*?\n/m, ''
+minutes.gsub! /\n( *)\[ comments:.*?\n\1 ? ?\]/m, ''
+
+_html do
+  _head do
+    _title 'Draft Meeting Minutes'
+    _script src: '/jquery-min.js'
+    _style %{
+      pre {margin: 0}
+      .ins {color: #060}
+      .del {color: #800}
+      .buttons {width: 56ex; text-align: center; margin: 1em}
+      ._stderr {font-weight:bold; color: #F00}
+      ._stdin:before {content: "$ "; color: blue}
+      ._stdin {color: purple; margin-top: 1em}
+      .log {background-color: #eedd82; border: 1px solid #000; border-radius:
+      1em; padding: 1em}
+      .log h3 {margin: 0}
+      form {display: inline}
+    }
+  end
+
+  _body? do
+    minutes_txt = agenda_txt.sub('_agenda_', '_minutes_')
+
+    if _.post? and not File.exist? minutes_txt and secretary
+      Dir.chdir File.dirname(minutes_txt) do
+        _div class: 'log' do
+          _h3 'Transcript'
+          _.system [
+            'svn', 'cp', 
+            File.basename(agenda_txt),
+            File.basename(minutes_txt)
+          ]
+
+          File.open(minutes_txt, 'w') {|fh| fh.write minutes}
+
+          _.system [
+            'svn', 'commit', 
+            '-m',  @message || "draft minutes for #{date}",
+            (['--username', $USER, '--password', $PASSWORD] if $PASSWORD),
+            File.basename(minutes_txt)
+          ]
+        end
+      end
+    end
+
+    _div class: 'buttons' do
+
+      _form do
+        if @format == 'diff'
+          _button 'Show Draft', type: "submit"
+        else
+          _input type: "hidden", name: "format", value: "diff"
+          _button 'Show Differences', type: "submit"
+        end
+      end
+
+      if secretary and not File.exist? minutes_txt
+        date = Date.parse(minutes_txt[/(\d[\w+]+)/,1].gsub('_','-'))
+        _form action: request, method: "post" do
+          _input type: "hidden", name: "message",  id: 'message',
+            value: "draft minutes for #{date}",
+            'data-value' => "draft minutes for #{date.strftime('%B %d, %Y')}"
+          _button 'Commit Draft', type: "submit", id: 'commit'
+        end
+      end
+
+    end
+
+    if not @format == 'diff'
+      _pre minutes
+    else
+      require 'open3'
+      require 'thread'
+      semaphore = Mutex.new
+      dest = agenda_txt.sub('_agenda_', '_minutes_')
+      if File.exist? dest
+        command = "diff -u - #{dest} \
+          --label '#{File.basename(dest).ljust(32)} (draft)' \
+          --label '#{File.basename(dest).ljust(32)} (subversion)'"
+      else
+        command = "diff -u #{agenda_txt} - \
+          --label '#{File.basename(agenda_txt).ljust(32)} (subversion)' \
+          --label '#{File.basename(dest).ljust(32)} (draft)'"
+      end
+      Open3.popen3(command) do |pin, pout, perr|
+        [
+          Thread.new do
+            until pout.eof?
+              out_line = pout.readline.chomp
+              semaphore.synchronize do
+                if out_line =~ /^\+/
+                  _pre out_line, class: 'ins'
+                elsif out_line =~ /^-/
+                  _pre out_line, class: 'del'
+                else
+                  _pre out_line
+                end
+              end
+            end
+          end,
+
+          Thread.new do
+            until perr.eof?
+              err_line = perr.readline.chomp
+              semaphore.synchronize { _pre err_line, class: '_stderr' }
+            end
+          end,
+
+          Thread.new do
+            pin.write minutes
+            pin.close
+          end
+        ].each {|thread| thread.join}
+      end
+    end
+
+    _script %{
+      $("#commit").click(function() {
+        var message = prompt("Commit Message?", 
+          $('#message').attr('data-value'));
+        if (message) {
+          $('#message').attr('value', message);
+          return true;
+        } else {
+          return false;
+        }
+      });
+    }
+  end
+end
diff --git a/www/board/publish_minutes.cgi b/www/board/publish_minutes.cgi
new file mode 100755
index 0000000..d6ecebc
--- /dev/null
+++ b/www/board/publish_minutes.cgi
@@ -0,0 +1,114 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require 'date'
+require '/var/tools/asf/svn'
+require 'shellwords'
+
+$SAFE = 1
+
+CONTENT = 'asf/infrastructure/site/trunk/content'
+BOARD_SITE = ASF::SVN["#{CONTENT}/foundation/board"]
+MINUTES = ASF::SVN["#{CONTENT}/foundation/records/minutes"]
+BOARD_PRIVATE = ASF::SVN['private/foundation/board']
+CALENDAR = "#{BOARD_SITE}/calendar.mdtext"
+
+Wunderbar.html do
+  _head do
+    _title 'Commit Minutes'
+    _style %{
+      ._stdin {display: none}
+      ._stdout, ._stderr {margin: 0}
+      ._stderr {color: red}
+      li {margin: 0.5em}
+    }
+  end
+  _body? do
+    calendar = File.read(CALENDAR)
+
+    # clean up summary; extract date and year from it
+    @summary = @summary.gsub(/\r\n/,"\n").sub(/\s+\Z/,'') + "\n"
+    date = @summary[/\[(.*?)\]/,1]
+    year = date.split(' ').last
+
+    # add year header
+    unless calendar.include? '#'+year
+      calendar[/^()#.*Board meeting minutes #/,1] =
+        "# #{year} Board meeting minutes # {##{year}}\n\n"
+      EOF
+    end
+
+    # add summary
+    if calendar.include? "\n- [#{date}]"
+      calendar.sub! /\n-\s+\[#{date}\].*?(\n[-#])/m, "\n" + @summary + '\1'
+    else
+      calendar[/# #{year} Board meeting minutes #.*\n()/,1] = "\n" + @summary
+    end
+
+    # remove from calendar
+    calendar.sub! /^(\s+-\s+#{date}\s*\n)/, ''
+
+    # parse and cleanup input
+    date = Date.parse(date).strftime("%Y_%m_%d")
+    year.untaint if year =~ /^\d+$/
+    message = Shellwords.escape(@message).untaint
+
+    _h1 'Publish the Minutes'
+
+    # update from svn
+    [MINUTES, BOARD_SITE, BOARD_PRIVATE].each {|dir| Dir.chdir(dir) {`svn up`}}
+
+    _h2 'Commit the Minutes'
+    Dir.chdir MINUTES do
+      unless Dir.exist? year
+        _.system "mkdir #{year}"
+        _.system "svn add #{year}"
+      end
+      if File.exist? "#{year}/board_minutes_#{date}.txt"
+        _p "#{year}/board_minutes_#{date}.txt already exists", class: '_stderr'
+      else
+        _.system "cp #{BOARD_PRIVATE}/board_minutes_#{date}.txt #{year}"
+        _.system "svn add #{year}/board_minutes_#{date}.txt"
+        _p
+        _.system "svn commit -m #{message} #{year}"
+      end
+    end
+
+    _h2 'Update the Calendar'
+    Dir.chdir BOARD_SITE do
+      if File.read(CALENDAR) == calendar
+        _p "#{File.basename CALENDAR} already up to date", class: '_stderr'
+      else
+        File.open(CALENDAR, 'w') {|fh| fh.write calendar}
+        _.system "svn diff #{File.basename CALENDAR}"
+        _p
+        _.system "svn commit -m #{message} #{File.basename CALENDAR}"
+      end
+    end
+
+    _h2 'Clean up board directory'
+    Dir.chdir BOARD_PRIVATE do
+      updated = false
+
+      if File.exist? "board_minutes_#{date}.txt"
+        _.system "svn rm board_minutes_#{date}.txt"
+        updated = true
+      end
+      
+      if File.exist? "board_agenda_#{date}.txt"
+        _.system "svn mv board_agenda_#{date}.txt archived_agendas"
+        updated = true
+      end
+
+      if updated
+        _p
+        _.system "svn commit -m #{message}"
+      else
+        _p "Nothing to clean up", class: '_stderr'
+      end
+    end
+
+    _h2 'Publish www site'
+    _a 'Proceed to CMS', href: 'https://cms.apache.org/www/publish'
+  end
+end
+
diff --git a/www/board/subscriptions.cgi b/www/board/subscriptions.cgi
new file mode 100755
index 0000000..ae7774d
--- /dev/null
+++ b/www/board/subscriptions.cgi
@@ -0,0 +1,169 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require '/var/tools/asf'
+
+SUBSCRIPTIONS = '/home/apmail/subscriptions/board'
+
+info_chairs = ASF::Committee.load_committee_info.group_by(&:chair)
+ldap_chairs = ASF.pmc_chairs
+
+_html do
+  _head_ do
+    _title 'Apache pmc-chair/board list'
+    _style %{
+      table {border-collapse: collapse}
+      th, td { border: 1pt solid black}
+      .issue, .issue a {color: red}
+    }
+  end
+
+  _body? do
+
+    _h1 'Apache pmc-chair/board list'
+
+    _p! do
+      _ 'This process starts with the list of subscribers to '
+      _a 'board@apache.org', href: 'https://mail-search.apache.org/members/private-arch/board/'
+      _ '.  '
+      _a 'members.txt', href: 'https://svn.apache.org/repos/private/foundation/members.txt'
+      _ ', '
+      _a 'iclas.txt', href: 'https://svn.apache.org/repos/private/foundation/officers/iclas.txt'
+      _ ', and '
+      _code 'ldapsearch mail'
+      _ ' to attempt to match the email address to an Apache ID.  '
+      _ 'Those that are not found are listed as '
+      _code.issue '*missing*'
+      _ '.  ASF members are '
+      _strong 'listed in bold'
+      _ '.  Emeritus members are '
+      _em 'listed in italics'
+      _ '.  Non ASF member, non-committee chairs are also '
+      _span.issue 'listed in red'
+      _ '.'
+    end
+
+    _p! do
+      _ 'The resulting list is then cross-checked against '
+      _a 'committee-info.text', href: 'https://svn.apache.org/repos/private/committers/board/committee-info.txt'
+      _ ' and '
+      _code 'ldapsearch cn=pmc-chairs'
+      _ '.  Membership that is only listed in one of these two sources is '
+      _span.issue 'listed in red'
+      _ '.'
+    end
+
+    _p! do
+      _ 'Committee chairs for which a matching email address can not be found are '
+      _a 'listed in a separate table', href: "#unsub"
+      _ '.'
+    end
+
+    ids = []
+
+    File.readlines(SUBSCRIPTIONS).each do |line|
+      person = ASF::Mail.list[line.downcase.strip]
+      person ||= ASF::Mail.list[line.downcase.strip.sub(/\+\w+@/,'@')]
+      if person
+        id = person.id
+        id = '*notinavail*' if id == 'notinavail'
+      else
+        person = ASF::Person.find('notinavail')
+        id = '*missing*'
+      end
+      ids << [id, person, line.strip]
+    end
+
+    _table_ border: '1', cellpadding: '2', cellspacing: '0' do
+      _tr do
+        _th 'id'
+        _th 'email'
+        _th 'name'
+        _th 'committee'
+      end
+
+      ids.sort.each do |id, person, email|
+        next if email == 'board-archive@apache.org'
+        _tr_ do
+          href = "/roster/committer/#{id}"
+          if person.asf_member?
+            if person.asf_member? == true
+              _td! {_strong {_a id, href: href}}
+            else
+            _td! {_em {_a id, href: href}}
+            end
+          elsif id.include? '*'
+            _td.issue id
+          elsif info_chairs.include? person or ldap_chairs.include? person
+            _td {_a id, href: href}
+          else
+            _td.issue {_a id, href: href}
+          end
+          _td email
+
+          if not id.include? '*'
+            _td person.public_name
+          else
+	    icla = ASF::ICLA.find_by_email(id)
+	    if icla
+              _td.issue icla.name
+	    else
+              _td.issue '*notinavail*'
+	    end
+          end
+
+          if info_chairs.include? person
+            text = info_chairs[person].uniq.map(&:display_name).join(', ')
+            if ldap_chairs.include? person or info_chairs[person].all? &:nonpmc?
+              _td text
+            else
+              _td.issue text
+            end
+          elsif ldap_chairs.include? person
+            _td.issue '***LDAP only***'
+          elsif person.asf_member?
+            _td
+          else
+            _td.issue '*** non-member, non-officer ***'
+          end
+        end
+      end
+    end
+
+    chairs = ( info_chairs.keys + ldap_chairs ).uniq
+    missing = chairs.map(&:id) - ids.map(&:first)
+
+    unless missing.empty?
+      _h3_.unsub! 'Not subscribed to the list'
+      _table border: '1', cellpadding: '2', cellspacing: '0' do
+	_tr do
+	  _th 'id'
+	  _th 'name'
+	  _th 'committee'
+	end
+	missing.sort.each do |id|
+          person = ASF::Person.find(id)
+	  _tr_ do
+	    if person.asf_member?
+	      _td! {_strong id}
+	    else
+	      _td id
+	    end
+	    _td person.public_name
+	    if info_chairs.include? person
+              text = info_chairs[person].uniq.map(&:display_name).join(', ')
+	      if ldap_chairs.include? person
+		_td text
+	      else
+		_td.issue text
+	      end
+	    elsif ldap_chairs.include? person
+	      _td.issue '***LDAP only***'
+	    else
+	      _td
+	    end
+	  end
+	end
+      end
+    end
+  end
+end
diff --git a/www/fundraising/invoice.cgi b/www/fundraising/invoice.cgi
new file mode 100755
index 0000000..b49dc87
--- /dev/null
+++ b/www/fundraising/invoice.cgi
@@ -0,0 +1,458 @@
+#!/usr/bin/ruby1.9.1
+# encoding: utf-8
+require 'wunderbar'
+require "date"
+require "yaml"
+
+require '/var/tools/asf'
+user = ASF::Person.new($USER)
+unless user.asf_member? or ASF.pmc_chairs.include? user or $USER=='ea'
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+HISTORY = '/var/tools/invoice'
+if %r{/(?<invoice>\d+)(\.\w+)?$} =~ ENV['PATH_INFO']
+  if File.exist? "#{HISTORY}/#{invoice.untaint}"
+    form = YAML.load_file("#{HISTORY}/#{invoice.untaint}")
+    ENV['QUERY_STRING'] =
+      form.map {|k,v| "#{k}=#{CGI.escape(v.first)}"}.join("&")
+  end
+end
+
+_html do
+  _head_ do
+    _title "ASF Invoice #{invoice}"
+    _style %{
+      .c1 {padding-top:2pt;margin-right:9pt;text-align:right;padding-bottom:2pt}
+      .c5 {vertical-align:top;width:51.8pt}
+      .c7 {vertical-align:top;width:134.1pt;border-style:solid;background-color:#f2f2f2;border-color:#888;border-width:1pt;padding:0pt 3.6pt 0pt 3.6pt}
+      table {border-collapse:collapse}
+      tr {height: 15pt}
+      .c10 {vertical-align:top;width:76.5pt;border-style:solid;border-color:#888;border-width:1pt;padding:0pt 3.6pt 0pt 3.6pt}
+      .c11 {vertical-align:top;width:72pt;border-style:solid;border-color:#888;border-width:1pt;padding:0pt 3.6pt 0pt 3.6pt}
+      .c13 {color:#404040}
+      .c15 {vertical-align:top;width:396pt;border-style:solid;border-color:#888;border-width:1pt;padding:0pt 3.6pt 0pt 3.6pt}
+      .c16 {vertical-align:top;width:67.5pt;padding:0pt 3.6pt 0pt 3.6pt}
+      .c17 {padding-top:2pt;padding-bottom:4pt}
+      .c18 {vertical-align:top;width:267.8pt;padding:0pt 3.6pt 0pt 3.6pt}
+      .c20 {vertical-align:top;width:267.8pt}
+      .c21 {text-align:right}
+      .c23 {width:287.2pt;padding:0pt 3.6pt 0pt 3.6pt}
+      .c26 {width:220.5pt}
+      .c29 {padding-top:2pt;text-align:center;padding-bottom:2pt}
+      .c30 {margin: 1em 5em}
+      th {font-size: 10pt; font-weight: normal; }
+      p {min-height:9pt;font-size:9pt;margin:0;font-family:Verdana}
+      form, img {margin-left: auto; margin-right: auto; display: block; padding-bottom: 10pt}
+      body {max-width:540pt; padding:0 36pt}
+      input, textarea {width: 300pt}
+      input[name=total] {background-color: #8e8; color: #000; border: outset 1px; padding: 2px; border-radius: 0.3em}
+      input[type=button] {width: 73pt}
+      .index {border-spacing: 20px 5px; border-collapse: separate}
+      .index th {border-bottom: solid black}
+      .index input[type=submit] {width: 10em; display: block; margin-left: auto; margin-right: auto}
+      .buttons a {text-decoration: none}
+      .buttons button {width: 100pt}
+    }
+
+    _script src: '/jquery.min.js'
+    _script src: '/jquery-ui.min.js'
+  end
+
+  _body? do
+    _img alt: "Logo", src: "https://id.apache.org/img/asf_logo_wide.png"
+
+    _svg width: '100%', height: 30 do
+      _path d: 'M0,0h230v14h-230z', fill: '#636'
+      _path d: 'M245,0h230v14h-230z', fill: '#996'
+      _path d: 'M490,0h230v14h-230z', fill: '#669'
+    end
+
+    invoice ||= @invoice_number
+    invoice ||= Dir.chdir(HISTORY) {Dir['*'].max || 1000}.succ
+    @invoice_number = nil if ENV['REQUEST_URI'].end_with? '?'
+
+    base = ENV['REQUEST_URI'].dup
+    base.chomp! ENV['QUERY_STRING']
+    base.chomp! '?'
+    base.chomp! ENV['PATH_INFO']
+
+    if ENV['PATH_INFO'].to_s.end_with? '/'
+
+      _table_.index do
+        _thead_ do
+          _tr do
+            _td colspan: 4 do
+              _form action: "#{base}/#{invoice}" do
+                _input type: 'submit', value: 'New Invoice' 
+              end
+            end
+          end
+          _tr do
+            _th 'Invoice'
+            _th 'Date'
+            _th 'Customer'
+            _th 'Amount'
+          end
+        end
+        _tbody do
+          Dir.chdir(HISTORY) do
+            Dir['*'].sort.reverse.each do |invoice|
+              _tr_ do
+                _td {_a invoice, href: invoice}
+                form = YAML.load_file("#{HISTORY}/#{invoice.untaint}")
+                _td Date.parse(form['date'].first)
+                _td form['customer'].first
+                _td.c21 form['total'].first.sub('$ ', '')
+              end
+            end
+          end
+        end
+      end
+
+    elsif not @invoice_number and not _.pdf?
+
+      start = Date.today
+      finish = Date.new(start.year+1, start.month, start.day)-1
+
+      _form_ method: 'post', action: "#{base}/#{invoice}" do
+        _table style: 'margin-left: auto; margin-right: auto' do
+          _tr.presets! style: 'display: none' do
+            _td 'Presets'
+            _td do
+              _input type: 'button', value: 'Bronze',   'data-amount' => 5_000
+              _input type: 'button', value: 'Silver',   'data-amount' => 20_000
+              _input type: 'button', value: 'Gold',     'data-amount' => 40_000
+              _input type: 'button', value: 'Platinum', 'data-amount' => 100_000
+            end
+          end
+
+          _tr do
+            _td 'E-Mail'
+            _td do
+              _input type: 'email', name: 'email', 
+                value: @email || 'fundraising@apache.org'
+            end
+          end
+
+          _tr do
+            _td 'Invoice Number'
+            _td { _input name: 'invoice_number', value: invoice}
+          end
+
+          _tr do
+            _td 'Customer Name'
+            _td do
+              _input name: 'customer', value: @customer,
+                required: true, autofocus: true
+            end
+          end
+
+          _tr do
+            _td 'Purchase Order #'
+            _td { _input name: 'po_number', value: @po_number }
+          end
+
+          _tr do
+            _td 'Bill to'
+            _td { _textarea @bill_to, name: 'bill_to', rows: 6, required: true }
+          end
+
+          _tr do
+            _td 'Item Description'
+            _td do
+              _textarea @item, name: 'item', rows: 6, required: true,
+                placeholder: "quantity - description @ $ price"
+            end
+          end
+
+          _tr do
+            _td 'Amount'
+            _td do
+              _input name: 'total', value: "#{@total or '$ 0'}"
+            end
+          end
+        end
+
+        _input name: 'date', type: 'hidden', value: start.strftime("%B %d, %Y")
+
+        _input type: 'submit', value: 'Save', style: 'margin-top: 1em; 
+          width: 10em; display: block; margin-left: auto; margin-right: auto'
+      end
+
+      _div.instructions! do
+        _h4 'Instructions:'
+        _p.c30 do
+          _'The'
+          _em 'Amount'
+          _ 'field contains the sum of the dollar amounts entered in the'
+          _em 'Item Description'
+          _ 'field.'
+        end
+        _p.c30 do
+          _ 'To have the dollar amount placed in the third column of the'
+          _ 'invoice form, place it at the end of the line preceeded by an'
+          _em '@'
+          _ 'sign.'
+        end
+        _p.c30 do
+          _ 'To enter a quantity, start the line with an integer followed by a'
+          _em '-'
+          _ '(dash) character.'
+        end
+      end
+
+      _script %{
+        $('#presets').show();
+        $('#presets input[type=button]').click(function() {
+          var amount = '$ ' + $(this).attr('data-amount');
+          amount = amount.toString().replace(/(\\d)(?=(\\d\\d\\d)+$)/g, "$1,");
+          var item = "2012 " + $(this).val() + " Sponsorship @ " + 
+            amount + "\\n\\n";
+          item += "Start Date: #{start.strftime("%B %d, %Y")}\\n\";
+          item += "End Date: #{finish.strftime("%B %d, %Y")}\\n";
+          $('textarea[name=item]').val(item).keyup();
+          if ($('input[name=customer]').val() == '') {
+            $('input[name=customer]').focus();
+          }
+        });
+
+        $('textarea[name=item]').keyup(function() {
+          var total = 0;
+
+          // text $price
+          var amounts = $(this).val().match(/\\$\\s?[,\\d]+(\\r|\\n|$)/g);
+          for (var i=0; amounts && i<amounts.length; i++) {
+            total += parseFloat(amounts[i].replace(/\\D/g, ''));
+          }
+
+          // quantity - text @ $ price
+          amounts = $(this).val().match(
+            /(^|\\r|\\n)\\d+\\s-[^\\n]*?[@-]\\s?\\$\\s?[,\\d]+(?=\\r|\\n|$)/g);
+
+          for (var i=0; amounts && i<amounts.length; i++) {
+            var quantity = parseInt(amounts[i].match(/\\d+/)[0]);
+            var price = amounts[i].match(/[.,\\d]+(\\r|\\n|$)/)[0];
+            total += (quantity-1) * parseFloat(price.replace(/\\D/g, ''));
+          }
+
+          total = total.toString().replace(/(\\d)(?=(\\d\\d\\d)+$)/g, "$1,");
+
+          if ($('input[name=total]').val() != '$ ' + total) {
+            $('input[name=total]').stop().css('backgroundColor', '#FF0').
+              val('$ ' + total).animate({'backgroundColor': '#8e8'}, 1000);
+            $("input[type=submit]").attr('disabled', (total=='0'));
+          }
+        }).keyup();
+
+        $("input[name=invoice_number],input[name=total]").
+          focus(function(){ $(this).blur(); });
+      }
+
+    else
+
+      _table_ do
+        unless _.pdf?
+          _thead_ do
+            _tr do
+              _th.buttons colspan: 2 do
+                _a href: "#{base}/#{invoice}?" do
+                  _button 'Edit' 
+                end
+                _a href: "#{base}/#{invoice}.pdf" do
+                  _button 'Generate PDF' 
+                end
+              end
+            end
+          end
+        end
+
+        _tbody do
+          _tr do
+            _td style: "width: 270pt; color: #006" do
+              _p "Dept. 9660"
+              _p "Los Angeles, CA 90084-9660"
+              _p "USA"
+              _p "E-mail: #{@email ||'fundraising@apache.org'}"
+            end
+            _td style: "width: 270pt; text-align: right" do
+              _p "Invoice", style: "font-size: 28pt; color: #636"
+              _p @date
+            end
+          end
+        end
+      end
+
+      _p
+
+      _table_ do
+        _tbody do
+          _tr do
+            _td.c26 do
+              _table do
+                _tbody do
+                  _tr do
+                    _td.c16 do
+                      _p "Invoice No.", class: "c17 c13"
+                    end
+                    _td.c23 do
+                      _p @invoice_number
+                    end
+                  end
+
+                  _tr do
+                    _td.c16 do
+                      _p "Customer:", class: "c17 c13"
+                    end
+                    _td.c23 do
+                      _p @customer
+                    end
+                  end
+
+                  if @po_number and not @po_number.empty?
+                    _tr do
+                      _td.c16 do
+                        _p "Reference:", class: "c17 c13"
+                      end
+                      _td.c23 do
+                        _p "PO##{@po_number}"
+                      end
+                    end
+                  end
+                end
+              end
+            end
+            _td.c5
+            _td.c20 do
+              _table do
+                _tbody do
+                  _tr do
+                    _td.c18 do
+                      _p 'Bill To:', class: "c17 c13"
+                    end
+                  end
+
+                  _tr do
+                    _td.c18 do
+                      @bill_to.lines.each do |line|
+                        _p line.chomp
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+      end
+
+      _p style: 'height: 30pt'
+
+      _table_ do
+        _thead do
+          _tr do
+            _th 'Quantity', class: "c11"
+            _th 'Item', class: "c15"
+            _th 'Total', class: "c11"
+          end
+        end
+        _tbody do
+          @item.lines.each do |line|
+            line.gsub!(/^(\d+)\s-\s*/,'')
+            quantity = $1
+            if line.match(/[-@]?\s?\$\s?([,\d]+)$/)
+              line.gsub!(/[-@]?\s?\$\s?([,\d]+)$/, '') unless quantity
+              quantity ||= '1'
+              price = quantity.to_i * $1.gsub(/\D/,'').to_i
+            end
+
+            price = price.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, '\1,')
+            _tr do
+              _td.c11 do
+                _p.c29 quantity
+              end
+              _td.c15 do
+                _p.c17 line.chomp
+              end
+              _td.c10 do
+                _p.c1 price
+              end
+            end
+          end
+          (10-@item.lines.count).times do
+            _tr do
+              _td.c11
+              _td.c15
+              _td.c10
+            end
+          end
+        end
+      end
+
+      _p
+      
+      _table_ style: "margin-left: auto" do
+        _tbody do
+          _tr do
+            _td.c7 do
+              _p "Subtotal:", class: "c17 c21 c13"
+            end
+            _td.c10 do
+              _p.c1 @total
+            end
+          end
+          _tr do
+            _td.c7 do
+              _p 'Tax:', class: "c17 c21 c13"
+            end
+            _td.c10 do
+              _p.c1 "-"
+            end
+          end
+          _tr do
+            _td.c7 do
+              _p 'Shipping:', class: "c17 c21 c13"
+            end
+            _td.c10 do
+              _p.c1 '-'
+            end
+          end
+          _tr do
+            _td.c7 do
+              _p "Miscellaneous:", class: "c17 c21 c13"
+            end
+            _td.c10 do
+              _p.c1 "-"
+            end
+          end
+          _tr do
+            _td.c7 do
+              _p "Balance Due:", class: "c17 c21 c13" 
+            end
+            _td.c10 do
+              _p.c1 @total
+            end
+          end
+        end
+      end
+
+      _div style: "margin-top: 30pt; color: #006" do
+        _p "Please make checks payable to “The Apache Software Foundation”."
+        _p
+        _p "Wire and ACH payments information:"
+        _p "Beneficiary: “Apache Software Foundation”"
+        _p "Routing #: 121 000 248 (for domestic wire or ACH)"
+        _p "SWIFT: WFBIU6S (for international wire)"
+        _p "Account #: 3189163755"
+        _p "Wells Fargo Bank"
+      end
+
+      @invoice_number.untaint if @invoice_number =~ /^\d+$/
+      File.open("#{HISTORY}/#{@invoice_number}", 'w') do |file|
+        YAML.dump(params, file) 
+      end
+    end
+  end
+end
diff --git a/www/fundraising/sponsorship.cgi b/www/fundraising/sponsorship.cgi
new file mode 100755
index 0000000..c2c5ac9
--- /dev/null
+++ b/www/fundraising/sponsorship.cgi
@@ -0,0 +1,87 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require '/var/tools/asf'
+require 'yaml'
+require 'date'
+
+user = ASF::Person.new($USER)
+unless user.asf_member? or ASF.pmc_chairs.include? user or $USER=='ea'
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+_html do
+  _head_ do
+    _title 'Fundraising Sponsors'
+    _style %{
+      th {border-bottom: solid black}
+      table {border-spacing: 1em 0.2em }
+      th span {float: right}
+      th span:after {padding-left: 0.5em; content: "\u2195"}
+      tr:hover {background-color: #FF8}
+      .headerSortUp span:after {content: " \u2198"}
+      .headerSortDown span:after {content: " \u2197"}
+      .remind {color: red}
+    }
+    _script src: '/jquery.min.js'
+    _script src: '/jquery.tablesorter.js'
+  end
+
+  _body? do
+    # common banner
+    _a href: 'https://id.apache.org/' do
+      _img alt: "Logo", src: "https://id.apache.org/img/asf_logo_wide.png"
+    end
+
+    _h1_ 'Fundraising Sponsors'
+
+    # parse sponsorship records
+    sponsorship = 'private/foundation/Fundraising/sponsorship'
+    sponsors = Dir["#{ASF::SVN[sponsorship]}/*.txt"].map do |name| 
+      next if name =~ /payments.*\.txt/
+      file = File.read(name.untaint)
+      file.gsub! /:\s*\?\s*\n/, ": '?'\n"    # make parseable
+      data = YAML.load(file)
+      next if String === data
+      data['date'] ||= data['invoice date']  # make uniform
+      [File.basename(name), data]
+    end
+
+    _table_ do
+      _thead_ do
+        _tr do
+          _th 'Date'
+          _th 'Sponsor'
+          _th 'Level'
+        end
+      end
+
+      _tbody do
+        sponsors.compact.each do |file, data|
+          _tr_ do
+            date = data['date'].to_s.sub(/(\d\d\d\d)(\d\d)(\d\d)/, '\1-\2-\3')
+            parsed = Date.parse(date) rescue Date.new
+            if parsed >= Date.today-366 and parsed <= Date.today-305
+              _td.remind date
+             else
+              _td date
+             end
+
+            _td! do
+              _a data['name'], 
+                href: "https://svn.apache.org/repos/#{sponsorship}/#{file}"
+            end
+
+            _td data['level']
+          end
+        end
+      end
+    end
+
+    _script %{
+      $("table").tablesorter({sortList: [[0,1]]});
+      $('th').append('<span></span>');
+    }
+  end
+end
diff --git a/www/incubator/moderators.cgi b/www/incubator/moderators.cgi
new file mode 100755
index 0000000..d0239db
--- /dev/null
+++ b/www/incubator/moderators.cgi
@@ -0,0 +1,141 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require '/var/tools/asf'
+require 'nokogiri'
+
+user = ASF::Person.new($USER)
+unless user.asf_member? or ASF::Committee['incubator'].members.include? user
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+SUBSCRIPTIONS = '/home/apmail/subscriptions/incubator-mods'
+PODLINGS = "#{ASF::SVN['asf/incubator/public/trunk/content']}/podlings.xml"
+
+exceptions = {
+  "beanvalidation" => "bval",
+  "manifoldcf" => "connectors",
+  "odftoolkit" => "odf",
+  "openofficeorg" => "ooo",
+  "zetacomponents" => "zeta"
+}
+
+_html do
+  _head do
+    _title 'Apache Incubator moderators'
+    _link rel: "stylesheet", type: 'text/css',
+      href: "http://incubator.apache.org/style/bootstrap-1-3-0-min.css"
+    _link rel: "stylesheet", type: 'text/css',
+      href: "http://incubator.apache.org/style/style.css"
+    _style %{
+      body { margin: 0 2em }
+      p, h3 {margin-left: 2em}
+      table {margin-left: 4em}
+      hr {margin-top: 1.5em}
+    }
+  end
+
+  _body? do
+    # Standard Incubator header
+    _div class: 'container' do
+      _div class: 'row' do
+        _div class: 'span12' do
+          _a href: "http://www.apache.org/" do
+            _img alt: "The Apache Software Foundation", border: "0",
+              src: "http://www.apache.org/images/asf_logo_wide.gif"
+          end
+        end
+        _div class: 'span4' do
+          _a href: "http://incubator.apache.org/" do
+            _img alt: "Apache Incubator", border: "0",
+              src: "http://incubator.apache.org/images/apache-incubator-logo.png"
+          end
+        end
+      end
+      _div class: 'row' do
+        _div class: 'span16' do
+          _hr noshade: 'noshade', size: '1'
+        end
+      end
+    end
+
+    podlings = Hash[Nokogiri::XML(File.read(PODLINGS)).search('podling').
+      map {|podling| [podling["resource"], podling["status"]]}]
+
+    _h1 'Apache Incubator moderators'
+
+    moderators = Hash[File.read(SUBSCRIPTIONS).split(/\n\n/).
+      map {|stanza| [stanza[/incubator.apache.org\/(.*)\//,1],
+      stanza.scan(/^(.*@.*)/).flatten]}]
+
+    _h1 'Index'
+
+    cols = 6
+    slice = (podlings.keys.length+cols-1)/cols
+    _table do
+      (0...slice).each do |i|
+        _tr do
+          (0...cols).each do |j|
+            _td do
+              podling = podlings.keys.sort[i+j*slice]
+	      anchor = exceptions[podling] || podling
+	      if moderators.keys.any? {|list| anchor == list.split('-').first}
+	        _a podling, href: "##{anchor}"
+              else
+	        _indented_text podling
+	      end
+            end
+	  end
+	end
+      end
+    end
+
+    current = nil
+    moderators.keys.sort.each do |list|
+      next unless list.include? '-'
+      podling = list.split('-').first
+      unless podling == current
+        _hr_ if current
+	name = podling if podlings.include? podling
+	name ||= exceptions.invert[podling]
+	if name
+          _h2 id: podling do
+	    _a podling, 
+	      href: "http://incubator.apache.org/projects/#{name}.html"
+	  end
+	else
+          _h2 podling, id: podling
+	end
+        _p "Podling Status: #{podlings[name] || 'unknown'}"
+        current = podling
+      end
+
+      _h3_ list.sub(podling, '')
+
+      _table do
+        moderators[list].sort.each do |moderator|
+          person = ASF::Person.find_by_email(moderator)
+	  _tr_ do
+            if person and person.id != 'notinavail'
+              _td! {_a person.id, href: "/roster/committer/#{person.id}"}
+              if person.asf_member?
+                if person.asf_member? == true
+                  _td! {_b person.public_name}
+                else
+                  _td! {_em person.public_name}
+                end
+              else
+                _td person.public_name
+              end
+            else
+              _td
+              _td! {_em 'unknown'}
+            end
+	    _td moderator
+	  end
+        end
+      end
+    end
+  end
+end
diff --git a/www/incubator/podlings/by-age.cgi b/www/incubator/podlings/by-age.cgi
new file mode 100755
index 0000000..5ab6955
--- /dev/null
+++ b/www/incubator/podlings/by-age.cgi
@@ -0,0 +1,124 @@
+#!/usr/bin/ruby1.9.1
+require 'nokogiri'
+require 'date'
+require 'net/http'
+require 'wunderbar'
+
+projects = URI.parse('http://incubator.apache.org/projects/')
+table = Nokogiri::HTML(Net::HTTP.get(projects)).at('table')
+
+# extract a list of [podling names, table row]
+podlings = table.search('tr').map do |tr|
+  tds = tr.search('td')
+  next if tds.empty?
+  [tds.last.text, tr]
+end
+
+# extract sorted list of durations, tally counts of podlings by years
+duration = []
+by_age = {}
+podlings.compact.sort.each do |date, tr|
+  duration << Date.today - Date.parse(date)
+  years = (duration.last / 365.25).to_i
+  by_age[years] = 1 + (by_age[years] or 0)
+end
+
+_html do
+  _head_ do
+    _meta charset: 'utf=8'
+    _title 'Incubated Projects - Apache Incubator'
+    _link rel: "stylesheet", type: 'text/css',
+      href: "http://incubator.apache.org/style/bootstrap-1-3-0-min.css"
+    _link rel: "stylesheet", type: 'text/css',
+      href: "http://incubator.apache.org/style/style.css"
+    _style %{
+      svg { float: right; width: 8em; height: 8em; padding-right: 5%; }
+      body { margin: 0 2em }
+    }
+  end
+
+  _body? do
+    # Standard Incubator header
+    _div.container do
+      _div.row do
+        _div.span12 do
+          _a href: "http://www.apache.org/" do
+            _img alt: "The Apache Software Foundation", border: "0",
+              src: "http://www.apache.org/images/asf_logo_wide.gif"
+          end
+        end
+        _div.span4 do
+          _a href: "http://incubator.apache.org/" do
+            _img alt: "Apache Incubator", border: "0",
+              src: "http://incubator.apache.org/images/apache-incubator-logo.png"
+          end
+        end
+      end
+
+      _div.row do
+        _div.span16 do
+          _hr noshade: 'noshade', size: '1'
+        end
+      end
+    end
+
+    # pie chart
+    theta = 0
+    colors = ['0F0', 'FF0', 'F80', 'F50', 'F00']
+
+    _svg_ viewBox: '-500 -500 1000 1000' do
+      _circle r: 480, stroke: "#000", fill: "#000"
+      by_age.keys.sort.each do |age|
+        p1 = [Math.sin(theta)*475, -Math.cos(theta)*475].map(&:round).join(',')
+        theta += Math::PI*2 * by_age[age]/duration.length
+        p2 = [Math.sin(theta)*475, -Math.cos(theta)*475].map(&:round).join(',')
+        _path d: "M0,0 L#{p1} A475,475 0 0 1 #{p2} Z", 
+          fill: '#' + colors[age], title: "#{by_age[age]} PMCs aged " +
+            "#{age} to #{age+1} year#{'s' if age>0}"
+      end
+    end
+
+    # statistics
+    if duration.length % 2 == 0
+      mean = (duration[duration.length/2-1] + duration[duration.length/2])/2
+    else
+      mean = duration[duration.length/2]
+    end
+
+    _h2 'Statistics'
+    _p! do
+      _ "Count:      #{duration.length} PPMCs ("
+      _a 'history', href: 'http://incubator.apache.org/history/'
+      _ ")"
+    end
+    _p "Mean age:   #{(mean+0.5).to_i} days"
+    _p "Median age: #{(duration.reduce(:+)/duration.length + 0.5).to_i} days"
+
+    # Sorted list of podlings
+    _h2_! do
+      _a 'Currently in incubation',
+       href: 'http://incubator.apache.org/projects/#current'
+      _ ', sorted by age'
+    end
+
+    _table do
+      _tr do
+        table.at('tr').search('th').each do |th|
+          _th th.text
+        end
+      end
+      podlings.compact.sort.each do |date, tr|
+        _tr_ do
+          tr.search('td').each do |td|
+            a = td.at('a')
+            if a
+              _td! {_a a.text, href: (projects + a['href']).to_s}
+            else
+              _td td.text
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/www/index.html b/www/index.html
index c5e452f..b4629e0 100644
--- a/www/index.html
+++ b/www/index.html
@@ -1,25 +1,64 @@
 <!DOCTYPE html>
-<html>
-<head>
-<title>Whimsy</title>
-</head>
-<body>
-<h1>Whimsy</h1>
-<ul>
-<li><a href="board/agenda/">Board Agenda</a></li>
-<li><a href="board/draft-minutes">Board Minutes -- draft</a></li>
-<li><a href="board/minutes/">Board Minutes Collated by PMC/officer/topic</a></li>
-<li><a href="roster/committer/">Email address lookup</a></li>
-<li><a href="fundraising/invoice/">Fundraising Invoice</a></li>
-<li><a href="incubator/moderators">Incubator moderators</a></li>
-<li><a href="incubator/podlings/by-age">Incubator podlings by age</a></li>
-<li><a href="members/subscriptions/">Member subscription cross-checks</a></li>
-<li><a href="members/watch/">Member watch</a></li>
-<li><a href="new-account-request-queue">New Account Requests Queue</a></li>
-<li><a href="board/subscriptions/">PMC-chair vs board subscriptions</a></li>
-<li><a href="roster/committee/">PMC Roster</a></li>
-<li><a href="voter/whatif">STV Explorer</a></li>
-</ul>
-<p><a href="https://issues.apache.org/jira/browse/INFRA/component/12318503">JIRA</a></p>
-</body>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta charset="utf-8"/>
+    <title>Whimsy</title>
+    <style type="text/css">
+      h2 {text-decoration: underline}
+    </style>
+  </head>
+
+  <body>
+    <img title="ASF Logo" src="https://id.apache.org/img/asf_logo_wide.png"/>
+    <a href="http://whimsy.apache.org/">
+      <img src="whimsy.svg" width="80" title="whimsy"/>
+    </a>
+
+    <h2>Whimsy</h2>
+    <p>
+      Whimsy is a site where a set of absolutely unnecessary yet often quite
+      handy applications are deployed. 
+    </p>
+    <p>
+     Feel free to <a href="technology.html">look under the hood</a>.
+    </p>
+
+    <h2>Open to the Public</h2>
+    <ul>
+      <li><a href="board/minutes/">Board Minutes Collated by PMC/officer/topic</a></li>
+      <li><a href="incubator/podlings/by-age">Incubator podlings by age</a></li>
+      <li><a href="new-account-request-queue">New Account Requests Queue</a></li>
+    </ul>
+
+    <h2>Open to Committers</h2>
+    <ul>
+      <li><a href="roster/committer/">Email address lookup</a></li>
+      <li><a href="roster/committee/">PMC Roster</a></li>
+    </ul>
+
+    <h2>Open to Officers and Members</h2>
+    <ul>
+      <li><a href="board/agenda/">Board Agenda</a></li>
+      <li><a href="board/draft-minutes">Board Minutes -- draft</a></li>
+      <li><a href="fundraising/invoice/">Fundraising Invoice</a></li>
+      <li><a href="fundraising/sponsorship/">Fundraising Sponsorship</a></li>
+      <li><a href="board/subscriptions/">PMC-chair vs board subscriptions</a></li>
+      <li><a href="treasurer/expenses">Treasurer Expenses</a></li>
+      <li><a href="treasurer/paypal">Treasurer PayPal</a></li>
+      <li><a href="treasurer/statements">Treasurer Statements</a></li>
+    </ul>
+
+    <h2>Member Only</h2>
+    <ul>
+      <li><a href="members/subscriptions/">Member subscription cross-checks</a></li>
+      <li><a href="members/watch/">Member watch</a></li>
+      <li><a href="voter/whatif">STV Explorer</a></li>
+    </ul>
+
+    <h2>Other</h2>
+    <ul>
+      <li><a href="incubator/moderators">Incubator moderators</a></li>
+      <li><a href="secretary/workbench/">Secretary Workbench</a></li>
+    </ul>
+  </body>
 </html>
diff --git a/www/infra/mlreq.cgi b/www/infra/mlreq.cgi
new file mode 100755
index 0000000..d2fb7c4
--- /dev/null
+++ b/www/infra/mlreq.cgi
@@ -0,0 +1,90 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require 'shellwords'
+
+_html do
+  _head_ do
+    _title 'ASF Mailing List Request'
+    _script src: '/jquery-min.js'
+    _style %{
+      textarea, .mod, label {display: block}
+      input[type=submit] {display: block; margin-top: 1em}
+      legend {background: #141; color: #DFD; padding: 0.4em}
+      .name2 {width: 9em}
+      .name {width: 6em}
+    }
+  end
+
+  _body? do
+    _form method: 'post' do
+      _fieldset do
+        _legend 'ASF Mailing List Request'
+
+        _h3_ 'List name'
+        _input.name2 name: 'subdomain', required: true, pattern: '^\w+(-\w+)?$'
+        _ '@'
+        _input.name name: 'localpart', required: true, pattern: '^\w+$'
+        _ '.'
+        _input.name2 name: 'domain', value: 'apache.org', readonly: true
+
+        _h3_ 'Replies'
+        _label do
+          _input type: 'checkbox', name: 'replyto', value: 'true'
+          _ 'Set Reply-To list header?'
+        end
+
+        _h3_ 'Moderation'
+        _label do
+          _input type: "radio", name: "muopts", value: "mu", required: true
+          _ 'allow subscribers to post, moderate all others'
+        end
+        _label do
+          _input type: "radio", name: "muopts", value: "Mu"
+          _ 'allow subscribers to post, reject all others'
+        end
+        _label do
+          _input type: "radio", name: "muopts", value: "mU"
+          _ 'moderate all posts'
+        end
+        
+        _h3_ 'Moderators'
+        _textarea name: 'mods'
+
+        _input type: 'submit', value: 'Submit Request'
+      end
+    end
+
+    if _.post?
+      mods = params.select {|name,value| name =~ /^mod\d+$/ and value != ['']}.
+        values.flatten.join(',')
+      mods = @mods.gsub(/\s+/,',') if @mods
+
+      vars = {
+        subdomain: @subdomain,
+        localpart: @localpart,
+        domain: @domain,
+        moderators: mods,
+        muopts: @muopts,
+        replytolist: @replyto || "false",
+        notifyee: "#{$USER}@apache.org"
+      }
+
+      _h2 'What would be submitted'
+      _pre vars.map {|name,value| "#{name}=#{Shellwords.shellescape value}"}.
+        join("\n")
+    end
+    
+    _script_ %{
+      $('textarea').replaceWith('<input type="email" required="required" class="mod" name="mod0"/>')
+      var fkeyup = function() {
+        var input = $('<input type="email" class="mod" val=""/>');
+        input.attr('name', 'mod' + $('.mod').length);
+        input.bind('keyup paste', fkeyup);
+        lastmod.after(input).unbind();
+        lastmod = input;
+      }
+      var lastmod = $('.mod:last');
+      $('.mod').bind('keyup paste', fkeyup);
+    }
+  end
+end
diff --git a/www/jquery-min.js b/www/jquery-min.js
new file mode 120000
index 0000000..1e5328f
--- /dev/null
+++ b/www/jquery-min.js
@@ -0,0 +1 @@
+jquery.min.js
\ No newline at end of file
diff --git a/www/jquery.tablesorter.pager.js b/www/jquery.tablesorter.pager.js
new file mode 100644
index 0000000..cce6ea2
--- /dev/null
+++ b/www/jquery.tablesorter.pager.js
@@ -0,0 +1,184 @@
+(function($) {
+	$.extend({
+		tablesorterPager: new function() {
+			
+			function updatePageDisplay(c) {
+				var s = $(c.cssPageDisplay,c.container).val((c.page+1) + c.seperator + c.totalPages);	
+			}
+			
+			function setPageSize(table,size) {
+				var c = table.config;
+				c.size = size;
+				c.totalPages = Math.ceil(c.totalRows / c.size);
+				c.pagerPositionSet = false;
+				moveToPage(table);
+				fixPosition(table);
+			}
+			
+			function fixPosition(table) {
+				var c = table.config;
+				if(!c.pagerPositionSet && c.positionFixed) {
+					var c = table.config, o = $(table);
+					if(o.offset) {
+						c.container.css({
+							top: o.offset().top + o.height() + 'px',
+							position: 'absolute'
+						});
+					}
+					c.pagerPositionSet = true;
+				}
+			}
+			
+			function moveToFirstPage(table) {
+				var c = table.config;
+				c.page = 0;
+				moveToPage(table);
+			}
+			
+			function moveToLastPage(table) {
+				var c = table.config;
+				c.page = (c.totalPages-1);
+				moveToPage(table);
+			}
+			
+			function moveToNextPage(table) {
+				var c = table.config;
+				c.page++;
+				if(c.page >= (c.totalPages-1)) {
+					c.page = (c.totalPages-1);
+				}
+				moveToPage(table);
+			}
+			
+			function moveToPrevPage(table) {
+				var c = table.config;
+				c.page--;
+				if(c.page <= 0) {
+					c.page = 0;
+				}
+				moveToPage(table);
+			}
+						
+			
+			function moveToPage(table) {
+				var c = table.config;
+				if(c.page < 0 || c.page > (c.totalPages-1)) {
+					c.page = 0;
+				}
+				
+				renderTable(table,c.rowsCopy);
+			}
+			
+			function renderTable(table,rows) {
+				
+				var c = table.config;
+				var l = rows.length;
+				var s = (c.page * c.size);
+				var e = (s + c.size);
+				if(e > rows.length ) {
+					e = rows.length;
+				}
+				
+				
+				var tableBody = $(table.tBodies[0]);
+				
+				// clear the table body
+				
+				$.tablesorter.clearTableBody(table);
+				
+				for(var i = s; i < e; i++) {
+					
+					//tableBody.append(rows[i]);
+					
+					var o = rows[i];
+					var l = o.length;
+					for(var j=0; j < l; j++) {
+						
+						tableBody[0].appendChild(o[j]);
+
+					}
+				}
+				
+				fixPosition(table,tableBody);
+				
+				$(table).trigger("applyWidgets");
+				
+				if( c.page >= c.totalPages ) {
+        			moveToLastPage(table);
+				}
+				
+				updatePageDisplay(c);
+			}
+			
+			this.appender = function(table,rows) {
+				
+				var c = table.config;
+				
+				c.rowsCopy = rows;
+				c.totalRows = rows.length;
+				c.totalPages = Math.ceil(c.totalRows / c.size);
+				
+				renderTable(table,rows);
+			};
+			
+			this.defaults = {
+				size: 10,
+				offset: 0,
+				page: 0,
+				totalRows: 0,
+				totalPages: 0,
+				container: null,
+				cssNext: '.next',
+				cssPrev: '.prev',
+				cssFirst: '.first',
+				cssLast: '.last',
+				cssPageDisplay: '.pagedisplay',
+				cssPageSize: '.pagesize',
+				seperator: "/",
+				positionFixed: true,
+				appender: this.appender
+			};
+			
+			this.construct = function(settings) {
+				
+				return this.each(function() {	
+					
+					config = $.extend(this.config, $.tablesorterPager.defaults, settings);
+					
+					var table = this, pager = config.container;
+				
+					$(this).trigger("appendCache");
+					
+					config.size = parseInt($(".pagesize",pager).val());
+					
+					$(config.cssFirst,pager).click(function() {
+						moveToFirstPage(table);
+						return false;
+					});
+					$(config.cssNext,pager).click(function() {
+						moveToNextPage(table);
+						return false;
+					});
+					$(config.cssPrev,pager).click(function() {
+						moveToPrevPage(table);
+						return false;
+					});
+					$(config.cssLast,pager).click(function() {
+						moveToLastPage(table);
+						return false;
+					});
+					$(config.cssPageSize,pager).change(function() {
+						setPageSize(table,parseInt($(this).val()));
+						return false;
+					});
+				});
+			};
+			
+		}
+	});
+	// extend plugin scope
+	$.fn.extend({
+        tablesorterPager: $.tablesorterPager.construct
+	});
+	
+})(jQuery);				
\ No newline at end of file
diff --git a/www/members/subscriptions.cgi b/www/members/subscriptions.cgi
new file mode 100755
index 0000000..d838ce3
--- /dev/null
+++ b/www/members/subscriptions.cgi
@@ -0,0 +1,149 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require '/var/tools/asf'
+
+SUBSCRIPTIONS = '/home/apmail/subscriptions/members'
+
+_html do
+  _head_ do
+    _title 'Apache Members cross-check'
+    _style %{
+      table {border-collapse: collapse}
+      th, td { border: 1pt solid black}
+      .issue {color: red}
+    }
+  end
+
+  _body? do
+
+    _h1_ 'Apache Members cross-check'
+
+    _p! do
+      _ 'This process starts with the list of subscribers to '
+      _a 'members@apache.org', href: 'https://mail-search.apache.org/members/private-arch/members/'
+      _ '.  It then uses '
+      _a 'members.txt', href: 'https://svn.apache.org/repos/private/foundation/members.txt'
+      _ ', '
+      _a 'iclas.txt', href: 'https://svn.apache.org/repos/private/foundation/officers/iclas.txt'
+      _ ', and '
+      _code 'ldapsearch mail'
+      _ ' to attempt to match the email address to an Apache ID.  '
+      _ 'Those that are not found are listed as '
+      _code.issue '*missing*'
+      _ '.  Emeritus members are '
+      _em 'listed in italics'
+      _ '.  Non ASF members are '
+      _span.issue 'listed in red'
+      _ '.'
+    end
+
+    _p! do
+      _ 'The resulting list is then cross-checked against '
+      _code 'ldapsearch cn=member'
+      _ '.  Membership that is only listed in one of these two sources is also '
+      _span.issue 'listed in red'
+      _ '.'
+    end
+
+    _p! do
+      _ 'ASF members for which a matching email address can not be found are '
+      _a 'listed in a separate table', href: "#unsub"
+      _ '.'
+    end
+
+    ldap = ASF::Group['member'].members
+
+    members = ASF::Member.new.map {|id, text| ASF::Person[id]}
+    ASF::Person.preload('cn', members)
+
+    subscriptions = []
+    File.readlines(SUBSCRIPTIONS).each do |line|
+      person = ASF::Mail.list[line.downcase.strip]
+      person ||= ASF::Mail.list[line.downcase.strip.sub(/\+\w+@/,'@')]
+      if person
+        id = person.id
+        id = '*notinavail*' if id == 'notinavail'
+      else
+        person = ASF::Person.find('notinavail')
+        id = '*missing*'
+      end
+      subscriptions << [id, person, line.strip]
+    end
+
+    _table_ border: '1', cellpadding: '2', cellspacing: '0' do
+      _tr do
+        _th 'id'
+        _th 'email'
+        _th 'name'
+      end
+      subscriptions.sort.each do |id, person, email|
+        next if email == 'members-archive@apache.org'
+        _tr_ do
+          if id.include? '*'
+            _td.issue id
+          elsif not person.asf_member?
+            _td.issue id, title: 'Non Member'
+          elsif person.asf_member? != true
+            _td {_em id, title: 'Emeritus'}
+          elsif not ldap.include? person
+            _td {_strong.issue id, title: 'Not in LDAP'}
+          else
+            _td id
+          end
+          _td email
+
+          if id.include? '*'
+            _td ''
+          else
+            _td person.public_name
+          end
+        end
+      end
+    end
+
+    missing = members - (subscriptions.map {|id,person,email| person})
+    missing.delete_if {|person| person.asf_member? != true} # remove emeritus
+
+    unless missing.empty?
+      _h3_.unsub! 'Not subscribed to the list'
+      _table border: 1, cellpadding: 2, cellspacing: 0 do
+	_tr_ do
+	  _th 'id'
+	  _th 'name'
+	end
+	missing.sort_by(&:name).each do |person|
+	  _tr do
+	    if not ldap.include? person
+	      _td {_strong.issue person.id, title: 'Not in LDAP'}
+	    else
+	      _td person.id
+	    end
+            if person.public_name
+	      _td person.public_name
+            else
+              _td.issue '*notinavail*'
+            end
+	  end
+	end
+      end
+    end
+
+    extras = ldap - members
+
+    unless extras.empty?
+      _h3_.ldap! 'In LDAP but not in members.txt'
+      _table border: 1, cellpadding: 2, cellspacing: 0 do
+	_tr_ do
+	  _th 'id'
+	  _th 'name'
+	end
+	extras.sort.each do |person|
+	  _tr do
+	    _td id
+	    _td person.public_name
+	  end
+	end
+      end
+    end
+  end
+end
diff --git a/www/members/watch.cgi b/www/members/watch.cgi
new file mode 100755
index 0000000..1aba777
--- /dev/null
+++ b/www/members/watch.cgi
@@ -0,0 +1,253 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require '/var/tools/asf'
+require 'nokogiri'
+require 'date'
+
+SVN_BOARD = "https://svn.apache.org/repos/private/foundation/board"
+meetings = ASF::SVN['private/foundation/Meetings']
+
+_html do
+  _head_ do
+    _title 'Potential Member Watch'
+    _style %{
+      th {border-bottom: solid black}
+      table {border-spacing: 1em 0.2em }
+      tr td:first-child {text-align: center}
+      .issue {color: red; font-weight: bold}
+      .header span {float: right}
+      .header span:after {padding-left: 0.5em}
+      .headerSortUp span:after {content: " \u2198"}
+      .headerSortDown span:after {content: " \u2197"}
+    }
+    _script src: '/jquery.min.js'
+    _script src: '/jquery.tablesorter.js'
+  end
+
+  _body? do
+    # common banner
+    _a href: 'https://id.apache.org/' do
+      _img title: "Logo", alt: "Logo",
+        src: "https://id.apache.org/img/asf_logo_wide.png"
+    end
+
+    # start with the Watch List itself
+    watch_list = ASF::Person.member_watch_list.keys
+
+    nominations = File.read("#{meetings}/20120522/nominated-members.txt").
+      scan(/^\s?\w+.*<(\S+)@apache.org>/).flatten
+    nominations += File.read("#{meetings}/20120522/nominated-members.txt").
+      scan(/^\s?\w+.*\(([a-z]+)\)/).flatten
+
+    # determine which list to report on, based on the URI
+    request = ENV['REQUEST_URI']
+    if request =~ /multiple/
+      _h2_ 'Active In Multiple Committees'
+      list = ASF::Committee.list.map {|committee| committee.members}.
+        reduce(&:+).group_by {|person| person}.
+        delete_if {|person,list| list.length<3}.keys
+      list -= ASF.members
+    elsif request =~ /chairs/
+      _h2_ 'PMC Chairs'
+      list = ASF.pmc_chairs
+      list -= ASF.members
+    elsif request =~ /nominees/
+      _h2_ 'Nominees'
+      list = nominations.uniq.map {|id| ASF::Person.find(id)}
+    elsif request =~ /appstatus/
+      _h2_ 'Application Status'
+      status = File.read("#{meetings}/20120522/memapp-received.txt").
+        scan(/^(yes|no)\s+(yes|no)\s+(yes|no)\s+(yes|no)\s+(\w+)\s/)
+      status = Hash[status.map {|tokens| [tokens.pop, tokens]}]
+      list = status.keys.map {|id| ASF::Person.find(id)}
+    else
+      _h2_ 'Watch List'
+      list = watch_list
+    end
+
+    # for efficiency, preload public_names
+    ASF::Person.preload('cn', list)
+
+    _table do
+
+      _thead_ do
+        _tr do
+          if request =~ /appstatus/
+            _th 'Invited?'
+            _th 'Applied?'
+            _th 'members@?'
+            _th 'Karma'
+          elsif request =~ /nominees/
+            _th 'Seconded?'
+          else
+            _th 'Nominated?'
+	  end
+          
+          _th 'AvailID'
+          _th 'Name'
+
+          if request !~ /appstatus/
+          _th 'Committees'
+          _th 'Chair Since'
+          end
+        end
+      end
+
+      _tbody do
+        list.sort_by {|id| id.public_name.to_s}.each do |person|
+
+          _tr_ do
+
+            if request =~ /appstatus/
+              cols = status[person.id]
+
+	      if cols[0] == 'yes'
+                _td cols[0]
+              else
+                _td.issue cols[0]
+	      end
+
+              _td cols[1]
+
+	      if cols[1] == 'no' or cols[2] == 'yes'
+                _td cols[2]
+              else
+                _td.issue cols[2]
+              end
+
+	      if cols[1] == 'no' or cols[3] == 'yes'
+                _td cols[3]
+              else
+                _td.issue cols[3]
+              end
+            elsif request =~ /nominees/
+              if person.member_nomination =~ /Seconded by: \w/
+                _td 'yes'
+              else
+                _td.issue 'no'
+              end
+	    else
+              if nominations.include? person.id
+                _td 'yes'
+              else
+                _td
+              end
+	    end
+
+            # ASF id
+            if person.id =~ /^notinavail_\d+$/
+              _td
+            elsif person.asf_member?
+              _td! do
+                _strong {_a person.id, href: "/roster/committer/#{person.id}"}
+              end
+            else
+              _td! {_a person.id, href: "/roster/committer/#{person.id}"}
+            end
+
+            # public name
+            _td person.public_name
+  
+
+            if request !~ /appstatus/
+	      # committees
+	      _td do
+		person.committees.sort_by(&:name).each do |committee|
+		  if committee.chair == person
+		    _strong do
+		      _a committee.name, href: "/roster/committee/#{committee.name}"
+		    end
+		  else
+		    _a committee.name, href: "/roster/committee/#{committee.name}"
+		  end
+		end
+	      end
+    
+	      # chair since
+	      chair = person.committees.find {|committee| committee.chair == person}
+	      if chair
+		minutes = Dir['/var/www/board/minutes/*'].find do |name|
+		  File.basename(name).split('.').first.downcase.gsub(/[_\W]/,'') ==
+		    "#{chair.name.gsub(/\W/,'')}"
+		end
+    
+		search_string = "RESOLVED, that #{person.public_name}"
+		search_string.force_encoding('utf-8')
+
+		# search published minutes
+		resolution = nil
+		minutes.untaint
+		Nokogiri::HTML(File.read(minutes)).search('pre').each do |pre|
+		  if pre.text.include? search_string
+		    resolution = pre
+		    while resolution and resolution.name != 'h2'
+		      resolution = resolution.previous
+		    end
+		    break if resolution
+		  end
+		end
+    
+		date = 'unknown'
+		minutes = '/board/minutes/' + File.basename(minutes)
+		if resolution
+		  minutes += '#' + resolution.at('a')['id']
+		  date = Date.parse(resolution.text)
+		else
+		  # search unpublished agendas
+		  board = ASF::SVN['private/foundation/board']
+		  Dir["#{board}/board_agenda_*"].sort.each do |agenda|
+		    agenda.untaint
+		    if File.read(agenda).include? search_string
+		      minutes = "#{SVN_BOARD}/#{File.basename(agenda)}"
+		      date = agenda.gsub('_','-')[/(\d+-\d+-\d+)/,1]
+		      break
+		    end
+		  end
+		end
+
+		_td do
+		  _a date, href: minutes
+		end
+              end
+            end
+          end
+        end
+      end
+    end
+
+    _h2_ 'Related Links'
+    _ul do
+      unless request =~ /appstatus/
+        _li do
+          _a 'Application Status', href: '/members/watch/nominees'
+        end
+      end
+      unless list == watch_list
+        _li do
+          _a 'Potential Member Watch List', href: '/members/watch'
+        end
+      end
+      unless request =~ /nominees/
+        _li do
+          _a 'Nominees', href: '/members/watch/nominees'
+        end
+      end
+      unless request =~ /multiple/
+        _li do
+          _a 'Active in Multiple (>=3) PMCs', href: '/members/watch/multiple'
+        end
+      end
+      unless request =~ /chairs/
+        _li do
+          _a 'Non-member PMC chairs', href: '/members/watch/chairs'
+        end
+      end
+    end
+
+    _script %{
+      var numheaders = $('thead th').length;
+      $('table').tablesorter({sortList: [[numheaders-1,0]]});
+      $('.header').append('<span></span>');
+    }
+  end
+end
diff --git a/www/new-account-request-queue.cgi b/www/new-account-request-queue.cgi
new file mode 100755
index 0000000..dca2f7a
--- /dev/null
+++ b/www/new-account-request-queue.cgi
@@ -0,0 +1,4 @@
+#!/usr/bin/ruby1.9.1
+ACREQ = '/var/tools/acreq'
+Dir.chdir '/var/tools'
+require "./new-account-request-queue"
diff --git a/www/roster/committee.cgi b/www/roster/committee.cgi
new file mode 100755
index 0000000..6689ae9
--- /dev/null
+++ b/www/roster/committee.cgi
@@ -0,0 +1,476 @@
+#!/usr/bin/ruby1.9.1
+
+require 'wunderbar'
+require '/var/tools/asf'
+
+# mapping of committee names to canonical names (generally from ldap)
+canonical = Hash.new {|hash, name| name}
+canonical.merge! \
+  'community development'       => 'comdev',
+  'conference planning'         => 'concom',
+  'conferences'                 => 'concom',
+  'http server'                 => 'httpd',
+  'httpserver'                  => 'httpd',
+  'java community process'      => 'jcp',
+  'quetzalcoatl'                => 'quetz',
+  'security team'               => 'security',
+  'c++ standard library'        => 'stdcxx',
+  'travel assistance'           => 'tac',
+  'traffic server'              => 'trafficserver',
+  'web services'                => 'ws',
+  'xml graphics'                => 'xmlgraphics'
+
+display_name = Hash.new {|hash, name| name}
+namemap = Proc.new do |name|
+  cname = canonical[name.downcase]
+  display_name[cname] = name unless display_name.include? cname
+  cname
+end
+
+# parse chairs and nonpmc names from committee-info.txt
+board = ASF::SVN['private/committers/board']
+committee = File.read("#{board}/committee-info.txt").split(/^\* /)
+reporting = committee.first[/^2.(.*)\n3/m,1].scan(/^    (\w.*?)(?:\s*#|$)/).
+  flatten.sort.map {|name| namemap.call(name)}.uniq
+head = committee.shift.split(/^\d\./)[1]
+chairs = Hash[head.scan(/^\s+(\w.*?)\s\s+.*<(\w+)@apache\.org>/).
+  map {|name, id| [namemap.call(name), id]}]
+nonpmcs = head.sub(/.*?also has/m,'').
+  scan(/^\s+(\w.*?)\s\s+.*<\w+@apache\.org>/).flatten.uniq.map(&namemap)
+
+# parse roster information and display names from committee-info.txt
+info = {}
+committee.each do |roster|
+  roster.gsub! /^.*\[\s*emeritus\s*\].*/i, ''
+  name =  roster[/(\w.*?)\s+\(/,1]
+  info[namemap.call(name)] = roster.scan(/<(.*?)@apache\.org>/).flatten
+end
+
+# parse site information
+site = {}
+templates = ASF::SVN['asf/infrastructure/site/trunk/templates']
+projects = File.read("#{templates}/blocks/projects.mdtext")
+found = false
+projects.scan(/\[(.*?)\]\((http.*?) "(.*)"\)/).each do |name, link, text|
+  site[namemap.call(name)] = [link, text]
+end
+
+skeleton = File.read("#{templates}/skeleton.html")
+projects = skeleton[/<h4>Foundation Projects<\/h4>(.*?)<h4>/m,1]
+projects.scan(/<a href="(.*?)" title="(.*?)">(.*?)</).each do |link, text, name|
+  cname =  namemap.call(name)
+  link = 'http://www.apache.org' + link if link =~ /^\//
+  nonpmcs << cname unless nonpmcs.include? cname
+  site[cname] = [link, text]
+end
+
+committers = ASF.committers.map(&:id)
+
+banned = ASF::Person.list('loginShell=/usr/bin/false').map(&:id)
+
+_html do
+  # extract pmc name from uri
+  if ENV['REQUEST_URI'] =~ /committee\/(.+)/
+    @pmc = CGI::unescape($1)
+  end
+
+  _head_ do
+    if @pmc.to_s.empty?
+      _title 'Apache Committees'
+    else
+      _title "Apache Committee - #{@pmc}"
+    end
+    _meta charset: 'utf-8'
+    _style %{
+      .issue {font-weight:bold; color: red}
+      td:last-child {font-weight:bold}
+      td:last-child:not(.chair) {color: red}
+      td:last-child:not(:empty):before {content: '\u21d0 '}
+      tr:hover {background-color: #FF8}
+      td span {display: none}
+      td:hover span {position: absolute; display: block; background-color: #FFF;
+        padding: 1em; border: 2px solid #0F0; border-radius: 1em;
+        color: black; font-weight: normal}
+    }
+  end
+
+  _body? do
+    # common banner
+    _a href: 'https://id.apache.org/' do
+      _img title: "Logo", alt: "Logo", 
+        src: "https://id.apache.org/img/asf_logo_wide.png"
+    end
+
+    if @pmc
+      # individual pmc display page
+      @pmc.untaint if @pmc =~ /^[-\w]+$/
+      name = canonical[@pmc.downcase]
+
+      # extract roster from committee-info.txt
+      info = (info[name] || []).map {|uid| ASF::Person.find(uid)}
+
+      # extract roster from ldap
+      if name.tainted?
+        committee = []
+        group = []
+      else
+        committee = ASF::Committee.find(name).members
+        group = ASF::Group.find(name).members
+      end
+
+      # merge the two sources
+      pmc = (info + committee).uniq
+
+      if name == 'orphans'
+        pmc = ASF::Person.list - 
+         ASF::Group.list.map(&:members).flatten - 
+         ASF::Committee.list.map(&:members).flatten - 
+         ASF.members
+      end
+
+      # header for pmc, and pmc wide notices
+      if site.include? name
+        # site information found, link to it
+        link, text = site[name]
+        _h1_ do
+          _a display_name[name], href: link, title: text
+        end
+        if pmc.empty?
+          _p 'Project not found, but is in the navigation ' +
+            'list of projects on apache.org', class: 'issue'
+        elsif info.empty?
+          _p 'Not in committee-info.txt', class: 'issue'
+        elsif committee.empty?
+          if nonpmcs.include? name
+            _p 'Not in ldap'
+          else
+            _p 'Not in ldap', class: 'issue'
+          end
+        elsif not reporting.include? name
+          _p 'Not in reporting schedule', class: 'issue'
+        end
+      else
+        # site information not found
+        _h1_ display_name[name]
+        if name == 'orphans'
+        elsif pmc.empty?
+          _p 'Project not found', class: 'issue'
+        else
+          if not nonpmcs.include? name
+            _p 'Not in the navigation list of projects on apache.org',
+              class: 'issue'
+          end
+          if committee.empty?
+            _p 'Not in LDAP', class: 'issue'
+          end
+          if info.empty?
+            _p 'Not in committee-info.txt', class: 'issue'
+          end
+          if not reporting.include? name
+            _p 'Not in reporting schedule', class: 'issue'
+          end
+        end
+      end
+
+      unless (group - pmc).empty?
+        _h2_ 'PMC'
+      end
+
+      # prevent complaining if the person is banned
+      recognized = committers + banned
+
+      _table_ do
+	pmc.sort_by {|person| person.id}.each do |person|
+	  _tr_ do
+            # availid
+	    _td do
+	      _a person.id, href: "../committer/#{person.id}"
+	    end
+
+            # display name
+            if not person.asf_member?
+	      _td person.public_name
+            elsif person.asf_member? == true
+	      _td { _strong person.public_name }
+            else
+	      _td { _em person.public_name }
+            end
+
+            # notices
+	    if not committee.include?(person) and not committee.empty?
+	      _td do
+                _indented_text! 'not in LDAP committee'
+                _span "modify_committee.pl #{name} --add #{person.id}"
+              end
+	    elsif not group.include?(person) and not group.empty?
+	      _td do
+                _indented_text! 'not in LDAP group'
+                _span "modify_unix_group.pl #{name} --add #{person.id}"
+              end
+	    elsif not info.empty? and not info.include? person
+	      _td do
+                _indented_text! 'not in committee-info.txt'
+                _span "modify_committee.pl #{name} --rm #{person.id}"
+              end
+            elsif not recognized.include? person.id
+              _td do
+                if name == 'orphans'
+                  _indented_text! 'Not disabled'
+                else
+                  _indented_text! 'Not in ASF list of committers'
+		  if person.public_name
+                    _span "modify_unix_group.pl committers --add #{person.id}"
+		  else
+                    _span "modify_unix_group.pl #{name} --rm #{person.id}"
+		  end
+		end
+              end
+	    elsif not person.icla
+	      _td do
+                _indented_text! 'missing ICLA'
+                _span "modify_unix_group.pl #{name} --rm #{person.id}"
+	      end
+	    elsif chairs[name] == person.id
+	      _td 'chair', class: 'chair'
+            else
+	      _td
+	    end
+	  end
+	end
+      end
+
+      unless (group - pmc).empty?
+        _h2_ 'Committers'
+        _table_ do
+	  group.sort_by {|person| person.id}.each do |person|
+            next if pmc.include? person
+	    _tr_ do
+              # availid
+	      _td do
+	        _a person.id, href: "../committer/#{person.id}"
+	      end
+
+              if not person.asf_member?
+	        _td person.public_name
+              elsif person.asf_member? == true
+	        _td { _strong person.public_name }
+              else
+	        _td { _em person.public_name }
+              end
+
+              if not recognized.include? person.name
+                _td do
+		  _indented_text! 'Not in ASF list of committers'
+		  if person.public_name
+                    _span "modify_unix_group.pl committers --add #{person.id}"
+		  else
+                    _span "modify_unix_group.pl #{name} --rm #{person.id}"
+		  end
+		end
+              elsif person.public_name
+                _td
+              else
+                _td do
+		  _indented_text! 'Missing ICLA'
+                  _span "modify_unix_group.pl #{name} --rm #{person.id}"
+		end
+              end
+            end
+          end
+        end
+      end
+
+      # links
+      _ul do
+        _li do
+	  _a 'How to grant SVN access to a project source repository',
+	    href: 'http://www.apache.org/dev/pmc.html#SVNaccess'
+	end
+        _li do
+	  _a 'infrastructure site README',
+	    href: 'http://svn.apache.org/repos/asf/infrastructure/site/trunk/README'
+	end
+        _li do
+	  _a 'committee-info.txt',
+	    href: 'https://svn.apache.org/repos/private/committers/board/committee-info.txt'
+	end
+      end
+
+    else # PMC list
+
+      pmcs = ASF::Committee.list
+
+      # get a list of chairs from LDAP
+      ldap_chairs = ASF.pmc_chairs
+
+      # membership of each PMC
+      pmc_members = Hash[
+        ASF.search_one(ASF::Committee.base, 'cn=*', %w(cn member)).
+          map {|attrs| [ attrs['cn'].first, 
+            (attrs['member'] || []).map {|uid| uid[/uid=(.*?),/,1]} ] }
+      ]
+
+      # membership of each group
+      groups = Hash[
+        ASF.search_one(ASF::Group.base, 'cn=*', %w(cn memberUid)).
+          map {|attrs| [ attrs['cn'].first, attrs['memberUid'] || [] ] }
+      ]
+
+      # list of pmcs from ldap 
+      pmcs = pmc_members.keys
+
+      # list of people with an ICLA
+      iclas = Hash[ASF::ICLA.new.each.map {|id, name, email| [id, 1]}]
+
+      # table has two sections, first a list of pmcs then other committees
+      pmcsection = true
+      _h1_ "PMCs"
+
+      # merge names from committee-info.txt, ldap and site, eliminating nonpmcs
+      names = (info.keys + pmcs + site.keys + reporting + chairs.keys).
+        uniq.compact
+
+      _table_ do
+        ((names-nonpmcs).sort + nonpmcs.sort).each do |name|
+
+          # this is admittedly kind-of a hack, but when encountering the
+          # first non-pmc, dump a list of ldap-chairs that are not currently
+          # chairs, then insert a header in the middle of the table
+          if pmcsection and nonpmcs.include? name
+            ldap_chairs.sort_by {|p| p.name}.each do |chair|
+              next if chairs.values.include? chair.name
+              _tr_ do
+	        _td { _em 'missing' }
+                if chair.asf_member?
+                  _td do
+                    _strong chair.public_name, title: chair.name
+                  end
+                else
+                  _td chair.public_name, title: chair.name
+                end
+	        _td 'pmc-chair not listed in committee-info.txt'
+	      end
+            end
+
+            _tr_ do
+              _td colspan: '3' do
+                _h1 "Other Offices and Committees", id: 'other'
+              end
+              _td
+            end
+            pmcsection = false
+          end
+
+          # extract committee roster from ldap
+          pmc_names = (pmc_members[name] || []).sort
+
+          _tr_ do
+            # committtee name, linking to page if there is a roster to be found
+            if not pmc_names.empty? or info.include? name
+              _td do
+                _a display_name[name], href: name
+              end
+            elsif site.include? name
+              # site information found, link to it
+              link, text = site[name]
+              _td do
+                _a display_name[name], href: link
+              end
+            else
+              _td display_name[name]
+            end
+
+            # chair name, bold if the chair is an ASF member
+            chair = ASF::Person.find(chairs[name])
+            if chair.asf_member?
+              _td do
+                _strong chair.public_name
+              end
+            elsif chair
+              _td chair.public_name
+            else
+	      _td { _em 'missing' }
+            end
+
+            # notices
+            if chair and not reporting.include? name
+              _td 'not in reporting schedule'
+            elsif not info[name] or info[name].empty?
+              if not pmc_names.empty?
+                _td 'ldap only'
+              elsif chair.icla and nonpmcs.include? name
+                _td 'chair only', class: 'chair'
+              elsif site.include? name
+                _td 'website only'
+              elsif chair
+                _td 'chair only'
+              elsif reporting.include?  name
+                _td 'only in reporting schedule'
+              else
+                _td 'not found'
+              end
+            elsif pmc_names.empty?
+              if nonpmcs.include? name
+                _td
+              else
+                _td 'committee-info.txt only'
+              end
+            elsif info[name].sort == pmc_names
+              if pmc_names.any? {|id| not iclas.include? id}
+                if pmc_names.one? {|id| not iclas.include? id}
+                  _td 'missing an ICLA on file'
+                else
+                  _td 'missing ICLAs on file'
+                end
+              elsif not site.include? name
+                _td 'not linked in sidebar on apache.org web site'
+              elsif not pmc_names.include? chairs[name]
+                if nonpmcs.include? name
+                  _td
+                else
+                  _td 'chair not in pmc-chairs ldap group'
+                end
+              elsif not groups[name]
+                if nonpmcs.include? name
+                  _td
+                else
+                  _td 'no corresponding LDAP group'
+                end
+              elsif not (pmc_members[name] - groups[name]).empty?
+                if (pmc_members[name] - groups[name]).length == 1
+                  _td 'one committee member not in LDAP group'
+                else
+                  _td 'multiple committee members not in LDAP group'
+	        end
+              elsif not (groups[name] - committers - banned).empty?
+	        if (groups[name] - committers - banned).length > 1
+                  _td 'multiple group members not in list of committers'
+	        else
+                  _td 'one group member not in list of committers'
+		end
+              else
+                _td
+              end
+            elsif (info[name] - pmc_names).empty?
+              if (pmc_names - info[name]).length == 1
+                _td 'ldap contains an additional entry'
+              else
+                _td 'ldap contains additional entries'
+              end
+            elsif (pmc_names - info[name]).empty?
+              if (info[name] - pmc_names).length == 1
+                _td 'committee-info.text contains an additional entry'
+              else
+                _td 'committee-info.text contains additional entries'
+	      end
+            else
+              _td 'multiple differences found'
+            end
+          end
+
+        end
+      end
+    end
+
+  end
+end
diff --git a/www/roster/committer.cgi b/www/roster/committer.cgi
new file mode 100755
index 0000000..28b57a6
--- /dev/null
+++ b/www/roster/committer.cgi
@@ -0,0 +1,321 @@
+#!/usr/bin/ruby1.9.1
+
+require 'wunderbar'
+require '/var/tools/asf'
+
+exceptions = %w(hudson-jobadmin).map {|name| ASF::Committee.find name}
+
+# location of pgp keys
+COMMITTER_KEYS = "https://people.apache.org/keys/committer/%s.asc"
+
+# extract committer email from uri
+if ENV['REQUEST_URI'] =~ /committer\/(.+?)(\?|$)/
+  ENV['QUERY_STRING'] = "email=#{CGI::escape($1)}@apache.org"
+end
+
+_json do
+  person = ASF::Person.find_by_email(@email)
+  if person
+    _availid person.id
+    _name person.public_name
+    _emails person.all_mail
+    _urls person.urls
+    _committees person.committees.map(&:name)
+    _member person.asf_member?
+    _banned person.banned? if person.banned?
+    _pgpkeys (person.pgp_key_fingerprints || [])
+    _groups person.groups.map(&:name)
+    _auth person.auth
+  end
+end
+
+_text do
+  person = ASF::Person.find_by_email(@email)
+  if person
+    _ "AvailId:    #{person.id}"
+    _ "Member:     #{person.asf_member?}"
+    if person.committees.empty?
+      _ "Committees: -"
+    else
+      _ "Committees: #{person.committees.map(&:name).sort.join(' ')}"
+    end
+  end
+end
+
+_html do
+  _head_ do
+    @email = @email.strip.sub(/^mailto:/, '').strip if @email
+    if @email.to_s =~ /(.*)@apache.org$/
+      _title "Apache committer - #{$1}"
+    else
+      _title 'Apache email address lookup'
+    end
+    _meta charset: 'utf-8'
+    _style %{
+      h2 {margin-bottom: 0}
+      table ul {margin: 0; padding: 0; list-style: none}
+      table {border-spacing: 0 1em}
+      td:first-child {text-align: right; padding: 0}
+      td:first-child:after {content: ' \u2014'}
+      td:last-child {border-left: solid 1px #000; padding: 0 0.5em}
+      table {padding-left: 1.5em}
+      .issue {color: red; font-weight:bold}
+    }
+
+    _script %q{
+      function trim_email(e) {
+        return e.replace(/^\s+/, '').replace(/\s+$/, '').replace(/^mailto:/, '');
+      }
+    }
+  end
+
+  _body? do
+    # common banner
+    _a href: 'https://id.apache.org/' do
+      _img title: "Logo", alt: "Logo", 
+        src: "https://id.apache.org/img/asf_logo_wide.png"
+    end
+
+    # header based on URI and http method employed
+    if @email.to_s.empty?
+      # display form (and matching header) if no email was provided, or this
+      # page was the result of a post (presumably from the form)
+      _h1_ 'Apache email address lookup'
+
+      _form method: 'post' do
+        _input id: 'email', name: 'email', type: 'email', value: @email,
+          onchange: 'value = trim_email(value);'
+      end
+    else
+      # individual committer page
+      _h2_ @email
+    end
+
+    unless @email.to_s.empty?
+      # individual committer page - start by looking up email address
+      person = ASF::Person.find_by_email(@email)
+
+      if person
+        _table do
+	  if person.id == 'notinavail'
+            _tr_ do
+	      _td 'name'
+	      _td ASF::ICLA.find_by_email(@email).name
+            end
+	  else
+            # committer's availid - but only if the email is non apache.org
+            unless @email =~ /@apache.org$/
+              _tr_ do
+                _td 'id'
+                _td person.id
+              end
+            end
+
+            # display name (typically from iclas.txt)
+            _tr_ do
+              _td 'name'
+              if person.icla
+                _td person.public_name
+              else
+                _td person.public_name || 'Not Found', class: 'issue', 
+                  title: 'No ICLA on file'
+              end
+            end
+
+            # membership information (from members.txt)
+            if person.asf_member? or person.icla
+              _tr_ do
+                _td 'ASF Member'
+                _td person.asf_member?
+              end
+            end
+
+            # personal urls
+            unless person.urls.empty?
+              _tr_ do
+                _td 'Personal URL'
+                _td do
+		  _ul do
+		    person.urls.each do |url|
+		      _li {_a url, href: url}
+		    end
+		  end
+                end
+              end
+            end
+
+            # if user is banned, flag this
+            if person.banned?
+              _tr_ do
+                _td 'login'
+                _td 'disabled', class: 'issue'
+              end
+            end
+
+            # list of committees that this committer is a member of (from ldap)
+            unless (person.committees-exceptions).empty?
+              _tr_ do
+                _td 'Committees'
+                _td do
+	          _ul do
+	            person.committees.sort_by(&:name).each do |committee|
+                      next if exceptions.include? committee
+                      name = committee.name 
+		      _li do
+                        if person.groups.any? {|group| group.name == name}
+                          _a name, href: "../committee/#{name}"
+                        else
+                          if committee.members.empty?
+                            _a name, href: "../committee/#{name}",
+                              title: "not in corresponding LDAP group"
+                          else
+                            _a name, href: "../committee/#{name}",
+                              title: "not in corresponding LDAP group",
+                              class: 'issue'
+                          end
+                        end
+                        _ '(chair)' if committee.chair == person
+                      end
+		    end
+		  end
+	        end
+              end
+            end
+
+            # list of groups that this committer is a member of (from ldap)
+            groups =  person.groups.select do |group| 
+              not person.committees.any? {|cmt| cmt.name == group.name}
+            end
+
+            unless groups.empty?
+              _tr_ do
+                _td 'Groups'
+                _td do
+	          _ul do
+	            groups.sort_by(&:name).each do |group|
+		      _li group.name
+		    end
+		  end
+	        end
+              end
+            end
+
+            # list of other authorities that this individual has
+            # (from asf-authorization-template)
+            auth = person.auth
+            exceptions.each do |exception| 
+              auth << exception.name if person.committees.include? exception
+            end
+            unless auth.empty?
+              _tr_ do
+                _td 'Auth'
+                _td do
+	          _ul do
+	            auth.sort.each do |group|
+		      _li group
+		    end
+		  end
+	        end
+              end
+	    end
+
+            if person.pgp_key_fingerprints
+              require 'net/https'
+              person.id.untaint if person.id =~ /^\w+/
+              uri = URI.parse(COMMITTER_KEYS % person.id)
+              _tr_ do
+                _td 'PGP Key'
+                found = false
+	        http = nil
+                begin
+		  http = Net::HTTP.new(uri.host, uri.port)
+		  http.use_ssl = true if uri.scheme == 'https'
+		  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+		  found = true if http.head(uri.path).code == '200'
+		ensure
+		  http.finish if http and http.started?
+		end
+                _td do
+                  _ul do
+                    person.pgp_key_fingerprints.each do |pgpkey|
+		      if found
+                        _li {_a pgpkey, href: uri}
+		      else
+                        _li pgpkey
+		      end
+                    end
+                  end
+                end
+              end
+            end
+
+            if ASF::Person.new($USER).asf_member?
+              emails = person.all_mail
+              emails.delete "#{person.id}@apache.org"
+              unless emails.empty?
+                _tr_ do
+                  _td 'Email addresses'
+                  _td do
+	            _ul do
+	              emails.sort.each do |email|
+                        if person.obsolete_emails.include? email
+		          _li {_del email}
+                        else
+		          _li email
+                        end
+		      end
+		    end
+		  end
+                end
+	      end
+
+              if person.asf_member?
+                if person.members_txt
+                  _tr_ do
+                    _td 'members.txt'
+                    _td { _pre " *) " + person.members_txt.strip }
+                  end
+                end
+              elsif person.member_nomination
+                _tr_ do
+                  _td do
+                   _a 'nominated-members', href: 'https://svn.apache.org/repos/private/foundation/Meetings/20120522/nominated-members.txt'
+                  end
+                  _td { _pre person.member_nomination.chomp }
+                end
+              elsif person.member_watch
+                _tr_ do
+                  _td do
+                   _a 'potential-member-watch', href: 'https://svn.apache.org/repos/private/foundation/potential-member-watch-list.txt'
+                  end
+                  _td { _pre person.member_watch.chomp }
+                end
+              end
+            end
+	  end
+        end
+      else
+        _p "not found"
+      end
+    end
+
+    # additional links (note some are member only)
+    _h2_ 'Sources'
+    _ul do
+      _li do
+        _a 'id.apache.org', href: 'https://id.apache.org/'
+      end
+      if ASF::Person.new($USER).asf_member?
+        _li do
+          _a 'members.txt', href: 'https://svn.apache.org/repos/private/foundation/members.txt'
+        end
+        _li do
+          _a 'iclas.txt', href: 'https://svn.apache.org/repos/private/foundation/officers/iclas.txt'
+        end
+        _li do
+          _a 'asf-authorization-template', href: 'https://svn.apache.org/repos/infra/infrastructure/trunk/subversion/authorization/asf-authorization-template'
+        end
+      end
+    end
+  end
+end
diff --git a/www/secretary/workbench/ccla.erb b/www/secretary/workbench/ccla.erb
new file mode 100644
index 0000000..fc031dd
--- /dev/null
+++ b/www/secretary/workbench/ccla.erb
@@ -0,0 +1,13 @@
+to:   <%= contact.inspect %> <<%= cemail %>>
+from: <%= from %>
+cc:   secretary@apache.org
+bcc:  <%= bcc %>
+subject: Your CCLA sent to Apache Secretary
+
+Dear <%= contact %>,
+
+This message acknowledges receipt of the following document, which has been filed in the Apache Software Foundation records:
+
+  <%= commit_message %>
+
+<%= sig %>
diff --git a/www/secretary/workbench/file.cgi b/www/secretary/workbench/file.cgi
new file mode 100755
index 0000000..bd9865e
--- /dev/null
+++ b/www/secretary/workbench/file.cgi
@@ -0,0 +1,881 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require 'open3'
+require './local_paths'
+require 'fileutils'
+require 'ostruct'
+require 'escape'
+
+ENV['LANG'] = 'en_US.UTF-8'
+
+def html_fragment(&block)
+  x = Wunderbar::HtmlMarkup.new({})
+  x.instance_eval(&block)
+  x._.target!.join
+end
+
+def asciize(name)
+  if name.match /[^\x00-\x7F]/
+    # digraphs.  May be culturally sensitive
+    name.gsub! /\u00df/, 'ss'
+    name.gsub! /\u00e4|a\u0308/, 'ae'
+    name.gsub! /\u00e5|a\u030a/, 'aa'
+    name.gsub! /\u00e6/, 'ae'
+    name.gsub! /\u00f1|n\u0303/, 'ny'
+    name.gsub! /\u00f6|o\u0308/, 'oe'
+    name.gsub! /\u00fc|u\u0308/, 'ue'
+
+    # latin 1
+    name.gsub! /[\u00e0-\u00e5]/, 'a'
+    name.gsub! /\u00e7/, 'c'
+    name.gsub! /[\u00e8-\u00eb]/, 'e'
+    name.gsub! /[\u00ec-\u00ef]/, 'i'
+    name.gsub! /[\u00f2-\u00f6]|\u00f8/, 'o'
+    name.gsub! /[\u00f9-\u00fc]/, 'u'
+    name.gsub! /[\u00fd\u00ff]/, 'y'
+
+    # Latin Extended-A
+    name.gsub! /[\u0100-\u0105]/, 'a'
+    name.gsub! /[\u0106-\u010d]/, 'c'
+    name.gsub! /[\u010e-\u0111]/, 'd'
+    name.gsub! /[\u0112-\u011b]/, 'e'
+    name.gsub! /[\u011c-\u0123]/, 'g'
+    name.gsub! /[\u0124-\u0127]/, 'h'
+    name.gsub! /[\u0128-\u0131]/, 'i'
+    name.gsub! /[\u0132-\u0133]/, 'ij'
+    name.gsub! /[\u0134-\u0135]/, 'j'
+    name.gsub! /[\u0136-\u0138]/, 'k'
+    name.gsub! /[\u0139-\u0142]/, 'l'
+    name.gsub! /[\u0143-\u014b]/, 'n'
+    name.gsub! /[\u014C-\u0151]/, 'o'
+    name.gsub! /[\u0152-\u0153]/, 'oe'
+    name.gsub! /[\u0154-\u0159]/, 'r'
+    name.gsub! /[\u015a-\u0162]/, 's'
+    name.gsub! /[\u0162-\u0167]/, 't'
+    name.gsub! /[\u0168-\u0173]/, 'u'
+    name.gsub! /[\u0174-\u0175]/, 'w'
+    name.gsub! /[\u0176-\u0178]/, 'y'
+    name.gsub! /[\u0179-\u017e]/, 'z'
+
+    # denormalized diacritics
+    name.gsub! /[\u0300-\u036f]/, ''
+  end
+
+  name.gsub /[^\w]+/, '-'
+end
+
+SUFFIXES = /^([Jj][Rr]\.?|I{2,3}|I?V|VI{1,3}|[A-Z]\.)$/
+
+# rearrange name in an order suitable for sorting
+def lname(name)
+  name = name.split.reverse
+  suffix = (name.shift if name.first =~ SUFFIXES)
+  suffix += ' ' + name.shift if name.first =~ SUFFIXES
+  name << name.shift
+  name << name.shift if name.first=='Lewis' and name.last=='Ship'
+  name << name.shift if name.first=='Gallardo' and name.last=='Rivera'
+  name << name.shift if name.first=="S\u00e1nchez" and name.last=='Vega'
+  # name << name.shift if name.first=='van'
+  name.last.sub! /^IJ/, 'Ij'
+  name.unshift(suffix) if suffix
+  name.map! {|word| asciize(word)}
+  name.reverse.join(' ')
+end
+
+# rearrange name in an order suitable for sorting
+def icla_lname(line)
+  return '' unless line =~ /^\w.*?:(.*?):(.*?):(.*?)(:(.*))?\n/
+  lname($1)
+end
+
+def update_pending fields, dest
+  # start with the fields provided
+  fields = Hash[fields]
+
+  # reject blank fields, normalize the rest
+  fields.reject! {|k,v| v == [""]}
+  fields.each_key {|k| fields[k]=fields[k].join(' ')}
+
+  # add properties from svn
+  at = svn_at(dest)
+  at += '/*' if File.directory?(dest) and `svn proplist #{dest}{at}`.empty?
+  `svn proplist #{dest}#{at}`.scan(/  \w+:[-\w]+/).each do |prop|
+    value = `svn propget #{prop.untaint} #{dest}#{at}`.chomp
+    value.gsub!(/\\x[0-9a-fA-F][0-9a-fA-F]/) {|c| [c[2..3].to_i(16)].pack('C')}
+    value.gsub!(/\\[0-7][0-7][0-7]/) {|c| [c[1..3].to_i(8)].pack('C')}
+    fields[prop.strip] = value
+  end
+
+  # copy email field
+  fields['email'] ||= fields['gemail'] || fields['cemail'] ||
+                      fields['nemail'] || fields['memail']
+  fields.delete('email') unless fields['email']
+  
+  # Concatenate the fields to the pending list and write to disk
+  pending = YAML.load(open(PENDING_YML)) rescue []
+  pending << fields
+  open(PENDING_YML, 'w') {|file| file.write pending.to_yaml}
+end
+
+class Wunderbar::XmlMarkup
+  def move source, dest
+    source = File.expand_path(source, RECEIVED)
+    source += svn_at(source)
+
+    if File.exist?(dest) and !File.directory?(dest)
+      # Since svn error messages aren't as helpful as they could be here,
+      # let's improve on it... by pretending to run the command and then
+      # producing a better error message.
+      @_builder.tag! :pre, "svn mv #{source.inspect} #{dest}", class: 'stdin'
+      @_builder.tag! "File #{dest} already exists.", class: 'stderr'
+    else
+      if (`svn --version --quiet`.chomp.split('.') <=> %w(1 5)) >= 1
+        self.system "svn mv #{source.inspect} #{dest}"
+      else
+        if `svn st #{source.inspect}` =~ /^A/
+          self.system "cp #{source.inspect} #{dest}"
+          self.system "svn add #{dest}"
+          `svn proplist #{source.inspect}`.scan(/  \w+:[-\w]+/).each do |prop|
+            value = `svn propget #{prop.strip} #{source.inspect}`.chomp
+            self.system "svn propset #{prop.strip} #{value.inspect} #{dest}"
+          end
+          self.system "svn revert #{source.inspect}"
+        elsif `svn st #{source.inspect}` !~ /^D/
+          self.system "svn mv --force #{source.inspect} #{dest}"
+        end
+      end
+      self.system "svn rm #{dest}/Thumbs.db" if File.exist?("#{dest}/Thumbs.db")
+    end
+  end
+end
+
+def check
+  email = {}
+  prev_name = nil
+  output = []
+
+  open("#{OFFICERS}/iclas.txt").each do |line|
+    next unless line =~ /^\w.*?:(.*?):(.*?):(.*?)(:(.*))?\n/
+    name = $1
+ 
+    if ! $3.index('@')
+      output << [ 'email', "#{$1}: #{$3}" ]
+    elsif ! $4 or  ! $4.index('CLA')
+      output << [ 'nocla', $2 ]
+    end
+ 
+    email[$3] = name
+
+    name.split.each do |word|
+      next if word.length == 1 and word !~ /\w/
+      next if word =~ /^\W/
+      next if %w(van von da de del der den dos i).include? word
+      output << ['case', name] if word !~ /[A-Z][a-z]*/
+    end
+
+    sort_name = icla_lname(line)
+    if prev_name and prev_name > sort_name
+      output << [ 'order', "#{prev_name} > #{sort_name}" ]
+    end
+    prev_name = sort_name
+  end
+
+  html_fragment do
+    if output.empty?
+      _p 'No icla.txt issues.'
+    else
+      _h3 'icla.txt issues'
+      _table border: 1, cellpadding: 10, cellspacing: 0 do
+        _thead do
+          _th 'issue'
+          _th 'name'
+        end
+        output.each do |type, message|
+          _tr do
+            _td type
+            _td message
+          end
+        end
+      end
+    end
+  end
+end
+
+def email(target, message)
+  pending = YAML.load(open(PENDING_YML))
+
+  require MAIL if defined?(MAIL)
+  require 'erb'
+
+  mails = []
+  pending.each do |pending_hash|
+    next unless pending_hash['email'] == target
+
+    vars = OpenStruct.new(pending_hash.map {|k,v| 
+      [k.gsub(/\W/,'_'), v.dup.untaint]
+    })
+    vars.commit_message = message
+
+    # send email, if template exists
+    template = vars.doctype + '.erb'
+    template.untaint if template =~ /^[.\w]+/
+    if defined?(MAIL) and File.exist?(template)
+
+      # extract fields from the Mail defaults
+      Mail.defaults do
+        vars.sig  = instance_eval {@sig.gsub(/^ +/,'').strip}
+        vars.from = instance_eval {@from}
+        vars.bcc  = instance_eval {@bcc}
+      end
+
+      # expand template
+      def vars.get_binding
+        binding
+      end
+      message = ERB.new(open(template).read.untaint).result(vars.get_binding)
+      headers = message.slice!(/\A(\w+: .*\r?\n)*(\r?\n)*/)
+
+      mail = Mail.new do
+        # apply headers
+        headers.scan(/(\w+):[ \t]*(.*)/).each do |name, value|
+          send name, value unless value.empty?
+        end
+
+        body message
+
+        # is this a reply?
+        if vars.email_id
+          in_reply_to vars.email_id
+          references  vars.email_id
+
+          # override subject?
+          if vars.email_subject and !vars.email_subject.empty?
+            if vars.email_subject =~ /^re:\s/i
+              subject vars.email_subject
+            else
+              subject 'Re: ' + vars.email_subject
+            end
+          end
+        end
+      end
+
+      # get the list of cc's as an array
+      cc = mail.cc.dup
+
+      # eliminate the legal-archive from the cc list
+      cc.reject! {|addr| addr =~ /\blegal-archive@apache\.org\b/}
+
+      # add additional cc if email:addr != email
+      if vars.email_addr and !vars.email_addr.include?(mail.to.to_s)
+        if vars.email_name
+          cc << "#{vars.email_name.inspect} <#{vars.email_addr}>"
+        else
+          cc << vars.email_addr
+        end
+      end
+
+      # add original cc list
+      cc << vars.email_cc if vars.email_cc
+
+      # add pmc and podling lists, if supplied
+      cc << "private@#{vars.pmc}.apache.org" if vars.pmc
+      cc << "#{vars.podling}-private@incubator.apache.org" if vars.podling
+      cc << "private@incubator.apache.org" if vars.podling and not vars.pmc
+
+      # replace the list of cc's
+      mail.cc = cc.uniq.join(', ')
+
+      # update bcc
+      if vars.email_bcc and not vars.email_bcc.empty?
+        bcc = mail.bcc.to_s.split(/,\s*/)
+        bcc += vars.email_bcc.to_s.split(/,\s*/)
+        mail.bcc = bcc.uniq.join(', ')
+      end
+
+      # for debugging purposes
+      mails << [vars.email, mail.to_s]
+
+      # ship it!
+      mail.deliver!
+
+      completed = YAML.load(open(COMPLETED_YML)) rescue []
+      completed << pending_hash
+      open(COMPLETED_YML, 'w') {|file| file.write completed.pop(10).to_yaml}
+
+      # clean up pending list
+      pending.delete pending_hash
+
+      if pending.empty?
+        FileUtils.rm_f PENDING_YML
+      else
+        open(PENDING_YML, 'w') {|file| file.write pending.to_yaml}
+      end
+    end
+  end
+
+  html_fragment do
+    mails.each do |dest, mail|
+      _h2 "email #{dest}"
+      _pre mail, class: 'email'
+    end
+  end
+end
+
+def committable
+  files = %W( #{FOUNDATION}/Correspondence/JCP/tck-nda-list.txt )
+  if defined?(MEETING)
+    files += %W(#{MEETING}/memapp-received.txt #{FOUNDATION}/members.txt)
+  end
+  files += [DOCUMENTS, OFFICERS]
+end
+
+_json do
+  safe = [
+    "svn update #{OFFICERS}",
+    "svn update #{DOCUMENTS}",
+  ]
+
+  _html do
+    if @cmd == 'icla.txt issues'
+      _! check
+    elsif @cmd =~ /email (.*)/
+      _! email $1, @message
+    elsif @cmd =~ /svn commit/ and committable.include? @file
+      message, file = @message, @file
+      _! html_fragment {
+        _.system [
+          'svn', 'commit', '-m', message,
+          (['--username', $USER, '--password', $PASSWORD] if $PASSWORD),
+          file
+        ]
+      }
+    else
+      cmd = @cmd.untaint
+      _! html_fragment { 
+        if safe.include? cmd
+          _.system cmd.untaint
+        else
+          _pre._stdin cmd
+          _pre._stderr 'Unauthorized command'
+        end
+      }
+    end
+  end
+end
+
+DESTINATION = {
+  "Jim"       => "to_jim",
+  "Sam"       => "to_sam",
+  "upayavira" => "to_upayavira",
+  "dup"       => "deadletter/dup",
+  "incomplete"=> "deadletter/incomplete" }
+
+exception = nil
+line = nil
+
+_html do
+  _head_ do
+    _title 'File Document'
+
+    if ! %w{check update commit}.include?(@action.to_s.downcase)
+      _script 'parent.frames[0].location.reload()'
+    end
+
+    _style %{
+      html {background-color: #F8F8FF}
+      pre {font-weight: bold; margin: 0}
+      pre._stdin, pre.todo {color: #C000C0; margin-top: 1em}
+      .todo {opacity: 0.2}
+      pre._stdout {color: #000}
+      pre._hilite {color: #000; background-color: #FF0}
+      pre._stderr {color: #F00}
+      pre.email {background-color: #BDF; padding: 1em 3em}
+      pre.email {border-radius: 1em}
+      .traceback {background-color:#ff0; margin: 1em 0; padding: 1em;
+        border: 2px solid}
+      #notice {color: green}
+    }
+  end
+
+  _body? do
+
+    begin
+      filename = [@filename, @cfilename, @gfilename, @mfilename, @nfilename].
+        find {|name| name and not name.empty?}
+      filename.untaint if filename and filename =~ /^[-.\w]+/
+      doctype = (@doctype == 'mem' ? 'member_apps' : @doctype.to_s+'s')
+      dest = File.join(DOCUMENTS, doctype, filename.to_s)
+      stem = ";#{filename.sub(/\.\w+$/,'').split('/').first}" if filename
+      alax = false
+
+      unless %w(clr rubys).include? $USER
+        @action = 'welcome' unless @action == 'view'
+      end
+
+      case (@action || @doctype).to_s.downcase
+      when 'welcome'
+        _h1 "Welcome!"
+        _p "This tools is for the Secretarial's team use only."
+        _p %{
+          Feel free to look around, but none of your actions will cause any
+          files to be moved, updated, or any emails to be sent.
+        }
+
+      when 'icla'
+        if @replaces != ''
+          remove_id, remove_email = @replaces.strip.split(':',2)
+        else
+          remove_id, remove_email = 'notinavail', nil
+        end
+
+        insert = [
+          remove_id, 
+          @realname.strip, 
+          @pubname.strip, 
+          @email.strip, 
+          "Signed CLA#{stem}\n"
+        ].join(':')
+
+        Dir.chdir(OFFICERS) do
+          input = open('iclas.txt') {|file| file.to_a}
+          open('iclas.txt','w') do |file|
+            input.each do |line|
+              if insert and icla_lname(line) >= icla_lname(insert)
+                if insert.split(':',2).last != line.split(':',2).last
+                  file.print insert
+                end
+                insert = nil
+              end
+              fields = line.split(':')
+              next if fields[0] == remove_id and fields[3] == remove_email
+              file.print line
+            end
+            file.print insert if insert
+          end
+
+          _h1 @pubname
+          if @source=~/[^\x00-\x7F]/ and RUBY_PLATFORM=~/darwin/i
+            require 'unicode'
+            @source = Unicode.normalize_KC(@source)
+          end
+          _.move @source, dest
+          _.system "svn diff iclas.txt", [@pubname]
+        end
+
+        update_pending cgi.params, dest
+
+      when 'grant'
+        insert = "#{@from.strip}" +
+          "\n  file: #{dest.split('/').last}" +
+          "\n  for: #{@description.strip.gsub(/\r?\n\s*/,"\n       ")}"
+
+        Dir.chdir(OFFICERS) do
+          input = open('grants.txt') {|file| file.read}
+          marker = "\n# registering.  documents on way to Secretary.\n"
+          input = input.split(marker).insert(1,"\n#{insert}\n",marker)
+          open('grants.txt','w') do |file|
+            file.write(input.join)
+          end
+
+          _h1 "Grant"
+          _.move @source, dest
+          _.system "svn diff grants.txt", insert.split("\n")
+        end
+
+        update_pending cgi.params, dest
+
+      when 'ccla'
+        insert = "notinavail:" + @company.strip
+         
+        unless @contact.empty?
+          insert += " - #{@contact.strip}"
+        end
+
+        insert += ":#{@cemail.strip}:Signed Corp CLA"
+
+        unless @employees.empty?
+          insert += " for #{@employees.strip.gsub(/\s*\n\s*/, ', ')}"
+        end
+
+        unless @product.empty?
+          insert += " for #{@product.strip}"
+        end
+
+        Dir.chdir(OFFICERS) do
+          open('cclas.txt','a') {|file| file.write(insert+"\n")}
+
+          _h1 @pubname
+          _.move @source, dest
+          _.system "svn diff cclas.txt", [insert]
+        end
+
+        update_pending cgi.params, dest
+
+      when 'nda'
+        @realname ||= @nname
+
+        _h1 "NDA for #{@realname}"
+        _move @source, dest
+
+        Dir.chdir(FOUNDATION) do
+          ndalist = "Correspondence/JCP/tck-nda-list.txt"
+          _.system "svn update #{ndalist}"
+          text = open(ndalist).read
+          open(ndalist, 'w') do |fh|
+            fh.write(text)
+            line = "#{@nname.ljust(20)} #{@nid.ljust(13)} "
+            line += Date.today.strftime("%Y/%m/%d    ")
+            line += `id -un`.chomp.ljust(10) + ' No TCK access yet'
+            fh.write("#{line}\n")
+          end
+          _.system "svn diff #{ndalist}", [@nid]
+        end
+
+        update_pending cgi.params, dest
+
+      when 'mem'
+        @realname ||= @mfname
+        @source.untaint if Dir.chdir(RECEIVED) {Dir['*']}.include? @source
+        dest.untaint if dest =~ /^[-.\w]+$/
+
+        _h1 "Membership Application for #{@realname}"
+        _.move @source, dest
+
+        if defined?(MEETING)
+          _.system "svn update #{MEETING}"
+          received = open("#{MEETING}/memapp-received.txt").read
+          begin
+            received[/(no )\s+\w+\s+\w+\s+#{@mavailid}/,1] = 'yes'
+          rescue
+            _pre $!, class: 'stderr'
+          end
+          open("#{MEETING}/memapp-received.txt", 'w') do |fh| 
+            fh.write(received)
+          end
+          _.system "svn diff #{MEETING}/memapp-received.txt", hilite: @mavailid
+        end
+
+        _.system "svn update #{FOUNDATION}/members.txt"
+        pattern = /^Active.*?^=+\n+(.*?)^Emeritus/m
+        members_txt = open("#{FOUNDATION}/members.txt").read
+        data = members_txt.scan(pattern).flatten.first
+        members = data.split(/^\s+\*\)\s+/)
+        members.shift
+
+        members.push [
+          "#{@mfname}",
+          "#{@maddr.gsub(/^/,'    ').gsub(/\r/,'')}",
+          ("    #{@mcountry}"     unless @mcountry.empty?),
+          "    Email: #{@memail}",
+          ("      Tel: #{@mtele}" unless @mtele.empty?),
+          ("      Fax: #{@mfax}"  unless @mfax.empty?),
+          " Forms on File: ASF Membership Application",
+          " Avail ID: #{@mavailid}"
+        ].compact.join("\n") + "\n"
+
+        sorted = members.sort_by {|member| lname(member.split("\n").first)}
+        members_txt[pattern,1] = " *) " + sorted.join("\n *) ")
+        members_txt[/We now number (\d+) active members\./,1] = 
+          members.length.to_s
+        open("#{FOUNDATION}/members.txt",'w') {|fh| fh.write(members_txt)}
+
+        _.system "svn diff #{FOUNDATION}/members.txt"
+
+        update_pending params, dest
+
+      when 'staple'
+        _h1 'Staple'
+        Dir.chdir(RECEIVED) do
+          @source.sub! /\/$/, ''
+          @source.untaint if Dir['*'].include? @source
+          selected = params.keys.grep(/include\d+/)
+          selected.map! {|key| "#{@source}/#{params[key].first}"}
+          selected=Dir["#{@source}/*"] if selected.empty?
+          cleanup = []
+
+          # convert to pdf, if necessary
+          sources = []
+          selected.sort.each do |file|
+            file.untaint if Dir["#{@source}/*"].include? file
+            ext = file.split('.').last
+            if ext.downcase == 'pdf'
+              sources << file
+            else
+              cleanup << file.sub(Regexp.new(ext+'$'),'pdf').sub(' ', '_')
+              sources << cleanup.last
+              _.system(['convert', file, cleanup.last])
+            end
+          end
+
+          dest,i = @source,0
+          dest = @source + (i+=1).to_s while File.exist?("#{dest}.pdf")
+          at = svn_at(@source)
+
+          # concatenate sources
+          if sources.length > 1
+            _.system "pdftk #{sources.sort.join(' ')} cat output #{dest}.pdf"
+            _.system "svn add #{dest}.pdf#{at}"
+          elsif selected.first =~ /\.pdf$/i
+            _.system "svn mv #{sources.first}#{at} #{dest}.pdf"
+          else
+            _.system "mv #{cleanup.shift} #{dest}.pdf"
+            _.system "svn add #{dest}.pdf#{at}"
+          end
+
+          # copy properties
+          sfx = at
+          `svn proplist #{@source}#{sfx}`.scan(/  \w+:[-\w]+/).each do |prop|
+            prop.untaint if prop.strip =~ /^\w+(:\w+)/
+            value = `svn propget #{prop} #{@source}#{sfx}`.chomp
+            _.system(['svn', 'propset', prop.strip, value, "#{dest}.pdf#{at}"])
+          end
+          _.system "svn propset svn:mime-type application/pdf #{dest}.pdf#{at}"
+
+          # remove temporary file and source directory
+          _.system "rm #{cleanup.join(' ')}" unless cleanup.empty?
+          if not (Dir["#{@source}/*"]-selected).empty?
+            selected.each do |file| 
+              if `svn st #{file}` !~ /^D/ and File.exist? file
+                _.system "svn rm --force #{file}" 
+              end
+            end
+            if Dir["#{@source}/*"].empty?
+              _.system "svn remove --force #{@source}#{at}"
+            end
+          elsif `svn st #{@source}#{at}` !~ /^D/ and File.exist? @source
+            _.system "svn remove --force #{@source}#{at}"
+          end
+        end
+
+      when 'commit'
+        _h1 'Commit'
+        log = Escape.shell_single_word(@message)
+        committable.each do |file|
+          unless `svn status #{file}`.empty?
+            _pre.todo "svn commit -m #{log} #{file}",
+              'data-message' => @message, 'data-file' => file
+          end
+        end
+
+        if File.exist?(PENDING_YML)
+          pending = YAML.load(open(PENDING_YML))
+
+          pending.each do |vars|
+            _h2 "email #{vars['email']}", class: 'todo',
+              'data-message' => @message
+          end
+        end
+
+        ajax = true
+
+      when 'other'
+        at = svn_at(@source)
+        Dir.chdir(RECEIVED) do
+          if @dest == 'burst'
+            _h1 'Burst'
+            dest = @source.sub(/\.\w+$/,'')
+
+            _.system "mkdir #{dest}"
+            _.system "pdftk #{@source} burst output #{dest}/%02d.pdf"
+            _.system "svn add #{dest}#{at}"
+            # copy properties
+            `svn proplist #{@source}#{at}`.scan(/ \w+:[-\w]+/).each do |prop|
+               next if prop.strip == 'svn:mime-type'
+               value = `svn propget #{prop} #{@source}#{at}`.chomp
+               _.system "svn propset #{prop.strip} #{value.inspect} " +
+                 "#{dest}#{at}"
+            end
+            _.system "svn rm '#{@source}#{at}'"
+            _.system "rm doc_data.txt"
+            _.system "svn rm #{@source}#{at}"
+          elsif @dest == 'flip'
+            _h1 'Flip'
+            _.system "pdftk #{@source} cat 1-endS output #{@source}.tmp"
+            _.system "mv #{@source}.tmp #{@source}"
+          elsif @dest == 'rotate right'
+            _h1 'Rotate Right'
+            _.system "pdftk #{@source} cat 1-endE output #{@source}.tmp"
+            _.system "mv #{@source}.tmp #{@source}"
+          elsif @dest == 'rotate left'
+            _h1 'Rotate Left'
+            _.system "pdftk #{@source} cat 1-endW output #{@source}.tmp"
+            _.system "mv #{@source}.tmp #{@source}"
+          elsif @dest == 'junk'
+            _.system(['svn', 'rm', '--force', "#{@source}#{at}"])
+          else
+            _.move @source, DESTINATION[@dest]
+          end
+        end
+
+      when 'update'
+        _h1 'Update'
+        _pre "svn update #{OFFICERS}", class: 'todo'
+        _pre "svn update #{DOCUMENTS}", class: 'todo'
+        _h3 'icla.txt issues', class: 'todo'
+        ajax = true
+        cleanup = Dir["#{DOCUMENTS}/received/*"].map(&:untaint).
+          select {|name| File.directory?(name) and Dir["#{name}/*"].empty?}.
+          reject {|name| name =~ /\/to_\w+$/}
+        unless cleanup.empty?
+          _h2 'Empty directories'
+          _ul do
+            cleanup.each { |name| _li name }
+          end
+        end
+
+      when 'view'
+        @dir.untaint if Dir.chdir(RECEIVED) {Dir['*'].include? @dir.chomp('/')}
+        files = Dir["#{RECEIVED}/#{@dir}/*"].sort
+
+        if files.length == 2
+          if files.last == files.first + '.sig'
+            _pre `gpg --verify #{files.last} #{files.first} 2>&1`
+          elsif files.last == files.first + '.asc'
+            _pre `gpg --verify #{files.last} #{files.first} 2>&1`
+          elsif files.last =~ /\/signature.asc$/
+            _pre `gpg --verify #{files.last} #{files.first} 2>&1`
+          elsif files.first =~ /\/signature.asc$/
+            _pre `gpg --verify #{files.first} #{files.last} 2>&1`
+          end
+        end
+
+        _form.buttons target: 'viewport', action: 'file.cgi', method: 'post' do
+          _ul style: 'list-style: none; padding: 0' do
+            files.each_with_index do |line,i|
+              file = line.split('/').last
+              _li do
+                _input type: :checkbox, name: "include#{i}", value: file
+                if %w(jpg).include?(file.split('.').last)
+                  _img src: "/received/#{@dir}/#{file}"
+                else
+                  _a file, href: "/received/#{@dir}/#{file}"
+                end
+              end
+            end
+          end
+
+          _input name: 'source', id: 'source', type: 'hidden', value: @dir
+
+          if files.length > 0
+            _input type: 'submit', name: 'action', value: 'Staple'
+          else
+            file = "#{RECEIVED}/#{@dir}"
+            _pre `gpg --verify #{file} 2>&1`
+            open(file) {|fh| _pre fh.read} 
+          end
+
+          _script src: "jquery-1.7.2.min.js"
+          _script %{
+            // first, check all of the checkboxes
+            $('input[@type=checkbox]').attr('checked', 'checked');
+
+            // on click, unclick all if all are checked.
+            $('input[@type=checkbox]').mousedown(function() {
+              if (!$('input[type=checkbox]:not(:checked)').length) {
+                $('input[@type=checkbox]').removeAttr('checked');
+              }
+            });
+          }
+        end
+
+      when 'cancel', 'check'
+        _h1 @action
+        check
+    
+      when 'edit cc'
+        _h1 @action
+
+        if File.exist?(PENDING_YML)
+          pending = YAML.load(open(PENDING_YML))
+
+          if @email
+            pending.each do |vars|
+              if vars['email'] == @email
+                vars['email:cc'] = @cc.strip.gsub(/\r?\n/, ", ") 
+                vars['email:bcc'] = @bcc.strip.gsub(/\r?\n/, ", ") 
+                vars.delete('email:bcc') if vars['email:bcc'].empty?
+
+                open(PENDING_YML, 'w') {|file| file.write pending.to_yaml}
+                _p "cc list for #{@email} updated", id: 'notice'
+              end
+            end
+          end
+
+          pending.each do |vars|
+            vars = OpenStruct.new(vars.map {|k,v| [k.gsub(/\W/,'_'),v]})
+            _h2 "email #{vars.email}"
+            _form do
+              _input name: 'email', value: vars.email, type: 'hidden'
+              _table do
+                _tr do
+                  _td 'cc:'
+                  _td do
+                    _textarea vars.email_cc.to_s.gsub(/,\s+/,"\n"),
+                      name: 'cc', cols: 60
+                  end
+                end
+                _tr do
+                  _td 'bcc:'
+                  _td do
+                    _textarea vars.email_bcc.to_s.gsub(/,\s+/,"\n"),
+                      name: 'bcc', cols: 60
+                  end
+                end
+              end
+              _input type: 'hidden', name: 'action', value: @action
+              _input type: 'submit', value: 'Update'
+            end
+          end
+        end
+    
+      else
+        _h2 'Unsupported action'
+        _table border: 1, cellpadding: 10, cellspacing: 0 do
+          params.sort.each do |key, value|
+            _tr do
+              _td key
+              _td value
+            end
+          end
+        end
+      end
+
+      if ajax
+        _script src: 'jquery-1.7.2.min.js'
+        _script %{
+          function execute_todos() {
+            var todo = $('.todo:first');
+            if (todo.length == 1) {
+              // add a spinner
+              var spinner = $('<img src="spinner.gif"/>');
+              todo.after(spinner);
+
+              // params = cmd plus all of the data-* attributes
+              var params = {cmd: todo.text()};
+              for (var i=0; i<todo[0].attributes.length; i++) {
+                var attr = todo[0].attributes[i];
+                if (attr.name.match("^data-")) {
+                  params[attr.name.substr(5)] = attr.value;
+                }
+              }
+
+              // issue request
+              $.post(#{ENV['SCRIPT_NAME'].inspect}, params, function(response) {
+                var replacement = $(response.html);
+                spinner.remove();
+                todo.replaceWith(replacement);
+                if (replacement.filter('._stderr,._traceback').length > 0) {
+                  if (!confirm("Error detected.  Continue?")) return;
+                }
+                execute_todos();
+              }, 'json');
+            } else {
+              parent.frames[0].location.reload();
+            }
+          }
+          execute_todos();
+        }
+      end
+    end
+  end
+end
diff --git a/www/secretary/workbench/grant.erb b/www/secretary/workbench/grant.erb
new file mode 100644
index 0000000..4f91d0f
--- /dev/null
+++ b/www/secretary/workbench/grant.erb
@@ -0,0 +1,13 @@
+to:   <%= gname.inspect %> <<%= gemail %>>
+from: <%= from %>
+cc:   secretary@apache.org
+bcc:  <%= bcc %>
+subject: Your Grant sent to Apache Secretary
+
+Dear <%= gname %>,
+
+This message acknowledges receipt of the following document, which has been filed in the Apache Software Foundation records:
+
+  <%= commit_message %>
+
+<%= sig %>
diff --git a/www/secretary/workbench/icla.erb b/www/secretary/workbench/icla.erb
new file mode 100644
index 0000000..d317ec5
--- /dev/null
+++ b/www/secretary/workbench/icla.erb
@@ -0,0 +1,16 @@
+to:   <%= pubname.inspect %> <<%= email %>>
+from: <%= from %>
+cc:   secretary@apache.org
+bcc:  <%= bcc %>
+subject: Your ICLA sent to Apache Secretary
+
+Dear <%= pubname %>,
+
+This message acknowledges receipt of your ICLA, which has been filed in the Apache Software Foundation records.
+
+If you have been invited as a committer, please advise the project PMC that your ICLA has been filed.
+
+Warm Regards,
+
+<%= sig %>
+
diff --git a/www/secretary/workbench/index.html b/www/secretary/workbench/index.html
new file mode 100644
index 0000000..f82a156
--- /dev/null
+++ b/www/secretary/workbench/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>ASF Secretary-Assistant Workbench</title>
+  </head>
+  <frameset cols="20%, 60%">
+    <frame src="worklist.cgi"/>
+    <frame name="viewport"/>
+  </frameset>
+</html>
diff --git a/www/secretary/workbench/jquery-1.2.6.min.js b/www/secretary/workbench/jquery-1.2.6.min.js
new file mode 100644
index 0000000..82b98e1
--- /dev/null
+++ b/www/secretary/workbench/jquery-1.2.6.min.js
@@ -0,0 +1,32 @@
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
+ * $Rev: 5685 $
+ */
+(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
+return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:functio
 n(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.
 domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
+return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
+selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}retu
 rn values;}else
+return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
+this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
+return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script
 "});else
+jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){var src=target[name],copy=options[name];if(target===copy)continue;if(deep&&copy&&typeof copy=="object"&&!copy.nodeType)target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);else if(copy!==undefined)target[name]=copy;}return target;};var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQ
 uery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
+script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){var name,i=0,length=object.length;if(args){if(length==undefined){for(name in object)if(callback.apply(object[name],args)===false)break
 ;}else
+for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
+for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback
 .call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
+jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i<stack.length;i++)if(color(stack[i])){swap[i
 ]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";for(i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem+='';if(typeof elem=="
 string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?
 div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
+ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&&notxml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha
 \([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else
+while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
+while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!=null)ret[ret.length]=value;}return ret.concat.apply([],ret);}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.exte
 nd({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,f
 n);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.pa
 rentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseI
 nt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a
 .firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textar
 ea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(node
 Name=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.m
 sie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t)
 ;if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstC
 hild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem
 =window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||
 elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
+for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(eve
 nt){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handle
 rs){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalE
 vent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||
 this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({
 bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i<args.length)jQuery.event.proxy(fn,args[i++]);return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;event.preventDefault();return args[this.lastToggle++].apply(this,arguments)||false;}));},hover:function(fnOver,fnOut){return this
 .bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
+jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){
 var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(
 typeof url!='string')return this._load(url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));})
 .map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.
 href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+
 jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="c
 omplete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else
+xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var mo
 dRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
+jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},
 httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
+for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
+s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",op
 acity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(thi
 s);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
+e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,f
 n){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.dis
 play="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hi
 de:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")]
 (this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documen
 tElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(ele
 m){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuer
 y.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();
\ No newline at end of file
diff --git a/www/secretary/workbench/jquery-1.7.2.min.js b/www/secretary/workbench/jquery-1.7.2.min.js
new file mode 100644
index 0000000..16ad06c
--- /dev/null
+++ b/www/secretary/workbench/jquery-1.7.2.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.2 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;
 g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);e
 lse d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d
 =parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaul
 tSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typ
 eof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c
 =a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;r
 eturn this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==nu
 ll?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),t
 ypeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready
 );var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:functio
 n(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[
 ];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f
 .concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date 
 RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],
 e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);re
 turn this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f
 .isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.va
 lue==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecke
 d=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="no
 ne",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position=
 "relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[
 n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(
 j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f
 ._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=th
 is,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof
  a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeCla
 ss"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a
 .attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);r
 eturn}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowsp
 an:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b}
 ,set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["r
 adio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
+a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.gui
 d,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remov
 e.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=
 f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.na
 mespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attr
 Name relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.prop
 s?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.
 type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.
 type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("ch
 ange",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e=
 =null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:funct
 ion(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.tes
 t(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,
 l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[
 t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFi
 lter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]
 |\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode=
 ==b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG
 :function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.
 parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a)
 {var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nod
 eType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p
 =o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,
 e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElemen
 t("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]
 );if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}
 }(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.select
 ors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.c
 ontext).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({p
 arent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P
 .call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^
 \s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChi
 ld;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
+.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;
 if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(functi
 on(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h))
 ,e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.
 createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;
 i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",vi
 sibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f
 .cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f
 ===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.su
 pport.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:f
 unction(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.e
 ach("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},
 ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if
 (!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.
 toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d
 .async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.json
 p!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||
 /loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{i
 f(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.
 css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark
 (this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"
 ),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{
 opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=nul
 l&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+
 this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b
 [c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&
 &c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f
 .fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offset
 Parent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.st
 yle?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
diff --git a/www/secretary/workbench/local_paths.rb b/www/secretary/workbench/local_paths.rb
new file mode 100644
index 0000000..d9cf1e3
--- /dev/null
+++ b/www/secretary/workbench/local_paths.rb
@@ -0,0 +1,34 @@
+# attempt to determine where 'HOME' is
+unless ENV['HOME']
+  ENV['HOME'] = $1 if ENV['SCRIPT_FILENAME'] =~ /(.*?)\/public_html\//
+  ENV['HOME'] = $1 if ENV['SCRIPT_FILENAME'] =~ /(.*?)\/Sites\//
+end
+
+# look for local_paths.yml or ~/.secassist (in that order)
+config = 'local_paths.yml'
+if not File.exist?(config) and ENV['HOME']
+  config = File.expand_path('~/.secassist')
+end
+
+# set constants based on the configuration file
+require 'yaml'
+YAML.load(open(config).read).each do |key, value|
+  Object.const_set key.upcase, File.expand_path(value).untaint
+end
+
+# pending file
+PENDING_YML = File.join(RECEIVED, 'pending.yml')
+COMPLETED_YML = File.join(RECEIVED, 'completed.yml')
+
+# svn >= 1.5 requires a trailing '@' if the file name contains an '@'
+# http://stackoverflow.com/questions/1985203/why-subversion-skips-files-which-contain-the-symbol
+def svn_at name
+  svn_version = `svn --version --quiet`.chomp.split('.').map {|s| s.to_i}
+  if (svn_version <=> [1,6,4]) < 1
+    ''
+  elsif name.include? '@'
+    '@'
+  else
+    ''
+  end
+end
diff --git a/www/secretary/workbench/local_paths.yml b/www/secretary/workbench/local_paths.yml
new file mode 100644
index 0000000..3473b79
--- /dev/null
+++ b/www/secretary/workbench/local_paths.yml
@@ -0,0 +1,6 @@
+meeting:    /var/tools/secretary/foundation/Meetings/20120522
+foundation: /var/tools/secretary/foundation
+officers:   /var/tools/secretary/foundation/officers
+documents:  /var/tools/secretary/documents
+received:   /var/tools/secretary/documents/received
+mail:       /var/tools/secretary/.secmail.rb
diff --git a/www/secretary/workbench/mem.erb b/www/secretary/workbench/mem.erb
new file mode 100644
index 0000000..e493e9b
--- /dev/null
+++ b/www/secretary/workbench/mem.erb
@@ -0,0 +1,15 @@
+to:   <%= realname.inspect %> <<%= memail %>>
+from: <%= from %>
+cc:   secretary@apache.org
+bcc:  <%= bcc %>
+subject: Your ASF Membership Application
+
+Dear <%= realname %>,
+
+This message acknowledges receipt of your membership application, which has been filed in the Apache Software Foundation records.
+
+You will be subscribed to the members@apache.org mailing list and will have access to the foundation repository shortly.
+
+Warm Regards,
+
+<%= sig %>
diff --git a/www/secretary/workbench/nda.erb b/www/secretary/workbench/nda.erb
new file mode 100644
index 0000000..5d57bac
--- /dev/null
+++ b/www/secretary/workbench/nda.erb
@@ -0,0 +1,13 @@
+to:   <%= realname.inspect %> <<%= nemail %>>
+from: <%= from %>
+cc:   secretary@apache.org
+bcc:  <%= bcc %>
+subject: Your JCP NDA
+
+Dear <%= realname %>,
+
+This message acknowledges receipt of your NDA, which has been filed in the Apache Software Foundation records.
+
+Warm Regards,
+
+<%= sig %>
diff --git a/www/secretary/workbench/spinner.gif b/www/secretary/workbench/spinner.gif
new file mode 100644
index 0000000..d0bce15
Binary files /dev/null and b/www/secretary/workbench/spinner.gif differ
diff --git a/www/secretary/workbench/worklist.cgi b/www/secretary/workbench/worklist.cgi
new file mode 100755
index 0000000..c3cd5c7
--- /dev/null
+++ b/www/secretary/workbench/worklist.cgi
@@ -0,0 +1,478 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require 'yaml'
+
+DOCTYPES = %w{icla grant ccla nda other}
+
+_html do
+  _head_ do
+    _title 'worklist'
+    _link rel: 'stylesheet', type: "text/css", href: "worklist.css"
+    _script src: "jquery-1.7.2.min.js"
+    _script src: 'worklist.js'
+  end
+
+  _body? do
+
+    _pre `date`.chomp
+
+    if `which svn`.empty?
+      _h2_.warn 'Unable to locate svn'
+      _p 'Search PATH used:'
+      _ul do
+        ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+          _li { _code path }
+        end
+      end
+    end
+
+    begin
+      begin
+        require './local_paths'
+        DOCTYPES.insert(-2, 'mem') if defined?(MEETING)
+      rescue
+        _h2_ 'Syntax error in local_paths.yml'
+        raise 
+      end
+
+      files = []
+      ENV['LANG']||="en_US.UTF-8"
+      if defined?(MEETING)
+        IO.popen("svn st #{FOUNDATION}/members.txt").each do |line|
+          files << line.sub(FOUNDATION, 'foundation')
+        end
+        IO.popen("svn st #{MEETING}").each do |line|
+          files << line.sub(MEETING, 'meeting')
+        end
+      end
+      IO.popen("svn st #{OFFICERS}").each do |line|
+        files << line.sub(OFFICERS, 'officers')
+      end
+      IO.popen("svn st #{DOCUMENTS}").each do |line| 
+        files << line.sub(DOCUMENTS, 'documents')
+      end
+
+      message = 'Faxes received'
+
+      if File.exist? PENDING_YML
+        pending = YAML.load(open(PENDING_YML))
+        if pending.size == 1
+          pending = pending.first
+          if pending['doctype'] == 'icla'
+            message = "ICLA from #{pending['realname']}"
+          elsif pending['doctype'] == 'ccla'
+            message = "CCLA from #{pending['company']}"
+
+            unless pending['employees'].nil? or pending['employees'].empty?
+              message += " for "
+              message += pending['employees'].strip.gsub(/\s*\n\s*/, ', ')
+            end
+          elsif pending['doctype'] == 'grant'
+            message = "Grant from #{pending['from']}"
+          elsif pending['doctype'] == 'mem'
+            message = "Membership Application from #{pending['realname']}"
+          elsif pending['doctype'] == 'nda'
+            message = "NDA for #{pending['realname']}"
+          end
+        end
+      end
+
+      files.reject! {|f| f=~ /\/(pending|completed)\.yml\s*$/}
+      unless files.empty? and !File.exist?(PENDING_YML)
+        _h2_ 'Pending'
+        files.each {|line| _pre line.strip.sub(/\s+/,' ')}
+        pending = YAML.load(open(PENDING_YML)) rescue []
+        pending.each {|vars| _pre "@ #{vars['email']}" if vars['email']}
+        _form.buttons target: 'viewport', action: 'file.cgi', method: 'post' do
+          _input name: 'message', id: 'message', type: 'hidden',
+            'data-value' => message
+          _input type: 'submit', name: 'action', value: 'Edit CC'
+          _input type: 'submit', name: 'action', value: 'Commit'
+        end
+      end
+
+      files = []
+      Dir.chdir("#{RECEIVED}") do
+        Dir["*"].sort_by {|name| File.stat(name.untaint).mtime}.each do |file|
+          next if %w{README deadletter archives}.include? file
+          next if %w{pending.yml completed.yml}.include? file
+          next if file =~ /^to_\w+$/
+          if File.directory? file
+            next if Dir.entries(file).reject {|name| name=~/^\./}.empty?
+          end
+          File.chmod 0644, file if file =~ /\.pdf$/
+          files << file
+        end
+      end
+
+      _h2_ 'Work List'
+      if files.empty?
+        _p.worklist! { _i 'Empty' }
+      else
+        _ul.worklist! do
+          files.each do |file|
+            _li do
+              dirflag = File.directory?(File.join(RECEIVED,file))
+              _a dirflag ? file+'/' : file
+            end
+          end
+        end
+      end
+
+      _div_.classify! do
+        _h2_ 'Classification'
+
+        _form.doctype! target: 'viewport', action: 'file.cgi', method: 'post' do
+          _table_ do
+            _tr do
+              DOCTYPES.each do |doctype|
+                _td align: 'center' do
+                  _input type: 'radio', name: 'doctype', value: doctype
+                end
+              end
+            end
+            _tr do
+              DOCTYPES.each do |doctype|
+                _td doctype, align: 'center'
+              end
+            end
+          end
+
+          _input name: 'source', id: 'source', type: 'hidden'
+
+          _table_ id: 'icla-form' do
+            _tr do
+              _td.label 'Real Name'
+              _td.input do
+                _input name: 'realname', id: 'realname', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'Public Name'
+              _td.input do
+                _input name: 'pubname', id: 'pubname', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'E-mail'
+              _td do 
+                _input name: 'email', id: 'email', type: 'email'
+              end
+            end
+            _tr do
+              _td.label 'File Name'
+              _td.input do
+                _input name: 'filename', id: 'filename', type: 'text'
+              end
+            end
+          end
+
+          _div_ id: 'nda-form' do
+            _table do
+              _tr do
+                _td do
+                  _label 'Name', for: 'nname'
+                end
+                _td do
+                  _input type: :text, name: 'nname', id: 'nname'
+                end
+              end
+
+              _tr do
+                _td do
+                  _label 'ASF ID', for: 'nid'
+                end
+                _td do
+                  _input type: :text, name: 'nid', id: 'nid'
+                end
+              end
+
+              _tr do
+                _td.label 'EMail'
+                _td.input do
+                  _input name: 'nemail', id: 'nemail', type: 'email'
+                end
+              end
+
+              _tr do
+                _td.label 'File Name'
+                _td.input do
+                  _input name: 'nfilename', id: 'nfilename', type: 'text'
+                end
+              end
+            end
+          end
+
+          _div id: 'mem-form' do
+            if defined?(MEETING)
+              received = open("#{MEETING}/memapp-received.txt").read
+            else
+              received = ''
+            end
+
+            _table do
+              _tr do
+                _td do
+                  _label 'Public Name', for: 'mpname'
+                end
+                _td do
+                  _select id: 'mavailid', name: 'mavailid' do
+                    pattern = /^\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(.*)\n/
+                    _option value: '', selected: true
+                    options = []
+                    received.scan(pattern) do |apply, mail, karma, id, name|
+                      next unless apply=='no'
+                      options << [ name.strip, id ]
+                    end
+                    options.sort.each do |name, id|
+                      _option name, value: id
+                    end
+                  end
+                end
+              end
+        
+              _tr do
+                _td do
+                  _label 'Full Name', for: 'mfname'
+                end
+                _td do
+                  _input type: :text, name: 'mfname', id: 'mfname'
+                end
+              end
+        
+              _tr do
+                _td do
+                  _label 'Address', for: 'maddr'
+                end
+                _td do
+                  _textarea rows: 5, name: 'maddr', id: 'maddr'
+                end
+              end
+                
+              _tr do
+                _td do
+                  _label 'Country', for: 'mcountry'
+                end
+                _td do
+                  _input type: :text, name: 'mcountry', id: 'mcountry'
+                end
+              end
+                
+              _tr do
+                _td do
+                  _label 'Telephone', for: 'mtele'
+                end
+                _td do
+                  _input type: :text, name: 'mtele', id: 'mtele'
+                end
+              end
+                
+              _tr do
+                _td do
+                  _label 'Fax', for: 'mfax'
+                end
+                _td do
+                  _input type: :text, name: 'mfax', id: 'mfax'
+                end
+              end
+                
+              _tr do
+                _td do
+                  _label 'E-Mail', for: 'memail'
+                end
+                _td do
+                  _input type: :email, name: 'memail', id: 'memail'
+                end
+              end
+                
+              _tr do
+                _td do
+                  _label 'File Name', for: 'mfilename'
+                end
+                _td do
+                  _input type: :text, name: 'mfilename', id: 'mfilename'
+                end
+              end
+            end
+          end
+
+          _div_ id: 'grant-form' do
+            _table do
+              _tr do
+                _td.label 'From'
+                _td do
+                  _input name: 'from', type: 'text'
+                end
+              end
+              _tr do
+                _td.label 'For'
+                _td do
+                  _textarea name: 'description', rows: 5
+                end
+              end
+              _tr do
+                _td.label 'Signed By'
+                _td do
+                  _input name: 'gname', id: 'gname', type: 'text'
+                end
+              end
+              _tr do
+                _td.label 'E-mail'
+                _td do
+                  _input name: 'gemail', id: 'gemail', type: 'email'
+                end
+              end
+              _tr do
+                _td.label 'File Name'
+                _td.input do
+                  _input name: 'gfilename', type: 'text'
+                end
+              end
+            end
+          end
+
+          _table_ id: 'ccla-form' do
+            _tr do
+              _td.label 'Corporation'
+              _td.input do
+                _input name: 'company', id: 'company', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'Product'
+              _td.input do
+                _input name: 'product', id: 'product', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'Contact'
+              _td do
+                _input name: 'contact', id: 'contact', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'E-mail'
+              _td do
+                _input name: 'cemail', id: 'cemail', type: 'email'
+              end
+            end
+            _tr do
+              _td.label 'Employees'
+              _td { _textarea name: 'employees', rows: 5 }
+            end
+            _tr do
+              _td.label 'File Name'
+              _td.input do
+                _input name: 'cfilename', type: 'text'
+              end
+            end
+          end
+
+          _input name: 'replaces', id: 'replaces', type: 'hidden'
+
+          _div_.buttons!.buttons do
+            _input type: 'submit', value: 'File'
+            # _input type: 'submit', id: 'archive', value: 'Archive',
+            # onclick: 'return namesFromArchive()'
+            _input type: 'submit', name: 'action', value: 'Cancel'
+          end
+
+          _div_.buckets!.buttons do
+            _fieldset do
+              _legend 'To:'
+              _input type: 'submit', name: 'dest', value: 'Jim'
+              _input type: 'submit', name: 'dest', value: 'Justin'
+              _input type: 'submit', name: 'dest', value: 'Geir'
+            end
+            _fieldset do
+              _legend 'Do:'
+              _input type: 'submit', name: 'dest', value: 'burst'
+              _input type: 'submit', name: 'dest', value: 'flip'
+              _input type: 'submit', name: 'dest', value: 'rotate right'
+              _input type: 'submit', name: 'dest', value: 'rotate left'
+            end
+            _fieldset do
+              _legend 'File:'
+              _input type: 'submit', name: 'dest', value: 'dup'
+              _input type: 'submit', name: 'dest', value: 'junk'
+              _input type: 'submit', name: 'dest', value: 'incomplete'
+            end
+          end
+
+          _table id: 'icla2-form' do
+            _tr do
+              _td.label 'User ID'
+              _td.input do
+                _input name: 'user', id: 'user', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'PMC'
+              _td.input do
+                _input name: 'pmc', id: 'pmc', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'Podling'
+              _td.input do
+                _input name: 'podling', id: 'podling', type: 'text'
+              end
+            end
+            _tr do
+              _td.label 'Vote Link'
+              _td.input do
+                _input name: 'votelink', id: 'votelink', type: 'text'
+              end
+            end
+          end
+        end
+      end
+
+      _h2_ 'Links'
+      _ul do
+        _li do
+          _a 'Mail Search', href: 'https://mail-search.apache.org/',
+            target: 'viewport'
+        end
+        _li do
+          query = ''
+
+          if File.exist? COMPLETED_YML
+            last = YAML.load(File.read COMPLETED_YML).last
+            params = {}
+            %w{email user pmc podling votelink}.each do |name|
+              params[name] = last[name] if last[name]
+            end
+            unless params.empty?
+              query = '?' + params.
+                map {|name,value| "#{name}=#{CGI.escape value}"}.join('&')
+            end
+          end
+
+          _a 'New Account', target: 'viewport',
+            href: 'https://id.apache.org/acreq/members/' + query
+        end
+        _li do
+          _a 'Committers by id', href: 'http://people.apache.org/committer-index.html',
+            target: 'viewport'
+        end
+        _li do
+          _a 'Board subscriptions', href: 'https://whimsy.apache.org/board/subscriptions/',
+            target: 'viewport'
+        end
+        _li do
+          _a 'Mail aliases', href: 'https://svn.apache.org/repos/private/committers/MailAlias.txt',
+            target: 'viewport'
+        end
+        _li do
+          _a 'Member list', href: 'https://svn.apache.org/repos/private/foundation/members.txt',
+            target: 'viewport'
+        end
+        _li do
+          _a 'How to use this tool', href: 'HOWTO.html',
+            target: 'viewport'
+        end
+      end
+    end
+  end
+end
diff --git a/www/secretary/workbench/worklist.css b/www/secretary/workbench/worklist.css
new file mode 100644
index 0000000..7ec5c34
--- /dev/null
+++ b/www/secretary/workbench/worklist.css
@@ -0,0 +1,23 @@
+html {background-color: #EEE}
+input[type="email"],input[type="text"],select {width: 100%}
+textarea {width: 100%}
+p.worklist {margin-left: 3em}
+#classify {display: none}
+#doctype > table:first-child {margin-bottom: 1em}
+table {width: 100%}
+td.label {width:10em;height:2.5em}
+td.input {width:100em}
+h2 {background: #303284; color:#FFF; border-radius: 1em; padding: .25em 1em}
+h2.warn {background:yellow; color:black}
+input[type="submit"].button {width: 5em} 
+input[type="submit"].bucket {width: 3.5em} 
+input[type="submit"] {border-radius: 2em}
+input.loading {background-color: #EF8}
+ul {list-style:none; padding-left:0}
+li {margin: 0.5em 2em 0 1em; padding-left: 1em, border-radius: 1em}
+li:hover {background-color: #F2EEB2}
+li.selected {background-color: #FE0}
+.buttons, .buckets {text-align:center; margin-bottom:0.5em}
+pre {margin:0 0 0 2em}
+.traceback {background-color:#ff0; border: 2px solid}
+.traceback {margin: 1em 0; padding: 1em}
diff --git a/www/secretary/workbench/worklist.js b/www/secretary/workbench/worklist.js
new file mode 100644
index 0000000..8be0a17
--- /dev/null
+++ b/www/secretary/workbench/worklist.js
@@ -0,0 +1,231 @@
+// prime the second frame
+if (parent.frames[1].location == 'about:blank') {
+  parent.frames[1].location.href = "file.cgi?action=update"
+}
+
+// Map non-ASCII characters to lower case ASCII
+function asciize(name) {
+  if (name.match(/[^\x00-\x7F]/)) {
+    // digraphs.  May be culturally sensitive
+    name=name.replace(/\u00df/g,'ss');
+    name=name.replace(/\u00e4|a\u0308/g,'ae');
+    name=name.replace(/\u00e5|a\u030a/g,'aa');
+    name=name.replace(/\u00e6/g,'ae');
+    name=name.replace(/\u00f1|n\u0303/g,'ny');
+    name=name.replace(/\u00f6|o\u0308/g,'oe');
+    name=name.replace(/\u00fc|u\u0308/g,'ue');
+
+    // latin 1
+    name=name.replace(/[\u00e0-\u00e5]/g,'a');
+    name=name.replace(/\u00e7/g,'c');
+    name=name.replace(/[\u00e8-\u00eb]/g,'e');
+    name=name.replace(/[\u00ec-\u00ef]/g,'i');
+    name=name.replace(/[\u00f2-\u00f6]|\u00f8/g,'o');
+    name=name.replace(/[\u00f9-\u00fc]/g,'u');
+    name=name.replace(/[\u00fd\u00ff]/g,'y');
+
+    // Latin Extended-A
+    name=name.replace(/[\u0100-\u0105]/g,'a');
+    name=name.replace(/[\u0106-\u010d]/g,'c');
+    name=name.replace(/[\u010e-\u0111]/g,'d');
+    name=name.replace(/[\u0112-\u011b]/g,'e');
+    name=name.replace(/[\u011c-\u0123]/g,'g');
+    name=name.replace(/[\u0124-\u0127]/g,'h');
+    name=name.replace(/[\u0128-\u0131]/g,'i');
+    name=name.replace(/[\u0132-\u0133]/g,'ij');
+    name=name.replace(/[\u0134-\u0135]/g,'j');
+    name=name.replace(/[\u0136-\u0138]/g,'k');
+    name=name.replace(/[\u0139-\u0142]/g,'l');
+    name=name.replace(/[\u0143-\u014b]/g,'n');
+    name=name.replace(/[\u014C-\u0151]/g,'o');
+    name=name.replace(/[\u0152-\u0153]/g,'oe');
+    name=name.replace(/[\u0154-\u0159]/g,'r');
+    name=name.replace(/[\u015a-\u0162]/g,'s');
+    name=name.replace(/[\u0162-\u0167]/g,'t');
+    name=name.replace(/[\u0168-\u0173]/g,'u');
+    name=name.replace(/[\u0174-\u0175]/g,'w');
+    name=name.replace(/[\u0176-\u0178]/g,'y');
+    name=name.replace(/[\u0179-\u017e]/g,'z');
+
+    // denormalized diacritics
+    name=name.replace(/[\u0300-\u036f]/g,'');
+  }
+
+  return name.replace(/[^\w]+/g,'-');
+}
+
+// Generate file name from real name (icla)
+function generateFileName(selection) {
+  var value = asciize($('#realname').val());
+  var source = $('#source').val();
+  if (source.indexOf('.')>0) {
+    if (source.indexOf('@')<0 || source.match(/\.pdf$/)) {
+      value+=source.replace(/.*\./,'.');
+    }
+  }
+  return value.replace(/-+/g, '-').toLowerCase();
+}
+
+// replace realname input field with a selection list
+function namesFromArchive() {
+  $.getJSON('unscanned.cgi', {}, function(unscanned) {
+    var select = $('<select name="realname" id="realname"/>')[0];
+    for (var i=0; i<unscanned.length; i++) {
+      select.options[i] = new Option(unscanned[i][1], i);
+    }
+    $('#realname').before(select).remove();
+
+    $("#archive").attr("disabled","disabled");
+
+    // process selection
+    $('#realname').focus().change(function() {
+      var icla = unscanned[$("#realname option:selected").val()];
+      $("#realname").before('<input type="text" ' +
+        'id="realname" name="realname"/>').remove();
+      $("#realname").val(icla[1]);
+      $("#pubname").val(icla[2]);
+      $("#email").val(icla[3]);
+      $("#replaces").val(icla[0] + ':' + icla[3]);
+      $("#filename").val('').focus();
+      $("#archive").removeAttr("disabled");
+    });
+  });
+  return false;
+}
+
+$(document).ready(function() {
+  // member autofill
+  $('#mavailid').change(function() {
+    var selected = $('#mavailid :selected'); 
+    if (!$('#memail').val()) $("#memail").val($(this).val()+"@apache.org");
+    $("#email").val($(this).val()+"@apache.org");
+    $("#mfname").val(selected.text());
+    $("#realname").val(selected.text());
+    $("#mfilename").val(generateFileName());
+    $("#maddr").focus();
+  });
+
+  // File selection
+  $('#worklist a').click(function() {
+    var link = $(this).text();
+    var directory = link.match("/$");
+    $("*[id$='-form']").hide();
+    $("#buttons").hide();
+    $("#buckets").hide();
+    $("#doctype")[0].reset();
+    $("#classify").show();
+    $("#source").val(link);
+
+    $("li:has(a)").removeClass('selected');
+    if (directory) {
+      $("li:has(a:contains('" + link + "/'))").addClass('selected');
+    } else {
+      $("li:has(a:contains('" + link + "'))").addClass('selected');
+    }
+
+    if (directory || link.match(/pgp\.txt$/)) {
+      parent.frames[1].location.href = 'file.cgi?action=view&dir=' +
+        encodeURIComponent(link);
+    } else {
+      parent.frames[1].location.href = '/received/' + link;
+    }
+
+    if (!link.match(/^eFax-\d+\.pdf$/)) {
+      $("#icla-form input").addClass("loading");
+      $("#ccla-form input").addClass("loading");
+      $("#grant-form input").addClass("loading");
+      $.getJSON('svninfo.cgi', {source: link}, function(info) {
+        if (!$('#realname').val()) $('#realname').val(info.from);
+        if (!$('#nname').val())    $('#nname').val(info.from);
+        if (!$('#contact').val())  $('#contact').val(info.from);
+        if (!$('#gname').val())    $('#gname').val(info.from);
+        if (!$('#email').val())    $('#email').val(info.email);
+        if (!$('#cemail').val())   $('#cemail').val(info.email);
+        if (!$('#gemail').val())   $('#gemail').val(info.email);
+        if (!$('#nemail').val())   $('#nemail').val(info.email);
+        if (!$('#memail').val())   $('#memail').val(info.email);
+        if (!$('#nid').val()) {
+          var email = $('#email').val();
+          if (email.match(/^\w+@apache.org$/)) {
+            $('#nid').val(email.split('@')[0]);
+          }
+        }
+        $("#icla-form input").removeClass("loading");
+        $("#ccla-form input").removeClass("loading");
+        $("#grant-form input").removeClass("loading");
+      });
+    }
+  });
+
+  // Classification
+  $('#doctype input[name=doctype]').click(function() {
+    var selection = $(this).attr('value');
+    $("*[id$='-form']").slideUp();
+    $("#"+selection+"-form").slideDown();
+    $("#"+selection+"2-form").slideDown();
+    if (selection == 'other') {
+      $("#buckets").show();
+      $("#buttons").hide();
+    } else {
+      $("#buckets").hide();
+      $("#buttons").show();
+    }
+    $("#replaces").val("");
+    if (selection == 'icla') {
+      $("#archive").removeAttr("disabled");
+    } else {
+      $("#archive").attr("disabled", "disabled");
+    }
+  });
+
+  // Fill in
+  $("#pubname").focus(function() {
+    if (this.value=='') this.value=$('#realname').val();
+  });
+
+  $("#email").focus(function() {
+    if (this.value=='') {
+      var source = $('#source').val();
+      if (source.indexOf('@') == -1) source='';
+      this.value = source.toLowerCase();
+    }
+  });
+
+  $("#filename, #nfilename").focus(function() {
+    if (this.value=='') this.value = generateFileName();
+  });
+
+  $("input[name=cfilename]").focus(function() {
+    if (this.value=='') {
+      var source = $('#source').val();
+      var value = $('#company').val();
+      var product = $('#product').val();
+      if (product) value += '-' + product;
+      value = asciize(value);
+      if (source.indexOf('.')>0) {
+        if (source.indexOf('@')<0 || source.match(/\.pdf$/)) {
+          value+=source.replace(/.*\./,'.');
+        }
+      }
+      value = value.replace(/-+/g,'-').toLowerCase();
+      value = value.replace(/-[.]/,'.');
+      value = value.replace(/-inc[.]/,'.');
+      this.value = value;
+    }
+  });
+
+  $("#nemail").focus(function() {
+    if (this.value=='') this.value=$('#nid').val()+'@apache.org';
+  });
+
+  // Commit prompt
+  $("input[value=Commit]").click(function() {
+    var message = prompt("Commit Message?", $('#message').attr('data-value'));
+    if (message) {
+      $('#message').attr('value', message);
+      return true;
+    } else {
+      return false;
+    }
+  });
+});
diff --git a/www/technology.html b/www/technology.html
new file mode 100644
index 0000000..7529d96
--- /dev/null
+++ b/www/technology.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta charset="utf-8"/>
+    <title>Technology behind Whimsy</title>
+    <style type="text/css">
+      h2 {text-decoration: underline}
+    </style>
+  </head>
+
+  <body>
+    <img title="ASF Logo" src="https://id.apache.org/img/asf_logo_wide.png"/>
+    <a href="http://whimsy.apache.org/">
+      <img src="whimsy.svg" width="80" title="whimsy"/>
+    </a>
+
+    <h2>Whimsy</h2>
+
+    <ul>
+      <li><a href="https://svn.apache.org/repos/infra/infrastructure/trunk/projects/whimsy">Source</a></li>
+      <li><a href="https://issues.apache.org/jira/browse/INFRA/component/12318503">Issue Tracker</a></li>
+    </ul>
+
+    <h2>Technology behind Whimsy</h2>
+
+    <ul>
+      <li><a href="http://www.w3.org/Style/CSS/">CSS</a></li>
+      <li><a href="http://dev.w3.org/html5/spec/spec.html">HTML5</a></li>
+      <li><a title="tecnically it is called ECMAScript" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">JavaScript</a></li>
+      <li><a href="http://jquery.com/">JQuery</a></li>
+      <li><a href="http://www.ruby-lang.org/en/">Ruby</a></li>
+      <li><a href="http://www.w3.org/TR/SVG/">SVG</a></li>
+      <li><a href="https://github.com/rubys/wunderbar#readme">Wunderbar</a></li>
+    </ul>
+
+    <h2>Technology behind the Technology</h2>
+
+    <ul>
+      <li><a href="http://httpd.apache.org/">Apache HTTPD</a></li>
+      <li><a href="http://tools.ietf.org/html/rfc3875">CGI</a></li>
+      <li><a href="http://www.openldap.org/">LDAP</a></li>
+      <li><a href="http://subversion.apache.org/">Subversion</a></li>
+    </ul>
+  </body>
+</html>
diff --git a/www/treasurer/expenses.cgi b/www/treasurer/expenses.cgi
new file mode 100755
index 0000000..753b3cf
--- /dev/null
+++ b/www/treasurer/expenses.cgi
@@ -0,0 +1,404 @@
+#!/usr/bin/ruby1.9.1
+require 'wunderbar'
+require 'yaml'
+require '/var/tools/asf'
+
+user = ASF::Person.new($USER)
+unless user.asf_member? or ASF.pmc_chairs.include? user or $USER=='ea'
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+categories = [
+  'Concom',
+  'Infrastructure',
+  'Public Relations',
+  'Secretary',
+  'Treasurer',
+  'President',
+  'TAC',
+  'Chair',
+  'Branding',
+  'Infrastructure Contractors',
+  'Public Relations Contractors',
+  'Executive Assistant',
+  'Uncategorized/Multiple',
+]
+
+paid = 'https://svn.apache.org/repos/private/financials/Bills/paid/'
+
+statements = '/var/tools/statements'
+dates = Dir["#{statements}/*.pdf","#{statements}/*.yml"].
+  map {|name| File.basename(name).chomp('.pdf').chomp('.yml')}.uniq.sort
+
+class Numeric
+  def currency
+    ('%.2f' % self).gsub(/(\d)(?=(\d{3})+\.)/, '\1,')
+  end
+end
+
+_html do
+  _head_ do
+    _title 'Statement'
+    _script src: '/jquery-min.js'
+    _script src: '/jquery.tablesorter.js'
+    _style %{
+      a {text-decoration: none}
+      tr:hover a {text-decoration: underline}
+      thead th {border-bottom: solid black}
+      tfoot th, tfoot td {border-top: solid black}
+      table {border-spacing: 1em 0.2em; float: left }
+      tbody tr:hover {background-color: #FF8}
+      th span {float: right}
+      .headerSortUp span:after {content: " \u2198"}
+      .headerSortDown span:after {content: " \u2197"}
+      svg {width: 30%; margin-left: 10%}
+      h2 {clear: both}
+    }
+  end
+
+  _body? do
+    # common banner
+    _a href: 'https://id.apache.org/' do
+      _img title: "Logo", alt: "Logo",
+        src: "https://id.apache.org/img/asf_logo_wide.png"
+    end
+
+    _h1_ 'Expenses'
+
+    @date ||= env['PATH_INFO'].to_s[/\/(\d{4}-\d\d)$/,1] || dates.last
+    @date = 'all' if env['PATH_INFO'] == '/all'
+    @date.untaint if @date =~ /^\d{4}-\d\d$/
+
+    if /expenses.*\/(?<category>.+)/ =~ env['REQUEST_URI']
+      @category = category unless category == 'all'
+      @date = 'all'
+    end
+
+    unless @category
+      request_uri = env['REQUEST_URI'].split('?').first
+      _form.month! method: 'post', action: request_uri.sub(/\d{4}-\d\d$/,'') do
+        _select name: 'date' do
+          dates.reverse.each do |date|
+            _option date, selected: (date == @date)
+          end
+          _option 'all', selected: (@date == 'all')
+        end
+        _input value: 'submit', type: 'submit'
+      end
+    end
+    
+    if @date == 'all'
+      debits = []
+      Dir["#{statements}/*.yml"].sort.each do |statement|
+        debits += YAML.load_file statement.untaint
+      end
+      if @category
+        debits.select! {|debit| debit['category'].gsub(/\W+/,'_') == @category}
+      end
+      statement = ''
+    elsif File.exist? "#{statements}/#{@date}.yml"
+      statement = ''
+      debits = YAML.load_file "#{statements}/#{@date}.yml"
+    else
+      statement = `pdftotext #{statements}/#{@date}.pdf -`
+      # credits = statement[/^Credits(.*)^Debits/m,1]
+      statement = statement[/^^Debits(.*)^Daily ledger/m,1].to_s
+      debits = []
+    end
+
+    if debits.empty? and not statement.empty?
+      dates = statement.scan(/^\d\d\/\d\d/)
+      amounts = statement.scan(/^[.,\d]+$/)
+      details = statement.
+	scan(/^(?:WT |Bill Pay|WF Bus|Client Anal|Safe Box|Online Transfer).*/)
+
+      _form_.debits! style: ('display: none' unless debits.empty?) do
+	_button 'File'
+	_select_.category! do
+	  _option ''
+	  categories.each do |category|
+	    _option category
+	  end
+	end
+	_select_.date! do
+	  dates.sort.each do |date|
+	    _option date, value: date
+	  end
+	end
+	_select_.amount! do
+	  amounts.each do |amount|
+	    _option amount, value: amount
+	  end
+	end
+	_select_.detail! do
+	  details.each do |detail|
+	    _option detail.strip, value: detail.strip
+	  end
+	end
+      end
+    end
+
+    subtotals = Hash.new(0)
+    debits.each do |transaction|
+      subtotals[transaction['category']] += transaction['amount'] 
+    end
+    total = subtotals.values.reduce(&:+) || 0
+
+    unless @category
+      _h2_ 'Summary'
+      colors = Hash.new('#000')
+
+      if total > 0
+        require 'color'
+        color = Color::RGB.from_html('#4488FF').to_hsl
+        step = 360.0 / ( PHI = (1 + Math.sqrt(5)) / 2 )
+
+        _svg_ viewBox: '-500 -500 1000 1000' do
+          _circle r: 480, stroke: '#000', fill: '#000'
+          theta = 0
+          subtotals.sort_by(&:last).reverse.each do |category, subtotal|
+            p1 = [Math.sin(theta)*475, -Math.cos(theta)*475].map(&:round)
+            theta += Math::PI*2 * subtotal/total
+            p2 = [Math.sin(theta)*475, -Math.cos(theta)*475].map(&:round)
+            arc = (subtotal*2 > total ? '1' : '0')
+            _path fill: color.html, title: category,
+              d: "M0,0 L#{p1.join(',')} A475,475 0 #{arc} 1 #{p2.join(',')} Z"
+            colors[category] = color.html
+            color.hue = (color.hue + step) % 360
+          end
+        end
+      end
+
+      _table do
+        _thead do
+          _tr do
+            _th 'Category'
+            _th 'Amount'
+          end
+        end
+        _tbody_ do
+          bullet = "\u25CF" unless total==0
+          (categories+subtotals.keys).sort.uniq.each do |category|
+            _tr_ style: ('display: none' if subtotals[category] == 0) do
+              _td!.category do
+                _a category, 
+                  href: "/treasurer/expenses/#{category.gsub(/\W+/,'_')}"
+              end
+              _td.subtotal subtotals[category].currency, align: 'right'
+              _td bullet, style: "color: #{colors[category]}"
+            end
+          end
+        end
+        _tfoot do
+          _tr do
+            _th 'Total'
+            _td.total! total.currency, align: 'right'
+          end
+        end
+      end
+    end
+
+    if @date =~ /\d{4}-\d\d/ or @category
+      _h2_ categories.find {|category| category.gsub(/\W+/,'_')==@category} ||
+         @category || 'Detail'
+      _table do
+        _thead_ do
+          _tr do
+            _th 'Date'
+            _th 'Amount' 
+            _th 'Category' unless @category
+            _th 'Detail'
+          end
+        end
+        _tbody.categorized! do
+          debits.each do |transaction|
+            _tr_ do
+              _td transaction['date']
+              _td transaction['amount'].currency, align: 'right'
+              _td transaction['category'] unless @category
+              if transaction['link']
+                _td! do
+                  _a transaction['detail'], href: paid + transaction['link']
+                end
+              else
+                _td transaction['detail'], title: transaction['notes']
+              end
+            end
+          end
+        end
+        if @category
+	  _tfoot do
+	    _tr do
+	      _th 'Total'
+	      _td.total! total.currency, align: 'right'
+	    end
+	  end
+        end
+      end
+    end
+
+    _script_ %q{
+      var year = null;
+      if (document.getElementById('month')) {
+        $('#month select').change(function() { 
+          location.href = "/treasurer/statements/" + $(this).val();
+          if ($(this).val()=='all') location.href = "/treasurer/expenses/all";
+        });
+        $('#month input').hide();
+        year = $('#month select').val().match(/(\d{4})-\d\d/);
+        if (year) year[1];
+      }
+
+      $('button').click(function() {
+        var tr = $('<tr></tr>');
+
+        var date = $('<td></td>').text($('#date').val());
+        $('#date option[value="'+date.text()+'"]:first').remove();
+        tr.append(date);
+
+        var category = $('<td></td>').text($('#category').val());
+        tr.append(category);
+
+        var amount = $('<td align="right"></td>').text($('#amount').val());
+        $('#amount option[value="'+amount.text()+'"]:first').remove();
+        tr.append(amount);
+
+        var detail = $('#detail').val();
+        $('#detail option[value="'+detail+'"]:first').remove();
+        detail = detail.replace(/WT \d+-\d+/,'WT');
+        detail = detail.replace(/WT Fed#\d+/,'WT Fed');
+        detail = detail.replace(/ Recurring.*/,'');
+        detail = detail.replace(/Auto Pay \d+ \d+/,'Auto Pay');
+        detail = detail.replace(/Srvc Chrg .*/,'Srvc Chrg');
+        detail = detail.replace(/on-Line [xX]\w* on .*/i,'');
+        detail = detail.replace(/on-Line No Account Number on .*/,'');
+        detail = detail.replace(/:Fee \d.*/,':Fee');
+        detail = $('<td></td>').text(detail);
+        tr.append(detail);
+        $('#detail').change();
+
+        $('.category').each(function() {
+          if ($(this).text() == category.text()) {
+            var tr = $(this).parent();
+            var td = $('td:last', tr);
+            var subtotal =
+              parseFloat(td.text().replace(/,/g,'')) +
+              parseFloat(amount.text().replace(/,/g,''));
+            subtotal = subtotal.toFixed(2);
+            subtotal = subtotal.replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
+            td.text(subtotal);
+            tr.show();
+          }
+        });
+
+        var total = 0;
+        $('.subtotal').each(function() {
+          total += parseFloat($(this).text().replace(/,/g,''));
+        });
+        total = total.toFixed(2);
+        total = total.replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
+        $('#total').text(total);
+        
+        $('#categorized').append(tr);
+
+        if (!$('#date').val() && !$('#detail').val() && !$('#amount').val()) {
+          var data = {month: $('#month select').val(), debits: []};
+          $('#categorized tr').each(function() {
+            var cols = $('td', $(this));
+            data.debits.push({
+              date:     year + '-' + cols[0].textContent.replace('/', '-'),
+              category: cols[1].textContent,
+              amount:   parseFloat(cols[2].textContent.replace(/,/g, '')),
+              detail:   cols[3].textContent
+            });
+          });
+          data.debits = JSON.stringify(data.debits)
+          $.post(location.href, data, function(_) {
+            $('#debits').replaceWith($('<p></p>').text(_.message));
+          }, 'json');
+        }
+
+        return false;
+      });
+
+      $('#date option:first').attr('selected', true);
+      $('#amount option:first').attr('selected', true);
+      $('#detail option:first').attr('selected', true);
+
+      var patterns = {
+        'Traci.Net':         'Infrastructure',
+        'Pctony':            'Infrastructure Contractors',
+        'Shahaf':            'Infrastructure Contractors',
+        '16 Degrees':        'Infrastructure Contractors',
+        'Sunstar':           'Infrastructure Contractors',
+        'Warnkin Recurring': 'Executive Assistant',
+        'Khudairi':          'Public Relations Contractors',
+        'PR Newswire':       'Public Relations',
+        'Globenewswire':     'Public Relations',
+        'Srvc Chrg':         'Treasurer',
+        'WF Bus Banking':    'Treasurer',
+        'Safe Box':          'Treasurer',
+        'The Company Corp':  'President',
+        'Nicholas Burch':    'Concom',
+      }
+
+      $('#category').change(function() {
+        $('button').attr('disabled', $('#category').val() == '');
+      });
+
+      $('#detail').change(function() {
+        var detail = $(this).val();
+        $('#category').val('').attr('selected', true);
+        if (detail) {
+          for (var pattern in patterns) {
+            if (detail.match(pattern)) {
+              $('#category').val(patterns[pattern]).attr('selected', true);
+            }
+          }
+        }
+
+        $('#category').change();
+      }).change();
+
+      $.tablesorter.addParser({ 
+        id: 'commafied', 
+        type: 'numeric',
+        is: function(s) { return s.match(/^[\d.,]+$/) }, 
+        format: function(s) { 
+          return jQuery.tablesorter.formatFloat(s.replace(/,/g, ""));
+        }
+      }); 
+
+      $('thead th').append('<span></span>');
+      $("table").tablesorter(
+        {sortList: [[0,0]], headers: {1: {sorter:'commafied'}}}
+      );
+
+      $('.category').each(function() {
+        var path = $('path[title="' + $('a', this).text() + '"]');
+        if (path.length == 0) return;
+
+        $(this).parents('tr').
+          mouseover(function() {
+            path.attr({'stroke-width': 35, stroke: path.attr('fill')});
+            path.parent().append(path);
+          }).
+          mouseout(function() {
+            path.removeAttr('stroke-width').removeAttr('stroke');
+          });
+      });
+
+      $('svg').attr('stroke-linejoin', 'round');
+    }
+  end
+end
+
+_json do
+  @month.untaint if @month =~ /^\d{4}-\d\d$/
+  File.open("#{statements}/#{@month}.yml",'w') do |file|
+    file.write YAML.dump(JSON.parse(@debits))
+  end
+  _message "Categorization complete"
+end
diff --git a/www/treasurer/index.cgi b/www/treasurer/index.cgi
new file mode 100755
index 0000000..7927927
--- /dev/null
+++ b/www/treasurer/index.cgi
@@ -0,0 +1,36 @@
+#!/usr/bin/ruby1.9.1
+require '/var/tools/asf'
+$SAFE = 1
+
+user = ASF::Person.new($USER)
+unless user.asf_member? or ASF.pmc_chairs.include? user or $USER=='ea'
+  print "Status: 401 Unauthorized\r\n"
+  print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n"
+  exit
+end
+
+request = ENV['REQUEST_URI'].sub(/^\/treasurer\/paypal\/?/, '')
+request.untaint if request =~ /^\d{4}-\d\d$/
+if request.tainted?
+  print "Status: 401 Forbidden\r\n"
+  print "Content-type: text/plain\r\n\r\n"
+  print "Forbidden"
+  exit
+end
+
+if File.exist?("/var/tools/treasurer/paypal/#{request}.html")
+  print "Content-type: text/html; charset=utf-8\r\n\r\n"
+  print File.read("/var/tools/treasurer/#{request}.html")
+  exit
+end
+
+if File.exist?("/var/tools/treasurer/paypal/#{request}.txt")
+  print "Content-type: text/plain; charset=utf-8\r\n\r\n"
+  print File.read("/var/tools/treasurer/#{request}.txt")
+  exit
+end
+
+print "Status: 404 Not-Found\r\n"
+print "Content-type: text/plain\r\n\r\n"
+print "Not here"
+exit
diff --git a/www/treasurer/statements.cgi b/www/treasurer/statements.cgi
new file mode 120000
index 0000000..51f2cb8
--- /dev/null
+++ b/www/treasurer/statements.cgi
@@ -0,0 +1 @@
+expenses.cgi
\ No newline at end of file
diff --git a/www/voter/jquery.min.js b/www/voter/jquery.min.js
new file mode 100644
index 0000000..198b3ff
--- /dev/null
+++ b/www/voter/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p
 ;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e i
 n b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==n
 ull)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&
 b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a
 ,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parse
 Float(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.pro
 totype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.
 context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].
 splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventLis
 tener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return nul
 l;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)bre
 ak;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([
 ],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},brows
 er:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.lengt
 h;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,th
 en:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(argument
 s,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.st
 yle.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendCh
 ild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;b
 order:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.rem
 oveChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(
 b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."
 ),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b
 )},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textare
 a)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){
 f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return
 !1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNod
 e,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttr
 ibute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{ta
 bIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""
 &&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,
 C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
+f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function
 (a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+
 f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"ev
 ents")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({
 elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pa
 geX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeun
 load=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.s
 topPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,".
 _submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusi
 n",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function"
 )d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin 
 focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]
 +)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n
 .expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break
 }}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e
 +=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.len
 gth,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?nu
 ll:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[
 3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},
 password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b
 ,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=n
 ull?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d
 .push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElement
 ById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=functi
 on(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.
 call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.co
 ntains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i
 ]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&t
 his[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},co
 ntents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summar
 y|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="obje
 ct"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:fun
 ction(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
+{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach()
 );return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0
 ];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(
 a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createText
 Node(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\
 )/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&
 &isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;i
 f(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"au
 to":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arg
 uments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSe
 nd".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m)
 {if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHead
 ers:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("
 ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));tr
 y{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(
 j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&
 e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.
 readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style
 ){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&
 (a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,
 c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a
 ,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;t
 his.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.anim
 atedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a
 .elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this
 [0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fi
 xed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f
 .css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this
 [d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
diff --git a/www/whimsy.svg b/www/whimsy.svg
new file mode 100644
index 0000000..af808b9
--- /dev/null
+++ b/www/whimsy.svg
@@ -0,0 +1,15 @@
+<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 84'>
+  <path fill='#0F0' d='M38,59c-2-86,73-42,73-42c0,0-35,3-36,13c-4,20-2,27-2,27z'/>
+  <path fill='#B7B' d='M38,59c-2-86,73-42,73-42c0,0-48-12-52,19c-3,21,0,21,0,21z'/>
+
+  <path fill='#F00' d='M57,54c-2-20-20-22-28-21c-14,2-22,38-19,44c-1,0,6-11,17-18c9-6,10,0,10,0z'/>
+
+  <path fill='#00F' d='M62,55c7-17,7-19,22-22c25-4,30,47,28,43c-24-29-32-17-32-16z'/>
+  <path fill='#B7B' d='M48,59c-18-37-38,18-38,18c-1,0,6-11,17-18c9-6,10,0,10,0zM71,61c16-42,40,15,41,15c-24-29-32-17-32-16z'/>
+
+  <path fill='#FA0' d='M27,75l-5-31l17,15l16-18l6,16l5-18l11,20l14-15l-6,15l1,15z'/>
+  <path fill='#B7B' d='M25,64h60l1,8h-59z'/>
+  <circle r='7' cx='10' cy='70' fill="#FF0" stroke="#FA0"/>
+  <circle r='7' cx='110' cy='74' fill="#FF0" stroke="#FA0"/>
+  <circle r='7' cx='110' cy='17' fill="#FF0" stroke="#FA0"/>
+</svg>

Mime
View raw message