hgbook
changeset 574:ad304b606163
Initial cut at web comment system import
line diff
1.1 --- a/.hgignore Mon Mar 09 23:42:31 2009 -0700 1.2 +++ b/.hgignore Tue Mar 10 21:42:19 2009 -0700 1.3 @@ -26,6 +26,7 @@ 1.4 *.pdf 1.5 *.png 1.6 *.ps 1.7 +*.pyc 1.8 *.rej 1.9 *.run 1.10 *.tmp 1.11 @@ -37,3 +38,4 @@ 1.12 .run 1.13 xsl/system-xsl 1.14 .validated-00book.xml 1.15 +web/hgbook/secrets.py
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/web/README Tue Mar 10 21:42:19 2009 -0700 2.3 @@ -0,0 +1,5 @@ 2.4 +This directory contains web-related files. Surprise! 2.5 + 2.6 +javascript - files used by the comment system, based on jQuery 2.7 +rwh - Django app that acts as the comment back end 2.8 +styles.css - style file
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/web/hgbook.conf Tue Mar 10 21:42:19 2009 -0700 3.3 @@ -0,0 +1,78 @@ 3.4 +# -*- apache -*- 3.5 + 3.6 +<VirtualHost *:80> 3.7 + ServerName www.hgbook.org 3.8 + ServerAdmin bos@serpentine.com 3.9 + ErrorLog logs/hgbook-error_log 3.10 + # Debian: 3.11 + # CustomLog logs/hgbook-access_log full 3.12 + # Fedora: 3.13 + CustomLog logs/hgbook-access_log combined 3.14 + Options +MultiViews 3.15 + DirectoryIndex index.html.var index.html 3.16 + DocumentRoot "/home/bos/hg/hgbook/en/html" 3.17 + 3.18 + # Actively redirect requests via a ServerAlias to the canonical hostname. 3.19 + RewriteEngine On 3.20 + RewriteCond %{HTTP_HOST} !=www.hgbook.org 3.21 + RewriteRule ^(.*) http://www.hgbook.org$1 [R] 3.22 + 3.23 + <Location "/"> 3.24 + SetHandler python-program 3.25 + # hg clone http://bitbucket.org/mirror/django-trunk/ 3.26 + PythonPath "['/home/bos/hg/django-trunk', '/home/bos/hg/hgbook/web'] + sys.path" 3.27 + PythonHandler django.core.handlers.modpython 3.28 + PythonAutoReload Off 3.29 + SetEnv DJANGO_SETTINGS_MODULE hgbook.settings 3.30 + PythonDebug Off 3.31 + </Location> 3.32 + 3.33 + <Location ~ "^/$"> 3.34 + SetHandler None 3.35 + DirectoryIndex index.html 3.36 + </Location> 3.37 + 3.38 + <Location ~ "^/index.html"> 3.39 + SetHandler None 3.40 + </Location> 3.41 + 3.42 + <Location ~ "^/robots.txt"> 3.43 + SetHandler None 3.44 + </Location> 3.45 + 3.46 + <Location "/read"> 3.47 + SetHandler None 3.48 + </Location> 3.49 + 3.50 + <Location "/support"> 3.51 + SetHandler None 3.52 + </Location> 3.53 + 3.54 + <Location "/media"> 3.55 + SetHandler None 3.56 + </Location> 3.57 + 3.58 + Alias /media /home/bos/hg/django-trunk/django/contrib/admin/media 3.59 + 3.60 + <Directory "/home/bos/hg/hgbook/en/html"> 3.61 + Options Indexes FollowSymlinks 3.62 + AllowOverride None 3.63 + Order allow,deny 3.64 + Allow from all 3.65 + </Directory> 3.66 + 3.67 + <Directory "/home/bos/hg/hgbook/en/html"> 3.68 + AllowOverride AuthConfig 3.69 + </Directory> 3.70 + 3.71 + <Directory "/home/bos/hg/hgbook/en/html/support"> 3.72 + Options None 3.73 + </Directory> 3.74 +</VirtualHost> 3.75 + 3.76 +<Directory "/home/bos/hg/django-trunk/django/contrib/admin/media"> 3.77 + Options None 3.78 + AllowOverride None 3.79 + Order allow,deny 3.80 + Allow from all 3.81 +</Directory>
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/web/hgbook/comments/feeds.py Tue Mar 10 21:42:19 2009 -0700 4.3 @@ -0,0 +1,35 @@ 4.4 +from django.core.exceptions import ObjectDoesNotExist 4.5 +from django.utils.feedgenerator import Atom1Feed 4.6 +from django.contrib.syndication.feeds import Feed 4.7 +from hgbook.comments.models import Comment, Element 4.8 + 4.9 +class MyAtomFeed(Atom1Feed): 4.10 + title_type = u'html' 4.11 + 4.12 +class Comments(Feed): 4.13 + feed_type = MyAtomFeed 4.14 + title = 'Real World Haskell: recent comments' 4.15 + subtitle = ('Recent comments on the text of “Real World ' 4.16 + 'Haskell”, from our readers') 4.17 + link = '/feeds/comments/' 4.18 + author_name = 'Our readers' 4.19 + 4.20 + def feedfilter(self, queryset): 4.21 + return queryset.order_by('-date')[:20] 4.22 + 4.23 + def items(self): 4.24 + return self.feedfilter(Comment.objects) 4.25 + 4.26 + def item_author_name(self, obj): 4.27 + return obj.submitter_name 4.28 + 4.29 + def item_pubdate(self, obj): 4.30 + return obj.date 4.31 + 4.32 + def get_object(self, bits): 4.33 + if len(bits) == 0: 4.34 + return self.items() 4.35 + elif len(bits) > 1: 4.36 + raise ObjectDoesNotExist 4.37 + return self.feedfilter(Comment.objects.filter(element__chapter=bits[0], 4.38 + hidden=False))
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/web/hgbook/comments/models.py Tue Mar 10 21:42:19 2009 -0700 5.3 @@ -0,0 +1,62 @@ 5.4 +from django.db import models 5.5 +import sha 5.6 + 5.7 +mutable = True 5.8 + 5.9 +class Element(models.Model): 5.10 + class Admin: 5.11 + search_fields = ['id', 'chapter'] 5.12 + list_filter = ['chapter', 'title'] 5.13 + 5.14 + id = models.CharField('ID attribute', max_length=64, editable=False, 5.15 + primary_key=True) 5.16 + chapter = models.CharField('Chapter ID', max_length=64, editable=False, 5.17 + db_index=True) 5.18 + title = models.CharField('Section title', max_length=256, editable=False) 5.19 + 5.20 + def __unicode__(self): 5.21 + return self.id 5.22 + 5.23 +class Comment(models.Model): 5.24 + class Admin: 5.25 + list_display = ['element', 'submitter_name', 'comment', 'reviewed', 5.26 + 'hidden', 'date'] 5.27 + search_fields = ['comment'] 5.28 + date_hierarchy = 'date' 5.29 + list_filter = ['date', 'submitter_name'] 5.30 + search_fields = ['title', 'submitter_name', 'submitter_url'] 5.31 + fields = ( 5.32 + (None, {'fields': ('submitter_name', 'element', 'comment')}), 5.33 + ('Review and presentation state', 5.34 + {'fields': ('reviewed', 'hidden')}), 5.35 + ('Other info', {'fields': ('date', 'submitter_url', 'ip')}), 5.36 + ) 5.37 + 5.38 + element = models.ForeignKey(Element, 5.39 + help_text='ID of paragraph that was commented on') 5.40 + comment = models.TextField(editable=mutable, 5.41 + help_text='Text of submitted comment (please do not modify)') 5.42 + submitter_name = models.CharField('Submitter', max_length=64, 5.43 + help_text='Self-reported name of submitter (may be bogus)') 5.44 + submitter_url = models.URLField('URL', blank=True, editable=mutable, 5.45 + help_text='Self-reported URL of submitter (may be empty or bogus)') 5.46 + ip = models.IPAddressField('IP address', editable=mutable, 5.47 + help_text='IP address from which comment was submitted') 5.48 + date = models.DateTimeField('date submitted', auto_now=True, 5.49 + auto_now_add=True) 5.50 + reviewed = models.BooleanField(default=False, db_index=True, 5.51 + help_text='Has this comment been reviewed by an author?') 5.52 + hidden = models.BooleanField(default=False, db_index=True, 5.53 + help_text='Has this comment been hidden from public display?') 5.54 + 5.55 + def __unicode__(self): 5.56 + return self.comment[:32] 5.57 + 5.58 + def get_absolute_url(self): 5.59 + s = sha.new() 5.60 + s.update(repr(self.comment)) 5.61 + s.update(repr(self.submitter_name)) 5.62 + s.update(str(self.date)) 5.63 + return '/read/%s.html#%s?comment=%s&uuid=%s' % ( 5.64 + self.element.chapter, self.element.id, self.id, s.hexdigest()[:20] 5.65 + )
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/web/hgbook/comments/sql/comment.mysql.sql Tue Mar 10 21:42:19 2009 -0700 6.3 @@ -0,0 +1,2 @@ 6.4 +alter table comments_comment convert to character set utf8 collate utf8_bin; 6.5 +alter table comments_comment default character set utf8 collate utf8_bin;
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/web/hgbook/comments/sql/element.mysql.sql Tue Mar 10 21:42:19 2009 -0700 7.3 @@ -0,0 +1,2 @@ 7.4 +alter table comments_element convert to character set utf8 collate utf8_bin; 7.5 +alter table comments_element default character set utf8 collate utf8_bin;
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/web/hgbook/comments/urls.py Tue Mar 10 21:42:19 2009 -0700 8.3 @@ -0,0 +1,8 @@ 8.4 +from django.conf.urls.defaults import * 8.5 + 8.6 +urlpatterns = patterns('', 8.7 + (r'chapter/(?P<id>[^/]+)/?$', 'hgbook.comments.views.chapter'), 8.8 + (r'chapter/(?P<id>[^/]+)/count/?$', 'hgbook.comments.views.chapter_count'), 8.9 + (r'single/(?P<id>[^/]+)/?$', 'hgbook.comments.views.single'), 8.10 + (r'submit/(?P<id>[^/]+)/?$', 'hgbook.comments.views.submit') 8.11 +)
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/web/hgbook/comments/views.py Tue Mar 10 21:42:19 2009 -0700 9.3 @@ -0,0 +1,101 @@ 9.4 +import django.newforms as forms 9.5 +from django.db import connection 9.6 +from django.http import HttpResponse 9.7 +from hgbook.comments.models import Comment, Element 9.8 +from django.shortcuts import get_object_or_404, render_to_response 9.9 +from django.template import Context 9.10 +from django.template.loader import get_template 9.11 +from django.utils.simplejson import dumps 9.12 + 9.13 +def dump_queries(): 9.14 + # requires settings.DEBUG to be set to True in order to work 9.15 + if len(connection.queries) == 1: 9.16 + print connection.queries 9.17 + else: 9.18 + qs = {} 9.19 + for q in connection.queries: 9.20 + qs[q['sql']] = qs.setdefault(q['sql'], 0) + 1 9.21 + for q in sorted(qs.items(), key=lambda x: x[1], reverse=True): 9.22 + print q 9.23 + print len(connection.queries) 9.24 + 9.25 +class CommentForm(forms.Form): 9.26 + id = forms.CharField(widget=forms.HiddenInput) 9.27 + name = forms.CharField(max_length=64) 9.28 + url = forms.URLField(max_length=128, required=False) 9.29 + comment = forms.CharField(widget=forms.Textarea(attrs={ 9.30 + 'rows': 8, 'cols': 60 9.31 + })) 9.32 + remember = forms.BooleanField(initial=True, required=False) 9.33 + 9.34 +def comments_by_chapter(id): 9.35 + objs = {} 9.36 + for c in Comment.objects.filter(element__chapter=id, hidden=False).order_by('date'): 9.37 + objs.setdefault(c.element_id, []).append(c) 9.38 + return objs 9.39 + 9.40 +def chapter(request, id): 9.41 + template = get_template('comment.html') 9.42 + resp = {} 9.43 + for elt, comments in comments_by_chapter(id).iteritems(): 9.44 + form = CommentForm(initial={ 9.45 + 'id': elt, 9.46 + 'name': request.session.get('name', ''), 9.47 + }) 9.48 + resp[elt] = template.render(Context({ 9.49 + 'id': elt, 9.50 + 'form': form, 9.51 + 'length': len(comments), 9.52 + 'query': comments, 9.53 + })) 9.54 + return HttpResponse(dumps(resp), mimetype='application/json') 9.55 + 9.56 +def chapter_count(request, id): 9.57 + resp = comments_by_chapter(id) 9.58 + for elt, comments in resp.iteritems(): 9.59 + resp[elt] = len(comments) 9.60 + return HttpResponse(dumps(resp), mimetype='application/json') 9.61 + 9.62 +def single(request, id, form=None, newid=None): 9.63 + queryset = Comment.objects.filter(element=id, hidden=False).order_by('date') 9.64 + if form is None: 9.65 + form = CommentForm(initial={ 9.66 + 'id': id, 9.67 + 'name': request.session.get('name', ''), 9.68 + }) 9.69 + try: 9.70 + error = form.errors[0] 9.71 + except: 9.72 + error = '' 9.73 + return render_to_response('comment.html', { 9.74 + 'id': id, 9.75 + 'form': form, 9.76 + 'length': len(queryset), 9.77 + 'query': queryset, 9.78 + 'newid': newid or True, 9.79 + 'error': error, 9.80 + }) 9.81 + 9.82 +def submit(request, id): 9.83 + element = get_object_or_404(Element, id=id) 9.84 + form = None 9.85 + newid = None 9.86 + if request.method == 'POST': 9.87 + form = CommentForm(request.POST) 9.88 + if form.is_valid(): 9.89 + data = form.cleaned_data 9.90 + if data.get('remember'): 9.91 + request.session['name'] = data['name'] 9.92 + request.session['url'] = data['url'] 9.93 + else: 9.94 + request.session.pop('name', None) 9.95 + request.session.pop('url', None) 9.96 + c = Comment(element=element, 9.97 + comment=data['comment'], 9.98 + submitter_name=data['name'], 9.99 + submitter_url=data['url'], 9.100 + ip=request.META.get('REMOTE_ADDR')) 9.101 + c.save() 9.102 + newid = c.id 9.103 + form = None 9.104 + return single(request, id, form, newid)
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/web/hgbook/dbutil.py Tue Mar 10 21:42:19 2009 -0700 10.3 @@ -0,0 +1,31 @@ 10.4 +import MySQLdb as mysql 10.5 + 10.6 +def connect(): 10.7 + try: 10.8 + import secrets 10.9 + except ImportError: 10.10 + print >> sys.stderr, 'Decrypt secrets.py.gpg or create a new copy!' 10.11 + sys.exit(1) 10.12 + 10.13 + if secrets.DATABASE_ENGINE != 'mysql': 10.14 + print >> sys.stderr, ('You are using a %s database' % 10.15 + secrets.DATABASE_ENGINE) 10.16 + sys.exit(1) 10.17 + 10.18 + kwargs = { 10.19 + 'charset': 'utf8', 10.20 + 'use_unicode': True, 10.21 + } 10.22 + if secrets.DATABASE_USER: 10.23 + kwargs['user'] = secrets.DATABASE_USER 10.24 + if secrets.DATABASE_NAME: 10.25 + kwargs['db'] = secrets.DATABASE_NAME 10.26 + if secrets.DATABASE_PASSWORD: 10.27 + kwargs['passwd'] = secrets.DATABASE_PASSWORD 10.28 + if secrets.DATABASE_HOST.startswith('/'): 10.29 + kwargs['unix_socket'] = secrets.DATABASE_HOST 10.30 + elif secrets.DATABASE_HOST: 10.31 + kwargs['host'] = secrets.DATABASE_HOST 10.32 + if secrets.DATABASE_PORT: 10.33 + kwargs['port'] = int(secrets.DATABASE_PORT) 10.34 + return mysql.connect(**kwargs)
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/web/hgbook/load_elements.py Tue Mar 10 21:42:19 2009 -0700 11.3 @@ -0,0 +1,18 @@ 11.4 +#!/usr/bin/env python 11.5 +# 11.6 +# This script updates the contents of the comments_element table. 11.7 +# It's fugly, but a lot less painful than trying to use Django's 11.8 +# fixtures system. 11.9 + 11.10 +import os, sys 11.11 +sys.path.append(os.path.dirname(__file__)) 11.12 +import dbutil 11.13 + 11.14 +os.system('make -C ../../en ids') 11.15 + 11.16 +conn = dbutil.connect() 11.17 +c = conn.cursor() 11.18 +c.execute('''load data local infile "../../en/all-ids.dat" replace 11.19 + into table comments_element 11.20 + fields terminated by "|"''') 11.21 +print 'Database updated'
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/web/hgbook/manage.py Tue Mar 10 21:42:19 2009 -0700 12.3 @@ -0,0 +1,11 @@ 12.4 +#!/usr/bin/env python 12.5 +from django.core.management import execute_manager 12.6 +try: 12.7 + import settings # Assumed to be in the same directory. 12.8 +except ImportError: 12.9 + import sys 12.10 + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) 12.11 + sys.exit(1) 12.12 + 12.13 +if __name__ == "__main__": 12.14 + execute_manager(settings)
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/web/hgbook/reviewers.py Tue Mar 10 21:42:19 2009 -0700 13.3 @@ -0,0 +1,81 @@ 13.4 +#!/usr/bin/env python 13.5 +# -*- coding: utf-8 -*- 13.6 + 13.7 +import os, sys 13.8 +sys.path.append(os.path.dirname(__file__)) 13.9 +import dbutil 13.10 + 13.11 +conn = dbutil.connect() 13.12 +c = conn.cursor() 13.13 + 13.14 +c.execute('''select submitter_name from comments_comment''') 13.15 + 13.16 +reviewers = {} 13.17 + 13.18 +mappings = { 13.19 + u'alejandro "tab-lover" dubrovsky': u'Alejandro Dubrovsky', 13.20 + u'alex hirzel <ahirzel@mtu.edu>': u'Alex Hirzel', 13.21 + u'anonymous coward': u'Anonymous', 13.22 + u'arthur van leeuwen': u'Arthur van Leeuwen', 13.23 + u'augustss': u'Lennart Augustsson', 13.24 + u'ed t': u'Anonymous', 13.25 + u'geogre moschovitis': u'George Moschovitis', 13.26 + u'george m': u'George Moschovitis', 13.27 + u'haskell newb': u'Anonymous', 13.28 + u'j. pablo fernandez': u'J. Pablo Fernández', 13.29 + u'kamal al-marhoobi': u'Kamal Al-Marhubi', 13.30 + u'kevin w.': u'Kevin Watters', 13.31 + u'max cantor (#haskell - mxc)': u'Max Cantor', 13.32 + u'michael campbell': u'Michael Campbell', 13.33 + u'mike btauwerman': u'Mike Brauwerman', 13.34 + u'no credit necessary': u'Anonymous', 13.35 + u'nykänen, matti': u'Matti Nykänen', 13.36 + u'omar antolin camarena': u'Omar Antolín Camarena', 13.37 + u'ryan t mulligan': u'Ryan T. Mulligan', 13.38 + u'sengan baring-gould': u'Sengan Baring-Gould', 13.39 + u'some guy': u'Anonymous', 13.40 + u'tomas janousek': u'Tomáš Janoušek', 13.41 + u'william halchin': u'William N. Halchin', 13.42 + } 13.43 + 13.44 +def fixup(s): 13.45 + try: 13.46 + return s.encode('ascii') 13.47 + except UnicodeEncodeError: 13.48 + def f(c): 13.49 + o = ord(c) 13.50 + if o < 128: 13.51 + return c 13.52 + return '&#%d;' % o 13.53 + return ''.join(map(f, s)) 13.54 + 13.55 +total = 0 13.56 +for r in c.fetchall(): 13.57 + r = r[0].decode('utf-8') 13.58 + if r in ("Bryan O'Sullivan", 'John Goerzen', 'Don Stewart'): 13.59 + continue 13.60 + total += 1 13.61 + m = mappings.get(r.lower()) 13.62 + if m: 13.63 + r = m 13.64 + elif len(r) < 2 or ' ' not in r: 13.65 + r = 'Anonymous' 13.66 + reviewers.setdefault(r, 0) 13.67 + reviewers[r] += 1 13.68 + 13.69 +reviewers = sorted(reviewers.iteritems(), key=lambda x: x[0]) 13.70 + 13.71 +cohorts = [(.01,1),(.002,.01)] 13.72 + 13.73 +for (lo,hi) in cohorts: 13.74 + lo = total * lo 13.75 + hi = total * hi 13.76 + for r in [n for n in reviewers if lo <= n[1] < hi]: 13.77 + if r[1] > 3: 13.78 + print '%s,' % fixup(r[0]) 13.79 + print 13.80 + 13.81 +lo = total * .002 13.82 +for n in reviewers: 13.83 + if n[1] < lo: 13.84 + print '%s,' % fixup(n[0])
14.1 Binary file web/hgbook/secrets.py.gpg has changed
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/web/hgbook/settings.py Tue Mar 10 21:42:19 2009 -0700 15.3 @@ -0,0 +1,87 @@ 15.4 +# Django settings for hgbook project. 15.5 + 15.6 +import os, sys 15.7 + 15.8 +DEBUG = False 15.9 +TEMPLATE_DEBUG = DEBUG 15.10 + 15.11 +ADMINS = ( 15.12 + ("Bryan O'Sullivan", 'bos@serpentine.com'), 15.13 +) 15.14 + 15.15 +MANAGERS = ADMINS 15.16 + 15.17 +ROOT = os.path.dirname(sys.modules[__name__].__file__) 15.18 + 15.19 +try: 15.20 + from secrets import DATABASE_ENGINE, DATABASE_NAME, DATABASE_USER, \ 15.21 + DATABASE_PASSWORD, DATABASE_HOST, DATABASE_PORT, SECRET_KEY 15.22 +except ImportError: 15.23 + print >> sys.stderr, 'Faking up some database configuration for you' 15.24 + DATABASE_ENGINE = 'sqlite3' 15.25 + DATABASE_NAME = os.path.join(ROOT, '.database.sqlite3') 15.26 + DATABASE_USER = '' 15.27 + DATABASE_PASSWORD = '' 15.28 + DATABASE_HOST = '' 15.29 + DATABASE_PORT = '' 15.30 + SECRET_KEY = '' 15.31 + 15.32 +# Local time zone for this installation. Choices can be found here: 15.33 +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 15.34 +# although not all choices may be avilable on all operating systems. 15.35 +# If running in a Windows environment this must be set to the same as your 15.36 +# system time zone. 15.37 +TIME_ZONE = 'America/Los_Angeles' 15.38 + 15.39 +# Language code for this installation. All choices can be found here: 15.40 +# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes 15.41 +LANGUAGE_CODE = 'en-us' 15.42 + 15.43 +SITE_ID = 1 15.44 + 15.45 +# If you set this to False, Django will make some optimizations so as not 15.46 +# to load the internationalization machinery. 15.47 +USE_I18N = True 15.48 + 15.49 +# Absolute path to the directory that holds media. 15.50 +# Example: "/home/media/media.lawrence.com/" 15.51 +MEDIA_ROOT = '' 15.52 + 15.53 +# URL that handles the media served from MEDIA_ROOT. Make sure to use a 15.54 +# trailing slash if there is a path component (optional in other cases). 15.55 +# Examples: "http://media.lawrence.com", "http://example.com/media/" 15.56 +MEDIA_URL = '' 15.57 + 15.58 +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 15.59 +# trailing slash. 15.60 +# Examples: "http://foo.com/media/", "/media/". 15.61 +ADMIN_MEDIA_PREFIX = '/media/' 15.62 + 15.63 +# List of callables that know how to import templates from various sources. 15.64 +TEMPLATE_LOADERS = ( 15.65 + 'django.template.loaders.filesystem.load_template_source', 15.66 + 'django.template.loaders.app_directories.load_template_source', 15.67 +# 'django.template.loaders.eggs.load_template_source', 15.68 +) 15.69 + 15.70 +MIDDLEWARE_CLASSES = ( 15.71 + 'django.middleware.common.CommonMiddleware', 15.72 + 'django.contrib.sessions.middleware.SessionMiddleware', 15.73 + 'django.contrib.auth.middleware.AuthenticationMiddleware', 15.74 + 'django.middleware.doc.XViewMiddleware', 15.75 +) 15.76 + 15.77 +ROOT_URLCONF = 'hgbook.urls' 15.78 + 15.79 +TEMPLATE_DIRS = ( 15.80 + os.path.join(ROOT, 'templates') 15.81 +) 15.82 + 15.83 +INSTALLED_APPS = ( 15.84 + 'django.contrib.admin', 15.85 + 'django.contrib.auth', 15.86 + 'django.contrib.contenttypes', 15.87 + 'django.contrib.sessions', 15.88 + 'django.contrib.sites', 15.89 + 'hgbook.comments', 15.90 +)
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/web/hgbook/templates/404.html Tue Mar 10 21:42:19 2009 -0700 16.3 @@ -0,0 +1,8 @@ 16.4 +{% extends "simple.html" %} 16.5 + 16.6 +{% block title %}Page Not Found{% endblock %} 16.7 + 16.8 +{% block body %} 16.9 +<p>Sorry, we hit <a href="http://www.haskell.org/haskellwiki/Bottom">⊥</a> when trying to find the 16.10 +page you requested.</p> 16.11 +{% endblock %}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/web/hgbook/templates/500.html Tue Mar 10 21:42:19 2009 -0700 17.3 @@ -0,0 +1,11 @@ 17.4 +{% extends "simple.html" %} 17.5 + 17.6 +{% block title %}Internal Server Error{% endblock %} 17.7 + 17.8 +{% block body %} 17.9 +<p>Sorry, we hit <a 17.10 +href="http://www.haskell.org/haskellwiki/Bottom">⊥</a> when 17.11 +trying to process your request. If possible, please let <a 17.12 +href="mailto:bos@serpentine.com">Bryan</a> know that this problem happened, 17.13 +and what you were doing when it occurred.</p> 17.14 +{% endblock %}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/web/hgbook/templates/boilerplate.html Tue Mar 10 21:42:19 2009 -0700 18.3 @@ -0,0 +1,34 @@ 18.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 18.5 +<html> 18.6 + <head> 18.7 + <title>{% block pagetitle %}Real World Haskell{% endblock %}</title> 18.8 + <link rel="stylesheet" href="/support/styles.css" type="text/css"/> 18.9 + <link rel="alternate" type="application/atom+xml" title="Comments" 18.10 + href="/feeds/comments/"/> 18.11 + <link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"/> 18.12 + <script type="text/javascript" src="/support/jquery.js"></script> 18.13 + <script type="text/javascript" src="/support/form.js"></script> 18.14 + <script type="text/javascript" src="/support/hsbook.js"></script> 18.15 + </head> 18.16 + 18.17 + <body> 18.18 + {% block bodycontent %}{% endblock %} 18.19 + 18.20 + <div class="hgbookfooter"> <p><img src="/support/figs/rss.png"> Want to stay 18.21 + up to date? Subscribe to comment feeds for any chapter, or 18.22 + the <a class="feed" 18.23 + href="/feeds/comments/">entire book</a>.</p> <p>Copyright 18.24 + 2007, 2008 Bryan O'Sullivan, Don Stewart, and John Goerzen. This 18.25 + work is licensed under a <a rel="license" href= 18.26 + "http://creativecommons.org/licenses/by-nc/3.0/">Creative 18.27 + Commons Attribution-Noncommercial 3.0 License</a>. Icons by 18.28 + <a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a 18.29 + href="http://mattahan.deviantart.com/">Mattahan</a>.</p> 18.30 + </div> 18.31 + 18.32 + <script src="http://www.google-analytics.com/urchin.js" 18.33 + type="text/javascript"></script> 18.34 + <script type="text/javascript">_uacct = "UA-1805907-3"; 18.35 + urchinTracker();</script> 18.36 + </body> 18.37 +</html>
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/web/hgbook/templates/comment.html Tue Mar 10 21:42:19 2009 -0700 19.3 @@ -0,0 +1,62 @@ 19.4 +{% ifequal length 1 %} 19.5 + <a class="commenttoggle" id="toggle_{{ id }}" 19.6 + onclick="return toggleComment('{{ id }}')" 19.7 + href="comments: show / hide">One comment</a> 19.8 +{% else %} 19.9 + {% if length %} 19.10 + <a class="commenttoggle" id="toggle_{{ id }}" 19.11 + onclick="return toggleComment('{{ id }}')" 19.12 + href="comments: show / hide">{{ length }} comments</a> 19.13 + {% else %} 19.14 + <a class="commenttoggle" id="toggle_{{ id }}" 19.15 + onclick="return toggleComment('{{ id }}')" 19.16 + href="comments: show / hide">No comments</a> 19.17 + <div class="comment" {% if not newid %} style="display: none;" {% endif %}> 19.18 + <div class="comment_body">Be the first to comment on this paragraph!</div> 19.19 + </div> 19.20 + {% endif %} 19.21 +{% endifequal %} 19.22 +{% for c in query %} 19.23 + <div class="{% ifequal c.id newid %}new_{% endifequal %}comment" 19.24 + {% if not newid %} style="display: none;" {% endif %} 19.25 + id="comment{{ c.id }}"> 19.26 + <a name="comment{{ c.id }}"/> 19.27 + <div class="comment_header"> 19.28 + <span class="comment_id"><a href="/admin/comments/comment/{{ c.id }}/">{{ c.id }}</a></span> 19.29 + {% if c.submitter_url %} 19.30 + <span class="comment_name"><a rel="nofollow" 19.31 + href="{{ c.submitter_url }}">{{ c.submitter_name|escape }}</a></span> 19.32 + {% else %} 19.33 + <span class="comment_name">{{ c.submitter_name|escape }}</span> 19.34 + {% endif %} 19.35 + <span class="comment_date">{{ c.date|date:"Y-m-d" }}</span> 19.36 + {% if c.reviewed %} 19.37 + <span class="comment_reviewed">(reviewed)</span> 19.38 + {% endif %} 19.39 + {% ifequal c.id newid %} 19.40 + <span class="comment_thanks">thank you for your comment!</span> 19.41 + {% endifequal %} 19.42 + </div> 19.43 + <div class="comment_body">{{ c.comment|escape|linebreaks }}</div> 19.44 + </div> 19.45 +{% endfor %} 19.46 +<form class="comment" id="form_{{ id }}" action="/comments/submit/{{ id }}/" 19.47 + method="post" {% if not newid %} style="display: none;" {% endif %}> 19.48 + {{ form.id }} 19.49 + <table> 19.50 + <tbody> 19.51 + <tr><td align="right" valign="top">Comment<br><a class="comment_help" 19.52 + href="web.html#web.comment">[ help ]</a></td> 19.53 + <td>{{ form.comment }}</td></tr> 19.54 + <tr><td align="right">Your name</td><td>{{ form.name }} 19.55 + <span class="comment_help"><b>Required</b> so we can <a 19.56 + href="web.html#web.comment.name">give you credit</a></span></td></tr> 19.57 + <tr><td align="right">Your URL</td><td>{{ form.url }} 19.58 + <span class="comment_help"><b>Optional</b> link to blog, home page, 19.59 + <i>etc</i>.</span></td></tr> 19.60 + <tr><td align="right">Remember you?</td><td>{{ form.remember }}</td></tr> 19.61 + <tr><td/><td><input name="submit" type="submit" 19.62 + value="Submit Comment"/><span class="comment_error">{{ error }}</span></td></tr> 19.63 + </tbody> 19.64 + </table> 19.65 +</form>
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/web/hgbook/templates/feeds/comments_description.html Tue Mar 10 21:42:19 2009 -0700 20.3 @@ -0,0 +1,12 @@ 20.4 +<p>On {{ obj.date|date:"Y-m-d" }}, 20.5 + {% if obj.submitter_url %} 20.6 + <a rel="nofollow" href="{{ obj.submitter_url }}">{{ obj.submitter_name|escape }}</a> 20.7 + {% else %} 20.8 + {{ obj.submitter_name|escape }} 20.9 + {% endif %} 20.10 +commented on “{{ obj.element.title|escape }}”:</p> 20.11 +<blockquote> 20.12 +{{ obj.comment|escape|linebreaks }} 20.13 +</blockquote> 20.14 +<p>To see this comment in context or to respond, visit <a 20.15 + href="http://{{ site.domain }}{{ obj.get_absolute_url }}">{{ site.domain }}</a></p>
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/web/hgbook/templates/feeds/comments_title.html Tue Mar 10 21:42:19 2009 -0700 21.3 @@ -0,0 +1,1 @@ 21.4 +Comment on “{{ obj.element.title|escape }}”
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/web/hgbook/templates/simple.html Tue Mar 10 21:42:19 2009 -0700 22.3 @@ -0,0 +1,7 @@ 22.4 +{% extends "boilerplate.html" %} 22.5 + 22.6 +{% block bodycontent %} 22.7 +<div class="navheader"><h1>{% block title %}{% endblock %}</h1></div> 22.8 + 22.9 +<div class="basetemplate">{% block body %}{% endblock %}</div> 22.10 +{% endblock %}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/web/hgbook/urls.py Tue Mar 10 21:42:19 2009 -0700 23.3 @@ -0,0 +1,22 @@ 23.4 +import os 23.5 +from django.conf.urls.defaults import * 23.6 +import hgbook.comments.feeds as feeds 23.7 + 23.8 +feeds = { 23.9 + 'comments': feeds.Comments, 23.10 + } 23.11 + 23.12 +urlpatterns = patterns('', 23.13 + (r'^comments/', include('hgbook.comments.urls')), 23.14 + 23.15 + (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', 23.16 + {'feed_dict': feeds}), 23.17 + 23.18 + # Only uncomment this for local testing without Apache. 23.19 + # (r'^html/(?P<path>.*)$', 'django.views.static.serve', 23.20 + # {'document_root': os.path.realpath(os.path.dirname( 23.21 + # sys.modules[__name__].__file__) + '/../../en/html'), 23.22 + 23.23 + # Uncomment this for admin: 23.24 + (r'^admin/', include('django.contrib.admin.urls')), 23.25 +)
24.1 Binary file web/icons/caution.png has changed
25.1 Binary file web/icons/favicon.png has changed
26.1 Binary file web/icons/important.png has changed
27.1 Binary file web/icons/note.png has changed
28.1 Binary file web/icons/remark.png has changed
29.1 Binary file web/icons/rss.png has changed
30.1 Binary file web/icons/shell.png has changed
31.1 Binary file web/icons/source.png has changed
32.1 Binary file web/icons/tip.png has changed
33.1 Binary file web/icons/warning.png has changed
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/web/javascript/form-min.js Tue Mar 10 21:42:19 2009 -0700 34.3 @@ -0,0 +1,1 @@ 34.4 +(function($){$.fn.ajaxSubmit=function(_2){if(typeof _2=="function"){_2={success:_2};}_2=$.extend({url:this.attr("action")||window.location,type:this.attr("method")||"GET"},_2||{});var _3={};$.event.trigger("form.pre.serialize",[this,_2,_3]);if(_3.veto){return this;}var a=this.formToArray(_2.semantic);if(_2.data){for(var n in _2.data){a.push({name:n,value:_2.data[n]});}}if(_2.beforeSubmit&&_2.beforeSubmit(a,this,_2)===false){return this;}$.event.trigger("form.submit.validate",[a,this,_2,_3]);if(_3.veto){return this;}var q=$.param(a);if(_2.type.toUpperCase()=="GET"){_2.url+=(_2.url.indexOf("?")>=0?"&":"?")+q;_2.data=null;}else{_2.data=q;}var _7=this,callbacks=[];if(_2.resetForm){callbacks.push(function(){_7.resetForm();});}if(_2.clearForm){callbacks.push(function(){_7.clearForm();});}if(!_2.dataType&&_2.target){var _8=_2.success||function(){};callbacks.push(function(_9){if(this.evalScripts){$(_2.target).attr("innerHTML",_9).evalScripts().each(_8,arguments);}else{$(_2.target).html(_9).each(_8,arguments);}});}else{if(_2.success){callbacks.push(_2.success);}}_2.success=function(_a,_b){for(var i=0,max=callbacks.length;i<max;i++){callbacks[i](_a,_b,_7);}};var _d=$("input:file",this).fieldValue();var _e=false;for(var j=0;j<_d.length;j++){if(_d[j]){_e=true;}}if(_2.iframe||_e){fileUpload();}else{$.ajax(_2);}$.event.trigger("form.submit.notify",[this,_2]);return this;function fileUpload(){var _10=_7[0];var _11=$.extend({},$.ajaxSettings,_2);var id="jqFormIO"+$.fn.ajaxSubmit.counter++;var $io=$("<iframe id=\""+id+"\" name=\""+id+"\" />");var io=$io[0];var op8=$.browser.opera&&window.opera.version()<9;if($.browser.msie||op8){io.src="javascript:false;document.write(\"\");";}$io.css({position:"absolute",top:"-1000px",left:"-1000px"});var xhr={responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){}};var g=_11.global;if(g&&!$.active++){$.event.trigger("ajaxStart");}if(g){$.event.trigger("ajaxSend",[xhr,_11]);}var _18=0;var _19=0;setTimeout(function(){$io.appendTo("body");io.attachEvent?io.attachEvent("onload",cb):io.addEventListener("load",cb,false);var _1a=_10.encoding?"encoding":"enctype";var t=_7.attr("target");_7.attr({target:id,method:"POST",action:_11.url});_10[_1a]="multipart/form-data";if(_11.timeout){setTimeout(function(){_19=true;cb();},_11.timeout);}_10.submit();_7.attr("target",t);},10);function cb(){if(_18++){return;}io.detachEvent?io.detachEvent("onload",cb):io.removeEventListener("load",cb,false);var ok=true;try{if(_19){throw "timeout";}var _1d,doc;doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;xhr.responseText=doc.body?doc.body.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(_11.dataType=="json"||_11.dataType=="script"){var ta=doc.getElementsByTagName("textarea")[0];_1d=ta?ta.value:xhr.responseText;if(_11.dataType=="json"){eval("data = "+_1d);}else{$.globalEval(_1d);}}else{if(_11.dataType=="xml"){_1d=xhr.responseXML;if(!_1d&&xhr.responseText!=null){_1d=toXml(xhr.responseText);}}else{_1d=xhr.responseText;}}}catch(e){ok=false;$.handleError(_11,xhr,"error",e);}if(ok){_11.success(_1d,"success");if(g){$.event.trigger("ajaxSuccess",[xhr,_11]);}}if(g){$.event.trigger("ajaxComplete",[xhr,_11]);}if(g&&!--$.active){$.event.trigger("ajaxStop");}if(_11.complete){_11.complete(xhr,ok?"success":"error");}setTimeout(function(){$io.remove();xhr.responseXML=null;},100);}function toXml(s,doc){if(window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(s);}else{doc=(new DOMParser()).parseFromString(s,"text/xml");}return (doc&&doc.documentElement&&doc.documentElement.tagName!="parsererror")?doc:null;}}};$.fn.ajaxSubmit.counter=0;$.fn.ajaxForm=function(_21){return this.ajaxFormUnbind().submit(submitHandler).each(function(){this.formPluginId=$.fn.ajaxForm.counter++;$.fn.ajaxForm.optionHash[this.formPluginId]=_21;$(":submit,input:image",this).click(clickHandler);});};$.fn.ajaxForm.counter=1;$.fn.ajaxForm.optionHash={};function clickHandler(e){var _23=this.form;_23.clk=this;if(this.type=="image"){if(e.offsetX!=undefined){_23.clk_x=e.offsetX;_23.clk_y=e.offsetY;}else{if(typeof $.fn.offset=="function"){var _24=$(this).offset();_23.clk_x=e.pageX-_24.left;_23.clk_y=e.pageY-_24.top;}else{_23.clk_x=e.pageX-this.offsetLeft;_23.clk_y=e.pageY-this.offsetTop;}}}setTimeout(function(){_23.clk=_23.clk_x=_23.clk_y=null;},10);}function submitHandler(){var id=this.formPluginId;var _26=$.fn.ajaxForm.optionHash[id];$(this).ajaxSubmit(_26);return false;}$.fn.ajaxFormUnbind=function(){this.unbind("submit",submitHandler);return this.each(function(){$(":submit,input:image",this).unbind("click",clickHandler);});};$.fn.formToArray=function(_27){var a=[];if(this.length==0){return a;}var _29=this[0];var els=_27?_29.getElementsByTagName("*"):_29.elements;if(!els){return a;}for(var i=0,max=els.length;i<max;i++){var el=els[i];var n=el.name;if(!n){continue;}if(_27&&_29.clk&&el.type=="image"){if(!el.disabled&&_29.clk==el){a.push({name:n+".x",value:_29.clk_x},{name:n+".y",value:_29.clk_y});}continue;}var v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(var j=0,jmax=v.length;j<jmax;j++){a.push({name:n,value:v[j]});}}else{if(v!==null&&typeof v!="undefined"){a.push({name:n,value:v});}}}if(!_27&&_29.clk){var _30=_29.getElementsByTagName("input");for(var i=0,max=_30.length;i<max;i++){var _32=_30[i];var n=_32.name;if(n&&!_32.disabled&&_32.type=="image"&&_29.clk==_32){a.push({name:n+".x",value:_29.clk_x},{name:n+".y",value:_29.clk_y});}}}return a;};$.fn.formSerialize=function(_34){return $.param(this.formToArray(_34));};$.fn.fieldSerialize=function(_35){var a=[];this.each(function(){var n=this.name;if(!n){return;}var v=$.fieldValue(this,_35);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++){a.push({name:n,value:v[i]});}}else{if(v!==null&&typeof v!="undefined"){a.push({name:this.name,value:v});}}});return $.param(a);};$.fn.fieldValue=function(_3a){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,_3a);if(v===null||typeof v=="undefined"||(v.constructor==Array&&!v.length)){continue;}v.constructor==Array?$.merge(val,v):val.push(v);}return val;};$.fieldValue=function(el,_3f){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(typeof _3f=="undefined"){_3f=true;}if(_3f&&(!n||el.disabled||t=="reset"||t=="button"||(t=="checkbox"||t=="radio")&&!el.checked||(t=="submit"||t=="image")&&el.form&&el.form.clk!=el||tag=="select"&&el.selectedIndex==-1)){return null;}if(tag=="select"){var _41=el.selectedIndex;if(_41<0){return null;}var a=[],ops=el.options;var one=(t=="select-one");var max=(one?_41+1:ops.length);for(var i=(one?_41:0);i<max;i++){var op=ops[i];if(op.selected){var v=$.browser.msie&&!(op.attributes["value"].specified)?op.text:op.value;if(one){return v;}a.push(v);}}return a;}return el.value;};$.fn.clearForm=function(){return this.each(function(){$("input,select,textarea",this).clearFields();});};$.fn.clearFields=$.fn.clearInputs=function(){return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(t=="text"||t=="password"||tag=="textarea"){this.value="";}else{if(t=="checkbox"||t=="radio"){this.checked=false;}else{if(tag=="select"){this.selectedIndex=-1;}}}});};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset();}});};})(jQuery); 34.5 \ No newline at end of file
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/web/javascript/form.js Tue Mar 10 21:42:19 2009 -0700 35.3 @@ -0,0 +1,819 @@ 35.4 +/* 35.5 + * jQuery Form Plugin 35.6 + * @requires jQuery v1.1 or later 35.7 + * 35.8 + * Examples at: http://malsup.com/jquery/form/ 35.9 + * Dual licensed under the MIT and GPL licenses: 35.10 + * http://www.opensource.org/licenses/mit-license.php 35.11 + * http://www.gnu.org/licenses/gpl.html 35.12 + * 35.13 + * Revision: $Id$ 35.14 + */ 35.15 + (function($) { 35.16 +/** 35.17 + * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX. 35.18 + * 35.19 + * ajaxSubmit accepts a single argument which can be either a success callback function 35.20 + * or an options Object. If a function is provided it will be invoked upon successful 35.21 + * completion of the submit and will be passed the response from the server. 35.22 + * If an options Object is provided, the following attributes are supported: 35.23 + * 35.24 + * target: Identifies the element(s) in the page to be updated with the server response. 35.25 + * This value may be specified as a jQuery selection string, a jQuery object, 35.26 + * or a DOM element. 35.27 + * default value: null 35.28 + * 35.29 + * url: URL to which the form data will be submitted. 35.30 + * default value: value of form's 'action' attribute 35.31 + * 35.32 + * type: The method in which the form data should be submitted, 'GET' or 'POST'. 35.33 + * default value: value of form's 'method' attribute (or 'GET' if none found) 35.34 + * 35.35 + * data: Additional data to add to the request, specified as key/value pairs (see $.ajax). 35.36 + * 35.37 + * beforeSubmit: Callback method to be invoked before the form is submitted. 35.38 + * default value: null 35.39 + * 35.40 + * success: Callback method to be invoked after the form has been successfully submitted 35.41 + * and the response has been returned from the server 35.42 + * default value: null 35.43 + * 35.44 + * dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json' 35.45 + * default value: null 35.46 + * 35.47 + * semantic: Boolean flag indicating whether data must be submitted in semantic order (slower). 35.48 + * default value: false 35.49 + * 35.50 + * resetForm: Boolean flag indicating whether the form should be reset if the submit is successful 35.51 + * 35.52 + * clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful 35.53 + * 35.54 + * 35.55 + * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for 35.56 + * validating the form data. If the 'beforeSubmit' callback returns false then the form will 35.57 + * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data 35.58 + * in array format, the jQuery object, and the options object passed into ajaxSubmit. 35.59 + * The form data array takes the following form: 35.60 + * 35.61 + * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 35.62 + * 35.63 + * If a 'success' callback method is provided it is invoked after the response has been returned 35.64 + * from the server. It is passed the responseText or responseXML value (depending on dataType). 35.65 + * See jQuery.ajax for further details. 35.66 + * 35.67 + * 35.68 + * The dataType option provides a means for specifying how the server response should be handled. 35.69 + * This maps directly to the jQuery.httpData method. The following values are supported: 35.70 + * 35.71 + * 'xml': if dataType == 'xml' the server response is treated as XML and the 'success' 35.72 + * callback method, if specified, will be passed the responseXML value 35.73 + * 'json': if dataType == 'json' the server response will be evaluted and passed to 35.74 + * the 'success' callback, if specified 35.75 + * 'script': if dataType == 'script' the server response is evaluated in the global context 35.76 + * 35.77 + * 35.78 + * Note that it does not make sense to use both the 'target' and 'dataType' options. If both 35.79 + * are provided the target will be ignored. 35.80 + * 35.81 + * The semantic argument can be used to force form serialization in semantic order. 35.82 + * This is normally true anyway, unless the form contains input elements of type='image'. 35.83 + * If your form must be submitted with name/value pairs in semantic order and your form 35.84 + * contains an input of type='image" then pass true for this arg, otherwise pass false 35.85 + * (or nothing) to avoid the overhead for this logic. 35.86 + * 35.87 + * 35.88 + * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this: 35.89 + * 35.90 + * $("#form-id").submit(function() { 35.91 + * $(this).ajaxSubmit(options); 35.92 + * return false; // cancel conventional submit 35.93 + * }); 35.94 + * 35.95 + * When using ajaxForm(), however, this is done for you. 35.96 + * 35.97 + * @example 35.98 + * $('#myForm').ajaxSubmit(function(data) { 35.99 + * alert('Form submit succeeded! Server returned: ' + data); 35.100 + * }); 35.101 + * @desc Submit form and alert server response 35.102 + * 35.103 + * 35.104 + * @example 35.105 + * var options = { 35.106 + * target: '#myTargetDiv' 35.107 + * }; 35.108 + * $('#myForm').ajaxSubmit(options); 35.109 + * @desc Submit form and update page element with server response 35.110 + * 35.111 + * 35.112 + * @example 35.113 + * var options = { 35.114 + * success: function(responseText) { 35.115 + * alert(responseText); 35.116 + * } 35.117 + * }; 35.118 + * $('#myForm').ajaxSubmit(options); 35.119 + * @desc Submit form and alert the server response 35.120 + * 35.121 + * 35.122 + * @example 35.123 + * var options = { 35.124 + * beforeSubmit: function(formArray, jqForm) { 35.125 + * if (formArray.length == 0) { 35.126 + * alert('Please enter data.'); 35.127 + * return false; 35.128 + * } 35.129 + * } 35.130 + * }; 35.131 + * $('#myForm').ajaxSubmit(options); 35.132 + * @desc Pre-submit validation which aborts the submit operation if form data is empty 35.133 + * 35.134 + * 35.135 + * @example 35.136 + * var options = { 35.137 + * url: myJsonUrl.php, 35.138 + * dataType: 'json', 35.139 + * success: function(data) { 35.140 + * // 'data' is an object representing the the evaluated json data 35.141 + * } 35.142 + * }; 35.143 + * $('#myForm').ajaxSubmit(options); 35.144 + * @desc json data returned and evaluated 35.145 + * 35.146 + * 35.147 + * @example 35.148 + * var options = { 35.149 + * url: myXmlUrl.php, 35.150 + * dataType: 'xml', 35.151 + * success: function(responseXML) { 35.152 + * // responseXML is XML document object 35.153 + * var data = $('myElement', responseXML).text(); 35.154 + * } 35.155 + * }; 35.156 + * $('#myForm').ajaxSubmit(options); 35.157 + * @desc XML data returned from server 35.158 + * 35.159 + * 35.160 + * @example 35.161 + * var options = { 35.162 + * resetForm: true 35.163 + * }; 35.164 + * $('#myForm').ajaxSubmit(options); 35.165 + * @desc submit form and reset it if successful 35.166 + * 35.167 + * @example 35.168 + * $('#myForm).submit(function() { 35.169 + * $(this).ajaxSubmit(); 35.170 + * return false; 35.171 + * }); 35.172 + * @desc Bind form's submit event to use ajaxSubmit 35.173 + * 35.174 + * 35.175 + * @name ajaxSubmit 35.176 + * @type jQuery 35.177 + * @param options object literal containing options which control the form submission process 35.178 + * @cat Plugins/Form 35.179 + * @return jQuery 35.180 + */ 35.181 +$.fn.ajaxSubmit = function(options) { 35.182 + if (typeof options == 'function') 35.183 + options = { success: options }; 35.184 + 35.185 + options = $.extend({ 35.186 + url: this.attr('action') || window.location, 35.187 + type: this.attr('method') || 'GET' 35.188 + }, options || {}); 35.189 + 35.190 + // hook for manipulating the form data before it is extracted; 35.191 + // convenient for use with rich editors like tinyMCE or FCKEditor 35.192 + var veto = {}; 35.193 + $.event.trigger('form.pre.serialize', [this, options, veto]); 35.194 + if (veto.veto) return this; 35.195 + 35.196 + var a = this.formToArray(options.semantic); 35.197 + if (options.data) { 35.198 + for (var n in options.data) 35.199 + a.push( { name: n, value: options.data[n] } ); 35.200 + } 35.201 + 35.202 + // give pre-submit callback an opportunity to abort the submit 35.203 + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this; 35.204 + 35.205 + // fire vetoable 'validate' event 35.206 + $.event.trigger('form.submit.validate', [a, this, options, veto]); 35.207 + if (veto.veto) return this; 35.208 + 35.209 + var q = $.param(a);//.replace(/%20/g,'+'); 35.210 + 35.211 + if (options.type.toUpperCase() == 'GET') { 35.212 + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; 35.213 + options.data = null; // data is null for 'get' 35.214 + } 35.215 + else 35.216 + options.data = q; // data is the query string for 'post' 35.217 + 35.218 + var $form = this, callbacks = []; 35.219 + if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); 35.220 + if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); 35.221 + 35.222 + // perform a load on the target only if dataType is not provided 35.223 + if (!options.dataType && options.target) { 35.224 + var oldSuccess = options.success || function(){}; 35.225 + callbacks.push(function(data) { 35.226 + if (this.evalScripts) 35.227 + $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments); 35.228 + else // jQuery v1.1.4 35.229 + $(options.target).html(data).each(oldSuccess, arguments); 35.230 + }); 35.231 + } 35.232 + else if (options.success) 35.233 + callbacks.push(options.success); 35.234 + 35.235 + options.success = function(data, status) { 35.236 + for (var i=0, max=callbacks.length; i < max; i++) 35.237 + callbacks[i](data, status, $form); 35.238 + }; 35.239 + 35.240 + // are there files to upload? 35.241 + var files = $('input:file', this).fieldValue(); 35.242 + var found = false; 35.243 + for (var j=0; j < files.length; j++) 35.244 + if (files[j]) 35.245 + found = true; 35.246 + 35.247 + if (options.iframe || found) // options.iframe allows user to force iframe mode 35.248 + fileUpload(); 35.249 + else 35.250 + $.ajax(options); 35.251 + 35.252 + // fire 'notify' event 35.253 + $.event.trigger('form.submit.notify', [this, options]); 35.254 + return this; 35.255 + 35.256 + 35.257 + // private function for handling file uploads (hat tip to YAHOO!) 35.258 + function fileUpload() { 35.259 + var form = $form[0]; 35.260 + var opts = $.extend({}, $.ajaxSettings, options); 35.261 + 35.262 + var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++; 35.263 + var $io = $('<iframe id="' + id + '" name="' + id + '" />'); 35.264 + var io = $io[0]; 35.265 + var op8 = $.browser.opera && window.opera.version() < 9; 35.266 + if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");'; 35.267 + $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); 35.268 + 35.269 + var xhr = { // mock object 35.270 + responseText: null, 35.271 + responseXML: null, 35.272 + status: 0, 35.273 + statusText: 'n/a', 35.274 + getAllResponseHeaders: function() {}, 35.275 + getResponseHeader: function() {}, 35.276 + setRequestHeader: function() {} 35.277 + }; 35.278 + 35.279 + var g = opts.global; 35.280 + // trigger ajax global events so that activity/block indicators work like normal 35.281 + if (g && ! $.active++) $.event.trigger("ajaxStart"); 35.282 + if (g) $.event.trigger("ajaxSend", [xhr, opts]); 35.283 + 35.284 + var cbInvoked = 0; 35.285 + var timedOut = 0; 35.286 + 35.287 + // take a breath so that pending repaints get some cpu time before the upload starts 35.288 + setTimeout(function() { 35.289 + $io.appendTo('body'); 35.290 + // jQuery's event binding doesn't work for iframe events in IE 35.291 + io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); 35.292 + 35.293 + // make sure form attrs are set 35.294 + var encAttr = form.encoding ? 'encoding' : 'enctype'; 35.295 + var t = $form.attr('target'); 35.296 + $form.attr({ 35.297 + target: id, 35.298 + method: 'POST', 35.299 + action: opts.url 35.300 + }); 35.301 + form[encAttr] = 'multipart/form-data'; 35.302 + 35.303 + // support timout 35.304 + if (opts.timeout) 35.305 + setTimeout(function() { timedOut = true; cb(); }, opts.timeout); 35.306 + 35.307 + form.submit(); 35.308 + $form.attr('target', t); // reset target 35.309 + }, 10); 35.310 + 35.311 + function cb() { 35.312 + if (cbInvoked++) return; 35.313 + 35.314 + io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); 35.315 + 35.316 + var ok = true; 35.317 + try { 35.318 + if (timedOut) throw 'timeout'; 35.319 + // extract the server response from the iframe 35.320 + var data, doc; 35.321 + doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; 35.322 + xhr.responseText = doc.body ? doc.body.innerHTML : null; 35.323 + xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; 35.324 + 35.325 + if (opts.dataType == 'json' || opts.dataType == 'script') { 35.326 + var ta = doc.getElementsByTagName('textarea')[0]; 35.327 + data = ta ? ta.value : xhr.responseText; 35.328 + if (opts.dataType == 'json') 35.329 + eval("data = " + data); 35.330 + else 35.331 + $.globalEval(data); 35.332 + } 35.333 + else if (opts.dataType == 'xml') { 35.334 + data = xhr.responseXML; 35.335 + if (!data && xhr.responseText != null) 35.336 + data = toXml(xhr.responseText); 35.337 + } 35.338 + else { 35.339 + data = xhr.responseText; 35.340 + } 35.341 + } 35.342 + catch(e){ 35.343 + ok = false; 35.344 + $.handleError(opts, xhr, 'error', e); 35.345 + } 35.346 + 35.347 + // ordering of these callbacks/triggers is odd, but that's how $.ajax does it 35.348 + if (ok) { 35.349 + opts.success(data, 'success'); 35.350 + if (g) $.event.trigger("ajaxSuccess", [xhr, opts]); 35.351 + } 35.352 + if (g) $.event.trigger("ajaxComplete", [xhr, opts]); 35.353 + if (g && ! --$.active) $.event.trigger("ajaxStop"); 35.354 + if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error'); 35.355 + 35.356 + // clean up 35.357 + setTimeout(function() { 35.358 + $io.remove(); 35.359 + xhr.responseXML = null; 35.360 + }, 100); 35.361 + }; 35.362 + 35.363 + function toXml(s, doc) { 35.364 + if (window.ActiveXObject) { 35.365 + doc = new ActiveXObject('Microsoft.XMLDOM'); 35.366 + doc.async = 'false'; 35.367 + doc.loadXML(s); 35.368 + } 35.369 + else 35.370 + doc = (new DOMParser()).parseFromString(s, 'text/xml'); 35.371 + return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null; 35.372 + }; 35.373 + }; 35.374 +}; 35.375 +$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids 35.376 + 35.377 +/** 35.378 + * ajaxForm() provides a mechanism for fully automating form submission. 35.379 + * 35.380 + * The advantages of using this method instead of ajaxSubmit() are: 35.381 + * 35.382 + * 1: This method will include coordinates for <input type="image" /> elements (if the element 35.383 + * is used to submit the form). 35.384 + * 2. This method will include the submit element's name/value data (for the element that was 35.385 + * used to submit the form). 35.386 + * 3. This method binds the submit() method to the form for you. 35.387 + * 35.388 + * Note that for accurate x/y coordinates of image submit elements in all browsers 35.389 + * you need to also use the "dimensions" plugin (this method will auto-detect its presence). 35.390 + * 35.391 + * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely 35.392 + * passes the options argument along after properly binding events for submit elements and 35.393 + * the form itself. See ajaxSubmit for a full description of the options argument. 35.394 + * 35.395 + * 35.396 + * @example 35.397 + * var options = { 35.398 + * target: '#myTargetDiv' 35.399 + * }; 35.400 + * $('#myForm').ajaxSForm(options); 35.401 + * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response 35.402 + * when the form is submitted. 35.403 + * 35.404 + * 35.405 + * @example 35.406 + * var options = { 35.407 + * success: function(responseText) { 35.408 + * alert(responseText); 35.409 + * } 35.410 + * }; 35.411 + * $('#myForm').ajaxSubmit(options); 35.412 + * @desc Bind form's submit event so that server response is alerted after the form is submitted. 35.413 + * 35.414 + * 35.415 + * @example 35.416 + * var options = { 35.417 + * beforeSubmit: function(formArray, jqForm) { 35.418 + * if (formArray.length == 0) { 35.419 + * alert('Please enter data.'); 35.420 + * return false; 35.421 + * } 35.422 + * } 35.423 + * }; 35.424 + * $('#myForm').ajaxSubmit(options); 35.425 + * @desc Bind form's submit event so that pre-submit callback is invoked before the form 35.426 + * is submitted. 35.427 + * 35.428 + * 35.429 + * @name ajaxForm 35.430 + * @param options object literal containing options which control the form submission process 35.431 + * @return jQuery 35.432 + * @cat Plugins/Form 35.433 + * @type jQuery 35.434 + */ 35.435 +$.fn.ajaxForm = function(options) { 35.436 + return this.ajaxFormUnbind().submit(submitHandler).each(function() { 35.437 + // store options in hash 35.438 + this.formPluginId = $.fn.ajaxForm.counter++; 35.439 + $.fn.ajaxForm.optionHash[this.formPluginId] = options; 35.440 + $(":submit,input:image", this).click(clickHandler); 35.441 + }); 35.442 +}; 35.443 + 35.444 +$.fn.ajaxForm.counter = 1; 35.445 +$.fn.ajaxForm.optionHash = {}; 35.446 + 35.447 +function clickHandler(e) { 35.448 + var $form = this.form; 35.449 + $form.clk = this; 35.450 + if (this.type == 'image') { 35.451 + if (e.offsetX != undefined) { 35.452 + $form.clk_x = e.offsetX; 35.453 + $form.clk_y = e.offsetY; 35.454 + } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin 35.455 + var offset = $(this).offset(); 35.456 + $form.clk_x = e.pageX - offset.left; 35.457 + $form.clk_y = e.pageY - offset.top; 35.458 + } else { 35.459 + $form.clk_x = e.pageX - this.offsetLeft; 35.460 + $form.clk_y = e.pageY - this.offsetTop; 35.461 + } 35.462 + } 35.463 + // clear form vars 35.464 + setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10); 35.465 +}; 35.466 + 35.467 +function submitHandler() { 35.468 + // retrieve options from hash 35.469 + var id = this.formPluginId; 35.470 + var options = $.fn.ajaxForm.optionHash[id]; 35.471 + $(this).ajaxSubmit(options); 35.472 + return false; 35.473 +}; 35.474 + 35.475 +/** 35.476 + * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 35.477 + * 35.478 + * @name ajaxFormUnbind 35.479 + * @return jQuery 35.480 + * @cat Plugins/Form 35.481 + * @type jQuery 35.482 + */ 35.483 +$.fn.ajaxFormUnbind = function() { 35.484 + this.unbind('submit', submitHandler); 35.485 + return this.each(function() { 35.486 + $(":submit,input:image", this).unbind('click', clickHandler); 35.487 + }); 35.488 + 35.489 +}; 35.490 + 35.491 +/** 35.492 + * formToArray() gathers form element data into an array of objects that can 35.493 + * be passed to any of the following ajax functions: $.get, $.post, or load. 35.494 + * Each object in the array has both a 'name' and 'value' property. An example of 35.495 + * an array for a simple login form might be: 35.496 + * 35.497 + * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 35.498 + * 35.499 + * It is this array that is passed to pre-submit callback functions provided to the 35.500 + * ajaxSubmit() and ajaxForm() methods. 35.501 + * 35.502 + * The semantic argument can be used to force form serialization in semantic order. 35.503 + * This is normally true anyway, unless the form contains input elements of type='image'. 35.504 + * If your form must be submitted with name/value pairs in semantic order and your form 35.505 + * contains an input of type='image" then pass true for this arg, otherwise pass false 35.506 + * (or nothing) to avoid the overhead for this logic. 35.507 + * 35.508 + * @example var data = $("#myForm").formToArray(); 35.509 + * $.post( "myscript.cgi", data ); 35.510 + * @desc Collect all the data from a form and submit it to the server. 35.511 + * 35.512 + * @name formToArray 35.513 + * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) 35.514 + * @type Array<Object> 35.515 + * @cat Plugins/Form 35.516 + */ 35.517 +$.fn.formToArray = function(semantic) { 35.518 + var a = []; 35.519 + if (this.length == 0) return a; 35.520 + 35.521 + var form = this[0]; 35.522 + var els = semantic ? form.getElementsByTagName('*') : form.elements; 35.523 + if (!els) return a; 35.524 + for(var i=0, max=els.length; i < max; i++) { 35.525 + var el = els[i]; 35.526 + var n = el.name; 35.527 + if (!n) continue; 35.528 + 35.529 + if (semantic && form.clk && el.type == "image") { 35.530 + // handle image inputs on the fly when semantic == true 35.531 + if(!el.disabled && form.clk == el) 35.532 + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 35.533 + continue; 35.534 + } 35.535 + 35.536 + var v = $.fieldValue(el, true); 35.537 + if (v && v.constructor == Array) { 35.538 + for(var j=0, jmax=v.length; j < jmax; j++) 35.539 + a.push({name: n, value: v[j]}); 35.540 + } 35.541 + else if (v !== null && typeof v != 'undefined') 35.542 + a.push({name: n, value: v}); 35.543 + } 35.544 + 35.545 + if (!semantic && form.clk) { 35.546 + // input type=='image' are not found in elements array! handle them here 35.547 + var inputs = form.getElementsByTagName("input"); 35.548 + for(var i=0, max=inputs.length; i < max; i++) { 35.549 + var input = inputs[i]; 35.550 + var n = input.name; 35.551 + if(n && !input.disabled && input.type == "image" && form.clk == input) 35.552 + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 35.553 + } 35.554 + } 35.555 + return a; 35.556 +}; 35.557 + 35.558 + 35.559 +/** 35.560 + * Serializes form data into a 'submittable' string. This method will return a string 35.561 + * in the format: name1=value1&name2=value2 35.562 + * 35.563 + * The semantic argument can be used to force form serialization in semantic order. 35.564 + * If your form must be submitted with name/value pairs in semantic order then pass 35.565 + * true for this arg, otherwise pass false (or nothing) to avoid the overhead for 35.566 + * this logic (which can be significant for very large forms). 35.567 + * 35.568 + * @example var data = $("#myForm").formSerialize(); 35.569 + * $.ajax('POST', "myscript.cgi", data); 35.570 + * @desc Collect all the data from a form into a single string 35.571 + * 35.572 + * @name formSerialize 35.573 + * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) 35.574 + * @type String 35.575 + * @cat Plugins/Form 35.576 + */ 35.577 +$.fn.formSerialize = function(semantic) { 35.578 + //hand off to jQuery.param for proper encoding 35.579 + return $.param(this.formToArray(semantic)); 35.580 +}; 35.581 + 35.582 + 35.583 +/** 35.584 + * Serializes all field elements in the jQuery object into a query string. 35.585 + * This method will return a string in the format: name1=value1&name2=value2 35.586 + * 35.587 + * The successful argument controls whether or not serialization is limited to 35.588 + * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 35.589 + * The default value of the successful argument is true. 35.590 + * 35.591 + * @example var data = $("input").formSerialize(); 35.592 + * @desc Collect the data from all successful input elements into a query string 35.593 + * 35.594 + * @example var data = $(":radio").formSerialize(); 35.595 + * @desc Collect the data from all successful radio input elements into a query string 35.596 + * 35.597 + * @example var data = $("#myForm :checkbox").formSerialize(); 35.598 + * @desc Collect the data from all successful checkbox input elements in myForm into a query string 35.599 + * 35.600 + * @example var data = $("#myForm :checkbox").formSerialize(false); 35.601 + * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string 35.602 + * 35.603 + * @example var data = $(":input").formSerialize(); 35.604 + * @desc Collect the data from all successful input, select, textarea and button elements into a query string 35.605 + * 35.606 + * @name fieldSerialize 35.607 + * @param successful true if only successful controls should be serialized (default is true) 35.608 + * @type String 35.609 + * @cat Plugins/Form 35.610 + */ 35.611 +$.fn.fieldSerialize = function(successful) { 35.612 + var a = []; 35.613 + this.each(function() { 35.614 + var n = this.name; 35.615 + if (!n) return; 35.616 + var v = $.fieldValue(this, successful); 35.617 + if (v && v.constructor == Array) { 35.618 + for (var i=0,max=v.length; i < max; i++) 35.619 + a.push({name: n, value: v[i]}); 35.620 + } 35.621 + else if (v !== null && typeof v != 'undefined') 35.622 + a.push({name: this.name, value: v}); 35.623 + }); 35.624 + //hand off to jQuery.param for proper encoding 35.625 + return $.param(a); 35.626 +}; 35.627 + 35.628 + 35.629 +/** 35.630 + * Returns the value(s) of the element in the matched set. For example, consider the following form: 35.631 + * 35.632 + * <form><fieldset> 35.633 + * <input name="A" type="text" /> 35.634 + * <input name="A" type="text" /> 35.635 + * <input name="B" type="checkbox" value="B1" /> 35.636 + * <input name="B" type="checkbox" value="B2"/> 35.637 + * <input name="C" type="radio" value="C1" /> 35.638 + * <input name="C" type="radio" value="C2" /> 35.639 + * </fieldset></form> 35.640 + * 35.641 + * var v = $(':text').fieldValue(); 35.642 + * // if no values are entered into the text inputs 35.643 + * v == ['',''] 35.644 + * // if values entered into the text inputs are 'foo' and 'bar' 35.645 + * v == ['foo','bar'] 35.646 + * 35.647 + * var v = $(':checkbox').fieldValue(); 35.648 + * // if neither checkbox is checked 35.649 + * v === undefined 35.650 + * // if both checkboxes are checked 35.651 + * v == ['B1', 'B2'] 35.652 + * 35.653 + * var v = $(':radio').fieldValue(); 35.654 + * // if neither radio is checked 35.655 + * v === undefined 35.656 + * // if first radio is checked 35.657 + * v == ['C1'] 35.658 + * 35.659 + * The successful argument controls whether or not the field element must be 'successful' 35.660 + * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 35.661 + * The default value of the successful argument is true. If this value is false the value(s) 35.662 + * for each element is returned. 35.663 + * 35.664 + * Note: This method *always* returns an array. If no valid value can be determined the 35.665 + * array will be empty, otherwise it will contain one or more values. 35.666 + * 35.667 + * @example var data = $("#myPasswordElement").fieldValue(); 35.668 + * alert(data[0]); 35.669 + * @desc Alerts the current value of the myPasswordElement element 35.670 + * 35.671 + * @example var data = $("#myForm :input").fieldValue(); 35.672 + * @desc Get the value(s) of the form elements in myForm 35.673 + * 35.674 + * @example var data = $("#myForm :checkbox").fieldValue(); 35.675 + * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object. 35.676 + * 35.677 + * @example var data = $("#mySingleSelect").fieldValue(); 35.678 + * @desc Get the value(s) of the select control 35.679 + * 35.680 + * @example var data = $(':text').fieldValue(); 35.681 + * @desc Get the value(s) of the text input or textarea elements 35.682 + * 35.683 + * @example var data = $("#myMultiSelect").fieldValue(); 35.684 + * @desc Get the values for the select-multiple control 35.685 + * 35.686 + * @name fieldValue 35.687 + * @param Boolean successful true if only the values for successful controls should be returned (default is true) 35.688 + * @type Array<String> 35.689 + * @cat Plugins/Form 35.690 + */ 35.691 +$.fn.fieldValue = function(successful) { 35.692 + for (var val=[], i=0, max=this.length; i < max; i++) { 35.693 + var el = this[i]; 35.694 + var v = $.fieldValue(el, successful); 35.695 + if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) 35.696 + continue; 35.697 + v.constructor == Array ? $.merge(val, v) : val.push(v); 35.698 + } 35.699 + return val; 35.700 +}; 35.701 + 35.702 +/** 35.703 + * Returns the value of the field element. 35.704 + * 35.705 + * The successful argument controls whether or not the field element must be 'successful' 35.706 + * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 35.707 + * The default value of the successful argument is true. If the given element is not 35.708 + * successful and the successful arg is not false then the returned value will be null. 35.709 + * 35.710 + * Note: If the successful flag is true (default) but the element is not successful, the return will be null 35.711 + * Note: The value returned for a successful select-multiple element will always be an array. 35.712 + * Note: If the element has no value the return value will be undefined. 35.713 + * 35.714 + * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]); 35.715 + * @desc Gets the current value of the myPasswordElement element 35.716 + * 35.717 + * @name fieldValue 35.718 + * @param Element el The DOM element for which the value will be returned 35.719 + * @param Boolean successful true if value returned must be for a successful controls (default is true) 35.720 + * @type String or Array<String> or null or undefined 35.721 + * @cat Plugins/Form 35.722 + */ 35.723 +$.fieldValue = function(el, successful) { 35.724 + var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); 35.725 + if (typeof successful == 'undefined') successful = true; 35.726 + 35.727 + if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || 35.728 + (t == 'checkbox' || t == 'radio') && !el.checked || 35.729 + (t == 'submit' || t == 'image') && el.form && el.form.clk != el || 35.730 + tag == 'select' && el.selectedIndex == -1)) 35.731 + return null; 35.732 + 35.733 + if (tag == 'select') { 35.734 + var index = el.selectedIndex; 35.735 + if (index < 0) return null; 35.736 + var a = [], ops = el.options; 35.737 + var one = (t == 'select-one'); 35.738 + var max = (one ? index+1 : ops.length); 35.739 + for(var i=(one ? index : 0); i < max; i++) { 35.740 + var op = ops[i]; 35.741 + if (op.selected) { 35.742 + // extra pain for IE... 35.743 + var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value; 35.744 + if (one) return v; 35.745 + a.push(v); 35.746 + } 35.747 + } 35.748 + return a; 35.749 + } 35.750 + return el.value; 35.751 +}; 35.752 + 35.753 + 35.754 +/** 35.755 + * Clears the form data. Takes the following actions on the form's input fields: 35.756 + * - input text fields will have their 'value' property set to the empty string 35.757 + * - select elements will have their 'selectedIndex' property set to -1 35.758 + * - checkbox and radio inputs will have their 'checked' property set to false 35.759 + * - inputs of type submit, button, reset, and hidden will *not* be effected 35.760 + * - button elements will *not* be effected 35.761 + * 35.762 + * @example $('form').clearForm(); 35.763 + * @desc Clears all forms on the page. 35.764 + * 35.765 + * @name clearForm 35.766 + * @type jQuery 35.767 + * @cat Plugins/Form 35.768 + */ 35.769 +$.fn.clearForm = function() { 35.770 + return this.each(function() { 35.771 + $('input,select,textarea', this).clearFields(); 35.772 + }); 35.773 +}; 35.774 + 35.775 +/** 35.776 + * Clears the selected form elements. Takes the following actions on the matched elements: 35.777 + * - input text fields will have their 'value' property set to the empty string 35.778 + * - select elements will have their 'selectedIndex' property set to -1 35.779 + * - checkbox and radio inputs will have their 'checked' property set to false 35.780 + * - inputs of type submit, button, reset, and hidden will *not* be effected 35.781 + * - button elements will *not* be effected 35.782 + * 35.783 + * @example $('.myInputs').clearFields(); 35.784 + * @desc Clears all inputs with class myInputs 35.785 + * 35.786 + * @name clearFields 35.787 + * @type jQuery 35.788 + * @cat Plugins/Form 35.789 + */ 35.790 +$.fn.clearFields = $.fn.clearInputs = function() { 35.791 + return this.each(function() { 35.792 + var t = this.type, tag = this.tagName.toLowerCase(); 35.793 + if (t == 'text' || t == 'password' || tag == 'textarea') 35.794 + this.value = ''; 35.795 + else if (t == 'checkbox' || t == 'radio') 35.796 + this.checked = false; 35.797 + else if (tag == 'select') 35.798 + this.selectedIndex = -1; 35.799 + }); 35.800 +}; 35.801 + 35.802 + 35.803 +/** 35.804 + * Resets the form data. Causes all form elements to be reset to their original value. 35.805 + * 35.806 + * @example $('form').resetForm(); 35.807 + * @desc Resets all forms on the page. 35.808 + * 35.809 + * @name resetForm 35.810 + * @type jQuery 35.811 + * @cat Plugins/Form 35.812 + */ 35.813 +$.fn.resetForm = function() { 35.814 + return this.each(function() { 35.815 + // guard against an input with the name of 'reset' 35.816 + // note that IE reports the reset function as an 'object' 35.817 + if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) 35.818 + this.reset(); 35.819 + }); 35.820 +}; 35.821 + 35.822 +})(jQuery);
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/web/javascript/hsbook.js Tue Mar 10 21:42:19 2009 -0700 36.3 @@ -0,0 +1,91 @@ 36.4 +function qid(id) { 36.5 + return id.replace(/([.:])/g, "\\$1"); 36.6 +} 36.7 + 36.8 +function beforeComment(formData, jqForm, options) { 36.9 + var form = jqForm[0]; 36.10 + if (!form.comment.value) { 36.11 + $(options.target + " span.comment_error").empty().append( 36.12 + "<span class=\"comment_error\">Your comment is empty</span>"); 36.13 + return false; 36.14 + } 36.15 + if (!form.name.value) { 36.16 + $(options.target + " span.comment_error").empty().append( 36.17 + "<span class=\"comment_error\">Please provide a name</span>"); 36.18 + return false; 36.19 + } 36.20 + $(options.target + " span.comment_error").empty().after( 36.21 + "<img src=\"figs/throbber.gif\" style=\"vertical-align: middle\"/>"); 36.22 + $(options.target + " input[@name=submit]").attr("disabled", true); 36.23 +} 36.24 + 36.25 +function ajaxifyForm(id) { 36.26 + var q = qid(id); 36.27 + 36.28 + $("#form_" + q).ajaxForm({ beforeSubmit: beforeComment, 36.29 + success: function() { ajaxifyForm(id); }, 36.30 + target: "#comments_" + q }); 36.31 +} 36.32 + 36.33 +function toggleComment(id) { 36.34 + $("#toggle_" + qid(id)).nextAll().toggle(); 36.35 + return false; 36.36 +} 36.37 + 36.38 +function loadComments(id) { 36.39 + $("#comments_" + qid(id)).load(location.protocol + "//" + location.host + 36.40 + "/comments/single/" + id + "/", function() { 36.41 + ajaxifyForm(id); 36.42 + }); 36.43 + return false; 36.44 +} 36.45 + 36.46 +function loadAllComments() { 36.47 + $("a.commenttoggle").each(function() { 36.48 + var id = $(this).attr("pid"); 36.49 + if (id) { 36.50 + loadComments(id); 36.51 + } 36.52 + }); 36.53 +} 36.54 + 36.55 +$(document).ready(function() { 36.56 + function loading(id) { 36.57 + return " <span id=\"comments_" + id + "\" class=\"comment\">" + 36.58 + "<span pid=\"" + id + "\" class=\"commenttoggle\">Loading..." + 36.59 + "</span></span>"; 36.60 + } 36.61 + $("div.toc>p") 36.62 + .after("<p style='display: none;'><a onclick='return loadAllComments()'>" + 36.63 + "Load all comments (<b>slow</b>)</a></p>") 36.64 + .toggle(function() { $(this).nextAll().show("normal"); }, 36.65 + function() { $(this).nextAll().hide("normal"); }) 36.66 + .hover(function() { $(this).fadeTo("normal", 0.8); }, 36.67 + function() { $(this).fadeTo("normal", 0.35); }); 36.68 + $("p[@id]").each(function() { 36.69 + $(this).append(loading($(this).attr("id"))); 36.70 + }); 36.71 + $("pre[@id]").each(function() { 36.72 + $(this).after(loading($(this).attr("id"))); 36.73 + }); 36.74 + var chapid = $("div.preface, div.chapter, div.appendix, div.bibliography").attr("id"); 36.75 + $("#chapterfeed").attr("href", 36.76 + $("#chapterfeed").attr("href") + chapid + "/"); 36.77 + $.getJSON(location.protocol + "//" + location.host + "/comments/chapter/" + 36.78 + chapid + "/count/", function(data) { 36.79 + $.each(data, function(id, item) { 36.80 + var s = item == 1 ? "" : "s"; 36.81 + $("#comments_" + qid(id) + " span.commenttoggle").replaceWith( 36.82 + "<a class='commenttoggle' id='toggle_" + id + "' " + 36.83 + "pid='" + id + "' " + 36.84 + "onclick='return loadComments(\"" + id + "\")' " + 36.85 + "href='comments: show / hide'>" + item + " comment" + s + "</a>"); 36.86 + }); 36.87 + $("span.commenttoggle").each(function() { 36.88 + var id = $(this).attr("pid"); 36.89 + $(this).replaceWith("<a class='commenttoggle' id='toggle_" + id + "' " + 36.90 + "onclick='return loadComments(\"" + id + "\")' " + 36.91 + "href='comment: add'>No comments</a>"); 36.92 + }); 36.93 + }); 36.94 +});
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/web/javascript/jquery-min.js Tue Mar 10 21:42:19 2009 -0700 37.3 @@ -0,0 +1,31 @@ 37.4 +/* 37.5 + * jQuery 1.2.1 - New Wave Javascript 37.6 + * 37.7 + * Copyright (c) 2007 John Resig (jquery.com) 37.8 + * Dual licensed under the MIT (MIT-LICENSE.txt) 37.9 + * and GPL (GPL-LICENSE.txt) licenses. 37.10 + * 37.11 + * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ 37.12 + * $Rev: 3353 $ 37.13 + */ 37.14 +(function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;this.length=1;return this;}else 37.15 +selector=[];}}else 37.16 +return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},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,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]: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){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(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],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){var val=jQuery.browser.msie&&!option.attributes["value"].specified?option.text:option.value;if(one)return val;a.push(val);}}return a;}else 37.17 +return this[0].value.replace(/\r/g,"");}}else 37.18 +return this.each(function(){if(val.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,val)>=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else 37.19 +this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else 37.20 +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a<al;a++)if((prop=arguments[a])!=null)for(var i in prop){if(target==prop[i])continue;if(deep&&typeof prop[i]=='object'&&target[i])jQuery.extend(target[i],prop[i]);else if(prop[i]!=undefined)target[i]=prop[i];}return target;};var expando="jQuery"+(new Date()).getTime(),uuid=0,win={};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/function/i.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){if(window.execScript)window.execScript(data);else if(jQuery.browser.safari)window.setTimeout(data,0);else 37.21 +eval.call(window,data);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?win: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?win: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(obj,fn,args){if(args){if(obj.length==undefined)for(var i in obj)fn.apply(obj[i],args);else 37.22 +for(var i=0,ol=obj.length;i<ol;i++)if(fn.apply(obj[i],args)===false)break;}else{if(obj.length==undefined)for(var i in obj)fn.call(obj[i],i,obj[i]);else 37.23 +for(var i=0,ol=obj.length,val=obj[0];i<ol&&fn.call(val,i,val)!==false;val=obj[++i]){}}return obj;},prop:function(elem,value,type,index,prop){if(jQuery.isFunction(value))value=value.call(elem,[index]);var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(prop)?value+"px":value;},className:{add:function(elem,c){jQuery.each((c||"").split(/\s+/),function(i,cur){if(!jQuery.className.has(elem.className,cur))elem.className+=(elem.className?" ":"")+cur;});},remove:function(elem,c){elem.className=c!=undefined?jQuery.grep(elem.className.split(/\s+/),function(cur){return!jQuery.className.has(c,cur);}).join(" "):"";},has:function(t,c){return jQuery.inArray(c,(t.className||t).toString().split(/\s+/))>-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a<stack.length;a++)if(color(stack[a])){swap[a]=stack[a].style.display;stack[a].style.display="block";}ret=prop=="display"&&swap[stack.length-1]!=null?"none":document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop)||"";for(a=0;a<swap.length;a++)if(swap[a]!=null)stack[a].style.display=swap[a];}if(prop=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var newProp=prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});ret=elem.currentStyle[prop]||elem.currentStyle[newProp];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var style=elem.style.left;var runtimeStyle=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;elem.style.left=ret||0;ret=elem.style.pixelLeft+"px";elem.style.left=style;elem.runtimeStyle.left=runtimeStyle;}}return ret;},clean:function(a,doc){var r=[];doc=doc||document;jQuery.each(a,function(i,arg){if(!arg)return;if(arg.constructor==Number)arg=arg.toString();if(typeof arg=="string"){arg=arg.replace(/(<(\w+)[^>]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+"></"+tag+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("<opt")&&[1,"<select>","</select>"]||!s.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!s.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!s.indexOf("<td")||!s.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!s.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf("<table")&&s.indexOf("<tbody")<0)tb=div.firstChild&&div.firstChild.childNodes;else if(wrap[1]=="<table>"&&s.indexOf("<tbody")<0)tb=div.childNodes;for(var n=tb.length-1;n>=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else 37.24 +r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");},makeArray:function(a){var r=[];if(typeof a!="array")for(var i=0,al=a.length;i<al;i++)r.push(a[i]);else 37.25 +r=a.slice(0);return r;},inArray:function(b,a){for(var i=0,al=a.length;i<al;i++)if(a[i]==b)return i;return-1;},merge:function(first,second){if(jQuery.browser.msie){for(var i=0;second[i];i++)if(second[i].nodeType!=8)first.push(second[i]);}else 37.26 +for(var i=0;second[i];i++)first.push(second[i]);return first;},unique:function(first){var r=[],done={};try{for(var i=0,fl=first.length;i<fl;i++){var id=jQuery.data(first[i]);if(!done[id]){done[id]=true;r.push(first[i]);}}}catch(e){r=first;}return r;},grep:function(elems,fn,inv){if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+"}");var result=[];for(var i=0,el=elems.length;i<el;i++)if(!inv&&fn(elems[i],i)||inv&&!fn(elems[i],i))result.push(elems[i]);return result;},map:function(elems,fn){if(typeof fn=="string")fn=eval("false||function(a){return "+fn+"}");var result=[];for(var i=0,el=elems.length;i<el;i++){var val=fn(elems[i],i);if(val!==null&&val!=undefined){if(val.constructor!=Array)val=[val];result=result.concat(val);}}return result;}});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.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",styleFloat:jQuery.browser.msie?"styleFloat":"cssFloat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,innerHTML:"innerHTML",className:"className",value:"value",disabled:"disabled",checked:"checked",readonly:"readOnly",selected:"selected",maxlength:"maxLength"}});jQuery.each({parent:"a.parentNode",parents:"jQuery.dir(a,'parentNode')",next:"jQuery.nth(a,2,'nextSibling')",prev:"jQuery.nth(a,2,'previousSibling')",nextAll:"jQuery.dir(a,'nextSibling')",prevAll:"jQuery.dir(a,'previousSibling')",siblings:"jQuery.sibling(a.parentNode.firstChild,a)",children:"jQuery.sibling(a.firstChild)",contents:"jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"},function(i,n){jQuery.fn[i]=function(a){var ret=jQuery.map(this,n);if(a&&typeof a=="string")ret=jQuery.multiFilter(a,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(i,n){jQuery.fn[i]=function(){var a=arguments;return this.each(function(){for(var j=0,al=a.length;j<al;j++)jQuery(a[j])[n](this);});};});jQuery.each({removeAttr:function(key){jQuery.attr(this,key,"");this.removeAttribute(key);},addClass:function(c){jQuery.className.add(this,c);},removeClass:function(c){jQuery.className.remove(this,c);},toggleClass:function(c){jQuery.className[jQuery.className.has(this,c)?"remove":"add"](this,c);},remove:function(a){if(!a||jQuery.filter(a,[this]).r.length){jQuery.removeData(this);this.parentNode.removeChild(this);}},empty:function(){jQuery("*",this).each(function(){jQuery.removeData(this);});while(this.firstChild)this.removeChild(this.firstChild);}},function(i,n){jQuery.fn[i]=function(){return this.each(n,arguments);};});jQuery.each(["Height","Width"],function(i,name){var n=name.toLowerCase();jQuery.fn[n]=function(h){return this[0]==window?jQuery.browser.safari&&self["inner"+name]||jQuery.boxModel&&Math.max(document.documentElement["client"+name],document.body["client"+name])||document.body["client"+name]:this[0]==document?Math.max(document.body["scroll"+name],document.body["offset"+name]):h==undefined?(this.length?jQuery.css(this[0],n):null):this.css(n,h.constructor==String?h:h+"px");};});var chars=jQuery.browser.safari&&parseInt(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:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"i<m[3]-0",gt:"i>m[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"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)context=null;context=context||document;var ret=[context],done=[],last;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){var 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&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName.toUpperCase()))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 nodeName=m[2],merge={};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.toUpperCase()){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.msie||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=jQuery.filter(m[3],r,true).r;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])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-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.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==1){if(last==0||node.nodeIndex==last)add=true;}else if((node.nodeIndex+last)%first==0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var f=jQuery.expr[m[1]];if(typeof f!="string")f=jQuery.expr[m[1]][m[2]];f=eval("false||function(a,i){return "+f+"}");r=jQuery.grep(r,f,not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var 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&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(element,type,handler,data){if(jQuery.browser.msie&&element.setInterval!=undefined)element=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var parts=type.split(".");type=parts[0];handler.type=parts[1];var events=jQuery.data(element,"events")||jQuery.data(element,"events",{});var handle=jQuery.data(element,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(element,arguments);return val;});var handlers=events[type];if(!handlers){handlers=events[type]={};if(element.addEventListener)element.addEventListener(type,handle,false);else 37.27 +element.attachEvent("on"+type,handle);}handlers[handler.guid]=handler;this.global[type]=true;},guid:1,global:{},remove:function(element,type,handler){var events=jQuery.data(element,"events"),ret,index;if(typeof type=="string"){var parts=type.split(".");type=parts[0];}if(events){if(type&&type.type){handler=type.handler;type=type.type;}if(!type){for(type in events)this.remove(element,type);}else if(events[type]){if(handler)delete events[type][handler.guid];else 37.28 +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(element.removeEventListener)element.removeEventListener(type,jQuery.data(element,"handle"),false);else 37.29 +element.detachEvent("on"+type,jQuery.data(element,"handle"));ret=null;delete events[type];}}for(ret in events)break;if(!ret){jQuery.removeData(element,"events");jQuery.removeData(element,"handle");}}},trigger:function(type,data,element,donative,extra){data=jQuery.makeArray(data||[]);if(!element){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{var val,ret,fn=jQuery.isFunction(element[type]||null),evt=!data[0]||!data[0].preventDefault;if(evt)data.unshift(this.fix({type:type,target:element}));data[0].type=type;if(jQuery.isFunction(jQuery.data(element,"handle")))val=jQuery.data(element,"handle").apply(element,data);if(!fn&&element["on"+type]&&element["on"+type].apply(element,data)===false)val=false;if(evt)data.shift();if(extra&&extra.apply(element,data)===false)val=false;if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(element,'a')&&type=="click")){this.triggered=true;element[type]();}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var c=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in c){args[0].handler=c[j];args[0].data=c[j].data;if(!parts[1]||c[j].type==parts[1]){var tmp=c[j].apply(this,args);if(val!==false)val=tmp;if(tmp===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target&&event.srcElement)event.target=event.srcElement;if(jQuery.browser.safari&&event.target.nodeType==3)event.target=originalEvent.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 e=document.documentElement,b=document.body;event.pageX=event.clientX+(e&&e.scrollLeft||b.scrollLeft||0);event.pageY=event.clientY+(e&&e.scrollTop||b.scrollTop||0);}if(!event.which&&(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;}};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){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},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){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(){var a=arguments;return this.click(function(e){this.lastToggle=0==this.lastToggle?1:0;e.preventDefault();return a[this.lastToggle].apply(this,[e])||false;});},hover:function(f,g){function handleHover(e){var p=e.relatedTarget;while(p&&p!=this)try{p=p.parentNode;}catch(e){p=this;};if(p==this)return false;return(e.type=="mouseover"?f:g).apply(this,[e]);}return this.mouseover(handleHover).mouseout(handleHover);},ready:function(f){bindReady();if(jQuery.isReady)f.apply(document,[jQuery]);else 37.30 +jQuery.readyList.push(function(){return f.apply(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.apply(document);});jQuery.readyList=null;}if(jQuery.browser.mozilla||jQuery.browser.opera)document.removeEventListener("DOMContentLoaded",jQuery.ready,false);if(!window.frames.length)jQuery(window).load(function(){jQuery("#__ie_init").remove();});}}});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,o){jQuery.fn[o]=function(f){return f?this.bind(o,f):this.trigger(o);};});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(jQuery.browser.mozilla||jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);else if(jQuery.browser.msie){document.write("<scr"+"ipt id=__ie_init defer=true "+"src=//:><\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;jQuery.ready();};script=null;}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready();}},10);jQuery.event.add(window,"load",jQuery.ready);}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("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,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);setTimeout(function(){self.each(callback,[res.responseText,status,res]);},13);}});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=(new Date).getTime();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:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="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);s.url=s.url.replace(jsre,"="+jsonp);s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get")s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if(!s.url.indexOf("http")&&s.dataType=="script"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(!jsonp&&(s.success||s.complete)){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async);if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else 37.31 +jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();return xml;function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";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 37.32 +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else 37.33 +s.push(encodeURIComponent(j)+"="+encodeURIComponent(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?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block";}).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");if(this.oldblock=="none")this.oldblock="block";this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"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 opt=jQuery.speed(speed,easing,callback);return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);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 37.34 +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)){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.apply(this);}});},stop:function(){var timers=jQuery.timers;return this.each(function(){for(var i=0;i<timers.length;i++)if(timers[i].elem==this)timers.splice(i--,1);}).dequeue();}});var queue=function(elem,type,array){if(!elem)return;var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?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].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){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:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(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:[],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.apply(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.display="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.curCSS(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.css(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();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(){return self.step();}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timers.length==1){var timer=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(timer);},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();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(){var t=(new Date()).getTime();if(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&&jQuery.isFunction(this.options.complete))this.options.complete.apply(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.fx.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 absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));if(msie){var border=jQuery("html").css("borderWidth");border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;add(-border,-border);}}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2)border(offsetParent);if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute")absolute=true;offsetParent=offsetParent.offsetParent;}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if(safari2&&absolute)add(-doc.body.offsetLeft,-doc.body.offsetTop);}results={top:top,left:left};}return results;function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}};})(); 37.35 \ No newline at end of file
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/web/javascript/jquery.js Tue Mar 10 21:42:19 2009 -0700 38.3 @@ -0,0 +1,2992 @@ 38.4 +(function(){ 38.5 +/* 38.6 + * jQuery 1.2.1 - New Wave Javascript 38.7 + * 38.8 + * Copyright (c) 2007 John Resig (jquery.com) 38.9 + * Dual licensed under the MIT (MIT-LICENSE.txt) 38.10 + * and GPL (GPL-LICENSE.txt) licenses. 38.11 + * 38.12 + * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ 38.13 + * $Rev: 3353 $ 38.14 + */ 38.15 + 38.16 +// Map over jQuery in case of overwrite 38.17 +if ( typeof jQuery != "undefined" ) 38.18 + var _jQuery = jQuery; 38.19 + 38.20 +var jQuery = window.jQuery = function(selector, context) { 38.21 + // If the context is a namespace object, return a new object 38.22 + return this instanceof jQuery ? 38.23 + this.init(selector, context) : 38.24 + new jQuery(selector, context); 38.25 +}; 38.26 + 38.27 +// Map over the $ in case of overwrite 38.28 +if ( typeof $ != "undefined" ) 38.29 + var _$ = $; 38.30 + 38.31 +// Map the jQuery namespace to the '$' one 38.32 +window.$ = jQuery; 38.33 + 38.34 +var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; 38.35 + 38.36 +jQuery.fn = jQuery.prototype = { 38.37 + init: function(selector, context) { 38.38 + // Make sure that a selection was provided 38.39 + selector = selector || document; 38.40 + 38.41 + // Handle HTML strings 38.42 + if ( typeof selector == "string" ) { 38.43 + var m = quickExpr.exec(selector); 38.44 + if ( m && (m[1] || !context) ) { 38.45 + // HANDLE: $(html) -> $(array) 38.46 + if ( m[1] ) 38.47 + selector = jQuery.clean( [ m[1] ], context ); 38.48 + 38.49 + // HANDLE: $("#id") 38.50 + else { 38.51 + var tmp = document.getElementById( m[3] ); 38.52 + if ( tmp ) 38.53 + // Handle the case where IE and Opera return items 38.54 + // by name instead of ID 38.55 + if ( tmp.id != m[3] ) 38.56 + return jQuery().find( selector ); 38.57 + else { 38.58 + this[0] = tmp; 38.59 + this.length = 1; 38.60 + return this; 38.61 + } 38.62 + else 38.63 + selector = []; 38.64 + } 38.65 + 38.66 + // HANDLE: $(expr) 38.67 + } else 38.68 + return new jQuery( context ).find( selector ); 38.69 + 38.70 + // HANDLE: $(function) 38.71 + // Shortcut for document ready 38.72 + } else if ( jQuery.isFunction(selector) ) 38.73 + return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 38.74 + 38.75 + return this.setArray( 38.76 + // HANDLE: $(array) 38.77 + selector.constructor == Array && selector || 38.78 + 38.79 + // HANDLE: $(arraylike) 38.80 + // Watch for when an array-like object is passed as the selector 38.81 + (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) || 38.82 + 38.83 + // HANDLE: $(*) 38.84 + [ selector ] ); 38.85 + }, 38.86 + 38.87 + jquery: "1.2.1", 38.88 + 38.89 + size: function() { 38.90 + return this.length; 38.91 + }, 38.92 + 38.93 + length: 0, 38.94 + 38.95 + get: function( num ) { 38.96 + return num == undefined ? 38.97 + 38.98 + // Return a 'clean' array 38.99 + jQuery.makeArray( this ) : 38.100 + 38.101 + // Return just the object 38.102 + this[num]; 38.103 + }, 38.104 + 38.105 + pushStack: function( a ) { 38.106 + var ret = jQuery(a); 38.107 + ret.prevObject = this; 38.108 + return ret; 38.109 + }, 38.110 + 38.111 + setArray: function( a ) { 38.112 + this.length = 0; 38.113 + Array.prototype.push.apply( this, a ); 38.114 + return this; 38.115 + }, 38.116 + 38.117 + each: function( fn, args ) { 38.118 + return jQuery.each( this, fn, args ); 38.119 + }, 38.120 + 38.121 + index: function( obj ) { 38.122 + var pos = -1; 38.123 + this.each(function(i){ 38.124 + if ( this == obj ) pos = i; 38.125 + }); 38.126 + return pos; 38.127 + }, 38.128 + 38.129 + attr: function( key, value, type ) { 38.130 + var obj = key; 38.131 + 38.132 + // Look for the case where we're accessing a style value 38.133 + if ( key.constructor == String ) 38.134 + if ( value == undefined ) 38.135 + return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined; 38.136 + else { 38.137 + obj = {}; 38.138 + obj[ key ] = value; 38.139 + } 38.140 + 38.141 + // Check to see if we're setting style values 38.142 + return this.each(function(index){ 38.143 + // Set all the styles 38.144 + for ( var prop in obj ) 38.145 + jQuery.attr( 38.146 + type ? this.style : this, 38.147 + prop, jQuery.prop(this, obj[prop], type, index, prop) 38.148 + ); 38.149 + }); 38.150 + }, 38.151 + 38.152 + css: function( key, value ) { 38.153 + return this.attr( key, value, "curCSS" ); 38.154 + }, 38.155 + 38.156 + text: function(e) { 38.157 + if ( typeof e != "object" && e != null ) 38.158 + return this.empty().append( document.createTextNode( e ) ); 38.159 + 38.160 + var t = ""; 38.161 + jQuery.each( e || this, function(){ 38.162 + jQuery.each( this.childNodes, function(){ 38.163 + if ( this.nodeType != 8 ) 38.164 + t += this.nodeType != 1 ? 38.165 + this.nodeValue : jQuery.fn.text([ this ]); 38.166 + }); 38.167 + }); 38.168 + return t; 38.169 + }, 38.170 + 38.171 + wrapAll: function(html) { 38.172 + if ( this[0] ) 38.173 + // The elements to wrap the target around 38.174 + jQuery(html, this[0].ownerDocument) 38.175 + .clone() 38.176 + .insertBefore(this[0]) 38.177 + .map(function(){ 38.178 + var elem = this; 38.179 + while ( elem.firstChild ) 38.180 + elem = elem.firstChild; 38.181 + return elem; 38.182 + }) 38.183 + .append(this); 38.184 + 38.185 + return this; 38.186 + }, 38.187 + 38.188 + wrapInner: function(html) { 38.189 + return this.each(function(){ 38.190 + jQuery(this).contents().wrapAll(html); 38.191 + }); 38.192 + }, 38.193 + 38.194 + wrap: function(html) { 38.195 + return this.each(function(){ 38.196 + jQuery(this).wrapAll(html); 38.197 + }); 38.198 + }, 38.199 + 38.200 + append: function() { 38.201 + return this.domManip(arguments, true, 1, function(a){ 38.202 + this.appendChild( a ); 38.203 + }); 38.204 + }, 38.205 + 38.206 + prepend: function() { 38.207 + return this.domManip(arguments, true, -1, function(a){ 38.208 + this.insertBefore( a, this.firstChild ); 38.209 + }); 38.210 + }, 38.211 + 38.212 + before: function() { 38.213 + return this.domManip(arguments, false, 1, function(a){ 38.214 + this.parentNode.insertBefore( a, this ); 38.215 + }); 38.216 + }, 38.217 + 38.218 + after: function() { 38.219 + return this.domManip(arguments, false, -1, function(a){ 38.220 + this.parentNode.insertBefore( a, this.nextSibling ); 38.221 + }); 38.222 + }, 38.223 + 38.224 + end: function() { 38.225 + return this.prevObject || jQuery([]); 38.226 + }, 38.227 + 38.228 + find: function(t) { 38.229 + var data = jQuery.map(this, function(a){ return jQuery.find(t,a); }); 38.230 + return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ? 38.231 + jQuery.unique( data ) : data ); 38.232 + }, 38.233 + 38.234 + clone: function(events) { 38.235 + // Do the clone 38.236 + var ret = this.map(function(){ 38.237 + return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true); 38.238 + }); 38.239 + 38.240 + // Need to set the expando to null on the cloned set if it exists 38.241 + // removeData doesn't work here, IE removes it from the original as well 38.242 + // this is primarily for IE but the data expando shouldn't be copied over in any browser 38.243 + var clone = ret.find("*").andSelf().each(function(){ 38.244 + if ( this[ expando ] != undefined ) 38.245 + this[ expando ] = null; 38.246 + }); 38.247 + 38.248 + // Copy the events from the original to the clone 38.249 + if (events === true) 38.250 + this.find("*").andSelf().each(function(i) { 38.251 + var events = jQuery.data(this, "events"); 38.252 + for ( var type in events ) 38.253 + for ( var handler in events[type] ) 38.254 + jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data); 38.255 + }); 38.256 + 38.257 + // Return the cloned set 38.258 + return ret; 38.259 + }, 38.260 + 38.261 + filter: function(t) { 38.262 + return this.pushStack( 38.263 + jQuery.isFunction( t ) && 38.264 + jQuery.grep(this, function(el, index){ 38.265 + return t.apply(el, [index]); 38.266 + }) || 38.267 + 38.268 + jQuery.multiFilter(t,this) ); 38.269 + }, 38.270 + 38.271 + not: function(t) { 38.272 + return this.pushStack( 38.273 + t.constructor == String && 38.274 + jQuery.multiFilter(t, this, true) || 38.275 + 38.276 + jQuery.grep(this, function(a) { 38.277 + return ( t.constructor == Array || t.jquery ) 38.278 + ? jQuery.inArray( a, t ) < 0 38.279 + : a != t; 38.280 + }) 38.281 + ); 38.282 + }, 38.283 + 38.284 + add: function(t) { 38.285 + return this.pushStack( jQuery.merge( 38.286 + this.get(), 38.287 + t.constructor == String ? 38.288 + jQuery(t).get() : 38.289 + t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ? 38.290 + t : [t] ) 38.291 + ); 38.292 + }, 38.293 + 38.294 + is: function(expr) { 38.295 + return expr ? jQuery.multiFilter(expr,this).length > 0 : false; 38.296 + }, 38.297 + 38.298 + hasClass: function(expr) { 38.299 + return this.is("." + expr); 38.300 + }, 38.301 + 38.302 + val: function( val ) { 38.303 + if ( val == undefined ) { 38.304 + if ( this.length ) { 38.305 + var elem = this[0]; 38.306 + 38.307 + // We need to handle select boxes special 38.308 + if ( jQuery.nodeName(elem, "select") ) { 38.309 + var index = elem.selectedIndex, 38.310 + a = [], 38.311 + options = elem.options, 38.312 + one = elem.type == "select-one"; 38.313 + 38.314 + // Nothing was selected 38.315 + if ( index < 0 ) 38.316 + return null; 38.317 + 38.318 + // Loop through all the selected options 38.319 + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 38.320 + var option = options[i]; 38.321 + if ( option.selected ) { 38.322 + // Get the specifc value for the option 38.323 + var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value; 38.324 + 38.325 + // We don't need an array for one selects 38.326 + if ( one ) 38.327 + return val; 38.328 + 38.329 + // Multi-Selects return an array 38.330 + a.push(val); 38.331 + } 38.332 + } 38.333 + 38.334 + return a; 38.335 + 38.336 + // Everything else, we just grab the value 38.337 + } else 38.338 + return this[0].value.replace(/\r/g, ""); 38.339 + } 38.340 + } else 38.341 + return this.each(function(){ 38.342 + if ( val.constructor == Array && /radio|checkbox/.test(this.type) ) 38.343 + this.checked = (jQuery.inArray(this.value, val) >= 0 || 38.344 + jQuery.inArray(this.name, val) >= 0); 38.345 + else if ( jQuery.nodeName(this, "select") ) { 38.346 + var tmp = val.constructor == Array ? val : [val]; 38.347 + 38.348 + jQuery("option", this).each(function(){ 38.349 + this.selected = (jQuery.inArray(this.value, tmp) >= 0 || 38.350 + jQuery.inArray(this.text, tmp) >= 0); 38.351 + }); 38.352 + 38.353 + if ( !tmp.length ) 38.354 + this.selectedIndex = -1; 38.355 + } else 38.356 + this.value = val; 38.357 + }); 38.358 + }, 38.359 + 38.360 + html: function( val ) { 38.361 + return val == undefined ? 38.362 + ( this.length ? this[0].innerHTML : null ) : 38.363 + this.empty().append( val ); 38.364 + }, 38.365 + 38.366 + replaceWith: function( val ) { 38.367 + return this.after( val ).remove(); 38.368 + }, 38.369 + 38.370 + eq: function(i){ 38.371 + return this.slice(i, i+1); 38.372 + }, 38.373 + 38.374 + slice: function() { 38.375 + return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 38.376 + }, 38.377 + 38.378 + map: function(fn) { 38.379 + return this.pushStack(jQuery.map( this, function(elem,i){ 38.380 + return fn.call( elem, i, elem ); 38.381 + })); 38.382 + }, 38.383 + 38.384 + andSelf: function() { 38.385 + return this.add( this.prevObject ); 38.386 + }, 38.387 + 38.388 + domManip: function(args, table, dir, fn) { 38.389 + var clone = this.length > 1, a; 38.390 + 38.391 + return this.each(function(){ 38.392 + if ( !a ) { 38.393 + a = jQuery.clean(args, this.ownerDocument); 38.394 + if ( dir < 0 ) 38.395 + a.reverse(); 38.396 + } 38.397 + 38.398 + var obj = this; 38.399 + 38.400 + if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") ) 38.401 + obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody")); 38.402 + 38.403 + jQuery.each( a, function(){ 38.404 + var elem = clone ? this.cloneNode(true) : this; 38.405 + if ( !evalScript(0, elem) ) 38.406 + fn.call( obj, elem ); 38.407 + }); 38.408 + }); 38.409 + } 38.410 +}; 38.411 + 38.412 +function evalScript(i, elem){ 38.413 + var script = jQuery.nodeName(elem, "script"); 38.414 + 38.415 + if ( script ) { 38.416 + if ( elem.src ) 38.417 + jQuery.ajax({ url: elem.src, async: false, dataType: "script" }); 38.418 + else 38.419 + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 38.420 + 38.421 + if ( elem.parentNode ) 38.422 + elem.parentNode.removeChild(elem); 38.423 + 38.424 + } else if ( elem.nodeType == 1 ) 38.425 + jQuery("script", elem).each(evalScript); 38.426 + 38.427 + return script; 38.428 +} 38.429 + 38.430 +jQuery.extend = jQuery.fn.extend = function() { 38.431 + // copy reference to target object 38.432 + var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false; 38.433 + 38.434 + // Handle a deep copy situation 38.435 + if ( target.constructor == Boolean ) { 38.436 + deep = target; 38.437 + target = arguments[1] || {}; 38.438 + } 38.439 + 38.440 + // extend jQuery itself if only one argument is passed 38.441 + if ( al == 1 ) { 38.442 + target = this; 38.443 + a = 0; 38.444 + } 38.445 + 38.446 + var prop; 38.447 + 38.448 + for ( ; a < al; a++ ) 38.449 + // Only deal with non-null/undefined values 38.450 + if ( (prop = arguments[a]) != null ) 38.451 + // Extend the base object 38.452 + for ( var i in prop ) { 38.453 + // Prevent never-ending loop 38.454 + if ( target == prop[i] ) 38.455 + continue; 38.456 + 38.457 + // Recurse if we're merging object values 38.458 + if ( deep && typeof prop[i] == 'object' && target[i] ) 38.459 + jQuery.extend( target[i], prop[i] ); 38.460 + 38.461 + // Don't bring in undefined values 38.462 + else if ( prop[i] != undefined ) 38.463 + target[i] = prop[i]; 38.464 + } 38.465 + 38.466 + // Return the modified object 38.467 + return target; 38.468 +}; 38.469 + 38.470 +var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {}; 38.471 + 38.472 +jQuery.extend({ 38.473 + noConflict: function(deep) { 38.474 + window.$ = _$; 38.475 + if ( deep ) 38.476 + window.jQuery = _jQuery; 38.477 + return jQuery; 38.478 + }, 38.479 + 38.480 + // This may seem like some crazy code, but trust me when I say that this 38.481 + // is the only cross-browser way to do this. --John 38.482 + isFunction: function( fn ) { 38.483 + return !!fn && typeof fn != "string" && !fn.nodeName && 38.484 + fn.constructor != Array && /function/i.test( fn + "" ); 38.485 + }, 38.486 + 38.487 + // check if an element is in a XML document 38.488 + isXMLDoc: function(elem) { 38.489 + return elem.documentElement && !elem.body || 38.490 + elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 38.491 + }, 38.492 + 38.493 + // Evalulates a script in a global context 38.494 + // Evaluates Async. in Safari 2 :-( 38.495 + globalEval: function( data ) { 38.496 + data = jQuery.trim( data ); 38.497 + if ( data ) { 38.498 + if ( window.execScript ) 38.499 + window.execScript( data ); 38.500 + else if ( jQuery.browser.safari ) 38.501 + // safari doesn't provide a synchronous global eval 38.502 + window.setTimeout( data, 0 ); 38.503 + else 38.504 + eval.call( window, data ); 38.505 + } 38.506 + }, 38.507 + 38.508 + nodeName: function( elem, name ) { 38.509 + return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 38.510 + }, 38.511 + 38.512 + cache: {}, 38.513 + 38.514 + data: function( elem, name, data ) { 38.515 + elem = elem == window ? win : elem; 38.516 + 38.517 + var id = elem[ expando ]; 38.518 + 38.519 + // Compute a unique ID for the element 38.520 + if ( !id ) 38.521 + id = elem[ expando ] = ++uuid; 38.522 + 38.523 + // Only generate the data cache if we're 38.524 + // trying to access or manipulate it 38.525 + if ( name && !jQuery.cache[ id ] ) 38.526 + jQuery.cache[ id ] = {}; 38.527 + 38.528 + // Prevent overriding the named cache with undefined values 38.529 + if ( data != undefined ) 38.530 + jQuery.cache[ id ][ name ] = data; 38.531 + 38.532 + // Return the named cache data, or the ID for the element 38.533 + return name ? jQuery.cache[ id ][ name ] : id; 38.534 + }, 38.535 + 38.536 + removeData: function( elem, name ) { 38.537 + elem = elem == window ? win : elem; 38.538 + 38.539 + var id = elem[ expando ]; 38.540 + 38.541 + // If we want to remove a specific section of the element's data 38.542 + if ( name ) { 38.543 + if ( jQuery.cache[ id ] ) { 38.544 + // Remove the section of cache data 38.545 + delete jQuery.cache[ id ][ name ]; 38.546 + 38.547 + // If we've removed all the data, remove the element's cache 38.548 + name = ""; 38.549 + for ( name in jQuery.cache[ id ] ) break; 38.550 + if ( !name ) 38.551 + jQuery.removeData( elem ); 38.552 + } 38.553 + 38.554 + // Otherwise, we want to remove all of the element's data 38.555 + } else { 38.556 + // Clean up the element expando 38.557 + try { 38.558 + delete elem[ expando ]; 38.559 + } catch(e){ 38.560 + // IE has trouble directly removing the expando 38.561 + // but it's ok with using removeAttribute 38.562 + if ( elem.removeAttribute ) 38.563 + elem.removeAttribute( expando ); 38.564 + } 38.565 + 38.566 + // Completely remove the data cache 38.567 + delete jQuery.cache[ id ]; 38.568 + } 38.569 + }, 38.570 + 38.571 + // args is for internal usage only 38.572 + each: function( obj, fn, args ) { 38.573 + if ( args ) { 38.574 + if ( obj.length == undefined ) 38.575 + for ( var i in obj ) 38.576 + fn.apply( obj[i], args ); 38.577 + else 38.578 + for ( var i = 0, ol = obj.length; i < ol; i++ ) 38.579 + if ( fn.apply( obj[i], args ) === false ) break; 38.580 + 38.581 + // A special, fast, case for the most common use of each 38.582 + } else { 38.583 + if ( obj.length == undefined ) 38.584 + for ( var i in obj ) 38.585 + fn.call( obj[i], i, obj[i] ); 38.586 + else 38.587 + for ( var i = 0, ol = obj.length, val = obj[0]; 38.588 + i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){} 38.589 + } 38.590 + 38.591 + return obj; 38.592 + }, 38.593 + 38.594 + prop: function(elem, value, type, index, prop){ 38.595 + // Handle executable functions 38.596 + if ( jQuery.isFunction( value ) ) 38.597 + value = value.call( elem, [index] ); 38.598 + 38.599 + // exclude the following css properties to add px 38.600 + var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; 38.601 + 38.602 + // Handle passing in a number to a CSS property 38.603 + return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ? 38.604 + value + "px" : 38.605 + value; 38.606 + }, 38.607 + 38.608 + className: { 38.609 + // internal only, use addClass("class") 38.610 + add: function( elem, c ){ 38.611 + jQuery.each( (c || "").split(/\s+/), function(i, cur){ 38.612 + if ( !jQuery.className.has( elem.className, cur ) ) 38.613 + elem.className += ( elem.className ? " " : "" ) + cur; 38.614 + }); 38.615 + }, 38.616 + 38.617 + // internal only, use removeClass("class") 38.618 + remove: function( elem, c ){ 38.619 + elem.className = c != undefined ? 38.620 + jQuery.grep( elem.className.split(/\s+/), function(cur){ 38.621 + return !jQuery.className.has( c, cur ); 38.622 + }).join(" ") : ""; 38.623 + }, 38.624 + 38.625 + // internal only, use is(".class") 38.626 + has: function( t, c ) { 38.627 + return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1; 38.628 + } 38.629 + }, 38.630 + 38.631 + swap: function(e,o,f) { 38.632 + for ( var i in o ) { 38.633 + e.style["old"+i] = e.style[i]; 38.634 + e.style[i] = o[i]; 38.635 + } 38.636 + f.apply( e, [] ); 38.637 + for ( var i in o ) 38.638 + e.style[i] = e.style["old"+i]; 38.639 + }, 38.640 + 38.641 + css: function(e,p) { 38.642 + if ( p == "height" || p == "width" ) { 38.643 + var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"]; 38.644 + 38.645 + jQuery.each( d, function(){ 38.646 + old["padding" + this] = 0; 38.647 + old["border" + this + "Width"] = 0; 38.648 + }); 38.649 + 38.650 + jQuery.swap( e, old, function() { 38.651 + if ( jQuery(e).is(':visible') ) { 38.652 + oHeight = e.offsetHeight; 38.653 + oWidth = e.offsetWidth; 38.654 + } else { 38.655 + e = jQuery(e.cloneNode(true)) 38.656 + .find(":radio").removeAttr("checked").end() 38.657 + .css({ 38.658 + visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0" 38.659 + }).appendTo(e.parentNode)[0]; 38.660 + 38.661 + var parPos = jQuery.css(e.parentNode,"position") || "static"; 38.662 + if ( parPos == "static" ) 38.663 + e.parentNode.style.position = "relative"; 38.664 + 38.665 + oHeight = e.clientHeight; 38.666 + oWidth = e.clientWidth; 38.667 + 38.668 + if ( parPos == "static" ) 38.669 + e.parentNode.style.position = "static"; 38.670 + 38.671 + e.parentNode.removeChild(e); 38.672 + } 38.673 + }); 38.674 + 38.675 + return p == "height" ? oHeight : oWidth; 38.676 + } 38.677 + 38.678 + return jQuery.curCSS( e, p ); 38.679 + }, 38.680 + 38.681 + curCSS: function(elem, prop, force) { 38.682 + var ret, stack = [], swap = []; 38.683 + 38.684 + // A helper method for determining if an element's values are broken 38.685 + function color(a){ 38.686 + if ( !jQuery.browser.safari ) 38.687 + return false; 38.688 + 38.689 + var ret = document.defaultView.getComputedStyle(a,null); 38.690 + return !ret || ret.getPropertyValue("color") == ""; 38.691 + } 38.692 + 38.693 + if (prop == "opacity" && jQuery.browser.msie) { 38.694 + ret = jQuery.attr(elem.style, "opacity"); 38.695 + return ret == "" ? "1" : ret; 38.696 + } 38.697 + 38.698 + if (prop.match(/float/i)) 38.699 + prop = styleFloat; 38.700 + 38.701 + if (!force && elem.style[prop]) 38.702 + ret = elem.style[prop]; 38.703 + 38.704 + else if (document.defaultView && document.defaultView.getComputedStyle) { 38.705 + 38.706 + if (prop.match(/float/i)) 38.707 + prop = "float"; 38.708 + 38.709 + prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase(); 38.710 + var cur = document.defaultView.getComputedStyle(elem, null); 38.711 + 38.712 + if ( cur && !color(elem) ) 38.713 + ret = cur.getPropertyValue(prop); 38.714 + 38.715 + // If the element isn't reporting its values properly in Safari 38.716 + // then some display: none elements are involved 38.717 + else { 38.718 + // Locate all of the parent display: none elements 38.719 + for ( var a = elem; a && color(a); a = a.parentNode ) 38.720 + stack.unshift(a); 38.721 + 38.722 + // Go through and make them visible, but in reverse 38.723 + // (It would be better if we knew the exact display type that they had) 38.724 + for ( a = 0; a < stack.length; a++ ) 38.725 + if ( color(stack[a]) ) { 38.726 + swap[a] = stack[a].style.display; 38.727 + stack[a].style.display = "block"; 38.728 + } 38.729 + 38.730 + // Since we flip the display style, we have to handle that 38.731 + // one special, otherwise get the value 38.732 + ret = prop == "display" && swap[stack.length-1] != null ? 38.733 + "none" : 38.734 + document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || ""; 38.735 + 38.736 + // Finally, revert the display styles back 38.737 + for ( a = 0; a < swap.length; a++ ) 38.738 + if ( swap[a] != null ) 38.739 + stack[a].style.display = swap[a]; 38.740 + } 38.741 + 38.742 + if ( prop == "opacity" && ret == "" ) 38.743 + ret = "1"; 38.744 + 38.745 + } else if (elem.currentStyle) { 38.746 + var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();}); 38.747 + ret = elem.currentStyle[prop] || elem.currentStyle[newProp]; 38.748 + 38.749 + // From the awesome hack by Dean Edwards 38.750 + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 38.751 + 38.752 + // If we're not dealing with a regular pixel number 38.753 + // but a number that has a weird ending, we need to convert it to pixels 38.754 + if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) { 38.755 + var style = elem.style.left; 38.756 + var runtimeStyle = elem.runtimeStyle.left; 38.757 + elem.runtimeStyle.left = elem.currentStyle.left; 38.758 + elem.style.left = ret || 0; 38.759 + ret = elem.style.pixelLeft + "px"; 38.760 + elem.style.left = style; 38.761 + elem.runtimeStyle.left = runtimeStyle; 38.762 + } 38.763 + } 38.764 + 38.765 + return ret; 38.766 + }, 38.767 + 38.768 + clean: function(a, doc) { 38.769 + var r = []; 38.770 + doc = doc || document; 38.771 + 38.772 + jQuery.each( a, function(i,arg){ 38.773 + if ( !arg ) return; 38.774 + 38.775 + if ( arg.constructor == Number ) 38.776 + arg = arg.toString(); 38.777 + 38.778 + // Convert html string into DOM nodes 38.779 + if ( typeof arg == "string" ) { 38.780 + // Fix "XHTML"-style tags in all browsers 38.781 + arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){ 38.782 + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">"; 38.783 + }); 38.784 + 38.785 + // Trim whitespace, otherwise indexOf won't work as expected 38.786 + var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = []; 38.787 + 38.788 + var wrap = 38.789 + // option or optgroup 38.790 + !s.indexOf("<opt") && 38.791 + [1, "<select>", "</select>"] || 38.792 + 38.793 + !s.indexOf("<leg") && 38.794 + [1, "<fieldset>", "</fieldset>"] || 38.795 + 38.796 + s.match(/^<(thead|tbody|tfoot|colg|cap)/) && 38.797 + [1, "<table>", "</table>"] || 38.798 + 38.799 + !s.indexOf("<tr") && 38.800 + [2, "<table><tbody>", "</tbody></table>"] || 38.801 + 38.802 + // <thead> matched above 38.803 + (!s.indexOf("<td") || !s.indexOf("<th")) && 38.804 + [3, "<table><tbody><tr>", "</tr></tbody></table>"] || 38.805 + 38.806 + !s.indexOf("<col") && 38.807 + [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] || 38.808 + 38.809 + // IE can't serialize <link> and <script> tags normally 38.810 + jQuery.browser.msie && 38.811 + [1, "div<div>", "</div>"] || 38.812 + 38.813 + [0,"",""]; 38.814 + 38.815 + // Go to html and back, then peel off extra wrappers 38.816 + div.innerHTML = wrap[1] + arg + wrap[2]; 38.817 + 38.818 + // Move to the right depth 38.819 + while ( wrap[0]-- ) 38.820 + div = div.lastChild; 38.821 + 38.822 + // Remove IE's autoinserted <tbody> from table fragments 38.823 + if ( jQuery.browser.msie ) { 38.824 + 38.825 + // String was a <table>, *may* have spurious <tbody> 38.826 + if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) 38.827 + tb = div.firstChild && div.firstChild.childNodes; 38.828 + 38.829 + // String was a bare <thead> or <tfoot> 38.830 + else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 ) 38.831 + tb = div.childNodes; 38.832 + 38.833 + for ( var n = tb.length-1; n >= 0 ; --n ) 38.834 + if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length ) 38.835 + tb[n].parentNode.removeChild(tb[n]); 38.836 + 38.837 + // IE completely kills leading whitespace when innerHTML is used 38.838 + if ( /^\s/.test(arg) ) 38.839 + div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild ); 38.840 + 38.841 + } 38.842 + 38.843 + arg = jQuery.makeArray( div.childNodes ); 38.844 + } 38.845 + 38.846 + if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) ) 38.847 + return; 38.848 + 38.849 + if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options ) 38.850 + r.push( arg ); 38.851 + else 38.852 + r = jQuery.merge( r, arg ); 38.853 + 38.854 + }); 38.855 + 38.856 + return r; 38.857 + }, 38.858 + 38.859 + attr: function(elem, name, value){ 38.860 + var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props; 38.861 + 38.862 + // Safari mis-reports the default selected property of a hidden option 38.863 + // Accessing the parent's selectedIndex property fixes it 38.864 + if ( name == "selected" && jQuery.browser.safari ) 38.865 + elem.parentNode.selectedIndex; 38.866 + 38.867 + // Certain attributes only work when accessed via the old DOM 0 way 38.868 + if ( fix[name] ) { 38.869 + if ( value != undefined ) elem[fix[name]] = value; 38.870 + return elem[fix[name]]; 38.871 + } else if ( jQuery.browser.msie && name == "style" ) 38.872 + return jQuery.attr( elem.style, "cssText", value ); 38.873 + 38.874 + else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") ) 38.875 + return elem.getAttributeNode(name).nodeValue; 38.876 + 38.877 + // IE elem.getAttribute passes even for style 38.878 + else if ( elem.tagName ) { 38.879 + 38.880 + if ( value != undefined ) { 38.881 + if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode ) 38.882 + throw "type property can't be changed"; 38.883 + elem.setAttribute( name, value ); 38.884 + } 38.885 + 38.886 + if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) ) 38.887 + return elem.getAttribute( name, 2 ); 38.888 + 38.889 + return elem.getAttribute( name ); 38.890 + 38.891 + // elem is actually elem.style ... set the style 38.892 + } else { 38.893 + // IE actually uses filters for opacity 38.894 + if ( name == "opacity" && jQuery.browser.msie ) { 38.895 + if ( value != undefined ) { 38.896 + // IE has trouble with opacity if it does not have layout 38.897 + // Force it by setting the zoom level 38.898 + elem.zoom = 1; 38.899 + 38.900 + // Set the alpha filter to set the opacity 38.901 + elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") + 38.902 + (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 38.903 + } 38.904 + 38.905 + return elem.filter ? 38.906 + (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : ""; 38.907 + } 38.908 + name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();}); 38.909 + if ( value != undefined ) elem[name] = value; 38.910 + return elem[name]; 38.911 + } 38.912 + }, 38.913 + 38.914 + trim: function(t){ 38.915 + return (t||"").replace(/^\s+|\s+$/g, ""); 38.916 + }, 38.917 + 38.918 + makeArray: function( a ) { 38.919 + var r = []; 38.920 + 38.921 + // Need to use typeof to fight Safari childNodes crashes 38.922 + if ( typeof a != "array" ) 38.923 + for ( var i = 0, al = a.length; i < al; i++ ) 38.924 + r.push( a[i] ); 38.925 + else 38.926 + r = a.slice( 0 ); 38.927 + 38.928 + return r; 38.929 + }, 38.930 + 38.931 + inArray: function( b, a ) { 38.932 + for ( var i = 0, al = a.length; i < al; i++ ) 38.933 + if ( a[i] == b ) 38.934 + return i; 38.935 + return -1; 38.936 + }, 38.937 + 38.938 + merge: function(first, second) { 38.939 + // We have to loop this way because IE & Opera overwrite the length 38.940 + // expando of getElementsByTagName 38.941 + 38.942 + // Also, we need to make sure that the correct elements are being returned 38.943 + // (IE returns comment nodes in a '*' query) 38.944 + if ( jQuery.browser.msie ) { 38.945 + for ( var i = 0; second[i]; i++ ) 38.946 + if ( second[i].nodeType != 8 ) 38.947 + first.push(second[i]); 38.948 + } else 38.949 + for ( var i = 0; second[i]; i++ ) 38.950 + first.push(second[i]); 38.951 + 38.952 + return first; 38.953 + }, 38.954 + 38.955 + unique: function(first) { 38.956 + var r = [], done = {}; 38.957 + 38.958 + try { 38.959 + for ( var i = 0, fl = first.length; i < fl; i++ ) { 38.960 + var id = jQuery.data(first[i]); 38.961 + if ( !done[id] ) { 38.962 + done[id] = true; 38.963 + r.push(first[i]); 38.964 + } 38.965 + } 38.966 + } catch(e) { 38.967 + r = first; 38.968 + } 38.969 + 38.970 + return r; 38.971 + }, 38.972 + 38.973 + grep: function(elems, fn, inv) { 38.974 + // If a string is passed in for the function, make a function 38.975 + // for it (a handy shortcut) 38.976 + if ( typeof fn == "string" ) 38.977 + fn = eval("false||function(a,i){return " + fn + "}"); 38.978 + 38.979 + var result = []; 38.980 + 38.981 + // Go through the array, only saving the items 38.982 + // that pass the validator function 38.983 + for ( var i = 0, el = elems.length; i < el; i++ ) 38.984 + if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) ) 38.985 + result.push( elems[i] ); 38.986 + 38.987 + return result; 38.988 + }, 38.989 + 38.990 + map: function(elems, fn) { 38.991 + // If a string is passed in for the function, make a function 38.992 + // for it (a handy shortcut) 38.993 + if ( typeof fn == "string" ) 38.994 + fn = eval("false||function(a){return " + fn + "}"); 38.995 + 38.996 + var result = []; 38.997 + 38.998 + // Go through the array, translating each of the items to their 38.999 + // new value (or values). 38.1000 + for ( var i = 0, el = elems.length; i < el; i++ ) { 38.1001 + var val = fn(elems[i],i); 38.1002 + 38.1003 + if ( val !== null && val != undefined ) { 38.1004 + if ( val.constructor != Array ) val = [val]; 38.1005 + result = result.concat( val ); 38.1006 + } 38.1007 + } 38.1008 + 38.1009 + return result; 38.1010 + } 38.1011 +}); 38.1012 + 38.1013 +var userAgent = navigator.userAgent.toLowerCase(); 38.1014 + 38.1015 +// Figure out what browser is being used 38.1016 +jQuery.browser = { 38.1017 + version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1], 38.1018 + safari: /webkit/.test(userAgent), 38.1019 + opera: /opera/.test(userAgent), 38.1020 + msie: /msie/.test(userAgent) && !/opera/.test(userAgent), 38.1021 + mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent) 38.1022 +}; 38.1023 + 38.1024 +var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat"; 38.1025 + 38.1026 +jQuery.extend({ 38.1027 + // Check to see if the W3C box model is being used 38.1028 + boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 38.1029 + 38.1030 + styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat", 38.1031 + 38.1032 + props: { 38.1033 + "for": "htmlFor", 38.1034 + "class": "className", 38.1035 + "float": styleFloat, 38.1036 + cssFloat: styleFloat, 38.1037 + styleFloat: styleFloat, 38.1038 + innerHTML: "innerHTML", 38.1039 + className: "className", 38.1040 + value: "value", 38.1041 + disabled: "disabled", 38.1042 + checked: "checked", 38.1043 + readonly: "readOnly", 38.1044 + selected: "selected", 38.1045 + maxlength: "maxLength" 38.1046 + } 38.1047 +}); 38.1048 + 38.1049 +jQuery.each({ 38.1050 + parent: "a.parentNode", 38.1051 + parents: "jQuery.dir(a,'parentNode')", 38.1052 + next: "jQuery.nth(a,2,'nextSibling')", 38.1053 + prev: "jQuery.nth(a,2,'previousSibling')", 38.1054 + nextAll: "jQuery.dir(a,'nextSibling')", 38.1055 + prevAll: "jQuery.dir(a,'previousSibling')", 38.1056 + siblings: "jQuery.sibling(a.parentNode.firstChild,a)", 38.1057 + children: "jQuery.sibling(a.firstChild)", 38.1058 + contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)" 38.1059 +}, function(i,n){ 38.1060 + jQuery.fn[ i ] = function(a) { 38.1061 + var ret = jQuery.map(this,n); 38.1062 + if ( a && typeof a == "string" ) 38.1063 + ret = jQuery.multiFilter(a,ret); 38.1064 + return this.pushStack( jQuery.unique(ret) ); 38.1065 + }; 38.1066 +}); 38.1067 + 38.1068 +jQuery.each({ 38.1069 + appendTo: "append", 38.1070 + prependTo: "prepend", 38.1071 + insertBefore: "before", 38.1072 + insertAfter: "after", 38.1073 + replaceAll: "replaceWith" 38.1074 +}, function(i,n){ 38.1075 + jQuery.fn[ i ] = function(){ 38.1076 + var a = arguments; 38.1077 + return this.each(function(){ 38.1078 + for ( var j = 0, al = a.length; j < al; j++ ) 38.1079 + jQuery(a[j])[n]( this ); 38.1080 + }); 38.1081 + }; 38.1082 +}); 38.1083 + 38.1084 +jQuery.each( { 38.1085 + removeAttr: function( key ) { 38.1086 + jQuery.attr( this, key, "" ); 38.1087 + this.removeAttribute( key ); 38.1088 + }, 38.1089 + addClass: function(c){ 38.1090 + jQuery.className.add(this,c); 38.1091 + }, 38.1092 + removeClass: function(c){ 38.1093 + jQuery.className.remove(this,c); 38.1094 + }, 38.1095 + toggleClass: function( c ){ 38.1096 + jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c); 38.1097 + }, 38.1098 + remove: function(a){ 38.1099 + if ( !a || jQuery.filter( a, [this] ).r.length ) { 38.1100 + jQuery.removeData( this ); 38.1101 + this.parentNode.removeChild( this ); 38.1102 + } 38.1103 + }, 38.1104 + empty: function() { 38.1105 + // Clean up the cache 38.1106 + jQuery("*", this).each(function(){ jQuery.removeData(this); }); 38.1107 + 38.1108 + while ( this.firstChild ) 38.1109 + this.removeChild( this.firstChild ); 38.1110 + } 38.1111 +}, function(i,n){ 38.1112 + jQuery.fn[ i ] = function() { 38.1113 + return this.each( n, arguments ); 38.1114 + }; 38.1115 +}); 38.1116 + 38.1117 +jQuery.each( [ "Height", "Width" ], function(i,name){ 38.1118 + var n = name.toLowerCase(); 38.1119 + 38.1120 + jQuery.fn[ n ] = function(h) { 38.1121 + return this[0] == window ? 38.1122 + jQuery.browser.safari && self["inner" + name] || 38.1123 + jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) || 38.1124 + document.body["client" + name] : 38.1125 + 38.1126 + this[0] == document ? 38.1127 + Math.max( document.body["scroll" + name], document.body["offset" + name] ) : 38.1128 + 38.1129 + h == undefined ? 38.1130 + ( this.length ? jQuery.css( this[0], n ) : null ) : 38.1131 + this.css( n, h.constructor == String ? h : h + "px" ); 38.1132 + }; 38.1133 +}); 38.1134 + 38.1135 +var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ? 38.1136 + "(?:[\\w*_-]|\\\\.)" : 38.1137 + "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)", 38.1138 + quickChild = new RegExp("^>\\s*(" + chars + "+)"), 38.1139 + quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"), 38.1140 + quickClass = new RegExp("^([#.]?)(" + chars + "*)"); 38.1141 + 38.1142 +jQuery.extend({ 38.1143 + expr: { 38.1144 + "": "m[2]=='*'||jQuery.nodeName(a,m[2])", 38.1145 + "#": "a.getAttribute('id')==m[2]", 38.1146 + ":": { 38.1147 + // Position Checks 38.1148 + lt: "i<m[3]-0", 38.1149 + gt: "i>m[3]-0", 38.1150 + nth: "m[3]-0==i", 38.1151 + eq: "m[3]-0==i", 38.1152 + first: "i==0", 38.1153 + last: "i==r.length-1", 38.1154 + even: "i%2==0", 38.1155 + odd: "i%2", 38.1156 + 38.1157 + // Child Checks 38.1158 + "first-child": "a.parentNode.getElementsByTagName('*')[0]==a", 38.1159 + "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a", 38.1160 + "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')", 38.1161 + 38.1162 + // Parent Checks 38.1163 + parent: "a.firstChild", 38.1164 + empty: "!a.firstChild", 38.1165 + 38.1166 + // Text Check 38.1167 + contains: "(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0", 38.1168 + 38.1169 + // Visibility 38.1170 + visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"', 38.1171 + hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"', 38.1172 + 38.1173 + // Form attributes 38.1174 + enabled: "!a.disabled", 38.1175 + disabled: "a.disabled", 38.1176 + checked: "a.checked", 38.1177 + selected: "a.selected||jQuery.attr(a,'selected')", 38.1178 + 38.1179 + // Form elements 38.1180 + text: "'text'==a.type", 38.1181 + radio: "'radio'==a.type", 38.1182 + checkbox: "'checkbox'==a.type", 38.1183 + file: "'file'==a.type", 38.1184 + password: "'password'==a.type", 38.1185 + submit: "'submit'==a.type", 38.1186 + image: "'image'==a.type", 38.1187 + reset: "'reset'==a.type", 38.1188 + button: '"button"==a.type||jQuery.nodeName(a,"button")', 38.1189 + input: "/input|select|textarea|button/i.test(a.nodeName)", 38.1190 + 38.1191 + // :has() 38.1192 + has: "jQuery.find(m[3],a).length", 38.1193 + 38.1194 + // :header 38.1195 + header: "/h\\d/i.test(a.nodeName)", 38.1196 + 38.1197 + // :animated 38.1198 + animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length" 38.1199 + } 38.1200 + }, 38.1201 + 38.1202 + // The regular expressions that power the parsing engine 38.1203 + parse: [ 38.1204 + // Match: [@value='test'], [@foo] 38.1205 + /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 38.1206 + 38.1207 + // Match: :contains('foo') 38.1208 + /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 38.1209 + 38.1210 + // Match: :even, :last-chlid, #id, .class 38.1211 + new RegExp("^([:.#]*)(" + chars + "+)") 38.1212 + ], 38.1213 + 38.1214 + multiFilter: function( expr, elems, not ) { 38.1215 + var old, cur = []; 38.1216 + 38.1217 + while ( expr && expr != old ) { 38.1218 + old = expr; 38.1219 + var f = jQuery.filter( expr, elems, not ); 38.1220 + expr = f.t.replace(/^\s*,\s*/, "" ); 38.1221 + cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 38.1222 + } 38.1223 + 38.1224 + return cur; 38.1225 + }, 38.1226 + 38.1227 + find: function( t, context ) { 38.1228 + // Quickly handle non-string expressions 38.1229 + if ( typeof t != "string" ) 38.1230 + return [ t ]; 38.1231 + 38.1232 + // Make sure that the context is a DOM Element 38.1233 + if ( context && !context.nodeType ) 38.1234 + context = null; 38.1235 + 38.1236 + // Set the correct context (if none is provided) 38.1237 + context = context || document; 38.1238 + 38.1239 + // Initialize the search 38.1240 + var ret = [context], done = [], last; 38.1241 + 38.1242 + // Continue while a selector expression exists, and while 38.1243 + // we're no longer looping upon ourselves 38.1244 + while ( t && last != t ) { 38.1245 + var r = []; 38.1246 + last = t; 38.1247 + 38.1248 + t = jQuery.trim(t); 38.1249 + 38.1250 + var foundToken = false; 38.1251 + 38.1252 + // An attempt at speeding up child selectors that 38.1253 + // point to a specific element tag 38.1254 + var re = quickChild; 38.1255 + var m = re.exec(t); 38.1256 + 38.1257 + if ( m ) { 38.1258 + var nodeName = m[1].toUpperCase(); 38.1259 + 38.1260 + // Perform our own iteration and filter 38.1261 + for ( var i = 0; ret[i]; i++ ) 38.1262 + for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 38.1263 + if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) ) 38.1264 + r.push( c ); 38.1265 + 38.1266 + ret = r; 38.1267 + t = t.replace( re, "" ); 38.1268 + if ( t.indexOf(" ") == 0 ) continue; 38.1269 + foundToken = true; 38.1270 + } else { 38.1271 + re = /^([>+~])\s*(\w*)/i; 38.1272 + 38.1273 + if ( (m = re.exec(t)) != null ) { 38.1274 + r = []; 38.1275 + 38.1276 + var nodeName = m[2], merge = {}; 38.1277 + m = m[1]; 38.1278 + 38.1279 + for ( var j = 0, rl = ret.length; j < rl; j++ ) { 38.1280 + var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 38.1281 + for ( ; n; n = n.nextSibling ) 38.1282 + if ( n.nodeType == 1 ) { 38.1283 + var id = jQuery.data(n); 38.1284 + 38.1285 + if ( m == "~" && merge[id] ) break; 38.1286 + 38.1287 + if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) { 38.1288 + if ( m == "~" ) merge[id] = true; 38.1289 + r.push( n ); 38.1290 + } 38.1291 + 38.1292 + if ( m == "+" ) break; 38.1293 + } 38.1294 + } 38.1295 + 38.1296 + ret = r; 38.1297 + 38.1298 + // And remove the token 38.1299 + t = jQuery.trim( t.replace( re, "" ) ); 38.1300 + foundToken = true; 38.1301 + } 38.1302 + } 38.1303 + 38.1304 + // See if there's still an expression, and that we haven't already 38.1305 + // matched a token 38.1306 + if ( t && !foundToken ) { 38.1307 + // Handle multiple expressions 38.1308 + if ( !t.indexOf(",") ) { 38.1309 + // Clean the result set 38.1310 + if ( context == ret[0] ) ret.shift(); 38.1311 + 38.1312 + // Merge the result sets 38.1313 + done = jQuery.merge( done, ret ); 38.1314 + 38.1315 + // Reset the context 38.1316 + r = ret = [context]; 38.1317 + 38.1318 + // Touch up the selector string 38.1319 + t = " " + t.substr(1,t.length); 38.1320 + 38.1321 + } else { 38.1322 + // Optimize for the case nodeName#idName 38.1323 + var re2 = quickID; 38.1324 + var m = re2.exec(t); 38.1325 + 38.1326 + // Re-organize the results, so that they're consistent 38.1327 + if ( m ) { 38.1328 + m = [ 0, m[2], m[3], m[1] ]; 38.1329 + 38.1330 + } else { 38.1331 + // Otherwise, do a traditional filter check for 38.1332 + // ID, class, and element selectors 38.1333 + re2 = quickClass; 38.1334 + m = re2.exec(t); 38.1335 + } 38.1336 + 38.1337 + m[2] = m[2].replace(/\\/g, ""); 38.1338 + 38.1339 + var elem = ret[ret.length-1]; 38.1340 + 38.1341 + // Try to do a global search by ID, where we can 38.1342 + if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 38.1343 + // Optimization for HTML document case 38.1344 + var oid = elem.getElementById(m[2]); 38.1345 + 38.1346 + // Do a quick check for the existence of the actual ID attribute 38.1347 + // to avoid selecting by the name attribute in IE 38.1348 + // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 38.1349 + if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 38.1350 + oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 38.1351 + 38.1352 + // Do a quick check for node name (where applicable) so 38.1353 + // that div#foo searches will be really fast 38.1354 + ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 38.1355 + } else { 38.1356 + // We need to find all descendant elements 38.1357 + for ( var i = 0; ret[i]; i++ ) { 38.1358 + // Grab the tag name being searched for 38.1359 + var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 38.1360 + 38.1361 + // Handle IE7 being really dumb about <object>s 38.1362 + if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 38.1363 + tag = "param"; 38.1364 + 38.1365 + r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 38.1366 + } 38.1367 + 38.1368 + // It's faster to filter by class and be done with it 38.1369 + if ( m[1] == "." ) 38.1370 + r = jQuery.classFilter( r, m[2] ); 38.1371 + 38.1372 + // Same with ID filtering 38.1373 + if ( m[1] == "#" ) { 38.1374 + var tmp = []; 38.1375 + 38.1376 + // Try to find the element with the ID 38.1377 + for ( var i = 0; r[i]; i++ ) 38.1378 + if ( r[i].getAttribute("id") == m[2] ) { 38.1379 + tmp = [ r[i] ]; 38.1380 + break; 38.1381 + } 38.1382 + 38.1383 + r = tmp; 38.1384 + } 38.1385 + 38.1386 + ret = r; 38.1387 + } 38.1388 + 38.1389 + t = t.replace( re2, "" ); 38.1390 + } 38.1391 + 38.1392 + } 38.1393 + 38.1394 + // If a selector string still exists 38.1395 + if ( t ) { 38.1396 + // Attempt to filter it 38.1397 + var val = jQuery.filter(t,r); 38.1398 + ret = r = val.r; 38.1399 + t = jQuery.trim(val.t); 38.1400 + } 38.1401 + } 38.1402 + 38.1403 + // An error occurred with the selector; 38.1404 + // just return an empty set instead 38.1405 + if ( t ) 38.1406 + ret = []; 38.1407 + 38.1408 + // Remove the root context 38.1409 + if ( ret && context == ret[0] ) 38.1410 + ret.shift(); 38.1411 + 38.1412 + // And combine the results 38.1413 + done = jQuery.merge( done, ret ); 38.1414 + 38.1415 + return done; 38.1416 + }, 38.1417 + 38.1418 + classFilter: function(r,m,not){ 38.1419 + m = " " + m + " "; 38.1420 + var tmp = []; 38.1421 + for ( var i = 0; r[i]; i++ ) { 38.1422 + var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 38.1423 + if ( !not && pass || not && !pass ) 38.1424 + tmp.push( r[i] ); 38.1425 + } 38.1426 + return tmp; 38.1427 + }, 38.1428 + 38.1429 + filter: function(t,r,not) { 38.1430 + var last; 38.1431 + 38.1432 + // Look for common filter expressions 38.1433 + while ( t && t != last ) { 38.1434 + last = t; 38.1435 + 38.1436 + var p = jQuery.parse, m; 38.1437 + 38.1438 + for ( var i = 0; p[i]; i++ ) { 38.1439 + m = p[i].exec( t ); 38.1440 + 38.1441 + if ( m ) { 38.1442 + // Remove what we just matched 38.1443 + t = t.substring( m[0].length ); 38.1444 + 38.1445 + m[2] = m[2].replace(/\\/g, ""); 38.1446 + break; 38.1447 + } 38.1448 + } 38.1449 + 38.1450 + if ( !m ) 38.1451 + break; 38.1452 + 38.1453 + // :not() is a special case that can be optimized by 38.1454 + // keeping it out of the expression list 38.1455 + if ( m[1] == ":" && m[2] == "not" ) 38.1456 + r = jQuery.filter(m[3], r, true).r; 38.1457 + 38.1458 + // We can get a big speed boost by filtering by class here 38.1459 + else if ( m[1] == "." ) 38.1460 + r = jQuery.classFilter(r, m[2], not); 38.1461 + 38.1462 + else if ( m[1] == "[" ) { 38.1463 + var tmp = [], type = m[3]; 38.1464 + 38.1465 + for ( var i = 0, rl = r.length; i < rl; i++ ) { 38.1466 + var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 38.1467 + 38.1468 + if ( z == null || /href|src|selected/.test(m[2]) ) 38.1469 + z = jQuery.attr(a,m[2]) || ''; 38.1470 + 38.1471 + if ( (type == "" && !!z || 38.1472 + type == "=" && z == m[5] || 38.1473 + type == "!=" && z != m[5] || 38.1474 + type == "^=" && z && !z.indexOf(m[5]) || 38.1475 + type == "$=" && z.substr(z.length - m[5].length) == m[5] || 38.1476 + (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 38.1477 + tmp.push( a ); 38.1478 + } 38.1479 + 38.1480 + r = tmp; 38.1481 + 38.1482 + // We can get a speed boost by handling nth-child here 38.1483 + } else if ( m[1] == ":" && m[2] == "nth-child" ) { 38.1484 + var merge = {}, tmp = [], 38.1485 + test = /(\d*)n\+?(\d*)/.exec( 38.1486 + m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 38.1487 + !/\D/.test(m[3]) && "n+" + m[3] || m[3]), 38.1488 + first = (test[1] || 1) - 0, last = test[2] - 0; 38.1489 + 38.1490 + for ( var i = 0, rl = r.length; i < rl; i++ ) { 38.1491 + var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 38.1492 + 38.1493 + if ( !merge[id] ) { 38.1494 + var c = 1; 38.1495 + 38.1496 + for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 38.1497 + if ( n.nodeType == 1 ) 38.1498 + n.nodeIndex = c++; 38.1499 + 38.1500 + merge[id] = true; 38.1501 + } 38.1502 + 38.1503 + var add = false; 38.1504 + 38.1505 + if ( first == 1 ) { 38.1506 + if ( last == 0 || node.nodeIndex == last ) 38.1507 + add = true; 38.1508 + } else if ( (node.nodeIndex + last) % first == 0 ) 38.1509 + add = true; 38.1510 + 38.1511 + if ( add ^ not ) 38.1512 + tmp.push( node ); 38.1513 + } 38.1514 + 38.1515 + r = tmp; 38.1516 + 38.1517 + // Otherwise, find the expression to execute 38.1518 + } else { 38.1519 + var f = jQuery.expr[m[1]]; 38.1520 + if ( typeof f != "string" ) 38.1521 + f = jQuery.expr[m[1]][m[2]]; 38.1522 + 38.1523 + // Build a custom macro to enclose it 38.1524 + f = eval("false||function(a,i){return " + f + "}"); 38.1525 + 38.1526 + // Execute it against the current filter 38.1527 + r = jQuery.grep( r, f, not ); 38.1528 + } 38.1529 + } 38.1530 + 38.1531 + // Return an array of filtered elements (r) 38.1532 + // and the modified expression string (t) 38.1533 + return { r: r, t: t }; 38.1534 + }, 38.1535 + 38.1536 + dir: function( elem, dir ){ 38.1537 + var matched = []; 38.1538 + var cur = elem[dir]; 38.1539 + while ( cur && cur != document ) { 38.1540 + if ( cur.nodeType == 1 ) 38.1541 + matched.push( cur ); 38.1542 + cur = cur[dir]; 38.1543 + } 38.1544 + return matched; 38.1545 + }, 38.1546 + 38.1547 + nth: function(cur,result,dir,elem){ 38.1548 + result = result || 1; 38.1549 + var num = 0; 38.1550 + 38.1551 + for ( ; cur; cur = cur[dir] ) 38.1552 + if ( cur.nodeType == 1 && ++num == result ) 38.1553 + break; 38.1554 + 38.1555 + return cur; 38.1556 + }, 38.1557 + 38.1558 + sibling: function( n, elem ) { 38.1559 + var r = []; 38.1560 + 38.1561 + for ( ; n; n = n.nextSibling ) { 38.1562 + if ( n.nodeType == 1 && (!elem || n != elem) ) 38.1563 + r.push( n ); 38.1564 + } 38.1565 + 38.1566 + return r; 38.1567 + } 38.1568 +}); 38.1569 +/* 38.1570 + * A number of helper functions used for managing events. 38.1571 + * Many of the ideas behind this code orignated from 38.1572 + * Dean Edwards' addEvent library. 38.1573 + */ 38.1574 +jQuery.event = { 38.1575 + 38.1576 + // Bind an event to an element 38.1577 + // Original by Dean Edwards 38.1578 + add: function(element, type, handler, data) { 38.1579 + // For whatever reason, IE has trouble passing the window object 38.1580 + // around, causing it to be cloned in the process 38.1581 + if ( jQuery.browser.msie && element.setInterval != undefined ) 38.1582 + element = window; 38.1583 + 38.1584 + // Make sure that the function being executed has a unique ID 38.1585 + if ( !handler.guid ) 38.1586 + handler.guid = this.guid++; 38.1587 + 38.1588 + // if data is passed, bind to handler 38.1589 + if( data != undefined ) { 38.1590 + // Create temporary function pointer to original handler 38.1591 + var fn = handler; 38.1592 + 38.1593 + // Create unique handler function, wrapped around original handler 38.1594 + handler = function() { 38.1595 + // Pass arguments and context to original handler 38.1596 + return fn.apply(this, arguments); 38.1597 + }; 38.1598 + 38.1599 + // Store data in unique handler 38.1600 + handler.data = data; 38.1601 + 38.1602 + // Set the guid of unique handler to the same of original handler, so it can be removed 38.1603 + handler.guid = fn.guid; 38.1604 + } 38.1605 + 38.1606 + // Namespaced event handlers 38.1607 + var parts = type.split("."); 38.1608 + type = parts[0]; 38.1609 + handler.type = parts[1]; 38.1610 + 38.1611 + // Init the element's event structure 38.1612 + var events = jQuery.data(element, "events") || jQuery.data(element, "events", {}); 38.1613 + 38.1614 + var handle = jQuery.data(element, "handle", function(){ 38.1615 + // returned undefined or false 38.1616 + var val; 38.1617 + 38.1618 + // Handle the second event of a trigger and when 38.1619 + // an event is called after a page has unloaded 38.1620 + if ( typeof jQuery == "undefined" || jQuery.event.triggered ) 38.1621 + return val; 38.1622 + 38.1623 + val = jQuery.event.handle.apply(element, arguments); 38.1624 + 38.1625 + return val; 38.1626 + }); 38.1627 + 38.1628 + // Get the current list of functions bound to this event 38.1629 + var handlers = events[type]; 38.1630 + 38.1631 + // Init the event handler queue 38.1632 + if (!handlers) { 38.1633 + handlers = events[type] = {}; 38.1634 + 38.1635 + // And bind the global event handler to the element 38.1636 + if (element.addEventListener) 38.1637 + element.addEventListener(type, handle, false); 38.1638 + else 38.1639 + element.attachEvent("on" + type, handle); 38.1640 + } 38.1641 + 38.1642 + // Add the function to the element's handler list 38.1643 + handlers[handler.guid] = handler; 38.1644 + 38.1645 + // Keep track of which events have been used, for global triggering 38.1646 + this.global[type] = true; 38.1647 + }, 38.1648 + 38.1649 + guid: 1, 38.1650 + global: {}, 38.1651 + 38.1652 + // Detach an event or set of events from an element 38.1653 + remove: function(element, type, handler) { 38.1654 + var events = jQuery.data(element, "events"), ret, index; 38.1655 + 38.1656 + // Namespaced event handlers 38.1657 + if ( typeof type == "string" ) { 38.1658 + var parts = type.split("."); 38.1659 + type = parts[0]; 38.1660 + } 38.1661 + 38.1662 + if ( events ) { 38.1663 + // type is actually an event object here 38.1664 + if ( type && type.type ) { 38.1665 + handler = type.handler; 38.1666 + type = type.type; 38.1667 + } 38.1668 + 38.1669 + if ( !type ) { 38.1670 + for ( type in events ) 38.1671 + this.remove( element, type ); 38.1672 + 38.1673 + } else if ( events[type] ) { 38.1674 + // remove the given handler for the given type 38.1675 + if ( handler ) 38.1676 + delete events[type][handler.guid]; 38.1677 + 38.1678 + // remove all handlers for the given type 38.1679 + else 38.1680 + for ( handler in events[type] ) 38.1681 + // Handle the removal of namespaced events 38.1682 + if ( !parts[1] || events[type][handler].type == parts[1] ) 38.1683 + delete events[type][handler]; 38.1684 + 38.1685 + // remove generic event handler if no more handlers exist 38.1686 + for ( ret in events[type] ) break; 38.1687 + if ( !ret ) { 38.1688 + if (element.removeEventListener) 38.1689 + element.removeEventListener(type, jQuery.data(element, "handle"), false); 38.1690 + else 38.1691 + element.detachEvent("on" + type, jQuery.data(element, "handle")); 38.1692 + ret = null; 38.1693 + delete events[type]; 38.1694 + } 38.1695 + } 38.1696 + 38.1697 + // Remove the expando if it's no longer used 38.1698 + for ( ret in events ) break; 38.1699 + if ( !ret ) { 38.1700 + jQuery.removeData( element, "events" ); 38.1701 + jQuery.removeData( element, "handle" ); 38.1702 + } 38.1703 + } 38.1704 + }, 38.1705 + 38.1706 + trigger: function(type, data, element, donative, extra) { 38.1707 + // Clone the incoming data, if any 38.1708 + data = jQuery.makeArray(data || []); 38.1709 + 38.1710 + // Handle a global trigger 38.1711 + if ( !element ) { 38.1712 + // Only trigger if we've ever bound an event for it 38.1713 + if ( this.global[type] ) 38.1714 + jQuery("*").add([window, document]).trigger(type, data); 38.1715 + 38.1716 + // Handle triggering a single element 38.1717 + } else { 38.1718 + var val, ret, fn = jQuery.isFunction( element[ type ] || null ), 38.1719 + // Check to see if we need to provide a fake event, or not 38.1720 + evt = !data[0] || !data[0].preventDefault; 38.1721 + 38.1722 + // Pass along a fake event 38.1723 + if ( evt ) 38.1724 + data.unshift( this.fix({ type: type, target: element }) ); 38.1725 + 38.1726 + // Enforce the right trigger type 38.1727 + data[0].type = type; 38.1728 + 38.1729 + // Trigger the event 38.1730 + if ( jQuery.isFunction( jQuery.data(element, "handle") ) ) 38.1731 + val = jQuery.data(element, "handle").apply( element, data ); 38.1732 + 38.1733 + // Handle triggering native .onfoo handlers 38.1734 + if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false ) 38.1735 + val = false; 38.1736 + 38.1737 + // Extra functions don't get the custom event object 38.1738 + if ( evt ) 38.1739 + data.shift(); 38.1740 + 38.1741 + // Handle triggering of extra function 38.1742 + if ( extra && extra.apply( element, data ) === false ) 38.1743 + val = false; 38.1744 + 38.1745 + // Trigger the native events (except for clicks on links) 38.1746 + if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) { 38.1747 + this.triggered = true; 38.1748 + element[ type ](); 38.1749 + } 38.1750 + 38.1751 + this.triggered = false; 38.1752 + } 38.1753 + 38.1754 + return val; 38.1755 + }, 38.1756 + 38.1757 + handle: function(event) { 38.1758 + // returned undefined or false 38.1759 + var val; 38.1760 + 38.1761 + // Empty object is for triggered events with no data 38.1762 + event = jQuery.event.fix( event || window.event || {} ); 38.1763 + 38.1764 + // Namespaced event handlers 38.1765 + var parts = event.type.split("."); 38.1766 + event.type = parts[0]; 38.1767 + 38.1768 + var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 ); 38.1769 + args.unshift( event ); 38.1770 + 38.1771 + for ( var j in c ) { 38.1772 + // Pass in a reference to the handler function itself 38.1773 + // So that we can later remove it 38.1774 + args[0].handler = c[j]; 38.1775 + args[0].data = c[j].data; 38.1776 + 38.1777 + // Filter the functions by class 38.1778 + if ( !parts[1] || c[j].type == parts[1] ) { 38.1779 + var tmp = c[j].apply( this, args ); 38.1780 + 38.1781 + if ( val !== false ) 38.1782 + val = tmp; 38.1783 + 38.1784 + if ( tmp === false ) { 38.1785 + event.preventDefault(); 38.1786 + event.stopPropagation(); 38.1787 + } 38.1788 + } 38.1789 + } 38.1790 + 38.1791 + // Clean up added properties in IE to prevent memory leak 38.1792 + if (jQuery.browser.msie) 38.1793 + event.target = event.preventDefault = event.stopPropagation = 38.1794 + event.handler = event.data = null; 38.1795 + 38.1796 + return val; 38.1797 + }, 38.1798 + 38.1799 + fix: function(event) { 38.1800 + // store a copy of the original event object 38.1801 + // and clone to set read-only properties 38.1802 + var originalEvent = event; 38.1803 + event = jQuery.extend({}, originalEvent); 38.1804 + 38.1805 + // add preventDefault and stopPropagation since 38.1806 + // they will not work on the clone 38.1807 + event.preventDefault = function() { 38.1808 + // if preventDefault exists run it on the original event 38.1809 + if (originalEvent.preventDefault) 38.1810 + originalEvent.preventDefault(); 38.1811 + // otherwise set the returnValue property of the original event to false (IE) 38.1812 + originalEvent.returnValue = false; 38.1813 + }; 38.1814 + event.stopPropagation = function() { 38.1815 + // if stopPropagation exists run it on the original event 38.1816 + if (originalEvent.stopPropagation) 38.1817 + originalEvent.stopPropagation(); 38.1818 + // otherwise set the cancelBubble property of the original event to true (IE) 38.1819 + originalEvent.cancelBubble = true; 38.1820 + }; 38.1821 + 38.1822 + // Fix target property, if necessary 38.1823 + if ( !event.target && event.srcElement ) 38.1824 + event.target = event.srcElement; 38.1825 + 38.1826 + // check if target is a textnode (safari) 38.1827 + if (jQuery.browser.safari && event.target.nodeType == 3) 38.1828 + event.target = originalEvent.target.parentNode; 38.1829 + 38.1830 + // Add relatedTarget, if necessary 38.1831 + if ( !event.relatedTarget && event.fromElement ) 38.1832 + event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 38.1833 + 38.1834 + // Calculate pageX/Y if missing and clientX/Y available 38.1835 + if ( event.pageX == null && event.clientX != null ) { 38.1836 + var e = document.documentElement, b = document.body; 38.1837 + event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0); 38.1838 + event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0); 38.1839 + } 38.1840 + 38.1841 + // Add which for key events 38.1842 + if ( !event.which && (event.charCode || event.keyCode) ) 38.1843 + event.which = event.charCode || event.keyCode; 38.1844 + 38.1845 + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 38.1846 + if ( !event.metaKey && event.ctrlKey ) 38.1847 + event.metaKey = event.ctrlKey; 38.1848 + 38.1849 + // Add which for click: 1 == left; 2 == middle; 3 == right 38.1850 + // Note: button is not normalized, so don't use it 38.1851 + if ( !event.which && event.button ) 38.1852 + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 38.1853 + 38.1854 + return event; 38.1855 + } 38.1856 +}; 38.1857 + 38.1858 +jQuery.fn.extend({ 38.1859 + bind: function( type, data, fn ) { 38.1860 + return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 38.1861 + jQuery.event.add( this, type, fn || data, fn && data ); 38.1862 + }); 38.1863 + }, 38.1864 + 38.1865 + one: function( type, data, fn ) { 38.1866 + return this.each(function(){ 38.1867 + jQuery.event.add( this, type, function(event) { 38.1868 + jQuery(this).unbind(event); 38.1869 + return (fn || data).apply( this, arguments); 38.1870 + }, fn && data); 38.1871 + }); 38.1872 + }, 38.1873 + 38.1874 + unbind: function( type, fn ) { 38.1875 + return this.each(function(){ 38.1876 + jQuery.event.remove( this, type, fn ); 38.1877 + }); 38.1878 + }, 38.1879 + 38.1880 + trigger: function( type, data, fn ) { 38.1881 + return this.each(function(){ 38.1882 + jQuery.event.trigger( type, data, this, true, fn ); 38.1883 + }); 38.1884 + }, 38.1885 + 38.1886 + triggerHandler: function( type, data, fn ) { 38.1887 + if ( this[0] ) 38.1888 + return jQuery.event.trigger( type, data, this[0], false, fn ); 38.1889 + }, 38.1890 + 38.1891 + toggle: function() { 38.1892 + // Save reference to arguments for access in closure 38.1893 + var a = arguments; 38.1894 + 38.1895 + return this.click(function(e) { 38.1896 + // Figure out which function to execute 38.1897 + this.lastToggle = 0 == this.lastToggle ? 1 : 0; 38.1898 + 38.1899 + // Make sure that clicks stop 38.1900 + e.preventDefault(); 38.1901 + 38.1902 + // and execute the function 38.1903 + return a[this.lastToggle].apply( this, [e] ) || false; 38.1904 + }); 38.1905 + }, 38.1906 + 38.1907 + hover: function(f,g) { 38.1908 + 38.1909 + // A private function for handling mouse 'hovering' 38.1910 + function handleHover(e) { 38.1911 + // Check if mouse(over|out) are still within the same parent element 38.1912 + var p = e.relatedTarget; 38.1913 + 38.1914 + // Traverse up the tree 38.1915 + while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; }; 38.1916 + 38.1917 + // If we actually just moused on to a sub-element, ignore it 38.1918 + if ( p == this ) return false; 38.1919 + 38.1920 + // Execute the right function 38.1921 + return (e.type == "mouseover" ? f : g).apply(this, [e]); 38.1922 + } 38.1923 + 38.1924 + // Bind the function to the two event listeners 38.1925 + return this.mouseover(handleHover).mouseout(handleHover); 38.1926 + }, 38.1927 + 38.1928 + ready: function(f) { 38.1929 + // Attach the listeners 38.1930 + bindReady(); 38.1931 + 38.1932 + // If the DOM is already ready 38.1933 + if ( jQuery.isReady ) 38.1934 + // Execute the function immediately 38.1935 + f.apply( document, [jQuery] ); 38.1936 + 38.1937 + // Otherwise, remember the function for later 38.1938 + else 38.1939 + // Add the function to the wait list 38.1940 + jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } ); 38.1941 + 38.1942 + return this; 38.1943 + } 38.1944 +}); 38.1945 + 38.1946 +jQuery.extend({ 38.1947 + /* 38.1948 + * All the code that makes DOM Ready work nicely. 38.1949 + */ 38.1950 + isReady: false, 38.1951 + readyList: [], 38.1952 + 38.1953 + // Handle when the DOM is ready 38.1954 + ready: function() { 38.1955 + // Make sure that the DOM is not already loaded 38.1956 + if ( !jQuery.isReady ) { 38.1957 + // Remember that the DOM is ready 38.1958 + jQuery.isReady = true; 38.1959 + 38.1960 + // If there are functions bound, to execute 38.1961 + if ( jQuery.readyList ) { 38.1962 + // Execute all of them 38.1963 + jQuery.each( jQuery.readyList, function(){ 38.1964 + this.apply( document ); 38.1965 + }); 38.1966 + 38.1967 + // Reset the list of functions 38.1968 + jQuery.readyList = null; 38.1969 + } 38.1970 + // Remove event listener to avoid memory leak 38.1971 + if ( jQuery.browser.mozilla || jQuery.browser.opera ) 38.1972 + document.removeEventListener( "DOMContentLoaded", jQuery.ready, false ); 38.1973 + 38.1974 + // Remove script element used by IE hack 38.1975 + if( !window.frames.length ) // don't remove if frames are present (#1187) 38.1976 + jQuery(window).load(function(){ jQuery("#__ie_init").remove(); }); 38.1977 + } 38.1978 + } 38.1979 +}); 38.1980 + 38.1981 +jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 38.1982 + "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 38.1983 + "submit,keydown,keypress,keyup,error").split(","), function(i,o){ 38.1984 + 38.1985 + // Handle event binding 38.1986 + jQuery.fn[o] = function(f){ 38.1987 + return f ? this.bind(o, f) : this.trigger(o); 38.1988 + }; 38.1989 +}); 38.1990 + 38.1991 +var readyBound = false; 38.1992 + 38.1993 +function bindReady(){ 38.1994 + if ( readyBound ) return; 38.1995 + readyBound = true; 38.1996 + 38.1997 + // If Mozilla is used 38.1998 + if ( jQuery.browser.mozilla || jQuery.browser.opera ) 38.1999 + // Use the handy event callback 38.2000 + document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 38.2001 + 38.2002 + // If IE is used, use the excellent hack by Matthias Miller 38.2003 + // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited 38.2004 + else if ( jQuery.browser.msie ) { 38.2005 + 38.2006 + // Only works if you document.write() it 38.2007 + document.write("<scr" + "ipt id=__ie_init defer=true " + 38.2008 + "src=//:><\/script>"); 38.2009 + 38.2010 + // Use the defer script hack 38.2011 + var script = document.getElementById("__ie_init"); 38.2012 + 38.2013 + // script does not exist if jQuery is loaded dynamically 38.2014 + if ( script ) 38.2015 + script.onreadystatechange = function() { 38.2016 + if ( this.readyState != "complete" ) return; 38.2017 + jQuery.ready(); 38.2018 + }; 38.2019 + 38.2020 + // Clear from memory 38.2021 + script = null; 38.2022 + 38.2023 + // If Safari is used 38.2024 + } else if ( jQuery.browser.safari ) 38.2025 + // Continually check to see if the document.readyState is valid 38.2026 + jQuery.safariTimer = setInterval(function(){ 38.2027 + // loaded and complete are both valid states 38.2028 + if ( document.readyState == "loaded" || 38.2029 + document.readyState == "complete" ) { 38.2030 + 38.2031 + // If either one are found, remove the timer 38.2032 + clearInterval( jQuery.safariTimer ); 38.2033 + jQuery.safariTimer = null; 38.2034 + 38.2035 + // and execute any waiting functions 38.2036 + jQuery.ready(); 38.2037 + } 38.2038 + }, 10); 38.2039 + 38.2040 + // A fallback to window.onload, that will always work 38.2041 + jQuery.event.add( window, "load", jQuery.ready ); 38.2042 +} 38.2043 +jQuery.fn.extend({ 38.2044 + load: function( url, params, callback ) { 38.2045 + if ( jQuery.isFunction( url ) ) 38.2046 + return this.bind("load", url); 38.2047 + 38.2048 + var off = url.indexOf(" "); 38.2049 + if ( off >= 0 ) { 38.2050 + var selector = url.slice(off, url.length); 38.2051 + url = url.slice(0, off); 38.2052 + } 38.2053 + 38.2054 + callback = callback || function(){}; 38.2055 + 38.2056 + // Default to a GET request 38.2057 + var type = "GET"; 38.2058 + 38.2059 + // If the second parameter was provided 38.2060 + if ( params ) 38.2061 + // If it's a function 38.2062 + if ( jQuery.isFunction( params ) ) { 38.2063 + // We assume that it's the callback 38.2064 + callback = params; 38.2065 + params = null; 38.2066 + 38.2067 + // Otherwise, build a param string 38.2068 + } else { 38.2069 + params = jQuery.param( params ); 38.2070 + type = "POST"; 38.2071 + } 38.2072 + 38.2073 + var self = this; 38.2074 + 38.2075 + // Request the remote document 38.2076 + jQuery.ajax({ 38.2077 + url: url, 38.2078 + type: type, 38.2079 + data: params, 38.2080 + complete: function(res, status){ 38.2081 + // If successful, inject the HTML into all the matched elements 38.2082 + if ( status == "success" || status == "notmodified" ) 38.2083 + // See if a selector was specified 38.2084 + self.html( selector ? 38.2085 + // Create a dummy div to hold the results 38.2086 + jQuery("<div/>") 38.2087 + // inject the contents of the document in, removing the scripts 38.2088 + // to avoid any 'Permission Denied' errors in IE 38.2089 + .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 38.2090 + 38.2091 + // Locate the specified elements 38.2092 + .find(selector) : 38.2093 + 38.2094 + // If not, just inject the full result 38.2095 + res.responseText ); 38.2096 + 38.2097 + // Add delay to account for Safari's delay in globalEval 38.2098 + setTimeout(function(){ 38.2099 + self.each( callback, [res.responseText, status, res] ); 38.2100 + }, 13); 38.2101 + } 38.2102 + }); 38.2103 + return this; 38.2104 + }, 38.2105 + 38.2106 + serialize: function() { 38.2107 + return jQuery.param(this.serializeArray()); 38.2108 + }, 38.2109 + serializeArray: function() { 38.2110 + return this.map(function(){ 38.2111 + return jQuery.nodeName(this, "form") ? 38.2112 + jQuery.makeArray(this.elements) : this; 38.2113 + }) 38.2114 + .filter(function(){ 38.2115 + return this.name && !this.disabled && 38.2116 + (this.checked || /select|textarea/i.test(this.nodeName) || 38.2117 + /text|hidden|password/i.test(this.type)); 38.2118 + }) 38.2119 + .map(function(i, elem){ 38.2120 + var val = jQuery(this).val(); 38.2121 + return val == null ? null : 38.2122 + val.constructor == Array ? 38.2123 + jQuery.map( val, function(val, i){ 38.2124 + return {name: elem.name, value: val}; 38.2125 + }) : 38.2126 + {name: elem.name, value: val}; 38.2127 + }).get(); 38.2128 + } 38.2129 +}); 38.2130 + 38.2131 +// Attach a bunch of functions for handling common AJAX events 38.2132 +jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 38.2133 + jQuery.fn[o] = function(f){ 38.2134 + return this.bind(o, f); 38.2135 + }; 38.2136 +}); 38.2137 + 38.2138 +var jsc = (new Date).getTime(); 38.2139 + 38.2140 +jQuery.extend({ 38.2141 + get: function( url, data, callback, type ) { 38.2142 + // shift arguments if data argument was ommited 38.2143 + if ( jQuery.isFunction( data ) ) { 38.2144 + callback = data; 38.2145 + data = null; 38.2146 + } 38.2147 + 38.2148 + return jQuery.ajax({ 38.2149 + type: "GET", 38.2150 + url: url, 38.2151 + data: data, 38.2152 + success: callback, 38.2153 + dataType: type 38.2154 + }); 38.2155 + }, 38.2156 + 38.2157 + getScript: function( url, callback ) { 38.2158 + return jQuery.get(url, null, callback, "script"); 38.2159 + }, 38.2160 + 38.2161 + getJSON: function( url, data, callback ) { 38.2162 + return jQuery.get(url, data, callback, "json"); 38.2163 + }, 38.2164 + 38.2165 + post: function( url, data, callback, type ) { 38.2166 + if ( jQuery.isFunction( data ) ) { 38.2167 + callback = data; 38.2168 + data = {}; 38.2169 + } 38.2170 + 38.2171 + return jQuery.ajax({ 38.2172 + type: "POST", 38.2173 + url: url, 38.2174 + data: data, 38.2175 + success: callback, 38.2176 + dataType: type 38.2177 + }); 38.2178 + }, 38.2179 + 38.2180 + ajaxSetup: function( settings ) { 38.2181 + jQuery.extend( jQuery.ajaxSettings, settings ); 38.2182 + }, 38.2183 + 38.2184 + ajaxSettings: { 38.2185 + global: true, 38.2186 + type: "GET", 38.2187 + timeout: 0, 38.2188 + contentType: "application/x-www-form-urlencoded", 38.2189 + processData: true, 38.2190 + async: true, 38.2191 + data: null 38.2192 + }, 38.2193 + 38.2194 + // Last-Modified header cache for next request 38.2195 + lastModified: {}, 38.2196 + 38.2197 + ajax: function( s ) { 38.2198 + var jsonp, jsre = /=(\?|%3F)/g, status, data; 38.2199 + 38.2200 + // Extend the settings, but re-extend 's' so that it can be 38.2201 + // checked again later (in the test suite, specifically) 38.2202 + s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 38.2203 + 38.2204 + // convert data if not already a string 38.2205 + if ( s.data && s.processData && typeof s.data != "string" ) 38.2206 + s.data = jQuery.param(s.data); 38.2207 + 38.2208 + // Handle JSONP Parameter Callbacks 38.2209 + if ( s.dataType == "jsonp" ) { 38.2210 + if ( s.type.toLowerCase() == "get" ) { 38.2211 + if ( !s.url.match(jsre) ) 38.2212 + s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 38.2213 + } else if ( !s.data || !s.data.match(jsre) ) 38.2214 + s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 38.2215 + s.dataType = "json"; 38.2216 + } 38.2217 + 38.2218 + // Build temporary JSONP function 38.2219 + if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 38.2220 + jsonp = "jsonp" + jsc++; 38.2221 + 38.2222 + // Replace the =? sequence both in the query string and the data 38.2223 + if ( s.data ) 38.2224 + s.data = s.data.replace(jsre, "=" + jsonp); 38.2225 + s.url = s.url.replace(jsre, "=" + jsonp); 38.2226 + 38.2227 + // We need to make sure 38.2228 + // that a JSONP style response is executed properly 38.2229 + s.dataType = "script"; 38.2230 + 38.2231 + // Handle JSONP-style loading 38.2232 + window[ jsonp ] = function(tmp){ 38.2233 + data = tmp; 38.2234 + success(); 38.2235 + complete(); 38.2236 + // Garbage collect 38.2237 + window[ jsonp ] = undefined; 38.2238 + try{ delete window[ jsonp ]; } catch(e){} 38.2239 + }; 38.2240 + } 38.2241 + 38.2242 + if ( s.dataType == "script" && s.cache == null ) 38.2243 + s.cache = false; 38.2244 + 38.2245 + if ( s.cache === false && s.type.toLowerCase() == "get" ) 38.2246 + s.url += (s.url.match(/\?/) ? "&" : "?") + "_=" + (new Date()).getTime(); 38.2247 + 38.2248 + // If data is available, append data to url for get requests 38.2249 + if ( s.data && s.type.toLowerCase() == "get" ) { 38.2250 + s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 38.2251 + 38.2252 + // IE likes to send both get and post data, prevent this 38.2253 + s.data = null; 38.2254 + } 38.2255 + 38.2256 + // Watch for a new set of requests 38.2257 + if ( s.global && ! jQuery.active++ ) 38.2258 + jQuery.event.trigger( "ajaxStart" ); 38.2259 + 38.2260 + // If we're requesting a remote document 38.2261 + // and trying to load JSON or Script 38.2262 + if ( !s.url.indexOf("http") && s.dataType == "script" ) { 38.2263 + var head = document.getElementsByTagName("head")[0]; 38.2264 + var script = document.createElement("script"); 38.2265 + script.src = s.url; 38.2266 + 38.2267 + // Handle Script loading 38.2268 + if ( !jsonp && (s.success || s.complete) ) { 38.2269 + var done = false; 38.2270 + 38.2271 + // Attach handlers for all browsers 38.2272 + script.onload = script.onreadystatechange = function(){ 38.2273 + if ( !done && (!this.readyState || 38.2274 + this.readyState == "loaded" || this.readyState == "complete") ) { 38.2275 + done = true; 38.2276 + success(); 38.2277 + complete(); 38.2278 + head.removeChild( script ); 38.2279 + } 38.2280 + }; 38.2281 + } 38.2282 + 38.2283 + head.appendChild(script); 38.2284 + 38.2285 + // We handle everything using the script element injection 38.2286 + return; 38.2287 + } 38.2288 + 38.2289 + var requestDone = false; 38.2290 + 38.2291 + // Create the request object; Microsoft failed to properly 38.2292 + // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 38.2293 + var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 38.2294 + 38.2295 + // Open the socket 38.2296 + xml.open(s.type, s.url, s.async); 38.2297 + 38.2298 + // Set the correct header, if data is being sent 38.2299 + if ( s.data ) 38.2300 + xml.setRequestHeader("Content-Type", s.contentType); 38.2301 + 38.2302 + // Set the If-Modified-Since header, if ifModified mode. 38.2303 + if ( s.ifModified ) 38.2304 + xml.setRequestHeader("If-Modified-Since", 38.2305 + jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 38.2306 + 38.2307 + // Set header so the called script knows that it's an XMLHttpRequest 38.2308 + xml.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 38.2309 + 38.2310 + // Allow custom headers/mimetypes 38.2311 + if ( s.beforeSend ) 38.2312 + s.beforeSend(xml); 38.2313 + 38.2314 + if ( s.global ) 38.2315 + jQuery.event.trigger("ajaxSend", [xml, s]); 38.2316 + 38.2317 + // Wait for a response to come back 38.2318 + var onreadystatechange = function(isTimeout){ 38.2319 + // The transfer is complete and the data is available, or the request timed out 38.2320 + if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) { 38.2321 + requestDone = true; 38.2322 + 38.2323 + // clear poll interval 38.2324 + if (ival) { 38.2325 + clearInterval(ival); 38.2326 + ival = null; 38.2327 + } 38.2328 + 38.2329 + status = isTimeout == "timeout" && "timeout" || 38.2330 + !jQuery.httpSuccess( xml ) && "error" || 38.2331 + s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" || 38.2332 + "success"; 38.2333 + 38.2334 + if ( status == "success" ) { 38.2335 + // Watch for, and catch, XML document parse errors 38.2336 + try { 38.2337 + // process the data (runs the xml through httpData regardless of callback) 38.2338 + data = jQuery.httpData( xml, s.dataType ); 38.2339 + } catch(e) { 38.2340 + status = "parsererror"; 38.2341 + } 38.2342 + } 38.2343 + 38.2344 + // Make sure that the request was successful or notmodified 38.2345 + if ( status == "success" ) { 38.2346 + // Cache Last-Modified header, if ifModified mode. 38.2347 + var modRes; 38.2348 + try { 38.2349 + modRes = xml.getResponseHeader("Last-Modified"); 38.2350 + } catch(e) {} // swallow exception thrown by FF if header is not available 38.2351 + 38.2352 + if ( s.ifModified && modRes ) 38.2353 + jQuery.lastModified[s.url] = modRes; 38.2354 + 38.2355 + // JSONP handles its own success callback 38.2356 + if ( !jsonp ) 38.2357 + success(); 38.2358 + } else 38.2359 + jQuery.handleError(s, xml, status); 38.2360 + 38.2361 + // Fire the complete handlers 38.2362 + complete(); 38.2363 + 38.2364 + // Stop memory leaks 38.2365 + if ( s.async ) 38.2366 + xml = null; 38.2367 + } 38.2368 + }; 38.2369 + 38.2370 + if ( s.async ) { 38.2371 + // don't attach the handler to the request, just poll it instead 38.2372 + var ival = setInterval(onreadystatechange, 13); 38.2373 + 38.2374 + // Timeout checker 38.2375 + if ( s.timeout > 0 ) 38.2376 + setTimeout(function(){ 38.2377 + // Check to see if the request is still happening 38.2378 + if ( xml ) { 38.2379 + // Cancel the request 38.2380 + xml.abort(); 38.2381 + 38.2382 + if( !requestDone ) 38.2383 + onreadystatechange( "timeout" ); 38.2384 + } 38.2385 + }, s.timeout); 38.2386 + } 38.2387 + 38.2388 + // Send the data 38.2389 + try { 38.2390 + xml.send(s.data); 38.2391 + } catch(e) { 38.2392 + jQuery.handleError(s, xml, null, e); 38.2393 + } 38.2394 + 38.2395 + // firefox 1.5 doesn't fire statechange for sync requests 38.2396 + if ( !s.async ) 38.2397 + onreadystatechange(); 38.2398 + 38.2399 + // return XMLHttpRequest to allow aborting the request etc. 38.2400 + return xml; 38.2401 + 38.2402 + function success(){ 38.2403 + // If a local callback was specified, fire it and pass it the data 38.2404 + if ( s.success ) 38.2405 + s.success( data, status ); 38.2406 + 38.2407 + // Fire the global callback 38.2408 + if ( s.global ) 38.2409 + jQuery.event.trigger( "ajaxSuccess", [xml, s] ); 38.2410 + } 38.2411 + 38.2412 + function complete(){ 38.2413 + // Process result 38.2414 + if ( s.complete ) 38.2415 + s.complete(xml, status); 38.2416 + 38.2417 + // The request was completed 38.2418 + if ( s.global ) 38.2419 + jQuery.event.trigger( "ajaxComplete", [xml, s] ); 38.2420 + 38.2421 + // Handle the global AJAX counter 38.2422 + if ( s.global && ! --jQuery.active ) 38.2423 + jQuery.event.trigger( "ajaxStop" ); 38.2424 + } 38.2425 + }, 38.2426 + 38.2427 + handleError: function( s, xml, status, e ) { 38.2428 + // If a local callback was specified, fire it 38.2429 + if ( s.error ) s.error( xml, status, e ); 38.2430 + 38.2431 + // Fire the global callback 38.2432 + if ( s.global ) 38.2433 + jQuery.event.trigger( "ajaxError", [xml, s, e] ); 38.2434 + }, 38.2435 + 38.2436 + // Counter for holding the number of active queries 38.2437 + active: 0, 38.2438 + 38.2439 + // Determines if an XMLHttpRequest was successful or not 38.2440 + httpSuccess: function( r ) { 38.2441 + try { 38.2442 + return !r.status && location.protocol == "file:" || 38.2443 + ( r.status >= 200 && r.status < 300 ) || r.status == 304 || 38.2444 + jQuery.browser.safari && r.status == undefined; 38.2445 + } catch(e){} 38.2446 + return false; 38.2447 + }, 38.2448 + 38.2449 + // Determines if an XMLHttpRequest returns NotModified 38.2450 + httpNotModified: function( xml, url ) { 38.2451 + try { 38.2452 + var xmlRes = xml.getResponseHeader("Last-Modified"); 38.2453 + 38.2454 + // Firefox always returns 200. check Last-Modified date 38.2455 + return xml.status == 304 || xmlRes == jQuery.lastModified[url] || 38.2456 + jQuery.browser.safari && xml.status == undefined; 38.2457 + } catch(e){} 38.2458 + return false; 38.2459 + }, 38.2460 + 38.2461 + httpData: function( r, type ) { 38.2462 + var ct = r.getResponseHeader("content-type"); 38.2463 + var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0; 38.2464 + var data = xml ? r.responseXML : r.responseText; 38.2465 + 38.2466 + if ( xml && data.documentElement.tagName == "parsererror" ) 38.2467 + throw "parsererror"; 38.2468 + 38.2469 + // If the type is "script", eval it in global context 38.2470 + if ( type == "script" ) 38.2471 + jQuery.globalEval( data ); 38.2472 + 38.2473 + // Get the JavaScript object, if JSON is used. 38.2474 + if ( type == "json" ) 38.2475 + data = eval("(" + data + ")"); 38.2476 + 38.2477 + return data; 38.2478 + }, 38.2479 + 38.2480 + // Serialize an array of form elements or a set of 38.2481 + // key/values into a query string 38.2482 + param: function( a ) { 38.2483 + var s = []; 38.2484 + 38.2485 + // If an array was passed in, assume that it is an array 38.2486 + // of form elements 38.2487 + if ( a.constructor == Array || a.jquery ) 38.2488 + // Serialize the form elements 38.2489 + jQuery.each( a, function(){ 38.2490 + s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); 38.2491 + }); 38.2492 + 38.2493 + // Otherwise, assume that it's an object of key/value pairs 38.2494 + else 38.2495 + // Serialize the key/values 38.2496 + for ( var j in a ) 38.2497 + // If the value is an array then the key names need to be repeated 38.2498 + if ( a[j] && a[j].constructor == Array ) 38.2499 + jQuery.each( a[j], function(){ 38.2500 + s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 38.2501 + }); 38.2502 + else 38.2503 + s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) ); 38.2504 + 38.2505 + // Return the resulting serialization 38.2506 + return s.join("&").replace(/%20/g, "+"); 38.2507 + } 38.2508 + 38.2509 +}); 38.2510 +jQuery.fn.extend({ 38.2511 + show: function(speed,callback){ 38.2512 + return speed ? 38.2513 + this.animate({ 38.2514 + height: "show", width: "show", opacity: "show" 38.2515 + }, speed, callback) : 38.2516 + 38.2517 + this.filter(":hidden").each(function(){ 38.2518 + this.style.display = this.oldblock ? this.oldblock : ""; 38.2519 + if ( jQuery.css(this,"display") == "none" ) 38.2520 + this.style.display = "block"; 38.2521 + }).end(); 38.2522 + }, 38.2523 + 38.2524 + hide: function(speed,callback){ 38.2525 + return speed ? 38.2526 + this.animate({ 38.2527 + height: "hide", width: "hide", opacity: "hide" 38.2528 + }, speed, callback) : 38.2529 + 38.2530 + this.filter(":visible").each(function(){ 38.2531 + this.oldblock = this.oldblock || jQuery.css(this,"display"); 38.2532 + if ( this.oldblock == "none" ) 38.2533 + this.oldblock = "block"; 38.2534 + this.style.display = "none"; 38.2535 + }).end(); 38.2536 + }, 38.2537 + 38.2538 + // Save the old toggle function 38.2539 + _toggle: jQuery.fn.toggle, 38.2540 + 38.2541 + toggle: function( fn, fn2 ){ 38.2542 + return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 38.2543 + this._toggle( fn, fn2 ) : 38.2544 + fn ? 38.2545 + this.animate({ 38.2546 + height: "toggle", width: "toggle", opacity: "toggle" 38.2547 + }, fn, fn2) : 38.2548 + this.each(function(){ 38.2549 + jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 38.2550 + }); 38.2551 + }, 38.2552 + 38.2553 + slideDown: function(speed,callback){ 38.2554 + return this.animate({height: "show"}, speed, callback); 38.2555 + }, 38.2556 + 38.2557 + slideUp: function(speed,callback){ 38.2558 + return this.animate({height: "hide"}, speed, callback); 38.2559 + }, 38.2560 + 38.2561 + slideToggle: function(speed, callback){ 38.2562 + return this.animate({height: "toggle"}, speed, callback); 38.2563 + }, 38.2564 + 38.2565 + fadeIn: function(speed, callback){ 38.2566 + return this.animate({opacity: "show"}, speed, callback); 38.2567 + }, 38.2568 + 38.2569 + fadeOut: function(speed, callback){ 38.2570 + return this.animate({opacity: "hide"}, speed, callback); 38.2571 + }, 38.2572 + 38.2573 + fadeTo: function(speed,to,callback){ 38.2574 + return this.animate({opacity: to}, speed, callback); 38.2575 + }, 38.2576 + 38.2577 + animate: function( prop, speed, easing, callback ) { 38.2578 + var opt = jQuery.speed(speed, easing, callback); 38.2579 + 38.2580 + return this[ opt.queue === false ? "each" : "queue" ](function(){ 38.2581 + opt = jQuery.extend({}, opt); 38.2582 + var hidden = jQuery(this).is(":hidden"), self = this; 38.2583 + 38.2584 + for ( var p in prop ) { 38.2585 + if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 38.2586 + return jQuery.isFunction(opt.complete) && opt.complete.apply(this); 38.2587 + 38.2588 + if ( p == "height" || p == "width" ) { 38.2589 + // Store display property 38.2590 + opt.display = jQuery.css(this, "display"); 38.2591 + 38.2592 + // Make sure that nothing sneaks out 38.2593 + opt.overflow = this.style.overflow; 38.2594 + } 38.2595 + } 38.2596 + 38.2597 + if ( opt.overflow != null ) 38.2598 + this.style.overflow = "hidden"; 38.2599 + 38.2600 + opt.curAnim = jQuery.extend({}, prop); 38.2601 + 38.2602 + jQuery.each( prop, function(name, val){ 38.2603 + var e = new jQuery.fx( self, opt, name ); 38.2604 + 38.2605 + if ( /toggle|show|hide/.test(val) ) 38.2606 + e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 38.2607 + else { 38.2608 + var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 38.2609 + start = e.cur(true) || 0; 38.2610 + 38.2611 + if ( parts ) { 38.2612 + var end = parseFloat(parts[2]), 38.2613 + unit = parts[3] || "px"; 38.2614 + 38.2615 + // We need to compute starting value 38.2616 + if ( unit != "px" ) { 38.2617 + self.style[ name ] = (end || 1) + unit; 38.2618 + start = ((end || 1) / e.cur(true)) * start; 38.2619 + self.style[ name ] = start + unit; 38.2620 + } 38.2621 + 38.2622 + // If a +=/-= token was provided, we're doing a relative animation 38.2623 + if ( parts[1] ) 38.2624 + end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 38.2625 + 38.2626 + e.custom( start, end, unit ); 38.2627 + } else 38.2628 + e.custom( start, val, "" ); 38.2629 + } 38.2630 + }); 38.2631 + 38.2632 + // For JS strict compliance 38.2633 + return true; 38.2634 + }); 38.2635 + }, 38.2636 + 38.2637 + queue: function(type, fn){ 38.2638 + if ( jQuery.isFunction(type) ) { 38.2639 + fn = type; 38.2640 + type = "fx"; 38.2641 + } 38.2642 + 38.2643 + if ( !type || (typeof type == "string" && !fn) ) 38.2644 + return queue( this[0], type ); 38.2645 + 38.2646 + return this.each(function(){ 38.2647 + if ( fn.constructor == Array ) 38.2648 + queue(this, type, fn); 38.2649 + else { 38.2650 + queue(this, type).push( fn ); 38.2651 + 38.2652 + if ( queue(this, type).length == 1 ) 38.2653 + fn.apply(this); 38.2654 + } 38.2655 + }); 38.2656 + }, 38.2657 + 38.2658 + stop: function(){ 38.2659 + var timers = jQuery.timers; 38.2660 + 38.2661 + return this.each(function(){ 38.2662 + for ( var i = 0; i < timers.length; i++ ) 38.2663 + if ( timers[i].elem == this ) 38.2664 + timers.splice(i--, 1); 38.2665 + }).dequeue(); 38.2666 + } 38.2667 + 38.2668 +}); 38.2669 + 38.2670 +var queue = function( elem, type, array ) { 38.2671 + if ( !elem ) 38.2672 + return; 38.2673 + 38.2674 + var q = jQuery.data( elem, type + "queue" ); 38.2675 + 38.2676 + if ( !q || array ) 38.2677 + q = jQuery.data( elem, type + "queue", 38.2678 + array ? jQuery.makeArray(array) : [] ); 38.2679 + 38.2680 + return q; 38.2681 +}; 38.2682 + 38.2683 +jQuery.fn.dequeue = function(type){ 38.2684 + type = type || "fx"; 38.2685 + 38.2686 + return this.each(function(){ 38.2687 + var q = queue(this, type); 38.2688 + 38.2689 + q.shift(); 38.2690 + 38.2691 + if ( q.length ) 38.2692 + q[0].apply( this ); 38.2693 + }); 38.2694 +}; 38.2695 + 38.2696 +jQuery.extend({ 38.2697 + 38.2698 + speed: function(speed, easing, fn) { 38.2699 + var opt = speed && speed.constructor == Object ? speed : { 38.2700 + complete: fn || !fn && easing || 38.2701 + jQuery.isFunction( speed ) && speed, 38.2702 + duration: speed, 38.2703 + easing: fn && easing || easing && easing.constructor != Function && easing 38.2704 + }; 38.2705 + 38.2706 + opt.duration = (opt.duration && opt.duration.constructor == Number ? 38.2707 + opt.duration : 38.2708 + { slow: 600, fast: 200 }[opt.duration]) || 400; 38.2709 + 38.2710 + // Queueing 38.2711 + opt.old = opt.complete; 38.2712 + opt.complete = function(){ 38.2713 + jQuery(this).dequeue(); 38.2714 + if ( jQuery.isFunction( opt.old ) ) 38.2715 + opt.old.apply( this ); 38.2716 + }; 38.2717 + 38.2718 + return opt; 38.2719 + }, 38.2720 + 38.2721 + easing: { 38.2722 + linear: function( p, n, firstNum, diff ) { 38.2723 + return firstNum + diff * p; 38.2724 + }, 38.2725 + swing: function( p, n, firstNum, diff ) { 38.2726 + return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 38.2727 + } 38.2728 + }, 38.2729 + 38.2730 + timers: [], 38.2731 + 38.2732 + fx: function( elem, options, prop ){ 38.2733 + this.options = options; 38.2734 + this.elem = elem; 38.2735 + this.prop = prop; 38.2736 + 38.2737 + if ( !options.orig ) 38.2738 + options.orig = {}; 38.2739 + } 38.2740 + 38.2741 +}); 38.2742 + 38.2743 +jQuery.fx.prototype = { 38.2744 + 38.2745 + // Simple function for setting a style value 38.2746 + update: function(){ 38.2747 + if ( this.options.step ) 38.2748 + this.options.step.apply( this.elem, [ this.now, this ] ); 38.2749 + 38.2750 + (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 38.2751 + 38.2752 + // Set display property to block for height/width animations 38.2753 + if ( this.prop == "height" || this.prop == "width" ) 38.2754 + this.elem.style.display = "block"; 38.2755 + }, 38.2756 + 38.2757 + // Get the current size 38.2758 + cur: function(force){ 38.2759 + if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null ) 38.2760 + return this.elem[ this.prop ]; 38.2761 + 38.2762 + var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force)); 38.2763 + return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0; 38.2764 + }, 38.2765 + 38.2766 + // Start an animation from one number to another 38.2767 + custom: function(from, to, unit){ 38.2768 + this.startTime = (new Date()).getTime(); 38.2769 + this.start = from; 38.2770 + this.end = to; 38.2771 + this.unit = unit || this.unit || "px"; 38.2772 + this.now = this.start; 38.2773 + this.pos = this.state = 0; 38.2774 + this.update(); 38.2775 + 38.2776 + var self = this; 38.2777 + function t(){ 38.2778 + return self.step(); 38.2779 + } 38.2780 + 38.2781 + t.elem = this.elem; 38.2782 + 38.2783 + jQuery.timers.push(t); 38.2784 + 38.2785 + if ( jQuery.timers.length == 1 ) { 38.2786 + var timer = setInterval(function(){ 38.2787 + var timers = jQuery.timers; 38.2788 + 38.2789 + for ( var i = 0; i < timers.length; i++ ) 38.2790 + if ( !timers[i]() ) 38.2791 + timers.splice(i--, 1); 38.2792 + 38.2793 + if ( !timers.length ) 38.2794 + clearInterval( timer ); 38.2795 + }, 13); 38.2796 + } 38.2797 + }, 38.2798 + 38.2799 + // Simple 'show' function 38.2800 + show: function(){ 38.2801 + // Remember where we started, so that we can go back to it later 38.2802 + this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 38.2803 + this.options.show = true; 38.2804 + 38.2805 + // Begin the animation 38.2806 + this.custom(0, this.cur()); 38.2807 + 38.2808 + // Make sure that we start at a small width/height to avoid any 38.2809 + // flash of content 38.2810 + if ( this.prop == "width" || this.prop == "height" ) 38.2811 + this.elem.style[this.prop] = "1px"; 38.2812 + 38.2813 + // Start by showing the element 38.2814 + jQuery(this.elem).show(); 38.2815 + }, 38.2816 + 38.2817 + // Simple 'hide' function 38.2818 + hide: function(){ 38.2819 + // Remember where we started, so that we can go back to it later 38.2820 + this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 38.2821 + this.options.hide = true; 38.2822 + 38.2823 + // Begin the animation 38.2824 + this.custom(this.cur(), 0); 38.2825 + }, 38.2826 + 38.2827 + // Each step of an animation 38.2828 + step: function(){ 38.2829 + var t = (new Date()).getTime(); 38.2830 + 38.2831 + if ( t > this.options.duration + this.startTime ) { 38.2832 + this.now = this.end; 38.2833 + this.pos = this.state = 1; 38.2834 + this.update(); 38.2835 + 38.2836 + this.options.curAnim[ this.prop ] = true; 38.2837 + 38.2838 + var done = true; 38.2839 + for ( var i in this.options.curAnim ) 38.2840 + if ( this.options.curAnim[i] !== true ) 38.2841 + done = false; 38.2842 + 38.2843 + if ( done ) { 38.2844 + if ( this.options.display != null ) { 38.2845 + // Reset the overflow 38.2846 + this.elem.style.overflow = this.options.overflow; 38.2847 + 38.2848 + // Reset the display 38.2849 + this.elem.style.display = this.options.display; 38.2850 + if ( jQuery.css(this.elem, "display") == "none" ) 38.2851 + this.elem.style.display = "block"; 38.2852 + } 38.2853 + 38.2854 + // Hide the element if the "hide" operation was done 38.2855 + if ( this.options.hide ) 38.2856 + this.elem.style.display = "none"; 38.2857 + 38.2858 + // Reset the properties, if the item has been hidden or shown 38.2859 + if ( this.options.hide || this.options.show ) 38.2860 + for ( var p in this.options.curAnim ) 38.2861 + jQuery.attr(this.elem.style, p, this.options.orig[p]); 38.2862 + } 38.2863 + 38.2864 + // If a callback was provided, execute it 38.2865 + if ( done && jQuery.isFunction( this.options.complete ) ) 38.2866 + // Execute the complete function 38.2867 + this.options.complete.apply( this.elem ); 38.2868 + 38.2869 + return false; 38.2870 + } else { 38.2871 + var n = t - this.startTime; 38.2872 + this.state = n / this.options.duration; 38.2873 + 38.2874 + // Perform the easing function, defaults to swing 38.2875 + this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 38.2876 + this.now = this.start + ((this.end - this.start) * this.pos); 38.2877 + 38.2878 + // Perform the next step of the animation 38.2879 + this.update(); 38.2880 + } 38.2881 + 38.2882 + return true; 38.2883 + } 38.2884 + 38.2885 +}; 38.2886 + 38.2887 +jQuery.fx.step = { 38.2888 + scrollLeft: function(fx){ 38.2889 + fx.elem.scrollLeft = fx.now; 38.2890 + }, 38.2891 + 38.2892 + scrollTop: function(fx){ 38.2893 + fx.elem.scrollTop = fx.now; 38.2894 + }, 38.2895 + 38.2896 + opacity: function(fx){ 38.2897 + jQuery.attr(fx.elem.style, "opacity", fx.now); 38.2898 + }, 38.2899 + 38.2900 + _default: function(fx){ 38.2901 + fx.elem.style[ fx.prop ] = fx.now + fx.unit; 38.2902 + } 38.2903 +}; 38.2904 +// The Offset Method 38.2905 +// Originally By Brandon Aaron, part of the Dimension Plugin 38.2906 +// http://jquery.com/plugins/project/dimensions 38.2907 +jQuery.fn.offset = function() { 38.2908 + var left = 0, top = 0, elem = this[0], results; 38.2909 + 38.2910 + if ( elem ) with ( jQuery.browser ) { 38.2911 + var absolute = jQuery.css(elem, "position") == "absolute", 38.2912 + parent = elem.parentNode, 38.2913 + offsetParent = elem.offsetParent, 38.2914 + doc = elem.ownerDocument, 38.2915 + safari2 = safari && parseInt(version) < 522; 38.2916 + 38.2917 + // Use getBoundingClientRect if available 38.2918 + if ( elem.getBoundingClientRect ) { 38.2919 + box = elem.getBoundingClientRect(); 38.2920 + 38.2921 + // Add the document scroll offsets 38.2922 + add( 38.2923 + box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 38.2924 + box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop) 38.2925 + ); 38.2926 + 38.2927 + // IE adds the HTML element's border, by default it is medium which is 2px 38.2928 + // IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; } 38.2929 + // IE 7 standards mode, the border is always 2px 38.2930 + if ( msie ) { 38.2931 + var border = jQuery("html").css("borderWidth"); 38.2932 + border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border; 38.2933 + add( -border, -border ); 38.2934 + } 38.2935 + 38.2936 + // Otherwise loop through the offsetParents and parentNodes 38.2937 + } else { 38.2938 + 38.2939 + // Initial element offsets 38.2940 + add( elem.offsetLeft, elem.offsetTop ); 38.2941 + 38.2942 + // Get parent offsets 38.2943 + while ( offsetParent ) { 38.2944 + // Add offsetParent offsets 38.2945 + add( offsetParent.offsetLeft, offsetParent.offsetTop ); 38.2946 + 38.2947 + // Mozilla and Safari > 2 does not include the border on offset parents 38.2948 + // However Mozilla adds the border for table cells 38.2949 + if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 ) 38.2950 + border( offsetParent ); 38.2951 + 38.2952 + // Safari <= 2 doubles body offsets with an absolutely positioned element or parent 38.2953 + if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" ) 38.2954 + absolute = true; 38.2955 + 38.2956 + // Get next offsetParent 38.2957 + offsetParent = offsetParent.offsetParent; 38.2958 + } 38.2959 + 38.2960 + // Get parent scroll offsets 38.2961 + while ( parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 38.2962 + // Work around opera inline/table scrollLeft/Top bug 38.2963 + if ( !/^inline|table-row.*$/i.test(jQuery.css(parent, "display")) ) 38.2964 + // Subtract parent scroll offsets 38.2965 + add( -parent.scrollLeft, -parent.scrollTop ); 38.2966 + 38.2967 + // Mozilla does not add the border for a parent that has overflow != visible 38.2968 + if ( mozilla && jQuery.css(parent, "overflow") != "visible" ) 38.2969 + border( parent ); 38.2970 + 38.2971 + // Get next parent 38.2972 + parent = parent.parentNode; 38.2973 + } 38.2974 + 38.2975 + // Safari doubles body offsets with an absolutely positioned element or parent 38.2976 + if ( safari2 && absolute ) 38.2977 + add( -doc.body.offsetLeft, -doc.body.offsetTop ); 38.2978 + } 38.2979 + 38.2980 + // Return an object with top and left properties 38.2981 + results = { top: top, left: left }; 38.2982 + } 38.2983 + 38.2984 + return results; 38.2985 + 38.2986 + function border(elem) { 38.2987 + add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") ); 38.2988 + } 38.2989 + 38.2990 + function add(l, t) { 38.2991 + left += parseInt(l) || 0; 38.2992 + top += parseInt(t) || 0; 38.2993 + } 38.2994 +}; 38.2995 +})();
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/web/robots.txt Tue Mar 10 21:42:19 2009 -0700 39.3 @@ -0,0 +1,2 @@ 39.4 +User-agent: * 39.5 +Disallow: /feeds/
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/web/texpand.py Tue Mar 10 21:42:19 2009 -0700 40.3 @@ -0,0 +1,35 @@ 40.4 +#!/usr/bin/env python 40.5 +# 40.6 +# Use Django's template machinery to expand static web pages. First 40.7 +# tries the default template path for a particular installation, then 40.8 +# looks for templates in the filesystem. 40.9 + 40.10 +from django.template import Context, TemplateDoesNotExist 40.11 +from django.template.loader import get_template, get_template_from_string 40.12 +from django.core.management import setup_environ 40.13 +import rwh.settings as settings 40.14 +import sys 40.15 + 40.16 +setup_environ(settings) 40.17 +c = Context() 40.18 + 40.19 +if len(sys.argv) == 2: 40.20 + in_name = sys.argv[1] 40.21 + out_name = 'stdout' 40.22 + out_fp = sys.stdout 40.23 +elif len(sys.argv) == 3: 40.24 + in_name = sys.argv[1] 40.25 + out_name = sys.argv[2] 40.26 + out_fp = None 40.27 +else: 40.28 + print >> sys.stderr, 'Usage: %s template-file [output-file]' 40.29 + sys.exit(1) 40.30 + 40.31 +try: 40.32 + t = get_template(in_name) 40.33 +except TemplateDoesNotExist: 40.34 + t = get_template_from_string(open(in_name).read(), name=in_name) 40.35 +if out_fp is None: 40.36 + out_fp = open(out_name, 'w') 40.37 +out_fp.write(t.render(c)) 40.38 +out_fp.close()