Updated with smarter commentary and better code.

This commit is contained in:
Ken Sternberg 2011-02-03 19:15:16 -08:00
parent ab8aa78c7c
commit e448dd503e
7 changed files with 8962 additions and 770 deletions

58
Makefile Normal file
View File

@ -0,0 +1,58 @@
.SUFFIXES: .nw .js .pdf .html .tex
NOTANGLE= notangle
NOWEAVE= noweave
ECHO= /bin/echo
all: index.html store.js
.nw.html:
$(NOWEAVE) -filter l2h -delay -x -index -autodefs c -html $*.nw > $*.html
.nw.tex:
$(NOWEAVE) -x -delay $*.nw > $*.tex #$
.tex.pdf:
xelatex $*.tex; \
while grep -s 'Rerun to get cross-references right' $*.log; \
do \
xelatex *$.tex; \
done
.nw.js:
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-js-tmp
@ if [ -s "$*.nw-js-tmp" ]; then \
mv $*.nw-js-tmp $@; \
else \
echo "$@ not found in $<"; \
rm $*.nw-js-tmp; \
fi
store.js: backbonestore.nw
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
@ if [ -s "$*.nw-html-tmp" ]; then \
mv $*.nw-html-tmp $@; \
else \
echo "$@ not found in $<"; \
rm $*.nw-tmp; \
fi
index.html:
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
@ if [ -s "$*.nw-html-tmp" ]; then \
mv $*.nw-html-tmp $@; \
else \
echo "$@ not found in $<"; \
rm $*.nw-tmp; \
fi
clean:
- rm -f *.tex *.dvi *.aux *.toc *.log *.out *.html *.js
realclean: clean
- rm -f *.pdf

View File

@ -1,4 +1,4 @@
// Backbone.js 0.3.2 // Backbone.js 0.3.3
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc. // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license. // Backbone may be freely distributed under the MIT license.
// For all details and documentation: // For all details and documentation:
@ -19,14 +19,14 @@
} }
// Current version of the library. Keep in sync with `package.json`. // Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '0.3.2'; Backbone.VERSION = '0.3.3';
// Require Underscore, if we're on the server, and it's not already present. // Require Underscore, if we're on the server, and it's not already present.
var _ = this._; var _ = this._;
if (!_ && (typeof require !== 'undefined')) _ = require("underscore")._; if (!_ && (typeof require !== 'undefined')) _ = require("underscore")._;
// For Backbone's purposes, jQuery owns the `$` variable. // For Backbone's purposes, either jQuery or Zepto owns the `$` variable.
var $ = this.jQuery; var $ = this.jQuery || this.Zepto;
// Turn on `emulateHTTP` to use support legacy HTTP servers. Setting this option will // Turn on `emulateHTTP` to use support legacy HTTP servers. Setting this option will
// fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a // fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
@ -116,6 +116,7 @@
attributes || (attributes = {}); attributes || (attributes = {});
if (this.defaults) attributes = _.extend({}, this.defaults, attributes); if (this.defaults) attributes = _.extend({}, this.defaults, attributes);
this.attributes = {}; this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c'); this.cid = _.uniqueId('c');
this.set(attributes, {silent : true}); this.set(attributes, {silent : true});
this._previousAttributes = _.clone(this.attributes); this._previousAttributes = _.clone(this.attributes);
@ -147,6 +148,14 @@
return this.attributes[attr]; return this.attributes[attr];
}, },
// Get the HTML-escaped value of an attribute.
escape : function(attr) {
var html;
if (html = this._escapedAttributes[attr]) return html;
var val = this.attributes[attr];
return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : val);
},
// Set a hash of model attributes on the object, firing `"change"` unless you // Set a hash of model attributes on the object, firing `"change"` unless you
// choose to silence it. // choose to silence it.
set : function(attrs, options) { set : function(attrs, options) {
@ -155,7 +164,7 @@
options || (options = {}); options || (options = {});
if (!attrs) return this; if (!attrs) return this;
if (attrs.attributes) attrs = attrs.attributes; if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes; var now = this.attributes, escaped = this._escapedAttributes;
// Run validation. // Run validation.
if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false; if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;
@ -168,15 +177,16 @@
var val = attrs[attr]; var val = attrs[attr];
if (!_.isEqual(now[attr], val)) { if (!_.isEqual(now[attr], val)) {
now[attr] = val; now[attr] = val;
delete escaped[attr];
if (!options.silent) { if (!options.silent) {
this._changed = true; this._changed = true;
this.trigger('change:' + attr, this, val); this.trigger('change:' + attr, this, val, options);
} }
} }
} }
// Fire the `"change"` event, if the model has been changed. // Fire the `"change"` event, if the model has been changed.
if (!options.silent && this._changed) this.change(); if (!options.silent && this._changed) this.change(options);
return this; return this;
}, },
@ -193,10 +203,11 @@
// Remove the attribute. // Remove the attribute.
delete this.attributes[attr]; delete this.attributes[attr];
delete this._escapedAttributes[attr];
if (!options.silent) { if (!options.silent) {
this._changed = true; this._changed = true;
this.trigger('change:' + attr, this); this.trigger('change:' + attr, this, void 0, options);
this.change(); this.change(options);
} }
return this; return this;
}, },
@ -213,12 +224,13 @@
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false; if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
this.attributes = {}; this.attributes = {};
this._escapedAttributes = {};
if (!options.silent) { if (!options.silent) {
this._changed = true; this._changed = true;
for (attr in old) { for (attr in old) {
this.trigger('change:' + attr, this); this.trigger('change:' + attr, this, void 0, options);
} }
this.change(); this.change(options);
} }
return this; return this;
}, },
@ -233,7 +245,7 @@
if (!model.set(model.parse(resp), options)) return false; if (!model.set(model.parse(resp), options)) return false;
if (options.success) options.success(model, resp); if (options.success) options.success(model, resp);
}; };
var error = options.error && _.bind(options.error, null, model); var error = wrapError(options.error, model, options);
(this.sync || Backbone.sync)('read', this, success, error); (this.sync || Backbone.sync)('read', this, success, error);
return this; return this;
}, },
@ -249,7 +261,7 @@
if (!model.set(model.parse(resp), options)) return false; if (!model.set(model.parse(resp), options)) return false;
if (options.success) options.success(model, resp); if (options.success) options.success(model, resp);
}; };
var error = options.error && _.bind(options.error, null, model); var error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update'; var method = this.isNew() ? 'create' : 'update';
(this.sync || Backbone.sync)(method, this, success, error); (this.sync || Backbone.sync)(method, this, success, error);
return this; return this;
@ -264,7 +276,7 @@
if (model.collection) model.collection.remove(model); if (model.collection) model.collection.remove(model);
if (options.success) options.success(model, resp); if (options.success) options.success(model, resp);
}; };
var error = options.error && _.bind(options.error, null, model); var error = wrapError(options.error, model, options);
(this.sync || Backbone.sync)('delete', this, success, error); (this.sync || Backbone.sync)('delete', this, success, error);
return this; return this;
}, },
@ -297,8 +309,8 @@
// Call this method to manually fire a `change` event for this model. // Call this method to manually fire a `change` event for this model.
// Calling this will cause all objects observing the model to update. // Calling this will cause all objects observing the model to update.
change : function() { change : function(options) {
this.trigger('change', this); this.trigger('change', this, options);
this._previousAttributes = _.clone(this.attributes); this._previousAttributes = _.clone(this.attributes);
this._changed = false; this._changed = false;
}, },
@ -349,7 +361,7 @@
if (options.error) { if (options.error) {
options.error(this, error); options.error(this, error);
} else { } else {
this.trigger('error', this, error); this.trigger('error', this, error, options);
} }
return false; return false;
} }
@ -441,7 +453,7 @@
options || (options = {}); options || (options = {});
if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
this.models = this.sortBy(this.comparator); this.models = this.sortBy(this.comparator);
if (!options.silent) this.trigger('refresh', this); if (!options.silent) this.trigger('refresh', this, options);
return this; return this;
}, },
@ -458,7 +470,7 @@
options || (options = {}); options || (options = {});
this._reset(); this._reset();
this.add(models, {silent: true}); this.add(models, {silent: true});
if (!options.silent) this.trigger('refresh', this); if (!options.silent) this.trigger('refresh', this, options);
return this; return this;
}, },
@ -471,7 +483,7 @@
collection.refresh(collection.parse(resp)); collection.refresh(collection.parse(resp));
if (options.success) options.success(collection, resp); if (options.success) options.success(collection, resp);
}; };
var error = options.error && _.bind(options.error, null, collection); var error = wrapError(options.error, collection, options);
(this.sync || Backbone.sync)('read', this, success, error); (this.sync || Backbone.sync)('read', this, success, error);
return this; return this;
}, },
@ -530,7 +542,7 @@
this.models.splice(index, 0, model); this.models.splice(index, 0, model);
model.bind('all', this._boundOnModelEvent); model.bind('all', this._boundOnModelEvent);
this.length++; this.length++;
if (!options.silent) model.trigger('add', model, this); if (!options.silent) model.trigger('add', model, this, options);
return model; return model;
}, },
@ -545,7 +557,7 @@
delete model.collection; delete model.collection;
this.models.splice(this.indexOf(model), 1); this.models.splice(this.indexOf(model), 1);
this.length--; this.length--;
if (!options.silent) model.trigger('remove', model, this); if (!options.silent) model.trigger('remove', model, this, options);
model.unbind('all', this._boundOnModelEvent); model.unbind('all', this._boundOnModelEvent);
return model; return model;
}, },
@ -669,8 +681,7 @@
// Get the cross-browser normalized URL fragment. // Get the cross-browser normalized URL fragment.
getFragment : function(loc) { getFragment : function(loc) {
var frag = (loc || window.location).hash.replace(hashStrip, ''); return (loc || window.location).hash.replace(hashStrip, '');
return frag;
}, },
// Start the hash change handling, returning `true` if the current URL matches // Start the hash change handling, returning `true` if the current URL matches
@ -751,10 +762,10 @@
this.initialize(options); this.initialize(options);
}; };
// jQuery lookup, scoped to DOM elements within the current view. // Element lookup, scoped to DOM elements within the current view.
// This should be prefered to global jQuery lookups, if you're dealing with // This should be prefered to global lookups, if you're dealing with
// a specific view. // a specific view.
var jQueryDelegate = function(selector) { var selectorDelegate = function(selector) {
return $(selector, this.el); return $(selector, this.el);
}; };
@ -767,9 +778,8 @@
// The default `tagName` of a View's element is `"div"`. // The default `tagName` of a View's element is `"div"`.
tagName : 'div', tagName : 'div',
// Attach the jQuery function as the `$` and `jQuery` properties. // Attach the `selectorDelegate` function as the `$` property.
$ : jQueryDelegate, $ : selectorDelegate,
jQuery : jQueryDelegate,
// Initialize is an empty function by default. Override it with your own // Initialize is an empty function by default. Override it with your own
// initialization logic. // initialization logic.
@ -811,7 +821,7 @@
// } // }
// //
// pairs. Callbacks will be bound to the view, with `this` set properly. // pairs. Callbacks will be bound to the view, with `this` set properly.
// Uses jQuery event delegation for efficiency. // Uses event delegation for efficiency.
// Omitting the selector binds the event to `this.el`. // Omitting the selector binds the event to `this.el`.
// This only works for delegate-able events: not `focus`, `blur`, and // This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer. // not `change`, `submit`, and `reset` in Internet Explorer.
@ -850,7 +860,7 @@
if (this.el) return; if (this.el) return;
var attrs = {}; var attrs = {};
if (this.id) attrs.id = this.id; if (this.id) attrs.id = this.id;
if (this.className) attrs.className = this.className; if (this.className) attrs["class"] = this.className;
this.el = this.make(this.tagName, attrs); this.el = this.make(this.tagName, attrs);
} }
@ -880,7 +890,7 @@
// Override this function to change the manner in which Backbone persists // Override this function to change the manner in which Backbone persists
// models to the server. You will be passed the type of request, and the // models to the server. You will be passed the type of request, and the
// model in question. By default, uses jQuery to make a RESTful Ajax request // model in question. By default, uses makes a RESTful Ajax request
// to the model's `url()`. Some possible customizations could be: // to the model's `url()`. Some possible customizations could be:
// //
// * Use `setTimeout` to batch rapid-fire updates into a single request. // * Use `setTimeout` to batch rapid-fire updates into a single request.
@ -982,4 +992,20 @@
return _.isFunction(object.url) ? object.url() : object.url; return _.isFunction(object.url) ? object.url() : object.url;
}; };
// Wrap an optional error callback with a fallback error event.
var wrapError = function(onError, model, options) {
return function(resp) {
if (onError) {
onError(model, resp);
} else {
model.trigger('error', model, resp, options);
}
};
};
// Helper function to escape a string for HTML rendering.
var escapeHTML = function(string) {
return string.replace(/&(?!\w+;)/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
};
})(); })();

View File

@ -1,3 +1,4 @@
% -*- Mode: noweb; noweb-code-mode: javascript-mode ; noweb-doc-mode: latex-mode -*-
\documentclass{article} \documentclass{article}
\usepackage{noweb} \usepackage{noweb}
\usepackage{hyperref} \usepackage{hyperref}
@ -9,44 +10,84 @@
% notangle -Rstore.js backbonestore.nw > store.js % notangle -Rstore.js backbonestore.nw > store.js
% notangle -Rindex.html backbonestore.nw > index.html % notangle -Rindex.html backbonestore.nw > index.html
I've been learning how to use \nwanchorto{http://documentcloud.github.com/backbone/}{Backbone.js}, a nifty little library for \section{Introduction}
organizing your client-side Javascript into a classic
Model-View-Controller paradigm while trying (and to some extent,
succeeding) in trying to burden you, the user, with as little
additional learning as possible. I consider this a good thing; the
overhead of learning a library and its accompaning DSL represent
additional cognitive loads that developers can better use elsewhere.
Keeping as much as possible within familiar paradigms is not just
useful, it's necessary as our programs get bigger.
The tutorial for Backbone is woefully lacking in specifics, and the I've been playing with
example program, Todo, doesn't really have much chops in teaching you \nwanchorto{http://documentcloud.github.com/backbone/}{Backbone.js}, a
the ins and outs of Backbone, especially not its new Controller and small but nifty Javascript library that provides a small
History modules. But in the announcement for Backbone.Controller, Model-View-Controller framework where Models can generate events that
Jeremy Ashkenas hid a clue: There's another library, Sammy.js, that trigger View changes, and vice versa, along with a Collections models
does something similar, and they do have a tutorial called \nwanchorto{http://code.quirkey.com/sammy/tutorials/json_store_part1.html}{The JsonStore}. so groups of models can cause view-level events, and a Sync library
that provides a basic REST architecture for propagating client-made
changes back to the server.
In the spirit of The JSON Store, I present The Backbone Store, and There are a number of good tutorials for Backbone (See:
online store written entirely in JSON and operating entirely within a \nwanchorto{http://www.plexical.com/blog/2010/11/18/backbone-js-tutorial/}{Meta
single page. Cloud},
\nwanchorto{http://andyet.net/blog/2010/oct/29/building-a-single-page-app-with-backbonejs-undersc/?utm_source=twitterfeed&utm_medium=twitter}{&Yet's
Tutorial},
\nwanchor{http://bennolan.com/2010/11/24/backbone-jquery-demo.html}{Backbone
Mobile} (which is written in
\nwanchorto{http://jashkenas.github.com/coffee-script/}{Coffee}), and
\nwanchor{http://joshbohde.com/2010/11/25/backbonejs-and-django/}{Backbone
and Django}. However, a couple of months ago I was attempting to
learn Sammy.js, a library very similar to Backbone, and they had a
nifty tutorial called
\nwanchorto{http://code.quirkey.com/sammy/tutorials/json_store_part1.html}{The
JsonStore}.
Let's start by showing you the HTML that we're going to be exploiting: In the spirit of The JSON Store, I present The Backbone Store.
\subsection{Literate Program}
A note: this article was written with the
\nwanchorto{http://en.wikipedia.org/wiki/Literate_programming}{Literate
Programming} toolkit
\nwanchorto{http://www.cs.tufts.edu/~nr/noweb/}{Noweb}. Where you see
something that looks like \<\<this\>\>, it's a placeholder for code
described elsewhere in the document. Placeholders with an equal sign
at the end of them indicate the place where that code is defined. The
link (U->) indicates that the code you're seeing is used later in the
document, and (<-U) indicates it was used earlier but is being defined
here.
\subsection{Revision}
This is version 1.2 of \textit{The Backbone Store}. It includes
changes to the store based upon a better understanding of what
Backbone.js can do. This version uses jQuery 1.5 and Backbone 0.3.3.
\subsection{The Store}
The store has three features: A list of products, a product detail
page, and a ``shopping cart'' that does nothing but tally up the
number of products total that you might wish to order. The main
viewport flips between a list of products and a product detail; the
shopping cart quantity tally is always visible.
Let's start by showing you the HTML that we're going to be
exploiting. As you can see, the shopping cart's primary display is
already present, with zero items shoving. DOM ID ``main'' is empty.
We'll fill it with templated data later.
\subsection{HTML}
<<index.html>>= <<index.html>>=
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>
The Backbone Store
<title>The Backbone Store</title> </title>
<link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" />
<<index template>> <<product list template>>
<<product template>> <<product template>>
</head> </head>
<body> <body>
<div id="container"> <div id="container">
<div id="header"> <div id="header">
@ -59,10 +100,9 @@ Let's start by showing you the HTML that we're going to be exploiting:
</div> </div>
</div> </div>
<div id="main"> <div id="main"> </div>
</div> </div>
</div> <script src="jquery-1.5.js" type="text/javascript"></script>
<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.min.js" type="text/javascript"></script> <script src="jquery.tmpl.min.js" type="text/javascript"></script>
<script src="underscore.js" type="text/javascript"></script> <script src="underscore.js" type="text/javascript"></script>
<script src="backbone.js" type="text/javascript"></script> <script src="backbone.js" type="text/javascript"></script>
@ -73,183 +113,93 @@ Let's start by showing you the HTML that we're going to be exploiting:
This is taken, more or less, straight from The JSON Store. I've This is taken, more or less, straight from The JSON Store. I've
included one extra thing, aside from jQuery and Backbone, and that's included one extra thing, aside from jQuery and Backbone, and that's
the \nwanchorto{https://github.com/jquery/jquery-tmpl}{jQuery Templates kit}. We'll discuss those in a minute. There's a the \nwanchorto{https://github.com/jquery/jquery-tmpl}{jQuery
simplified JSON file that comes in the download; it contains six Templates kit}. There is also a simplified JSON file that comes in
record albums that the store sells. (Unlike the JSON store, these the download; it contains six record albums that the store sells.
albums don't exist; the covers were generated during a round of \nwanchorto{http://elfs.livejournal.com/756709.html}{The Album Cover (Unlike the JSON store, these albums do not exist; the covers were
generated during a round of
\nwanchorto{http://elfs.livejournal.com/756709.html}{The Album Cover
Game}.) Game}.)
There are two views, the index and the item. So, using \section{The Program}
[[Backbone.Controller]], we're going to route the following:
<<routes>>= And here's the skeleton of the program we're going to be writing:
routes: {
"": "index", <<store.js>>=
"item/:id": "item", (function() {
},
<<product models>>
<<shopping cart models>>
<<shopping cart view>>
<<product list view>>
<<product view>>
<<application>>
<<initialization>>
}).call(this);
@ @
Unlike Sammy, Backbone mostly only routes GET commands. Routes are to \section{Models and Collections for the Store}
routes to views; everything else happens more or less under the
covers.
As Backbone is running, the [[Backbone.History]] module is listening to Products are basically what we're selling. In Backbone, a product
the hash object, waiting for it to change so that it can trigger a maps to a Backbone Model. Backbone's Model class provides a full
``route'' event, in which case the function named as the value in the suite of methods for setting and deleting attributes.
route is called.
There are a few things I want to track: the index view, the individual One of things I've found useful is to expose the CID (an internal and
product views, and the shopping cart. locally unique ``client ID'' generated by Backbone) and use it to
decorate DOM id's and classes. So, here, I override the Models's
<<application variables>>= [[toJSON()]] and add the CID to the representation. In production,
_index: null, I've typically created a parent class for all of my classes, overriden
_products: null, [[toJSON()]], and extended that instead.
_cart :null,
@
Using backbone, I have a list of products. So, I should declare
those. The basic product is just a model, with nothing to show for
it; the list of products is a [[Backbone.Collection]], with one feature,
the [[comparator]], which sorts the albums in order by album title.
<<product models>>= <<product models>>=
var Product = Backbone.Model.extend({}); var Product = Backbone.Model.extend({
toJSON: function() {
return _.extend(_.clone(this.attributes), {cid: this.cid})
}
});
@
A store has a lot of products, so we use a Backbone Collection to keep
track of them. A Collection always has a Model object associated with
it; if you attempt to add an object to the Collection that is not an
instance of [[Backbone.Model]], the Collection will attempt to coerce
that object into it [[model]] type.
Both Models and Collections have a [[toJSON()]] method. The Model
creates a JSON representation of its attributes, and the collection
creates a JSON representation of an array, calling [[Model.toJSON()]]
for each model in contains.
The other novel thing here is the comparator; Backbone uses it define
the default ordering for the collection. If not defined, calling
[[sort()]] on the collection raises an exception.
<<product models>>=
var ProductCollection = Backbone.Collection.extend({ var ProductCollection = Backbone.Collection.extend({
model: Product, model: Product,
comparator: function(item) { comparator: function(item) {
return item.get('title'); return item.get('title');
} }
}); });
@ @
That's not very exciting. Let's show this list, with a View. Let's Shopping carts are a bit strange. The typical cart has items: each
call it IndexView: item represents one product and the quantity the user wants to buy.
So a cart may have two items, but the user may be buying five things:
one of the first item, and four of the second, and so forth.
<<index view>>= For our (simple) purpose, I'm just going to have an item that you can
var IndexView = Backbone.View.extend({ add amounts to, that get stored as a 'quantity'.
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var sg = this;
this.el.fadeOut('fast', function() {
sg.el.empty();
$.tmpl(sg.indexTemplate, sg.model.toArray()).appendTo(sg.el);
sg.el.fadeIn('fast');
});
return this;
}
});
@
This code defines a [[Backbone.View]] object, in which the parent element
is \#main, the render function fades out the existing elements in that
position and replaces them with the contents of a rendered jQuery
template, and then fades the element back in.
The index template looks like this:
<<index template>>=
<script id="indexTmpl" type="text/x-jquery-tmpl">
<div class="item">
<div class="item-image">
<a href="#item/${cid}"><img src="${attributes.image}" alt="${attributes.title}" /></a>
</div>
<div class="item-artist">${attributes.artist}</div>
<div class="item-title">${attributes.title}</div>
<div class="item-price">$${attributes.price}</div>
</div>
</script>
@
There's some
\nwanchorto{http://en.wikipedia.org/wiki/Law_of_Demeter}{Demeter violations}
going on here, in that I have to know about the [[attributes]] of a
Backbone model, something that's normally hidden within the class.
But this is good enough for our purposes. The above is a jQuery
template, and the [[\$\{\}]] syntax is what's used to dereference
variables within a template.
(As an aside, I think that the [[set]] and [[get]] methods of
[[Backbone.Model]] are a poor access mechanism. I understand why they're
there, and I can only hope that someday
\nwanchorto{http://ejohn.org/blog/javascript-getters-and-setters/}{Javascript
Getter and Setters} become so well-established as to make [[set]]
and [[get]] irrelevant.)
Now, we can render the index view:
<<index render call>>=
index: function() {
this._index.render();
},
@
At this point, well, we need an application. A controller. And we
need to initialize it, and call it. Here's what it looks like (some
of this, you've already seen):
<<workspace>>=
var Workspace = Backbone.Controller.extend({
<<application variables>>
<<routes>>
<<initialization>>
<<index render call>>
<<product render call>>
});
workspace = new Workspace();
Backbone.history.start();
@
There are two things left in our workspace, that we haven't defined.
The intialization, and the product render.
Initialization consists of getting our product list, creating a
shopping cart to hold ``desired'' products (and in quantity!), and
creating the index view. (Product views, we'll discuss in a moment).
<<initialization>>=
initialize: function() {
var ws = this;
if (this._index === null) {
$.ajax({
url: 'data/items.json',
dataType: 'json',
data: {},
success: function(data) {
ws._cart = new Cart();
new CartView({model: ws._cart});
ws._products = new ProductCollection(data);
ws._index = new IndexView({model: ws._products});
Backbone.history.loadUrl();
}
});
return this;
}
return this;
},
@
We haven't defined the Cart yet, but that's all right. We'll get to
it.) But here you see a lot of what's already existent being used: we
get a ProductCollection, and an IndexView.
That last line is curious. It's an instruction to Backbone to look at
the URL; if the user navigated to something other than the home page,
it's to use the routes defined to go there. Users can now bookmark
places in your site other than the home page. Yes, the bookmark will
be funny and have at least one
\nwanchorto{http://en.wiktionary.org/wiki/octothorpe}{octothorpe} in it, but
it will work.
Let's deal with the shopping cart:
<<shopping cart models>>= <<shopping cart models>>=
var CartItem = Backbone.Model.extend({ var CartItem = Backbone.Model.extend({
@ -258,162 +208,149 @@ var CartItem = Backbone.Model.extend({
} }
}); });
@
The other feature is that, for the collection, I will want to find the
CartItem not by its ID, but by the ID of the product it contains. So
I have added the method [[getByProductId]].
<<shopping cart models>>=
var Cart = Backbone.Collection.extend({ var Cart = Backbone.Collection.extend({
model: CartItem, model: CartItem,
getByPid: function(pid) { getByProductId: function(pid) {
return this.detect(function(obj) { return (obj.get('product').cid == pid); }); return this.detect(function(obj) { return (obj.get('product').cid == pid); });
}, },
}); });
@ @
A little rocket science here: A [[Cart]] contains [[CartItems]]. Each \section{Views}
``item'' represents a quantity of a [[Product]]. (I know, that always
struck me as odd, but that's how most online stores do it.)
[[CartItem]] has an update method that allows you to add more (but not
remove any-- hey, the Sammy store wasn't any smarter, and this is For
Demonstration Purposes Only), and we use the [[set]] method to make
sure that a ``change'' event is triggered.
The [[Cart]], in turn, has a method, getByPid (``Product ID''), which Backbone Views are simple policy objects. They often have a root
is meant to assist other objects in finding the [[CartItem]] element, the contents of which they manipulate, a model or collection
associated with a specific product. Here, I'm just using the Backbone they represent within that root element, events that may occur within
default client id. that root element that they monitor and consequently act on. Views
are not rigid; it's just Javascript and the DOM, and you can hook
external events as needed. (This can be useful, for example, when
doing drag-and-drop with jQueryUI to highlight valid drop zones.)
More importantly, it is sensitive to events \textit{within its model
or collection}, and can respond to changes automatically, without
having to manually invoke the view.
The cart is represented by a little tag in the upper right-hand corner There are three views here: the CartView, the ProductListView, and a
of the view; it never goes away, and its count is always the total single ProductView.
number of [[Products]] (not [[CartItem]]s) ordered. So the
[[CartView]] needs to update whenever a [[CartItem]] is added or The [[CartView]] lives in the upper-right-hand corner of our screen,
updated. And we want a nifty little animation to go with it: and just shows the quantity of items in our shopping cart. It has a
default [[el]], where it will draw its quantity. This view
illustrates the binding to its collection: whenever the collection is
updated in some way, the [[CartView]] automagically updates itself.
The programmer is now relieved of any responsibility of remembering to
update the view, which is a huge win. The [[\_.bind()]] method
associates the [[render]] with the instance of the [[CartView]].
The [[render()]] method is the conventional name for rendering the
elements. Nothing in Backbone calls [[render()]] directly; it's up to
the developer to decide how and when an object should should be
rendered.
This also illustrates the use of jQuery animations in Backbone.
<<shopping cart view>>= <<shopping cart view>>=
var CartView = Backbone.View.extend({ var CartView = Backbone.View.extend({
el: $('.cart-info'), el: $('.cart-info'),
initialize: function() { initialize: function() {
this.model.bind('change', _.bind(this.render, this)); this.collection.bind('change', _.bind(this.render, this));
}, },
render: function() { render: function() {
var sum = this.model.reduce(function(m, n) { return m + n.get('quantity'); }, 0); var sum = this.collection.reduce(function(m, n) { return m + n.get('quantity'); }, 0);
this.el this.el
.find('.cart-items').text(sum).end() .find('.cart-items').text(sum).end()
.animate({paddingTop: '30px'}) .animate({paddingTop: '30px'})
.animate({paddingTop: '10px'}); .animate({paddingTop: '10px'});
} }
}); });
@
%$
The [[ProductListView]] again has a root element, this time the
[[#main]] DIV of our HTML, into which we're going to draw a jQuery
template list of our record albums.
The only tricks here are the compilation of the jQuery template when
the View is instantiated, and the use of an enclosured (is that a
word?) [[self]] variable to provide a hard context for the [[this]]
variable within inner jQuery calls.
<<product list view>>=
var ProductListView = Backbone.View.extend({
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var self = this;
this.el.fadeOut('fast', function() {
self.el.html($.tmpl(self.indexTemplate, self.model.toJSON()));
self.el.fadeIn('fast');
});
return this;
}
});
@ @
A couple of things here: the render is rebound to [[this]] to make The view uses a jQuery template. This is a simple, repeatable
sure it renders in the context of the view. I found that that was not template that jQuery.Template, upon encountering an array, repeats
always happening. Note the use of [[reduce]], a nifty method from until the array is exhausted. Note the presence of [[\${cid}]].
[[underscore.js]] that allows you to build a result out an array using
an anonymous function. This reduce, obviously, sums up the total
quantity of items in the cart. Also, jQuery enthusiasts could learn
(I certainly did!) from the [[.find()]] and [[.end()]] methods, which
push a child object onto the stack to be animated, and then pop it off
after the operation has been applied.
The biggest thing left is the [[ProductView]]. It's skeleton looks <<product list template>>=
like this: <script id="indexTmpl" type="text/x-jquery-tmpl">
<div class="item">
<div class="item-image">
<a href="#item/${cid}"><img src="${image}" alt="${title}" /></a>
</div>
<div class="item-artist">${artist}</div>
<div class="item-title">${title}</div>
<div class="item-price">$${price}</div>
</div>
</script>
@
%$
The most complicated object in our ecosystem is the product view. It
actually does something! The prefix ought to be familiar, but note
that we're again using [[#main]] as our target; we'll be replacing
these contents over and over.
<<product view>>= <<product view>>=
var ProductView = Backbone.View.extend({ var ProductView = Backbone.View.extend({
el: $('#main'), el: $('#main'),
itemTemplate: $("#itemTmpl").template(), itemTemplate: $("#itemTmpl").template(),
<<product events>>
initialize: function(options) { initialize: function(options) {
this.cart = options.cart; this.cart = options.cart;
},
<<update product>>
<<render product>>
});
@
First, we find the element we're going to work with, and the template.
I expect the ProductView to be where we'll add items to the cart, so
the initializer here expects to have a handle on the cart.
And the template:
<<product template>>=
<script id="itemTmpl" type="text/x-jquery-tmpl">
<div class="item-detail">
<div class="item-image"><img src="${attributes.large_image}" alt="${attributes.title}" /></div>
<div class="item-info">
<div class="item-artist">${attributes.artist}</div>
<div class="item-title">${attributes.title}</div>
<div class="item-price">$${attributes.price}</div>
<div class="item-form">
<form action="#/cart" method="post">
<input type="hidden" name="item_id" value="${cid}" />
<p>
<label>Quantity:</label>
<input type="text" size="2" name="quantity" value="1" class="uqf" />
</p>
<p><input type="submit" value="Add to Cart" class="uq" /></p>
</form>
</div>
<div class="item-link"><a href="${attributes.url}">Buy this item on Amazon</a></div>
<div class="back-link"><a href="#">&laquo; Back to Items</a></div>
</div>
</div>
</script>
@
One extra item: note the octothorpe used as the target link for
``Home''. I kept thinking an empty link or just ``/'' would be
appropriate, but no, it's an octothorpe.
Rendering the product is not difficult:
<<render product>>=
render: function() {
var sg = this;
this.el.fadeOut('fast', function() {
sg.el.empty();
$.tmpl(sg.itemTemplate, sg.model).appendTo(sg.el);
sg.el.fadeIn('fast');
});
return this; return this;
}
@
That looks familiar.
Updating the product, however, is a whole 'nother story. Note that
each product has a form associated with it. We need to intercept any
form update events and manipulate our shopping cart. We have two
objects that can do that: the input field, and the submit button. I
need to intercept those events:
<<product events>>=
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
}, },
@ @
Backbone uses a curious definition of an event with an ``event We want to update the cart as needed. Remember that when we update
selector'', followed by a target method of the View class. Backbone the cart item, the CartView will be notified automagically. Later,
is also limited about what events can be used here, as the following I'll show how when we initialize and route to a product view, we pass
events cannot be wrapped by jQuery's delegate method and do not work: in the model associated with it. This code ought to be fairly
``focus'', ``blur'', ``change'', ``submit'', and ``reset''. readable: the only specialness is that it's receiving an event, and
we're ``silencing'' the call to [[cart.add()]], which means that the
cart collection will not publish any events. There are only events
when the item has more than zero, and that gets called on
[[cart_item.update()]].
The update then becomes straightforward. We're in a view for a <<product view>>=
specific product; we must see if the customer has a [[CartItem]] for
that product in the [[Cart]], and add or update it as needed. Like
so:
<<update product>>=
update: function(e) { update: function(e) {
e.preventDefault(); e.preventDefault();
var cart_item = this.cart.getByPid(this.model.cid); var cart_item = this.cart.getByProductId(this.model.cid);
if (_.isUndefined(cart_item)) { if (_.isUndefined(cart_item)) {
cart_item = new CartItem({product: this.model, quantity: 0}); cart_item = new CartItem({product: this.model, quantity: 0});
this.cart.add(cart_item, {silent: true}); this.cart.add(cart_item, {silent: true});
@ -426,48 +363,199 @@ so:
return this.update(e); return this.update(e);
} }
}, },
@
%$
These are the events in which we're interested: keypresses and clicks
on the update button and the quantity form. (Okay, ``UQ'' isn't the
best for ``update quantity''. I admit that.) Note the peculiar
syntax of ``EVENT SELECTOR'': ``methodByName'' for each event.
Backbone tells us that the only events it can track by itself are
those that jQuery's ``delegate'' understands. As of 1.5, that seems
to be just about all of them.
One thing that I was not aware of until recently: if you remove and
replace the [[el]] object during the lifespan of your view (including
in [[initialize()]]), you must then call [[delegateEvents()]] again on
the new object for these events to work.
<<product view>>=
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
},
@ @
We [[preventDefault]] to keep the traditional meaning of the submit And finally the render. There is no rocket science here. You've seen
button from triggering. When the [[CartItem]] is updated, it triggers this before.
a ``change'' event, and the [[CartView]] will update itself
automatically. I added the ``silent'' option to keep the ``change''
event from triggering twice when adding a new [[CartItem]] to the
[[Cart]].
And now I'm down to one last thing. I haven't defined that product %'
render call in the application controller. The one thing I don't want <<product view>>=
to do is have [[ProductViews]] for every product, if I don't need render: function() {
them. So I want to build them as-needed, but keep them, and associate var self = this;
them with the local [[Product]], so they can be recalled whenever we this.el.fadeOut('fast', function() {
want. The underscore function [[isUndefined]] is excellent for this. self.el.html($.tmpl(self.itemTemplate, self.model.toJSON()));
self.el.fadeIn('fast');
});
return this;
}
});
<<product render call>>= @
The template for a ProductView is straightforward. It contains the
form with the [[uq]] objects, the actions of which we intercept and
operate on internally. Backbone does this automatically using
jQuery's [[delegate]] method.
<<product template>>=
<script id="itemTmpl" type="text/x-jquery-tmpl">
<div class="item-detail">
<div class="item-image"><img src="${large_image}" alt="${title}" /></div>
<div class="item-info">
<div class="item-artist">${artist}</div>
<div class="item-title">${title}</div>
<div class="item-price">$${price}</div>
<div class="item-form">
<form action="#/cart" method="post">
<input type="hidden" name="item_id" value="${cid}" />
<p>
<label>Quantity:</label>
<input type="text" size="2" name="quantity" value="1" class="uqf" />
</p>
<p><input type="submit" value="Add to Cart" class="uq" /></p>
</form>
</div>
<div class="item-link"><a href="${url}">Buy this item on Amazon</a></div>
<div class="back-link"><a href="#">&laquo; Back to Items</a></div>
</div>
</div>
</script>
@
%'
\section{The Router}
The router is a fairly straightforward component. It's purpose is to
pay attention to the ``\#hash'' portion of your URL and, when it
changes, do something. Anything, really. [[Backbone.History]] is the
event listener for the hash, so it has to be activated after the
application. In many ways, a Backbone ``Controller'' is just a big
View with authority over the entire Viewport.
To begin with, I'm going to keep track of the ``three'' views I care
about: the CartView, the ProductListView, and the ProductView. I'm
going to cheat by attaching the ProductViews to their individual
products, and invoke that view as necessary.
<<application>>=
var BackboneStore = Backbone.Controller.extend({
_index: null,
_products: null,
_cart :null,
@
%$
There are only two routes: home, and item:
<<application>>=
routes: {
"": "index",
"item/:id": "item",
},
@
Here's where things get interesting. There are two schools of thought
over the Controller; one, that the Controller ought to be able to get
all the data it needs, and two, that the Controller ought to begin
with enough data to do the job sensibly. I fall into the second camp.
I'm going to pass in to the [[initialize()]] method an array of
objects representing all the products in the system.
<<application>>=
initialize: function(data) {
this._cart = new Cart();
new CartView({collection: this._cart});
this._products = new ProductCollection(data);
this._index = new ProductListView({model: this._products});
return this;
},
@
When we're routed to the [[index]] method, all we need to do is render
the index:
<<application>>=
index: function() {
this._index.render();
},
@
When we are routed to a product, we need to find that product, get its
view if it has one or create one if it doesn't, then call render:
<<application>>=
item: function(id) { item: function(id) {
if (_.isUndefined(this._products.getByCid(id)._view)) { var product = this._products.getByCid(id);
this._products.getByCid(id)._view = new ProductView({model: this._products.getByCid(id), if (_.isUndefined(product._view)) {
product._view = new ProductView({model: product,
cart: this._cart}); cart: this._cart});
} }
this._products.getByCid(id)._view.render(); product._view.render();
} }
});
@ @
And now my store looks like And that's the entirety of the application.
<<store.js>>= \section{Initialization}
<<product models>>
<<shopping cart models>> Initialization for most single-page applications happens when the DOM
is ready. So I'll do exactly that.
<<shopping cart view>> This should be obvious, except what the Hell is that when/then
construct? That's a new feature of jQuery 1.5 called Deferreds (also
known as Promises or Futures). All jQuery 1.5 ajax calls are
Deferreds that return data when you dereference them; [[when()]] is an
instruction to wait until the ajax call is done, and [[then()]] is a
chained instruction on what to do next.
<<product view>> This is a trivial example, but when you have multiple streams of data
coming in (say, you're loading independent schemas, or you have
multiple, orthagonal data sets in your application, each with their
own URL as per the Richardson Maturity Model), you can pass the array
of ajax objects to [[when()]] and [[then()]] won't fire until they're
all done. Automagic synchronization is a miracle.
<<index view>> <<initialization>>=
$(document).ready(function() {
var fetch_items = function() {
return $.ajax({
url: 'data/items.json',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
<<workspace>> $.when(fetch_items()).then(function(data) {
new BackboneStore(data);
Backbone.history.start();
});
});
@ @
And that's it. Put it all together, and you've got yourself a working
Backbone Store.
As always, this code is available at github. This code is available at my github at
\nwanchorto{https://github.com/elfsternberg/The-Backbone-Store}{The
Backbone Store}.
\end{document} \end{document}

View File

@ -2,29 +2,29 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>
The Backbone Store
<title>The Backbone Store</title> </title>
<link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" />
<script id="indexTmpl" type="text/x-jquery-tmpl"> <script id="indexTmpl" type="text/x-jquery-tmpl">
<div class="item"> <div class="item">
<div class="item-image"> <div class="item-image">
<a href="#item/${cid}"><img src="${attributes.image}" alt="${attributes.title}" /></a> <a href="#item/${cid}"><img src="${image}" alt="${title}" /></a>
</div> </div>
<div class="item-artist">${attributes.artist}</div> <div class="item-artist">${artist}</div>
<div class="item-title">${attributes.title}</div> <div class="item-title">${title}</div>
<div class="item-price">$${attributes.price}</div> <div class="item-price">$${price}</div>
</div> </div>
</script> </script>
<script id="itemTmpl" type="text/x-jquery-tmpl"> <script id="itemTmpl" type="text/x-jquery-tmpl">
<div class="item-detail"> <div class="item-detail">
<div class="item-image"><img src="${attributes.large_image}" alt="${attributes.title}" /></div> <div class="item-image"><img src="${large_image}" alt="${title}" /></div>
<div class="item-info"> <div class="item-info">
<div class="item-artist">${attributes.artist}</div> <div class="item-artist">${artist}</div>
<div class="item-title">${attributes.title}</div> <div class="item-title">${title}</div>
<div class="item-price">$${attributes.price}</div> <div class="item-price">$${price}</div>
<div class="item-form"> <div class="item-form">
<form action="#/cart" method="post"> <form action="#/cart" method="post">
<input type="hidden" name="item_id" value="${cid}" /> <input type="hidden" name="item_id" value="${cid}" />
@ -35,13 +35,14 @@
<p><input type="submit" value="Add to Cart" class="uq" /></p> <p><input type="submit" value="Add to Cart" class="uq" /></p>
</form> </form>
</div> </div>
<div class="item-link"><a href="${attributes.url}">Buy this item on Amazon</a></div> <div class="item-link"><a href="${url}">Buy this item on Amazon</a></div>
<div class="back-link"><a href="#">&laquo; Back to Items</a></div> <div class="back-link"><a href="#">&laquo; Back to Items</a></div>
</div> </div>
</div> </div>
</script> </script>
</head> </head>
<body> <body>
<div id="container"> <div id="container">
<div id="header"> <div id="header">
@ -54,10 +55,9 @@
</div> </div>
</div> </div>
<div id="main"> <div id="main"> </div>
</div> </div>
</div> <script src="jquery-1.5.js" type="text/javascript"></script>
<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.min.js" type="text/javascript"></script> <script src="jquery.tmpl.min.js" type="text/javascript"></script>
<script src="underscore.js" type="text/javascript"></script> <script src="underscore.js" type="text/javascript"></script>
<script src="backbone.js" type="text/javascript"></script> <script src="backbone.js" type="text/javascript"></script>

167
jquery-1.4.4.min.js vendored
View File

@ -1,167 +0,0 @@
/*!
* jQuery JavaScript Library v1.4.4
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Thu Nov 11 19:04:53 2010 -0500
*/
(function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h=
h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;k<J.length;k++){h=J[k];h.origType.replace(X,"")===a.type?f.push(h.selector):J.splice(k--,1)}f=c(a.target).closest(f,a.currentTarget);o=0;for(x=f.length;o<x;o++){r=f[o];for(k=0;k<J.length;k++){h=J[k];if(r.selector===h.selector&&(!A||A.test(h.namespace))){l=r.elem;e=null;if(h.preType==="mouseenter"||
h.preType==="mouseleave"){a.type=h.preType;e=c(a.relatedTarget).closest(h.selector)[0]}if(!e||e!==l)C.push({elem:l,handleObj:h,level:r.level})}}}o=0;for(x=C.length;o<x;o++){f=C[o];if(d&&f.level>d)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La,
"`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this,
e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a,
"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+
a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,
C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j,
s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this,
j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length},
toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j===
-1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false;
if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K<Q;K++)if((j=arguments[K])!=null)for(s in j){v=G[s];z=j[s];if(G!==z)if(ga&&z&&(b.isPlainObject(z)||(H=b.isArray(z)))){if(H){H=false;v=v&&b.isArray(v)?v:[]}else v=v&&b.isPlainObject(v)?v:{};G[s]=b.extend(ga,v,z)}else if(z!==B)G[s]=z}return G};b.extend({noConflict:function(j){E.$=e;if(j)E.jQuery=d;return b},isReady:false,readyWait:1,ready:function(j){j===true&&b.readyWait--;
if(!b.readyWait||j!==true&&!b.isReady){if(!t.body)return setTimeout(b.ready,1);b.isReady=true;if(!(j!==true&&--b.readyWait>0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload",
b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&&
!F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&&
l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H<G;){if(s.apply(j[H++],v)===false)break}else if(K)for(z in j){if(s.call(j[z],
z,j[z])===false)break}else for(v=j[0];H<G&&s.call(v,H,v)!==false;v=j[++H]);return j},trim:O?function(j){return j==null?"":O.call(j)}:function(j){return j==null?"":j.toString().replace(k,"").replace(o,"")},makeArray:function(j,s){var v=s||[];if(j!=null){var z=b.type(j);j.length==null||z==="string"||z==="function"||z==="regexp"||b.isWindow(j)?M.call(v,j):b.merge(v,j)}return v},inArray:function(j,s){if(s.indexOf)return s.indexOf(j);for(var v=0,z=s.length;v<z;v++)if(s[v]===j)return v;return-1},merge:function(j,
s){var v=j.length,z=0;if(typeof s.length==="number")for(var H=s.length;z<H;z++)j[v++]=s[z];else for(;s[z]!==B;)j[v++]=s[z++];j.length=v;return j},grep:function(j,s,v){var z=[],H;v=!!v;for(var G=0,K=j.length;G<K;G++){H=!!s(j[G],G);v!==H&&z.push(j[G])}return z},map:function(j,s,v){for(var z=[],H,G=0,K=j.length;G<K;G++){H=s(j[G],G,v);if(H!=null)z[z.length]=H}return z.concat.apply([],z)},guid:1,proxy:function(j,s,v){if(arguments.length===2)if(typeof s==="string"){v=j;j=v[s];s=B}else if(s&&!b.isFunction(s)){v=
s;s=B}if(!s&&j)s=function(){return j.apply(v||this,arguments)};if(j)s.guid=j.guid=j.guid||s.guid||b.guid++;return s},access:function(j,s,v,z,H,G){var K=j.length;if(typeof s==="object"){for(var Q in s)b.access(j,Q,s[Q],z,H,v);return j}if(v!==B){z=!G&&z&&b.isFunction(v);for(Q=0;Q<K;Q++)H(j[Q],s,z?v.call(j[Q],Q,H(j[Q],s)):v,G);return j}return K?H(j[0],s):B},now:function(){return(new Date).getTime()},uaMatch:function(j){j=j.toLowerCase();j=L.exec(j)||g.exec(j)||i.exec(j)||j.indexOf("compatible")<0&&n.exec(j)||
[];return{browser:j[1]||"",version:j[2]||"0"}},browser:{}});b.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(j,s){R["[object "+s+"]"]=s.toLowerCase()});m=b.uaMatch(m);if(m.browser){b.browser[m.browser]=true;b.browser.version=m.version}if(b.browser.webkit)b.browser.safari=true;if(D)b.inArray=function(j,s){return D.call(s,j)};if(!/\s/.test("\u00a0")){k=/^[\s\xA0]+/;o=/[\s\xA0]+$/}f=b(t);if(t.addEventListener)u=function(){t.removeEventListener("DOMContentLoaded",u,
false);b.ready()};else if(t.attachEvent)u=function(){if(t.readyState==="complete"){t.detachEvent("onreadystatechange",u);b.ready()}};return E.jQuery=E.$=b}();(function(){c.support={};var a=t.documentElement,b=t.createElement("script"),d=t.createElement("div"),e="script"+c.now();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"),
k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false,
scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent=
false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom=
1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="<div style='width:4px;'></div>";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display=
"none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h=
c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando);
else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h<l;h++){f=e[h].name;if(f.indexOf("data-")===0){f=f.substr(5);ka(this[0],f,d[f])}}}return d}else if(typeof a==="object")return this.each(function(){c.data(this,
a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(b===B){d=this.triggerHandler("getData"+k[1]+"!",[k[0]]);if(d===B&&this.length){d=c.data(this[0],a);d=ka(this[0],a,d)}return d===B&&k[1]?this.data(k[0]):d}else return this.each(function(){var o=c(this),x=[k[0],b];o.triggerHandler("setData"+k[1]+"!",x);c.data(this,a,b);o.triggerHandler("changeData"+k[1]+"!",x)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e=
c.data(a,b);if(!d)return e||[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===B)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,
a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var sa=/[\n\t]/g,ha=/\s+/,Sa=/\r/g,Ta=/^(?:href|src|style)$/,Ua=/^(?:button|input)$/i,Va=/^(?:button|input|object|select|textarea)$/i,Wa=/^a(?:rea)?$/i,ta=/^(?:radio|checkbox)$/i;c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",
colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(x){var r=c(this);r.addClass(a.call(this,x,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===
1)if(f.className){for(var h=" "+f.className+" ",l=f.className,k=0,o=b.length;k<o;k++)if(h.indexOf(" "+b[k]+" ")<0)l+=" "+b[k];f.className=c.trim(l)}else f.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var x=c(this);x.removeClass(a.call(this,o,x.attr("class")))});if(a&&typeof a==="string"||a===B)for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1&&f.className)if(a){for(var h=(" "+f.className+" ").replace(sa," "),
l=0,k=b.length;l<k;l++)h=h.replace(" "+b[l]+" "," ");f.className=c.trim(h)}else f.className=""}return this},toggleClass:function(a,b){var d=typeof a,e=typeof b==="boolean";if(c.isFunction(a))return this.each(function(f){var h=c(this);h.toggleClass(a.call(this,f,h.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var f,h=0,l=c(this),k=b,o=a.split(ha);f=o[h++];){k=e?k:!l.hasClass(f);l[k?"addClass":"removeClass"](f)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,
"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(sa," ").indexOf(a)>-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one";
if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h<e;h++){var l=f[h];if(l.selected&&(c.support.optDisabled?!l.disabled:l.getAttribute("disabled")===null)&&(!l.parentNode.disabled||!c.nodeName(l.parentNode,"optgroup"))){a=c(l).val();if(b)return a;d.push(a)}}return d}if(ta.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Sa,"")}return B}var k=c.isFunction(a);return this.each(function(o){var x=c(this),r=a;if(this.nodeType===1){if(k)r=
a.call(this,o,x.val());if(r==null)r="";else if(typeof r==="number")r+="";else if(c.isArray(r))r=c.map(r,function(C){return C==null?"":C+""});if(c.isArray(r)&&ta.test(this.type))this.checked=c.inArray(x.val(),r)>=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},
attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&
b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0};
c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,
arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid=
d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+
c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h<A.length;h++){C=A[h];if(d.guid===C.guid){if(k||x.test(C.namespace)){e==null&&A.splice(h--,1);r.remove&&r.remove.call(a,C)}if(e!=null)break}}if(A.length===0||e!=null&&A.length===1){if(!r.teardown||r.teardown.call(a,o)===false)c.removeEvent(a,f,w.handle);delete I[f]}}else for(h=0;h<A.length;h++){C=A[h];if(k||x.test(C.namespace)){c.event.remove(a,r,C.handler,h);A.splice(h--,1)}}}if(c.isEmptyObject(I)){if(b=
w.handle)b.elem=null;delete w.events;delete w.handle;if(typeof w==="function")c.removeData(a,J);else c.isEmptyObject(w)&&c.removeData(a)}}}}},trigger:function(a,b,d,e){var f=a.type||a;if(!e){a=typeof a==="object"?a[c.expando]?a:c.extend(c.Event(f),a):c.Event(f);if(f.indexOf("!")>=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k===
"click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+
d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f<l;f++){var k=d[f];if(b||e.test(k.namespace)){a.handler=k.handler;a.data=k.data;a.handleObj=k;k=k.handler.apply(this,h);if(k!==B){a.result=k;if(k===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[c.expando])return a;var b=a;a=c.Event(b);for(var d=this.props.length,e;d;){e=this.props[--d];a[e]=b[e]}if(!a.target)a.target=a.srcElement||t;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=t.documentElement;d=t.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(a.which==null&&(a.charCode!=null||a.keyCode!=null))a.which=a.charCode!=null?a.charCode:a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==B)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,Y(a.origType,a.selector),c.extend({},a,{handler:Ka,guid:a.handler.guid}))},remove:function(a){c.event.remove(this,
Y(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,d){if(c.isWindow(this))this.onbeforeunload=d},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.removeEvent=t.removeEventListener?function(a,b,d){a.removeEventListener&&a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent&&a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=
c.now();this[c.expando]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ca;var a=this.originalEvent;if(a)if(a.preventDefault)a.preventDefault();else a.returnValue=false},stopPropagation:function(){this.isPropagationStopped=ca;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ca;this.stopPropagation()},isDefaultPrevented:U,isPropagationStopped:U,isImmediatePropagationStopped:U};
var va=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},wa=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?wa:va,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?wa:va)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(){if(this.nodeName.toLowerCase()!==
"form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length){a.liveFired=B;return la("submit",this,arguments)}});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13){a.liveFired=B;return la("submit",this,arguments)}})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};if(!c.support.changeBubbles){var V,
xa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired=
B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type===
"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]===
0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h<k;h++)c.event.add(this[h],d,l,e)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var d in a)this.unbind(d,
a[d]);else{d=0;for(var e=this.length;d<e;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,e){return this.live(b,d,e,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var d=c.Event(a);d.preventDefault();d.stopPropagation();c.event.trigger(d,b,this[0]);return d.result}},toggle:function(a){for(var b=arguments,d=
1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(e){var f=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,f+1);e.preventDefault();return b[f].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var ya={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,e,f,h){var l,k=0,o,x,r=h||this.selector;h=h?this:c(this.context);if(typeof d===
"object"&&!d.preventDefault){for(l in d)h[b](l,e,d[l],r);return this}if(c.isFunction(e)){f=e;e=B}for(d=(d||"").split(" ");(l=d[k++])!=null;){o=X.exec(l);x="";if(o){x=o[0];l=l.replace(X,"")}if(l==="hover")d.push("mouseenter"+x,"mouseleave"+x);else{o=l;if(l==="focus"||l==="blur"){d.push(ya[l]+x);l+=x}else l=(ya[l]||l)+x;if(b==="live"){x=0;for(var A=h.length;x<A;x++)c.event.add(h[x],"live."+Y(l,r),{data:e,selector:r,handler:f,origType:l,origHandler:f,preType:o})}else h.unbind("live."+Y(l,r),f)}}return this}});
c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d,e){if(e==null){e=d;d=null}return arguments.length>0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
(function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1&&!q){y.sizcache=n;y.sizset=p}if(y.nodeName.toLowerCase()===i){F=y;break}y=y[g]}m[p]=F}}}function b(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1){if(!q){y.sizcache=n;y.sizset=p}if(typeof i!=="string"){if(y===i){F=true;break}}else if(k.filter(i,
[y]).length>0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3];
break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr,
q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h=
l;g.sort(w);if(h)for(var i=1;i<g.length;i++)g[i]===g[i-1]&&g.splice(i--,1)}return g};k.matches=function(g,i){return k(g,null,null,i)};k.matchesSelector=function(g,i){return k(i,null,null,[g]).length>0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p<q;p++){var u,y=o.order[p];if(u=o.leftMatch[y].exec(g)){var F=u[1];u.splice(1,1);if(F.substr(F.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");m=o.find[y](u,i,n);if(m!=null){g=g.replace(o.match[y],"");break}}}}m||(m=i.getElementsByTagName("*"));
return{set:m,expr:g}};k.filter=function(g,i,n,m){for(var p,q,u=g,y=[],F=i,M=i&&i[0]&&k.isXML(i[0]);g&&i.length;){for(var N in o.filter)if((p=o.leftMatch[N].exec(g))!=null&&p[2]){var O,D,R=o.filter[N];D=p[1];q=false;p.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(F===y)y=[];if(o.preFilter[N])if(p=o.preFilter[N](p,F,n,y,m,M)){if(p===true)continue}else q=O=true;if(p)for(var j=0;(D=F[j])!=null;j++)if(D){O=R(D,p,j,F);var s=m^!!O;if(n&&O!=null)if(s)q=true;else F[j]=false;else if(s){y.push(D);q=true}}if(O!==
B){n||(F=y);g=g.replace(o.match[N],"");if(!q)return[];break}}}if(g===u)if(q==null)k.error(g);else break;u=g}return F};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var o=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,i){var n=typeof i==="string",m=n&&!/\W/.test(i);n=n&&!m;if(m)i=i.toLowerCase();m=0;for(var p=g.length,q;m<p;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=n||q&&q.nodeName.toLowerCase()===
i?q||false:q===i}n&&k.filter(i,g,true)},">":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p<q;p++){if(n=g[p]){n=n.parentNode;g[p]=n.nodeName.toLowerCase()===i?n:false}}else{for(;p<q;p++)if(n=g[p])g[p]=m?n.parentNode:n.parentNode===i;m&&k.filter(i,g,true)}},"":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=i=i.toLowerCase();q=a}q("parentNode",i,p,g,m,n)},"~":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=
i=i.toLowerCase();q=a}q("previousSibling",i,p,g,m,n)}},find:{ID:function(g,i,n){if(typeof i.getElementById!=="undefined"&&!n)return(g=i.getElementById(g[1]))&&g.parentNode?[g]:[]},NAME:function(g,i){if(typeof i.getElementsByName!=="undefined"){for(var n=[],m=i.getElementsByName(g[1]),p=0,q=m.length;p<q;p++)m[p].getAttribute("name")===g[1]&&n.push(m[p]);return n.length===0?null:n}},TAG:function(g,i){return i.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,i,n,m,p,q){g=" "+g[1].replace(/\\/g,
"")+" ";if(q)return g;q=0;for(var u;(u=i[q])!=null;q++)if(u)if(p^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n,
m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===
true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===
g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return i<n[3]-0},gt:function(g,i,n){return i>n[3]-0},nth:function(g,i,n){return n[3]-
0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n<m;n++)if(i[n]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+p)},CHILD:function(g,i){var n=i[1],m=g;switch(n){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(n===
"first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":n=i[2];var p=i[3];if(n===1&&p===0)return true;var q=i[0],u=g.parentNode;if(u&&(u.sizcache!==q||!g.nodeIndex)){var y=0;for(m=u.firstChild;m;m=m.nextSibling)if(m.nodeType===1)m.nodeIndex=++y;u.sizcache=q}m=g.nodeIndex-p;return n===0?m===0:m%n===0&&m/n>=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===
i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]];
if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m,
g);else if(typeof g.length==="number")for(var p=g.length;n<p;n++)m.push(g[n]);else for(;g[n];n++)m.push(g[n]);return m}}var w,I;if(t.documentElement.compareDocumentPosition)w=function(g,i){if(g===i){h=true;return 0}if(!g.compareDocumentPosition||!i.compareDocumentPosition)return g.compareDocumentPosition?-1:1;return g.compareDocumentPosition(i)&4?-1:1};else{w=function(g,i){var n,m,p=[],q=[];n=g.parentNode;m=i.parentNode;var u=n;if(g===i){h=true;return 0}else if(n===m)return I(g,i);else if(n){if(!m)return 1}else return-1;
for(;u;){p.unshift(u);u=u.parentNode}for(u=m;u;){q.unshift(u);u=u.parentNode}n=p.length;m=q.length;for(u=0;u<n&&u<m;u++)if(p[u]!==q[u])return I(p[u],q[u]);return u===n?I(g,q[u],-1):I(p[u],i,1)};I=function(g,i,n){if(g===i)return n;for(g=g.nextSibling;g;){if(g===i)return-1;g=g.nextSibling}return 1}}k.getText=function(g){for(var i="",n,m=0;g[m];m++){n=g[m];if(n.nodeType===3||n.nodeType===4)i+=n.nodeValue;else if(n.nodeType!==8)i+=k.getText(n.childNodes)}return i};(function(){var g=t.createElement("div"),
i="script"+(new Date).getTime(),n=t.documentElement;g.innerHTML="<a name='"+i+"'/>";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g);
n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&&
function(){var g=k,i=t.createElement("div");i.innerHTML="<p class='TEST'></p>";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F||
p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g=
t.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition?
function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n<u;n++)k(g,q[n],m);return k.filter(p,m)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=k.getText;c.isXMLDoc=k.isXML;
c.contains=k.contains})();var Za=/Until$/,$a=/^(?:parents|prevUntil|prevAll)/,ab=/,/,Na=/^.[^:#\[\.,]*$/,bb=Array.prototype.slice,cb=c.expr.match.POS;c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,e=0,f=this.length;e<f;e++){d=b.length;c.find(a,this[e],b);if(e>0)for(var h=d;h<b.length;h++)for(var l=0;l<d;l++)if(b[l]===b[h]){b.splice(h--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,e=b.length;d<e;d++)if(c.contains(this,b[d]))return true})},
not:function(a){return this.pushStack(ma(this,a,false),"not",a)},filter:function(a){return this.pushStack(ma(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e<f;e++){l=a[e];k[l]||(k[l]=c.expr.match.POS.test(l)?c(l,b||this.context):l)}for(;h&&h.ownerDocument&&h!==b;){for(l in k){e=k[l];if(e.jquery?e.index(h)>-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h=
h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e<f;e++)for(h=this[e];h;)if(l?l.index(h)>-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):
c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,
2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,
b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&
e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/<tbody/i,eb=/<|&#?\w+;/,Ca=/<(?:script|object|embed|option|style)/i,Da=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/\=([^="'>\s]+\/)>/g,P={option:[1,
"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null;
else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1></$2>");try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(e){this.empty().append(a)}}else c.isFunction(a)?this.each(function(f){var h=c(this);h.html(a.call(this,f,h.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=
c(this),e=d.html();d.replaceWith(a.call(this,b,e))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){var e,f,h,l=a[0],k=[];if(!c.support.checkClone&&arguments.length===3&&typeof l==="string"&&Da.test(l))return this.each(function(){c(this).domManip(a,
b,d,true)});if(c.isFunction(l))return this.each(function(x){var r=c(this);a[0]=l.call(this,x,b?r.html():B);r.domManip(a,b,d)});if(this[0]){e=l&&l.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:c.buildFragment(a,this,k);h=e.fragment;if(f=h.childNodes.length===1?h=h.firstChild:h.firstChild){b=b&&c.nodeName(f,"tr");f=0;for(var o=this.length;f<o;f++)d.call(b?c.nodeName(this[f],"table")?this[f].getElementsByTagName("tbody")[0]||this[f].appendChild(this[f].ownerDocument.createElement("tbody")):
this[f]:this[f],f>0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",
prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f<h;f++){var l=(f>0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument||
b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1></$2>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]==="<table>"&&!x?r.childNodes:[];for(o=k.length-
1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));
d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i,
jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,
zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),
h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b);
if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=
d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left;
e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b===
"object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("<div>").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&
!this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})},
getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html",
script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data||
!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache=
false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset;
A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type",
b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&&
c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d||
c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]=
encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess",
[b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),
e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}});
if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show",
3),a,b,d);else{d=0;for(var e=this.length;d<e;d++){a=this[d];b=a.style.display;if(!c.data(a,"olddisplay")&&b==="none")b=a.style.display="";b===""&&c.css(a,"display")==="none"&&c.data(a,"olddisplay",qa(a.nodeName))}for(d=0;d<e;d++){a=this[d];b=a.style.display;if(b===""||b==="none")a.style.display=c.data(a,"olddisplay")||""}return this}},hide:function(a,b,d){if(a||a===0)return this.animate(S("hide",3),a,b,d);else{a=0;for(b=this.length;a<b;a++){d=c.css(this[a],"display");d!=="none"&&c.data(this[a],"olddisplay",
d)}for(a=0;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b,d){var e=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||e?this.each(function(){var f=e?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(S("toggle",3),a,b,d);return this},fadeTo:function(a,b,d,e){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d,e)},animate:function(a,b,d,e){var f=c.speed(b,
d,e);if(c.isEmptyObject(a))return this.each(f.complete);return this[f.queue===false?"each":"queue"](function(){var h=c.extend({},f),l,k=this.nodeType===1,o=k&&c(this).is(":hidden"),x=this;for(l in a){var r=c.camelCase(l);if(l!==r){a[r]=a[l];delete a[l];l=r}if(a[l]==="hide"&&o||a[l]==="show"&&!o)return h.complete.call(this);if(k&&(l==="height"||l==="width")){h.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(c.css(this,"display")==="inline"&&c.css(this,"float")==="none")if(c.support.inlineBlockNeedsLayout)if(qa(this.nodeName)===
"inline")this.style.display="inline-block";else{this.style.display="inline";this.style.zoom=1}else this.style.display="inline-block"}if(c.isArray(a[l])){(h.specialEasing=h.specialEasing||{})[l]=a[l][1];a[l]=a[l][0]}}if(h.overflow!=null)this.style.overflow="hidden";h.curAnim=c.extend({},a);c.each(a,function(A,C){var J=new c.fx(x,h,A);if(vb.test(C))J[C==="toggle"?o?"show":"hide":C](a);else{var w=wb.exec(C),I=J.cur()||0;if(w){var L=parseFloat(w[2]),g=w[3]||"px";if(g!=="px"){c.style(x,A,(L||1)+g);I=(L||
1)/J.cur()*I;c.style(x,A,I+g)}if(w[1])L=(w[1]==="-="?-1:1)*L+I;J.custom(I,L,g)}else J.custom(I,C,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var e=d.length-1;e>=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b,
d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a*
Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)}
var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;
this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide||
this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=
c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},interval:13,stop:function(){clearInterval(ba);ba=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===
b.elem}).length};var xb=/^t(?:able|d|h)$/i,Ia=/^(?:body|html)$/i;c.fn.offset="getBoundingClientRect"in t.documentElement?function(a){var b=this[0],d;if(a)return this.each(function(l){c.offset.setOffset(this,a,l)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);try{d=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,h=f.documentElement;if(!d||!c.contains(h,b))return d||{top:0,left:0};b=f.body;f=fa(f);return{top:d.top+(f.pageYOffset||c.support.boxModel&&
h.scrollTop||b.scrollTop)-(h.clientTop||b.clientTop||0),left:d.left+(f.pageXOffset||c.support.boxModel&&h.scrollLeft||b.scrollLeft)-(h.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(x){c.offset.setOffset(this,a,x)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d,e=b.offsetParent,f=b.ownerDocument,h=f.documentElement,l=f.body;d=(f=f.defaultView)?f.getComputedStyle(b,null):b.currentStyle;
for(var k=b.offsetTop,o=b.offsetLeft;(b=b.parentNode)&&b!==l&&b!==h;){if(c.offset.supportsFixedPosition&&d.position==="fixed")break;d=f?f.getComputedStyle(b,null):b.currentStyle;k-=b.scrollTop;o-=b.scrollLeft;if(b===e){k+=b.offsetTop;o+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&xb.test(b.nodeName))){k+=parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}e=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"){k+=
parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}d=d}if(d.position==="relative"||d.position==="static"){k+=l.offsetTop;o+=l.offsetLeft}if(c.offset.supportsFixedPosition&&d.position==="fixed"){k+=Math.max(h.scrollTop,l.scrollTop);o+=Math.max(h.scrollLeft,l.scrollLeft)}return{top:k,left:o}};c.offset={initialize:function(){var a=t.body,b=t.createElement("div"),d,e,f,h=parseFloat(c.css(a,"marginTop"))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",
height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);d=b.firstChild;e=d.firstChild;f=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=e.offsetTop!==5;this.doesAddBorderForTableAndCells=
f.offsetTop===5;e.style.position="fixed";e.style.top="20px";this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15;e.style.position=e.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==h;a.removeChild(b);c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.css(a,
"marginTop"))||0;d+=parseFloat(c.css(a,"marginLeft"))||0}return{top:b,left:d}},setOffset:function(a,b,d){var e=c.css(a,"position");if(e==="static")a.style.position="relative";var f=c(a),h=f.offset(),l=c.css(a,"top"),k=c.css(a,"left"),o=e==="absolute"&&c.inArray("auto",[l,k])>-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a,
e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&&
c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();
c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+
b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window);

8176
jquery-1.5.js vendored Normal file

File diff suppressed because it is too large Load Diff

119
store.js
View File

@ -1,7 +1,14 @@
var Product = Backbone.Model.extend({}); (function() {
var Product = Backbone.Model.extend({
toJSON: function() {
return _.extend(_.clone(this.attributes), {cid: this.cid})
}
});
var ProductCollection = Backbone.Collection.extend({ var ProductCollection = Backbone.Collection.extend({
model: Product, model: Product,
comparator: function(item) { comparator: function(item) {
return item.get('title'); return item.get('title');
} }
@ -13,23 +20,23 @@ var CartItem = Backbone.Model.extend({
} }
}); });
var Cart = Backbone.Collection.extend({ var Cart = Backbone.Collection.extend({
model: CartItem, model: CartItem,
getByPid: function(pid) { getByProductId: function(pid) {
return this.detect(function(obj) { return (obj.get('product').cid == pid); }); return this.detect(function(obj) { return (obj.get('product').cid == pid); });
}, },
}); });
var CartView = Backbone.View.extend({ var CartView = Backbone.View.extend({
el: $('.cart-info'), el: $('.cart-info'),
initialize: function() { initialize: function() {
this.model.bind('change', _.bind(this.render, this)); this.collection.bind('change', _.bind(this.render, this));
}, },
render: function() { render: function() {
var sum = this.model.reduce(function(m, n) { return m + n.get('quantity'); }, 0); var sum = this.collection.reduce(function(m, n) { return m + n.get('quantity'); }, 0);
this.el this.el
.find('.cart-items').text(sum).end() .find('.cart-items').text(sum).end()
.animate({paddingTop: '30px'}) .animate({paddingTop: '30px'})
@ -37,22 +44,34 @@ var CartView = Backbone.View.extend({
} }
}); });
var ProductListView = Backbone.View.extend({
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var self = this;
this.el.fadeOut('fast', function() {
self.el.html($.tmpl(self.indexTemplate, self.model.toJSON()));
self.el.fadeIn('fast');
});
return this;
}
});
var ProductView = Backbone.View.extend({ var ProductView = Backbone.View.extend({
el: $('#main'), el: $('#main'),
itemTemplate: $("#itemTmpl").template(), itemTemplate: $("#itemTmpl").template(),
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
},
initialize: function(options) { initialize: function(options) {
this.cart = options.cart; this.cart = options.cart;
return this;
}, },
update: function(e) { update: function(e) {
e.preventDefault(); e.preventDefault();
var cart_item = this.cart.getByPid(this.model.cid); var cart_item = this.cart.getByProductId(this.model.cid);
if (_.isUndefined(cart_item)) { if (_.isUndefined(cart_item)) {
cart_item = new CartItem({product: this.model, quantity: 0}); cart_item = new CartItem({product: this.model, quantity: 0});
this.cart.add(cart_item, {silent: true}); this.cart.add(cart_item, {silent: true});
@ -66,61 +85,36 @@ var ProductView = Backbone.View.extend({
} }
}, },
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
},
render: function() { render: function() {
var sg = this; var self = this;
this.el.fadeOut('fast', function() { this.el.fadeOut('fast', function() {
sg.el.empty(); self.el.html($.tmpl(self.itemTemplate, self.model.toJSON()));
$.tmpl(sg.itemTemplate, sg.model).appendTo(sg.el); self.el.fadeIn('fast');
sg.el.fadeIn('fast');
}); });
return this; return this;
} }
}); });
var IndexView = Backbone.View.extend({ var BackboneStore = Backbone.Controller.extend({
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var sg = this;
this.el.fadeOut('fast', function() {
sg.el.empty();
$.tmpl(sg.indexTemplate, sg.model.toArray()).appendTo(sg.el);
sg.el.fadeIn('fast');
});
return this;
}
});
var Workspace = Backbone.Controller.extend({
_index: null, _index: null,
_products: null, _products: null,
_cart :null, _cart :null,
routes: { routes: {
"": "index", "": "index",
"item/:id": "item", "item/:id": "item",
}, },
initialize: function() { initialize: function(data) {
var ws = this; this._cart = new Cart();
if (this._index === null) { new CartView({collection: this._cart});
$.ajax({ this._products = new ProductCollection(data);
url: 'data/items.json', this._index = new ProductListView({model: this._products});
dataType: 'json',
data: {},
success: function(data) {
ws._cart = new Cart();
new CartView({model: ws._cart});
ws._products = new ProductCollection(data);
ws._index = new IndexView({model: ws._products});
Backbone.history.loadUrl();
}
});
return this;
}
return this; return this;
}, },
@ -129,13 +123,30 @@ var Workspace = Backbone.Controller.extend({
}, },
item: function(id) { item: function(id) {
if (_.isUndefined(this._products.getByCid(id)._view)) { var product = this._products.getByCid(id);
this._products.getByCid(id)._view = new ProductView({model: this._products.getByCid(id), if (_.isUndefined(product._view)) {
product._view = new ProductView({model: product,
cart: this._cart}); cart: this._cart});
} }
this._products.getByCid(id)._view.render(); product._view.render();
} }
}); });
workspace = new Workspace();
$(document).ready(function() {
var fetch_items = function() {
return $.ajax({
url: 'data/items.json',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
$.when(fetch_items()).then(function(data) {
new BackboneStore(data);
Backbone.history.start(); Backbone.history.start();
});
});
}).call(this);