Commit 54918bd4 authored by Pascal Hartig's avatar Pascal Hartig

Merge branch 'stephenplusplus-maria' into gh-pages

parents 47a21f2d d019d29f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "agilityjs", "name": "agilityjs",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"agility": "~0.1.3", "agility": "~0.1.3",
"jquery": "~1.9.1" "jquery": "~1.9.1"
} }
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
{
"name": "todomvc-common",
"version": "0.1.0",
"gitHead": "63628bfbeff187f6db5bc982a0a222e66e62901e",
"_id": "todomvc-common@0.1.0",
"readme": "ERROR: No README.md file found!",
"description": "ERROR: No README.md file found!",
"repository": {
"type": "git",
"url": "git://github.com/TasteJS/todomvc-common.git"
}
}
\ No newline at end of file
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "~1.0.5", "angular": "~1.0.5",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "~1.0.5", "angular": "~1.0.5",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
}, },
"devDependencies": { "devDependencies": {
"angular-mocks": "~1.0.5" "angular-mocks": "~1.0.5"
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"backbone": "~1.0.0", "backbone": "~1.0.0",
"underscore": "~1.4.4", "underscore": "~1.4.4",
"jquery": "~1.9.1", "jquery": "~1.9.1",
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"backbone.localStorage": "~1.1.0" "backbone.localStorage": "~1.1.0"
} }
} }
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
"dependencies": { "dependencies": {
"jquery": "~1.9.1", "jquery": "~1.9.1",
"canjs": "~1.1.4", "canjs": "~1.1.4",
"canjs-localstorage": "~0.1.0" "canjs-localstorage": "~0.1.0",
"todomvc-common": "~0.1.4"
} }
} }
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
{
"name": "todomvc-common",
"version": "0.1.1",
"gitHead": "639b3e310c9fd6970e8ccda893ad564915e715f5",
"_id": "todomvc-common@0.1.1",
"readme": "ERROR: No README.md file found!",
"description": "ERROR: No README.md file found!",
"repository": {
"type": "git",
"url": "git://github.com/tastejs/todomvc-common.git"
}
}
\ No newline at end of file
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
"name": "todomvc-closure", "name": "todomvc-closure",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -29,9 +28,8 @@ ...@@ -29,9 +28,8 @@
} }
function redirect() { function redirect() {
if (location.hostname === 'addyosmani.github.com') { if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.com/todomvc', location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
'todomvc.com');
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-emberjs", "name": "todomvc-emberjs",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"jquery": "~1.9.1", "jquery": "~1.9.1",
"handlebars": "~1.0.0-rc.3", "handlebars": "~1.0.0-rc.3",
"ember": "~1.0.0-rc.1", "ember": "~1.0.0-rc.1",
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
"dependencies": { "dependencies": {
"jquery": "~1.9.1", "jquery": "~1.9.1",
"handlebars": "~1.0.0-rc.3", "handlebars": "~1.0.0-rc.3",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-knockoutjs", "name": "todomvc-knockoutjs",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"knockout.js": "~2.2.0rc", "knockout.js": "~2.2.0rc",
"director": "~1.1.10" "director": "~1.1.10"
} }
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
{
"name": "todomvc-maria",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.4",
"director": "~1.2.0"
}
}
//
// Generated on Sun Dec 16 2012 22:47:05 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon).
// Version 1.1.9
//
(function (exports) {
/*
* browser.js: Browser specific functionality for director.
*
* (C) 2011, Nodejitsu Inc.
* MIT LICENSE
*
*/
if (!Array.prototype.filter) {
Array.prototype.filter = function(filter, that) {
var other = [], v;
for (var i = 0, n = this.length; i < n; i++) {
if (i in this && filter.call(that, v = this[i], i, this)) {
other.push(v);
}
}
return other;
};
}
if (!Array.isArray){
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
}
var dloc = document.location;
function dlocHashEmpty() {
// Non-IE browsers return '' when the address bar shows '#'; Director's logic
// assumes both mean empty.
return dloc.hash === '' || dloc.hash === '#';
}
var listener = {
mode: 'modern',
hash: dloc.hash,
history: false,
check: function () {
var h = dloc.hash;
if (h != this.hash) {
this.hash = h;
this.onHashChanged();
}
},
fire: function () {
if (this.mode === 'modern') {
this.history === true ? window.onpopstate() : window.onhashchange();
}
else {
this.onHashChanged();
}
},
init: function (fn, history) {
var self = this;
this.history = history;
if (!Router.listeners) {
Router.listeners = [];
}
function onchange(onChangeEvent) {
for (var i = 0, l = Router.listeners.length; i < l; i++) {
Router.listeners[i](onChangeEvent);
}
}
//note IE8 is being counted as 'modern' because it has the hashchange event
if ('onhashchange' in window && (document.documentMode === undefined
|| document.documentMode > 7)) {
// At least for now HTML5 history is available for 'modern' browsers only
if (this.history === true) {
// There is an old bug in Chrome that causes onpopstate to fire even
// upon initial page load. Since the handler is run manually in init(),
// this would cause Chrome to run it twise. Currently the only
// workaround seems to be to set the handler after the initial page load
// http://code.google.com/p/chromium/issues/detail?id=63040
setTimeout(function() {
window.onpopstate = onchange;
}, 500);
}
else {
window.onhashchange = onchange;
}
this.mode = 'modern';
}
else {
//
// IE support, based on a concept by Erik Arvidson ...
//
var frame = document.createElement('iframe');
frame.id = 'state-frame';
frame.style.display = 'none';
document.body.appendChild(frame);
this.writeFrame('');
if ('onpropertychange' in document && 'attachEvent' in document) {
document.attachEvent('onpropertychange', function () {
if (event.propertyName === 'location') {
self.check();
}
});
}
window.setInterval(function () { self.check(); }, 50);
this.onHashChanged = onchange;
this.mode = 'legacy';
}
Router.listeners.push(fn);
return this.mode;
},
destroy: function (fn) {
if (!Router || !Router.listeners) {
return;
}
var listeners = Router.listeners;
for (var i = listeners.length - 1; i >= 0; i--) {
if (listeners[i] === fn) {
listeners.splice(i, 1);
}
}
},
setHash: function (s) {
// Mozilla always adds an entry to the history
if (this.mode === 'legacy') {
this.writeFrame(s);
}
if (this.history === true) {
window.history.pushState({}, document.title, s);
// Fire an onpopstate event manually since pushing does not obviously
// trigger the pop event.
this.fire();
} else {
dloc.hash = (s[0] === '/') ? s : '/' + s;
}
return this;
},
writeFrame: function (s) {
// IE support...
var f = document.getElementById('state-frame');
var d = f.contentDocument || f.contentWindow.document;
d.open();
d.write("<script>_hash = '" + s + "'; onload = parent.listener.syncHash;<script>");
d.close();
},
syncHash: function () {
// IE support...
var s = this._hash;
if (s != dloc.hash) {
dloc.hash = s;
}
return this;
},
onHashChanged: function () {}
};
var Router = exports.Router = function (routes) {
if (!(this instanceof Router)) return new Router(routes);
this.params = {};
this.routes = {};
this.methods = ['on', 'once', 'after', 'before'];
this.scope = [];
this._methods = {};
this._insert = this.insert;
this.insert = this.insertEx;
this.historySupport = (window.history != null ? window.history.pushState : null) != null
this.configure();
this.mount(routes || {});
};
Router.prototype.init = function (r) {
var self = this;
this.handler = function(onChangeEvent) {
var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, '');
self.dispatch('on', url);
};
listener.init(this.handler, this.history);
if (this.history === false) {
if (dlocHashEmpty() && r) {
dloc.hash = r;
} else if (!dlocHashEmpty()) {
self.dispatch('on', dloc.hash.replace(/^#/, ''));
}
}
else {
var routeTo = dlocHashEmpty() && r ? r : !dlocHashEmpty() ? dloc.hash.replace(/^#/, '') : null;
if (routeTo) {
window.history.replaceState({}, document.title, routeTo);
}
// Router has been initialized, but due to the chrome bug it will not
// yet actually route HTML5 history state changes. Thus, decide if should route.
if (routeTo || this.run_in_init === true) {
this.handler();
}
}
return this;
};
Router.prototype.explode = function () {
var v = this.history === true ? this.getPath() : dloc.hash;
if (v.charAt(1) === '/') { v=v.slice(1) }
return v.slice(1, v.length).split("/");
};
Router.prototype.setRoute = function (i, v, val) {
var url = this.explode();
if (typeof i === 'number' && typeof v === 'string') {
url[i] = v;
}
else if (typeof val === 'string') {
url.splice(i, v, s);
}
else {
url = [i];
}
listener.setHash(url.join('/'));
return url;
};
//
// ### function insertEx(method, path, route, parent)
// #### @method {string} Method to insert the specific `route`.
// #### @path {Array} Parsed path to insert the `route` at.
// #### @route {Array|function} Route handlers to insert.
// #### @parent {Object} **Optional** Parent "routes" to insert into.
// insert a callback that will only occur once per the matched route.
//
Router.prototype.insertEx = function(method, path, route, parent) {
if (method === "once") {
method = "on";
route = function(route) {
var once = false;
return function() {
if (once) return;
once = true;
return route.apply(this, arguments);
};
}(route);
}
return this._insert(method, path, route, parent);
};
Router.prototype.getRoute = function (v) {
var ret = v;
if (typeof v === "number") {
ret = this.explode()[v];
}
else if (typeof v === "string"){
var h = this.explode();
ret = h.indexOf(v);
}
else {
ret = this.explode();
}
return ret;
};
Router.prototype.destroy = function () {
listener.destroy(this.handler);
return this;
};
Router.prototype.getPath = function () {
var path = window.location.pathname;
if (path.substr(0, 1) !== '/') {
path = '/' + path;
}
return path;
};
function _every(arr, iterator) {
for (var i = 0; i < arr.length; i += 1) {
if (iterator(arr[i], i, arr) === false) {
return;
}
}
}
function _flatten(arr) {
var flat = [];
for (var i = 0, n = arr.length; i < n; i++) {
flat = flat.concat(arr[i]);
}
return flat;
}
function _asyncEverySeries(arr, iterator, callback) {
if (!arr.length) {
return callback();
}
var completed = 0;
(function iterate() {
iterator(arr[completed], function(err) {
if (err || err === false) {
callback(err);
callback = function() {};
} else {
completed += 1;
if (completed === arr.length) {
callback();
} else {
iterate();
}
}
});
})();
}
function paramifyString(str, params, mod) {
mod = str;
for (var param in params) {
if (params.hasOwnProperty(param)) {
mod = params[param](str);
if (mod !== str) {
break;
}
}
}
return mod === str ? "([._a-zA-Z0-9-]+)" : mod;
}
function regifyString(str, params) {
var matches, last = 0, out = "";
while (matches = str.substr(last).match(/[^\w\d\- %@&]*\*[^\w\d\- %@&]*/)) {
last = matches.index + matches[0].length;
matches[0] = matches[0].replace(/^\*/, "([_.()!\\ %@&a-zA-Z0-9-]+)");
out += str.substr(0, matches.index) + matches[0];
}
str = out += str.substr(last);
var captures = str.match(/:([^\/]+)/ig), length;
if (captures) {
length = captures.length;
for (var i = 0; i < length; i++) {
str = str.replace(captures[i], paramifyString(captures[i], params));
}
}
return str;
}
function terminator(routes, delimiter, start, stop) {
var last = 0, left = 0, right = 0, start = (start || "(").toString(), stop = (stop || ")").toString(), i;
for (i = 0; i < routes.length; i++) {
var chunk = routes[i];
if (chunk.indexOf(start, last) > chunk.indexOf(stop, last) || ~chunk.indexOf(start, last) && !~chunk.indexOf(stop, last) || !~chunk.indexOf(start, last) && ~chunk.indexOf(stop, last)) {
left = chunk.indexOf(start, last);
right = chunk.indexOf(stop, last);
if (~left && !~right || !~left && ~right) {
var tmp = routes.slice(0, (i || 1) + 1).join(delimiter);
routes = [ tmp ].concat(routes.slice((i || 1) + 1));
}
last = (right > left ? right : left) + 1;
i = 0;
} else {
last = 0;
}
}
return routes;
}
Router.prototype.configure = function(options) {
options = options || {};
for (var i = 0; i < this.methods.length; i++) {
this._methods[this.methods[i]] = true;
}
this.recurse = options.recurse || this.recurse || false;
this.async = options.async || false;
this.delimiter = options.delimiter || "/";
this.strict = typeof options.strict === "undefined" ? true : options.strict;
this.notfound = options.notfound;
this.resource = options.resource;
this.history = options.html5history && this.historySupport || false;
this.run_in_init = this.history === true && options.run_handler_in_init !== false;
this.every = {
after: options.after || null,
before: options.before || null,
on: options.on || null
};
return this;
};
Router.prototype.param = function(token, matcher) {
if (token[0] !== ":") {
token = ":" + token;
}
var compiled = new RegExp(token, "g");
this.params[token] = function(str) {
return str.replace(compiled, matcher.source || matcher);
};
};
Router.prototype.on = Router.prototype.route = function(method, path, route) {
var self = this;
if (!route && typeof path == "function") {
route = path;
path = method;
method = "on";
}
if (Array.isArray(path)) {
return path.forEach(function(p) {
self.on(method, p, route);
});
}
if (path.source) {
path = path.source.replace(/\\\//ig, "/");
}
if (Array.isArray(method)) {
return method.forEach(function(m) {
self.on(m.toLowerCase(), path, route);
});
}
path = path.split(new RegExp(this.delimiter));
path = terminator(path, this.delimiter);
this.insert(method, this.scope.concat(path), route);
};
Router.prototype.dispatch = function(method, path, callback) {
var self = this, fns = this.traverse(method, path, this.routes, ""), invoked = this._invoked, after;
this._invoked = true;
if (!fns || fns.length === 0) {
this.last = [];
if (typeof this.notfound === "function") {
this.invoke([ this.notfound ], {
method: method,
path: path
}, callback);
}
return false;
}
if (this.recurse === "forward") {
fns = fns.reverse();
}
function updateAndInvoke() {
self.last = fns.after;
self.invoke(self.runlist(fns), self, callback);
}
after = this.every && this.every.after ? [ this.every.after ].concat(this.last) : [ this.last ];
if (after && after.length > 0 && invoked) {
if (this.async) {
this.invoke(after, this, updateAndInvoke);
} else {
this.invoke(after, this);
updateAndInvoke();
}
return true;
}
updateAndInvoke();
return true;
};
Router.prototype.invoke = function(fns, thisArg, callback) {
var self = this;
if (this.async) {
_asyncEverySeries(fns, function apply(fn, next) {
if (Array.isArray(fn)) {
return _asyncEverySeries(fn, apply, next);
} else if (typeof fn == "function") {
fn.apply(thisArg, fns.captures.concat(next));
}
}, function() {
if (callback) {
callback.apply(thisArg, arguments);
}
});
} else {
_every(fns, function apply(fn) {
if (Array.isArray(fn)) {
return _every(fn, apply);
} else if (typeof fn === "function") {
return fn.apply(thisArg, fns.captures || []);
} else if (typeof fn === "string" && self.resource) {
self.resource[fn].apply(thisArg, fns.captures || []);
}
});
}
};
Router.prototype.traverse = function(method, path, routes, regexp, filter) {
var fns = [], current, exact, match, next, that;
function filterRoutes(routes) {
if (!filter) {
return routes;
}
function deepCopy(source) {
var result = [];
for (var i = 0; i < source.length; i++) {
result[i] = Array.isArray(source[i]) ? deepCopy(source[i]) : source[i];
}
return result;
}
function applyFilter(fns) {
for (var i = fns.length - 1; i >= 0; i--) {
if (Array.isArray(fns[i])) {
applyFilter(fns[i]);
if (fns[i].length === 0) {
fns.splice(i, 1);
}
} else {
if (!filter(fns[i])) {
fns.splice(i, 1);
}
}
}
}
var newRoutes = deepCopy(routes);
newRoutes.matched = routes.matched;
newRoutes.captures = routes.captures;
newRoutes.after = routes.after.filter(filter);
applyFilter(newRoutes);
return newRoutes;
}
if (path === this.delimiter && routes[method]) {
next = [ [ routes.before, routes[method] ].filter(Boolean) ];
next.after = [ routes.after ].filter(Boolean);
next.matched = true;
next.captures = [];
return filterRoutes(next);
}
for (var r in routes) {
if (routes.hasOwnProperty(r) && (!this._methods[r] || this._methods[r] && typeof routes[r] === "object" && !Array.isArray(routes[r]))) {
current = exact = regexp + this.delimiter + r;
if (!this.strict) {
exact += "[" + this.delimiter + "]?";
}
match = path.match(new RegExp("^" + exact));
if (!match) {
continue;
}
if (match[0] && match[0] == path && routes[r][method]) {
next = [ [ routes[r].before, routes[r][method] ].filter(Boolean) ];
next.after = [ routes[r].after ].filter(Boolean);
next.matched = true;
next.captures = match.slice(1);
if (this.recurse && routes === this.routes) {
next.push([ routes.before, routes.on ].filter(Boolean));
next.after = next.after.concat([ routes.after ].filter(Boolean));
}
return filterRoutes(next);
}
next = this.traverse(method, path, routes[r], current);
if (next.matched) {
if (next.length > 0) {
fns = fns.concat(next);
}
if (this.recurse) {
fns.push([ routes[r].before, routes[r].on ].filter(Boolean));
next.after = next.after.concat([ routes[r].after ].filter(Boolean));
if (routes === this.routes) {
fns.push([ routes["before"], routes["on"] ].filter(Boolean));
next.after = next.after.concat([ routes["after"] ].filter(Boolean));
}
}
fns.matched = true;
fns.captures = next.captures;
fns.after = next.after;
return filterRoutes(fns);
}
}
}
return false;
};
Router.prototype.insert = function(method, path, route, parent) {
var methodType, parentType, isArray, nested, part;
path = path.filter(function(p) {
return p && p.length > 0;
});
parent = parent || this.routes;
part = path.shift();
if (/\:|\*/.test(part) && !/\\d|\\w/.test(part)) {
part = regifyString(part, this.params);
}
if (path.length > 0) {
parent[part] = parent[part] || {};
return this.insert(method, path, route, parent[part]);
}
if (!part && !path.length && parent === this.routes) {
methodType = typeof parent[method];
switch (methodType) {
case "function":
parent[method] = [ parent[method], route ];
return;
case "object":
parent[method].push(route);
return;
case "undefined":
parent[method] = route;
return;
}
return;
}
parentType = typeof parent[part];
isArray = Array.isArray(parent[part]);
if (parent[part] && !isArray && parentType == "object") {
methodType = typeof parent[part][method];
switch (methodType) {
case "function":
parent[part][method] = [ parent[part][method], route ];
return;
case "object":
parent[part][method].push(route);
return;
case "undefined":
parent[part][method] = route;
return;
}
} else if (parentType == "undefined") {
nested = {};
nested[method] = route;
parent[part] = nested;
return;
}
throw new Error("Invalid route context: " + parentType);
};
Router.prototype.extend = function(methods) {
var self = this, len = methods.length, i;
function extend(method) {
self._methods[method] = true;
self[method] = function() {
var extra = arguments.length === 1 ? [ method, "" ] : [ method ];
self.on.apply(self, extra.concat(Array.prototype.slice.call(arguments)));
};
}
for (i = 0; i < len; i++) {
extend(methods[i]);
}
};
Router.prototype.runlist = function(fns) {
var runlist = this.every && this.every.before ? [ this.every.before ].concat(_flatten(fns)) : _flatten(fns);
if (this.every && this.every.on) {
runlist.push(this.every.on);
}
runlist.captures = fns.captures;
runlist.source = fns.source;
return runlist;
};
Router.prototype.mount = function(routes, path) {
if (!routes || typeof routes !== "object" || Array.isArray(routes)) {
return;
}
var self = this;
path = path || [];
if (!Array.isArray(path)) {
path = path.split(self.delimiter);
}
function insertOrMount(route, local) {
var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename;
if (isRoute) {
rename = rename.slice((rename.match(new RegExp(self.delimiter)) || [ "" ])[0].length);
parts.shift();
}
if (isRoute && routeType === "object" && !Array.isArray(routes[route])) {
local = local.concat(parts);
self.mount(routes[route], local);
return;
}
if (isRoute) {
local = local.concat(rename.split(self.delimiter));
local = terminator(local, self.delimiter);
}
self.insert(event, local, routes[route]);
}
for (var route in routes) {
if (routes.hasOwnProperty(route)) {
insertOrMount(route, path.slice(0));
}
}
};
}(typeof exports === "object" ? exports : window));
\ No newline at end of file
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
label[for='toggle-all'] {
display: none;
}
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all:checked:before {
color: #737373;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.editing {
border-bottom: none;
padding: 0;
}
#todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list li label {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li .edit {
display: none;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: 1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
float: left;
text-align: left;
}
#filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
#filters li {
display: inline;
}
#filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
}
#filters li a.selected {
font-weight: bold;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
}
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
}
(function () {
'use strict';
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function getSourcePath() {
// If accessed via addyosmani.github.io/todomvc/, strip the project path.
if (location.hostname.indexOf('github.io') > 0) {
return location.pathname.replace(/todomvc\//, '');
}
return location.pathname;
}
function appendSourceLink() {
var sourceLink = document.createElement('a');
var paragraph = document.createElement('p');
var footer = document.getElementById('info');
var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';
if (footer) {
sourceLink.href = urlBase + getSourcePath();
sourceLink.appendChild(document.createTextNode('Check out the source'));
paragraph.appendChild(sourceLink);
footer.appendChild(paragraph);
}
}
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink();
redirect();
})();
...@@ -3,16 +3,20 @@ ...@@ -3,16 +3,20 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Maria • TodoMVC</title> <title>Maria • TodoMVC</title>
<link href="components/todomvc-common/base.css" rel="stylesheet">
<link href="../../../assets/base.css" rel="stylesheet">
<link href="css/app.css" rel="stylesheet"> <link href="css/app.css" rel="stylesheet">
</head> </head>
<body> <body>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/petermichaux">Peter Michaux</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="../lib/maria/maria.js"></script> <script src="components/todomvc-common/base.js"></script>
<script src="../lib/aristocrat/aristocrat.js"></script> <script src="components/director/build/director.js"></script>
<script src="../../../assets/director.min.js"></script> <script src="lib/maria/maria.js"></script>
<script src="lib/aristocrat/aristocrat.js"></script>
<script src="js/namespace.js"></script> <script src="js/namespace.js"></script>
<script src="js/util.js"></script> <script src="js/util.js"></script>
...@@ -25,12 +29,5 @@ ...@@ -25,12 +29,5 @@
<script src="js/views/TodoView.js"></script> <script src="js/views/TodoView.js"></script>
<script src="js/controllers/TodoController.js"></script> <script src="js/controllers/TodoController.js"></script>
<script src="js/bootstrap.js"></script> <script src="js/bootstrap.js"></script>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/petermichaux">Peter Michaux</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
</body> </body>
</html> </html>
/*jshint strict: false */ /*jshint strict: false */
/*global maria, Router, checkit */ /*global maria, Router, checkit */
maria.on(window, 'load', function() { maria.on(window, 'load', function () {
var model; var model;
if ((typeof localStorage === 'object') && (typeof JSON === 'object')) { if ((typeof localStorage === 'object') && (typeof JSON === 'object')) {
var store = localStorage.getItem('todos-maria'); var store = localStorage.getItem('todos-maria');
model = store ? checkit.TodosModel.fromJSON(JSON.parse(store)) :
new checkit.TodosModel(); if (store) {
maria.on(model, 'change', function() { model = checkit.TodosModel.fromJSON(JSON.parse(store));
} else {
model = new checkit.TodosModel();
}
maria.on(model, 'change', function () {
localStorage.setItem('todos-maria', JSON.stringify(model.toJSON())); localStorage.setItem('todos-maria', JSON.stringify(model.toJSON()));
}); });
} } else {
else {
model = new checkit.TodosModel(); model = new checkit.TodosModel();
} }
var routes = { var routes = {
'/': function() { '/': function () {
model.setMode('all'); model.setMode('all');
}, },
'/active': function() { '/active': function () {
model.setMode('incompleted'); model.setMode('incompleted');
}, },
'/completed': function() { '/completed': function () {
model.setMode('completed'); model.setMode('completed');
} }
}; };
var router = Router(routes);
var router = new Router(routes);
router.init(); router.init();
var view = new checkit.TodosAppView(model); var view = new checkit.TodosAppView(model);
......
...@@ -3,35 +3,41 @@ ...@@ -3,35 +3,41 @@
maria.Controller.subclass(checkit, 'TodoController', { maria.Controller.subclass(checkit, 'TodoController', {
properties: { properties: {
onClickDestroy: function() { onClickDestroy: function () {
this.getModel().destroy(); this.getModel().destroy();
}, },
onClickToggle: function() {
onClickToggle: function () {
this.getModel().toggleCompleted(); this.getModel().toggleCompleted();
}, },
onDblclickLabel: function() {
onDblclickLabel: function () {
this.getView().showEdit(); this.getView().showEdit();
}, },
onKeyupEdit: function(evt) {
onKeyupEdit: function (evt) {
var keyCode = evt.keyCode; var keyCode = evt.keyCode;
if (checkit.isEnterKeyCode(keyCode)) { if (checkit.isEnterKeyCode(keyCode)) {
this.onBlurEdit(); this.onBlurEdit();
} } else if (checkit.isEscapeKeyCode(keyCode)) {
else if (checkit.isEscapeKeyCode(keyCode)) {
var view = this.getView(); var view = this.getView();
view.resetEdit(); view.resetEdit();
view.showDisplay(); view.showDisplay();
} }
}, },
onBlurEdit: function() {
onBlurEdit: function () {
var model = this.getModel(); var model = this.getModel();
var view = this.getView(); var view = this.getView();
var value = view.getInputValue(); var value = view.getInputValue();
view.showDisplay(); view.showDisplay();
if (checkit.isBlank(value)) { if (checkit.isBlank(value)) {
model.destroy(); model.destroy();
} } else {
else {
model.setTitle(value); model.setTitle(value);
} }
} }
......
...@@ -3,28 +3,33 @@ ...@@ -3,28 +3,33 @@
maria.Controller.subclass(checkit, 'TodosAppController', { maria.Controller.subclass(checkit, 'TodosAppController', {
properties: { properties: {
onKeyupNewTodo: function(evt) { onKeyupNewTodo: function (evt) {
if (checkit.isEnterKeyCode(evt.keyCode)) { if (checkit.isEnterKeyCode(evt.keyCode)) {
var view = this.getView(); var view = this.getView();
var value = view.getInputValue(); var value = view.getInputValue();
if (!checkit.isBlank(value)) { if (!checkit.isBlank(value)) {
var todo = new checkit.TodoModel(); var todo = new checkit.TodoModel();
todo.setTitle(value); todo.setTitle(value);
this.getModel().add(todo); this.getModel().add(todo);
view.clearInput(); view.clearInput();
} }
} }
}, },
onClickToggleAll: function() {
onClickToggleAll: function () {
var model = this.getModel(); var model = this.getModel();
if (model.isAllCompleted()) { if (model.isAllCompleted()) {
model.markAllIncompleted(); model.markAllIncompleted();
} } else {
else {
model.markAllCompleted(); model.markAllCompleted();
} }
}, },
onClickClearCompleted: function() {
onClickClearCompleted: function () {
this.getModel().deleteCompleted(); this.getModel().deleteCompleted();
} }
} }
......
...@@ -5,30 +5,40 @@ maria.Model.subclass(checkit, 'TodoModel', { ...@@ -5,30 +5,40 @@ maria.Model.subclass(checkit, 'TodoModel', {
properties: { properties: {
_title: '', _title: '',
_completed: false, _completed: false,
getTitle: function() {
getTitle: function () {
return this._title; return this._title;
}, },
setTitle: function(title) {
setTitle: function (title) {
title = ('' + title).trim(); title = ('' + title).trim();
if (this._title !== title) { if (this._title !== title) {
this._title = title; this._title = title;
this.dispatchEvent({type: 'change'});
this.dispatchEvent({ type: 'change' });
} }
}, },
isCompleted: function() {
isCompleted: function () {
return this._completed; return this._completed;
}, },
setCompleted: function(completed) {
setCompleted: function (completed) {
completed = !!completed; completed = !!completed;
if (this._completed !== completed) { if (this._completed !== completed) {
this._completed = completed; this._completed = completed;
this.dispatchEvent({type: 'change'});
this.dispatchEvent({ type: 'change' });
} }
}, },
toggleCompleted: function() {
toggleCompleted: function () {
this.setCompleted(!this.isCompleted()); this.setCompleted(!this.isCompleted());
}, },
toJSON: function() {
toJSON: function () {
return { return {
title: this._title, title: this._title,
completed: this._completed completed: this._completed
...@@ -37,9 +47,11 @@ maria.Model.subclass(checkit, 'TodoModel', { ...@@ -37,9 +47,11 @@ maria.Model.subclass(checkit, 'TodoModel', {
} }
}); });
checkit.TodoModel.fromJSON = function(todoJSON) { checkit.TodoModel.fromJSON = function (todoJSON) {
var model = new checkit.TodoModel(); var model = new checkit.TodoModel();
model._title = todoJSON.title; model._title = todoJSON.title;
model._completed = todoJSON.completed; model._completed = todoJSON.completed;
return model; return model;
}; };
...@@ -4,61 +4,79 @@ ...@@ -4,61 +4,79 @@
maria.SetModel.subclass(checkit, 'TodosModel', { maria.SetModel.subclass(checkit, 'TodosModel', {
properties: { properties: {
_mode: 'all', _mode: 'all',
getPossibleModes: function() {
getPossibleModes: function () {
return ['all', 'incompleted', 'completed']; return ['all', 'incompleted', 'completed'];
}, },
getMode: function() {
getMode: function () {
return this._mode; return this._mode;
}, },
setMode: function(mode) {
if (this.getPossibleModes().some(function(m) {return m === mode;})) { setMode: function (mode) {
var modePossible = this.getPossibleModes().some(function (m) {
return m === mode;
});
if (modePossible) {
if (this._mode !== mode) { if (this._mode !== mode) {
this._mode = mode; this._mode = mode;
this.dispatchEvent({type: 'change'});
} this.dispatchEvent({ type: 'change' });
} }
else { } else {
throw new Error('checkit.TodosModel.prototype.setMode: unsupported mode "'+mode+'".'); throw new Error('checkit.TodosModel.prototype.setMode: unsupported mode "' + mode + '".');
} }
}, },
getCompleted: function() {
return this.filter(function(todo) { getCompleted: function () {
return this.filter(function (todo) {
return todo.isCompleted(); return todo.isCompleted();
}); });
}, },
getIncompleted: function() {
return this.filter(function(todo) { getIncompleted: function () {
return this.filter(function (todo) {
return !todo.isCompleted(); return !todo.isCompleted();
}); });
}, },
isAllCompleted: function() {
isAllCompleted: function () {
return (this.length > 0) && (this.getCompleted().length === this.length); return (this.length > 0) && (this.getCompleted().length === this.length);
}, },
markAllCompleted: function() {
this.forEach(function(todo) { markAllCompleted: function () {
this.forEach(function (todo) {
todo.setCompleted(true); todo.setCompleted(true);
}); });
}, },
markAllIncompleted: function() {
this.forEach(function(todo) { markAllIncompleted: function () {
this.forEach(function (todo) {
todo.setCompleted(false); todo.setCompleted(false);
}); });
}, },
deleteCompleted: function() {
deleteCompleted: function () {
this['delete'].apply(this, this.getCompleted()); this['delete'].apply(this, this.getCompleted());
}, },
toJSON: function() {
return this.map(function(todo) { toJSON: function () {
return this.map(function (todo) {
return todo.toJSON(); return todo.toJSON();
}); });
} }
} }
}); });
checkit.TodosModel.fromJSON = function(todosJSON) { checkit.TodosModel.fromJSON = function (todosJSON) {
var model = new checkit.TodosModel(); var model = new checkit.TodosModel();
for (var i = 0, ilen = todosJSON.length; i < ilen; i++) { var i;
var ilen;
for (i = 0, ilen = todosJSON.length; i < ilen; i++) {
model.add(checkit.TodoModel.fromJSON(todosJSON[i])); model.add(checkit.TodoModel.fromJSON(todosJSON[i]));
} }
return model; return model;
}; };
/*jshint strict: false */ /*jshint strict: false */
/*global checkit */ /*global checkit */
checkit.isBlank = function(str) { checkit.isBlank = function (str) {
return (/^\s*$/).test(str); return (/^\s*$/).test(str);
}; };
checkit.escapeHTML = function(str) { checkit.escapeHTML = function (str) {
return String(str) return String(str)
.replace(/&(?!\w+;)/g, '&amp;') .replace(/&(?!\w+;)/g, '&amp;')
.replace(/</g, '&lt;') .replace(/</g, '&lt;')
...@@ -13,10 +13,10 @@ checkit.escapeHTML = function(str) { ...@@ -13,10 +13,10 @@ checkit.escapeHTML = function(str) {
.replace(/"/g, '&quot;'); .replace(/"/g, '&quot;');
}; };
checkit.isEnterKeyCode = function(keyCode) { checkit.isEnterKeyCode = function (keyCode) {
return keyCode === 13; return keyCode === 13;
}; };
checkit.isEscapeKeyCode = function(keyCode) { checkit.isEscapeKeyCode = function (keyCode) {
return keyCode === 27; return keyCode === 27;
}; };
...@@ -3,17 +3,18 @@ ...@@ -3,17 +3,18 @@
maria.ElementView.subclass(checkit, 'TodoView', { maria.ElementView.subclass(checkit, 'TodoView', {
uiActions: { uiActions: {
'click .destroy': 'onClickDestroy' , 'click .destroy': 'onClickDestroy',
'click .toggle' : 'onClickToggle' , 'click .toggle': 'onClickToggle',
'dblclick label' : 'onDblclickLabel', 'dblclick label': 'onDblclickLabel',
'keyup .edit' : 'onKeyupEdit' , 'keyup .edit': 'onKeyupEdit',
'blur .edit' : 'onBlurEdit' 'blur .edit': 'onBlurEdit'
}, },
properties: { properties: {
buildData: function() { buildData: function () {
var model = this.getModel(); var model = this.getModel();
var item = this.find('li'); var item = this.find('li');
aristocrat.removeClass(item, '(in|)completed'); aristocrat.removeClass(item, '(in|)completed');
aristocrat.addClass(item, (model.isCompleted() ? 'completed' : 'incompleted')); aristocrat.addClass(item, (model.isCompleted() ? 'completed' : 'incompleted'));
...@@ -21,23 +22,32 @@ maria.ElementView.subclass(checkit, 'TodoView', { ...@@ -21,23 +22,32 @@ maria.ElementView.subclass(checkit, 'TodoView', {
this.find('.toggle').checked = model.isCompleted(); this.find('.toggle').checked = model.isCompleted();
}, },
update: function() {
update: function () {
this.buildData(); this.buildData();
}, },
resetEdit: function() {
resetEdit: function () {
var input = this.find('.edit'); var input = this.find('.edit');
input.value = this.getModel().getTitle(); input.value = this.getModel().getTitle();
}, },
showEdit: function() {
this.resetEdit(); showEdit: function () {
var input = this.find('.edit'); var input = this.find('.edit');
this.resetEdit();
aristocrat.addClass(this.find('li'), 'editing'); aristocrat.addClass(this.find('li'), 'editing');
input.focus(); input.focus();
}, },
showDisplay: function() {
showDisplay: function () {
aristocrat.removeClass(this.find('li'), 'editing'); aristocrat.removeClass(this.find('li'), 'editing');
}, },
getInputValue: function() {
getInputValue: function () {
return this.find('.edit').value; return this.find('.edit').value;
} }
} }
......
...@@ -3,12 +3,13 @@ ...@@ -3,12 +3,13 @@
maria.SetView.subclass(checkit, 'TodosAppView', { maria.SetView.subclass(checkit, 'TodosAppView', {
uiActions: { uiActions: {
'keyup #new-todo' : 'onKeyupNewTodo' , 'keyup #new-todo': 'onKeyupNewTodo',
'click #toggle-all' : 'onClickToggleAll' , 'click #toggle-all': 'onClickToggleAll',
'click #clear-completed': 'onClickClearCompleted' 'click #clear-completed': 'onClickClearCompleted'
}, },
properties: { properties: {
buildData: function() { buildData: function () {
var model = this.getModel(); var model = this.getModel();
var length = model.length; var length = model.length;
...@@ -20,7 +21,7 @@ maria.SetView.subclass(checkit, 'TodosAppView', { ...@@ -20,7 +21,7 @@ maria.SetView.subclass(checkit, 'TodosAppView', {
checkbox.disabled = model.isEmpty(); checkbox.disabled = model.isEmpty();
var todoList = this.find('#todo-list'); var todoList = this.find('#todo-list');
model.getPossibleModes().forEach(function(mode) { model.getPossibleModes().forEach(function (mode) {
aristocrat.removeClass(todoList, mode); aristocrat.removeClass(todoList, mode);
}); });
aristocrat.addClass(todoList, model.getMode()); aristocrat.addClass(todoList, model.getMode());
...@@ -42,21 +43,27 @@ maria.SetView.subclass(checkit, 'TodosAppView', { ...@@ -42,21 +43,27 @@ maria.SetView.subclass(checkit, 'TodosAppView', {
clearButton.style.display = (completedLength > 0) ? '' : 'none'; clearButton.style.display = (completedLength > 0) ? '' : 'none';
clearButton.innerHTML = 'Clear completed (' + completedLength + ')'; clearButton.innerHTML = 'Clear completed (' + completedLength + ')';
}, },
update: function(evt) {
update: function (evt) {
maria.SetView.prototype.update.call(this, evt); maria.SetView.prototype.update.call(this, evt);
this.buildData(); this.buildData();
}, },
getContainerEl: function() {
getContainerEl: function () {
// child views will be appended to this element // child views will be appended to this element
return this.find('#todo-list'); return this.find('#todo-list');
}, },
createChildView: function(todoModel) {
createChildView: function (todoModel) {
return new checkit.TodoView(todoModel); return new checkit.TodoView(todoModel);
}, },
getInputValue: function() {
getInputValue: function () {
return this.find('#new-todo').value; return this.find('#new-todo').value;
}, },
clearInput: function() {
clearInput: function () {
this.find('#new-todo').value = ''; this.find('#new-todo').value = '';
} }
} }
......
...@@ -4,19 +4,25 @@ Copyright (c) 2012, Peter Michaux ...@@ -4,19 +4,25 @@ Copyright (c) 2012, Peter Michaux
All rights reserved. All rights reserved.
Licensed under the Simplified BSD License. Licensed under the Simplified BSD License.
https://github.com/petermichaux/evento/blob/master/LICENSE https://github.com/petermichaux/evento/blob/master/LICENSE
*/var evento = {}; */
/** /**
@property evento.EventTarget The root namespace for the Evento library.
@description @namespace
*/
var evento = {};
/**
A constructor function for creating event target objects. A constructor function for creating event target objects.
var et = new evento.EventTarget(); var et = new evento.EventTarget();
The methods of an event target object are inspired by the DOM2 standard. The methods of an event target object are inspired by the DOM2 standard.
@constructor
*/ */
evento.EventTarget = function() {}; evento.EventTarget = function() {};
...@@ -36,25 +42,21 @@ evento.EventTarget = function() {}; ...@@ -36,25 +42,21 @@ evento.EventTarget = function() {};
/** /**
@property evento.EventTarget.prototype.addEventListener
@parameter type {string} The name of the event.
@parameter listener {object|function} The listener object or callback function.
@description
If the listener is an object then when a matching event type is dispatched on If the listener is an object then when a matching event type is dispatched on
the event target, the listener object's handleEvent method will be called. the event target, the listener object's `handleEvent` method will be called.
If the listener is a function then when a matching event type is dispatched on If the listener is a function then when a matching event type is dispatched on
the event target, the listener function is called with event target object set as the event target, the listener function is called with event target object set as
the "this" object. the `this` object.
One listener (or type/listener pair to be more precise) can be added only once. One listener (or type/listener pair to be more precise) can be added only once.
et.addEventListener('change', {handleEvent:function(){}}); et.addEventListener('change', {handleEvent:function(){}});
et.addEventListener('change', function(){}); et.addEventListener('change', function(){});
@param {string} type The name of the event.
@param {(Object|function)} listener The listener object or callback function.
*/ */
evento.EventTarget.prototype.addEventListener = function(type, listener) { evento.EventTarget.prototype.addEventListener = function(type, listener) {
...@@ -72,20 +74,16 @@ et.addEventListener('change', function(){}); ...@@ -72,20 +74,16 @@ et.addEventListener('change', function(){});
/** /**
@property evento.EventTarget.prototype.removeEventListener
@parameter type {string} The name of the event.
@parameter listener {object|function} The listener object or callback function.
@description
Removes added listener matching the type/listener combination exactly. Removes added listener matching the type/listener combination exactly.
If this combination is not found there are no errors. If this combination is not found there are no errors.
var o = {handleEvent:function(){}}; var o = {handleEvent:function(){}};
et.removeEventListener('change', o); et.removeEventListener('change', o);
et.removeEventListener('change', fn); et.removeEventListener('change', fn);
@param {string} type The name of the event.
@param {(Object|function)} listener The listener object or callback function.
*/ */
evento.EventTarget.prototype.removeEventListener = function(type, listener) { evento.EventTarget.prototype.removeEventListener = function(type, listener) {
...@@ -105,20 +103,16 @@ et.removeEventListener('change', fn); ...@@ -105,20 +103,16 @@ et.removeEventListener('change', fn);
/** /**
@property evento.EventTarget.prototype.addParentEventTarget
@parameter parent {EventTarget} A parent to call when bubbling an event.
@description
When an event is dispatched on an event target, if that event target has parents When an event is dispatched on an event target, if that event target has parents
then the event is also dispatched on the parents as long as bubbling has not then the event is also dispatched on the parents as long as bubbling has not
been canceled on the event. been canceled on the event.
One parent can be added only once. One parent can be added only once.
var o = new evento.EventTarget(); var o = new evento.EventTarget();
et.addParentEventTarget(o); et.addParentEventTarget(o);
@param {EventTarget} parent A parent to call when bubbling an event.
*/ */
evento.EventTarget.prototype.addParentEventTarget = function(parent) { evento.EventTarget.prototype.addParentEventTarget = function(parent) {
...@@ -138,17 +132,13 @@ et.addParentEventTarget(o); ...@@ -138,17 +132,13 @@ et.addParentEventTarget(o);
/** /**
@property evento.EventTarget.prototype.removeParentEventTarget Removes parent added with addParentEventTarget. If the parent is
not found, there are no errors.
@parameter parent {EventTarget} The parent to remove.
@description var o = {handleEvent:function(){}};
et.removeParentEventTarget(o);
Removes parent added with addParentEventTarget. If the listener is @param {EventTarget} parent The parent to remove.
not found there are no errors.
var o = {handleEvent:function(){}};
et.removeParentEventTarget(o);
*/ */
evento.EventTarget.prototype.removeParentEventTarget = function(parent) { evento.EventTarget.prototype.removeParentEventTarget = function(parent) {
...@@ -166,23 +156,19 @@ et.removeParentEventTarget(o); ...@@ -166,23 +156,19 @@ et.removeParentEventTarget(o);
/** /**
@property evento.EventTarget.prototype.dispatchEvent The `event.type` property is required. All listeners registered for this
event type are called with `event` passed as an argument to the listeners.
@parameter evt {object} The event object to dispatch to all listeners.
@description If not set, the `event.target` property will be set to be this event target.
The evt.type property is required. All listeners registered for this The `evt.currentTarget` will be set to be this event target.
event type are called with evt passed as an argument to the listeners.
If not set, the evt.target property will be set to be the event target. Call `evt.stopPropagation()` to stop bubbling to parents.
The evt.currentTarget will be set to be the event target. et.dispatchEvent({type:'change'});
et.dispatchEvent({type:'change', extraData:'abc'});
Call evt.stopPropagation() to stop bubbling to parents. @param {Object} event The event object to dispatch to all listeners.
et.dispatchEvent({type:'change'});
et.dispatchEvent({type:'change', extraData:'abc'});
*/ */
evento.EventTarget.prototype.dispatchEvent = function(evt) { evento.EventTarget.prototype.dispatchEvent = function(evt) {
...@@ -207,7 +193,7 @@ et.dispatchEvent({type:'change', extraData:'abc'}); ...@@ -207,7 +193,7 @@ et.dispatchEvent({type:'change', extraData:'abc'});
// a not-yet-called listener. One listener removing // a not-yet-called listener. One listener removing
// a not-yet-called listener would result in skipping that // a not-yet-called listener would result in skipping that
// not-yet-called listner. The worst case scenario // not-yet-called listner. The worst case scenario
// is a listener adding itself again which would // is a listener removing and adding itself again which would
// create an infinite loop. // create an infinite loop.
// //
var listeners = this._evento_listeners[evt.type].slice(0); var listeners = this._evento_listeners[evt.type].slice(0);
...@@ -235,22 +221,16 @@ et.dispatchEvent({type:'change', extraData:'abc'}); ...@@ -235,22 +221,16 @@ et.dispatchEvent({type:'change', extraData:'abc'});
/** /**
@property evento.EventTarget.mixin
@parameter obj {object} The object to be made into an event target.
@description
Mixes in the event target methods into any object. Mixes in the event target methods into any object.
// Example 1 Example 1
app.Person = function(name) { app.Person = function(name) {
evento.EventTarget.call(this); evento.EventTarget.call(this);
this.setName(name); this.setName(name);
}; };
evento.EventTarget.mixin(app.Person.prototype); evento.EventTarget.mixin(app.Person.prototype);
app.Person.prototype.setName = function(newName) { app.Person.prototype.setName = function(newName) {
var oldName = this.name; var oldName = this.name;
this.name = newName; this.name = newName;
this.dispatchEvent({ this.dispatchEvent({
...@@ -258,20 +238,22 @@ app.Person.prototype.setName = function(newName) { ...@@ -258,20 +238,22 @@ app.Person.prototype.setName = function(newName) {
oldName: oldName, oldName: oldName,
newName: newName newName: newName
}); });
}; };
var person = new app.Person('David'); var person = new app.Person('David');
person.addEventListener('change', function(evt) { person.addEventListener('change', function(evt) {
alert('"' + evt.oldName + '" is now called "' + evt.newName + '".'); alert('"' + evt.oldName + '" is now called "' + evt.newName + '".');
}); });
person.setName('Dave'); person.setName('Dave');
// Example 2 Example 2
var o = {}; var o = {};
evento.EventTarget.mixin(o); evento.EventTarget.mixin(o);
o.addEventListener('change', function(){alert('change');}); o.addEventListener('change', function(){alert('change');});
o.dispatchEvent({type:'change'}); o.dispatchEvent({type:'change'});
@param {Object} obj The object to be made into an event target.
*/ */
evento.EventTarget.mixin = function(obj) { evento.EventTarget.mixin = function(obj) {
...@@ -292,103 +274,93 @@ o.dispatchEvent({type:'change'}); ...@@ -292,103 +274,93 @@ o.dispatchEvent({type:'change'});
}()); }());
/** /**
@property evento.on
@parameter element {EventTarget} The object you'd like to observe.
@parameter type {string} The name of the event.
@parameter listener {object|function} The listener object or callback function.
@parameter auxArg {string|object} Optional. See description.
@description
If the listener is an object then when a matching event type is dispatched on If the listener is an object then when a matching event type is dispatched on
the event target, the listener object's handleEvent method will be called. the event target, the listener object's `handleEvent` method will be called.
By supplying a string value for auxArg you can specify the name of By supplying a string value for `auxArg`, you can specify the name of
the method to be called. You can also supply a function object for auxArg for the method to be called. You can also supply a function object for `auxArg` for
early binding. early binding.
If the listener is a function then when a matching event type is dispatched on If the listener is a function then when a matching event type is dispatched on
the event target, the listener function is called with event target object set as the event target, the listener function is called with event target object set as
the "this" object. Using the auxArg you can specifiy a different object to be the `this` object. Using the `auxArg`, you can specifiy a different object to be
the "this" object. the `this` object.
One listener (or type/listener/auxArg pair to be more precise) can be added One listener (or type/listener/auxArg pair to be more precise) can be added
only once. only once.
var o = { var o = {
handleEvent: function(){}, handleEvent: function(){},
handleClick: function(){} handleClick: function(){}
}; };
// late binding. handleEvent is found when each event is dispatched
evento.on(document.body, 'click', o);
// late binding. handleClick is found when each event is dispatched // late binding. handleEvent is found when each event is dispatched
evento.on(document.body, 'click', o, 'handleClick'); evento.on(document.body, 'click', o);
// early binding. The supplied function is bound now // late binding. handleClick is found when each event is dispatched
evento.on(document.body, 'click', o, o.handleClick); evento.on(document.body, 'click', o, 'handleClick');
evento.on(document.body, 'click', o, function(){});
// supplied function will be called with document.body as this object // early binding. The supplied function is bound now
evento.on(document.body, 'click', function(){}); evento.on(document.body, 'click', o, o.handleClick);
evento.on(document.body, 'click', o, function(){});
// The following form is supported but is not neccessary given the options // supplied function will be called with document.body as this object
// above and it is recommended you avoid it. evento.on(document.body, 'click', function(){});
evento.on(document.body, 'click', this.handleClick, this);
*/ // The following form is supported but is not neccessary given the options
// above and it is recommended you avoid it.
evento.on(document.body, 'click', this.handleClick, this);
/** @method evento.on
@property evento.off @param {EventTarget} element The object you'd like to observe.
@parameter element {EventTarget} The object you'd like to stop observing. @param {string} type The name of the event.
@parameter type {string} The name of the event. @param {(Object|function)} listener The listener object or callback function.
@parameter listener {object|function} The listener object or callback function. @param {(string|Object)} [auxArg] See description.
@parameter auxArg {string|object} Optional. */
@description /**
Removes added listener matching the element/type/listener/auxArg combination exactly. Removes added listener matching the element/type/listener/auxArg combination exactly.
If this combination is not found there are no errors. If this combination is not found there are no errors.
var o = {handleEvent:function(){}, handleClick:function(){}}; var o = {handleEvent:function(){}, handleClick:function(){}};
evento.off(document.body, 'click', o); evento.off(document.body, 'click', o);
evento.off(document.body, 'click', o, 'handleClick'); evento.off(document.body, 'click', o, 'handleClick');
evento.off(document.body, 'click', o, fn); evento.off(document.body, 'click', o, fn);
evento.off(document.body, 'click', fn); evento.off(document.body, 'click', fn);
evento.off(document.body, 'click', this.handleClick, this); evento.off(document.body, 'click', this.handleClick, this);
*/ @method evento.off
/** @param {EventTarget} element The object you'd like to stop observing.
@property evento.purge @param {string} type The name of the event.
@parameter listener {EventListener} The listener object that should stop listening. @param {(Object|function)} listener The listener object or callback function.
@description @param {(string|Object)} [auxArg] See description.
*/
Removes all registrations of the listener added through evento.on. /**
Removes all registrations of the listener added through `evento.on`.
This purging should be done before your application code looses its last reference This purging should be done before your application code looses its last reference
to listener. (This can also be done with more work using evento.off for to listener. (This can also be done with more work using `evento.off` for
each registeration.) If the listeners are not removed or purged, the listener each registeration.) If the listeners are not removed or purged, the listener
will continue to observe the EventTarget and cannot be garbage collected. In an will continue to observe the `EventTarget` and cannot be garbage collected. In an
MVC application this can lead to "zombie views" if the model data cannot be MVC application this can lead to "zombie views" if the model data cannot be
garbage collected. Event listeners need to be removed from event targets in browsers garbage collected. Event listeners need to be removed from event targets in browsers
with circular reference memory leak problems (i.e. old versions of Internet Explorer.) with circular reference memory leak problems (i.e. old versions of Internet Explorer.)
The primary motivation for this purge function is to easy cleanup in MVC View destroy The primary motivation for this `purge` function is to ease cleanup in MVC View destroy
methods. For example, methods. For example,
var APP_BoxView = function(model, controller) { var APP_BoxView = function(model, controller) {
this.model = model || new APP_BoxModel(); this.model = model || new APP_BoxModel();
this.controller = controller || new APP_BoxController(); this.controller = controller || new APP_BoxController();
this.rootEl = document.createElement('div'); this.rootEl = document.createElement('div');
...@@ -399,24 +371,28 @@ var APP_BoxView = function(model, controller) { ...@@ -399,24 +371,28 @@ var APP_BoxView = function(model, controller) {
// //
evento.on(this.rootEl, 'click', this, 'handleClick'); evento.on(this.rootEl, 'click', this, 'handleClick');
evento.on(this.model, 'change', this, 'handleModelChange'); evento.on(this.model, 'change', this, 'handleModelChange');
}; };
APP_BoxView.prototype.handleClick = function() { APP_BoxView.prototype.handleClick = function() {
// might subscribe/unsubscribe to more DOM nodes or models here // might subscribe/unsubscribe to more DOM nodes or models here
}; };
APP_BoxView.prototype.handleModelChange = function() { APP_BoxView.prototype.handleModelChange = function() {
// might subscribe/unsubscribe to more DOM nodes or models here // might subscribe/unsubscribe to more DOM nodes or models here
}; };
APP_BoxView.prototype.destroy = function() { APP_BoxView.prototype.destroy = function() {
// Programmer doesn't need to remember anything. Purge all subscriptions // Programmer doesn't need to remember anything. Purge all subscriptions
// to DOM nodes, model objects, or anything else implementing // to DOM nodes, model objects, or anything else implementing
// the EventTarget interface in one fell swoop. // the EventTarget interface in one fell swoop.
// //
evento.purge(this); evento.purge(this);
}; };
@method evento.purge
@param {EventListener} listener The listener object that should stop listening.
*/ */
...@@ -535,36 +511,32 @@ APP_BoxView.prototype.destroy = function() { ...@@ -535,36 +511,32 @@ APP_BoxView.prototype.destroy = function() {
}()); }());
/* /*
Hijos version 2 Hijos version 3
Copyright (c) 2012, Peter Michaux Copyright (c) 2013, Peter Michaux
All rights reserved. All rights reserved.
Licensed under the Simplified BSD License. Licensed under the Simplified BSD License.
https://github.com/petermichaux/hijos/blob/master/LICENSE https://github.com/petermichaux/hijos/blob/master/LICENSE
*/ */
var hijos = {};
/** /**
@property hijos.Leaf The root namespace for the Hijos library.
@description @namespace
A constructor function for creating Leaf objects to be used as part */
of the composite design pattern. var hijos = {};
/**
Leaf objects have three read-only properties describing the Leaf object's A constructor function for creating `Leaf` objects to be used as part
relationships to other Leaf and Node objects participating in of the composite design pattern.
the composite pattern.
1. parentNode var leaf = new hijos.Leaf();
2. previousSibling
3. nextSibling
These properties will be null when the Leaf is not a child To attach a `Leaf` to a `Node`, use the `Node`'s child
of a Node object. To attach a Leaf to a Node, use the Node's child manipulation methods: `appendChild`, `insertBefore`, `replaceChild`.
manipulation methods: appendChild, insertBefore, replaceChild. To remove a `Leaf` from a `Node` use the `Node`'s `removeChild` method.
To remove a Leaf from a Node use the Node's removeChild method.
var leaf = new hijos.Leaf(); @constructor
*/ */
hijos.Leaf = function() { hijos.Leaf = function() {
...@@ -575,13 +547,48 @@ hijos.Leaf = function() { ...@@ -575,13 +547,48 @@ hijos.Leaf = function() {
/** /**
@property hijos.Leaf.prototype.destroy The parent `Node` of this object. Null if this object is not the child of
any `Node`.
@member hijos.Leaf.prototype.parentNode
@type {hijos.Leaf}
@readonly
*/
/**
The previous sibling `Leaf` of this object. Null if this object is not the child of
any `Node` or this object is the first child of a `Node`.
@member hijos.Leaf.prototype.previousSibling
@type {hijos.Leaf}
@readonly
*/
@description /**
The next sibling `Leaf` of this object. Null if this object is not the child of
any `Node` or this object is the last child of a `Node`.
@member hijos.Leaf.prototype.nextSibling
@type {hijos.Leaf}
@readonly
*/
/**
Call before your application code looses its last reference to the object. Call before your application code looses its last reference to the object.
Generally this will be called for you by the destroy method of the containing Generally this will be called for you by the destroy method of the containing
Node object unless this Leaf object is not contained by a Node. `Node` object unless this `Leaf` object is not contained by a `Node`.
*/ */
hijos.Leaf.prototype.destroy = function() { hijos.Leaf.prototype.destroy = function() {
...@@ -596,19 +603,15 @@ hijos.Leaf.call(hijos.Leaf.prototype); ...@@ -596,19 +603,15 @@ hijos.Leaf.call(hijos.Leaf.prototype);
/** /**
@property hijos.Leaf.mixin Mixes in the `Leaf` methods into any object. Be sure to call the `hijos.Leaf`
constructor to initialize the `Leaf`'s properties.
@parameter obj {object} The object to become a Leaf. app.MyView = function() {
@description
Mixes in the Leaf methods into any object. Be sure to call the hijos.Leaf
constructor to initialize the Leaf's properties.
app.MyView = function() {
hijos.Leaf.call(this); hijos.Leaf.call(this);
}; };
hijos.Leaf.mixin(app.MyView.prototype); hijos.Leaf.mixin(app.MyView.prototype);
@param {Object} obj The object to become a `Leaf`.
*/ */
hijos.Leaf.mixin = function(obj) { hijos.Leaf.mixin = function(obj) {
...@@ -617,33 +620,18 @@ hijos.Leaf.mixin = function(obj) { ...@@ -617,33 +620,18 @@ hijos.Leaf.mixin = function(obj) {
}; };
/** /**
@property hijos.Node A constructor function for creating `Node` objects with ordered children
@description
A constructor function for creating Node objects with ordered children
to be used as part of the composite design pattern. to be used as part of the composite design pattern.
Node objects have six read-only properties describing the Node's Do not mutate the elements of the `childNodes` array directly.
relationships to other Leaf and Node objects participating in Instead use the `appendChild`, `insertBefore`, `replaceChild`, and `removeChild`
the composite pattern.
1. childNodes
2. firstChild
3. lastChild
4. parentNode
5. previousSibling
6. nextSibling
The firstChild and lastChild properties will be null when the Node has
no children. Do not mutate the elements of the childNodes array directly.
Instead use the appendChild, insertBefore, replaceChild, and removeChild
methods to manage the children. methods to manage the children.
The parentNode, previousSibling, and nextSibling properties will be null var node = new hijos.Node();
when the Node object is not a child of another Node object.
@constructor
var node = new hijos.Node(); @extends hijos.Leaf
*/ */
hijos.Node = function() { hijos.Node = function() {
...@@ -653,17 +641,59 @@ hijos.Node = function() { ...@@ -653,17 +641,59 @@ hijos.Node = function() {
this.lastChild = null; this.lastChild = null;
}; };
hijos.Leaf.mixin(hijos.Node.prototype); // Inherit from hijos.Leaf. Not all browsers have Object.create
// so write out the equivalent inline.
hijos.Node.prototype = (function() {
function F() {}
F.prototype = hijos.Leaf.prototype;
return new F();
}());
hijos.Node.prototype.constructor = hijos.Node;
/** /**
@property hijos.Node.prototype.destroy The array of child objects.
@description @member hijos.Node.prototype.childNodes
@type {Array}
@readonly
*/
/**
The first child of this object. Null if this object has no children.
@member hijos.Node.prototype.firstChild
@type {hijos.Leaf}
@readonly
*/
/**
The last child of this object. Null if this object has no children.
@member hijos.Node.prototype.lastChild
@type {hijos.Leaf}
@readonly
*/
/**
Call before your application code looses its last reference to the object. Call before your application code looses its last reference to the object.
Generally this will be called for you by the destroy method of the containing Generally this will be called for you by the destroy method of the containing
Node object unless this object is not contained by another Node. `Node` object unless this object is not contained by another `Node`.
@override
*/ */
hijos.Node.prototype.destroy = function() { hijos.Node.prototype.destroy = function() {
...@@ -681,11 +711,9 @@ hijos.Node.prototype.destroy = function() { ...@@ -681,11 +711,9 @@ hijos.Node.prototype.destroy = function() {
/** /**
@property hijos.Node.prototype.hasChildNodes Does this `Node` have any children?
@description
Returns true if this Node has children. Otherwise returns false. @return {boolean} `true` if this `Node` has children. Otherwise `false`.
*/ */
hijos.Node.prototype.hasChildNodes = function() { hijos.Node.prototype.hasChildNodes = function() {
...@@ -694,23 +722,19 @@ hijos.Node.prototype.hasChildNodes = function() { ...@@ -694,23 +722,19 @@ hijos.Node.prototype.hasChildNodes = function() {
/** /**
@property hijos.Node.prototype.insertBefore Inserts `newChild` before `oldChild`. If `oldChild` is `null` then this is equivalent
to appending `newChild`. If `newChild` is a child of another `Node` then `newChild` is
@parameter newChild {object} The Leaf or Node object to insert. removed from that other `Node` before appending to this `Node`.
@parameter oldChild {object|null} The child object to insert before.
@description var parent = new hijos.Node();
var child0 = new hijos.Leaf();
parent.insertBefore(child0, null);
var child1 = new hijos.Node();
parent.insertBefore(child1, child0);
Inserts newChild before oldChild. If oldChild is null then this is equivalent @param {Object} newChild The Leaf or Node object to insert.
to appending newChild. If newChild is a child of another Node then newChild is
removed from that other Node before appending to this Node.
var parent = new hijos.Node(); @param {(Object|null)} [oldChild] The child object to insert before.
var child0 = new hijos.Leaf();
parent.insertBefore(child0, null);
var child1 = new hijos.Node();
parent.insertBefore(child1, child0);
*/ */
hijos.Node.prototype.insertBefore = function(newChild, oldChild) { hijos.Node.prototype.insertBefore = function(newChild, oldChild) {
...@@ -776,21 +800,17 @@ hijos.Node.prototype.insertBefore = function(newChild, oldChild) { ...@@ -776,21 +800,17 @@ hijos.Node.prototype.insertBefore = function(newChild, oldChild) {
/** /**
@property hijos.Node.prototype.appendChild Adds `newChild` as the last child of this `Node`. If `newChild` is a child of
another `Node` then `newChild` is removed from that other `Node` before appending
to this `Node`.
@parameter newChild {object} The Leaf or Node object to append. var parent = new hijos.Node();
var child = new hijos.Leaf();
parent.appendChild(child);
var child = new hijos.Node();
parent.appendChild(child);
@description @param {Object} newChild The Leaf or Node object to append.
Adds newChild as the last child of this Node. If newChild is a child of
another Node then newChild is removed from that other Node before appending
to this Node.
var parent = new hijos.Node();
var child = new hijos.Leaf();
parent.appendChild(child);
var child = new hijos.Node();
parent.appendChild(child);
*/ */
hijos.Node.prototype.appendChild = function(newChild) { hijos.Node.prototype.appendChild = function(newChild) {
...@@ -802,22 +822,18 @@ hijos.Node.prototype.appendChild = function(newChild) { ...@@ -802,22 +822,18 @@ hijos.Node.prototype.appendChild = function(newChild) {
/** /**
@property hijos.Node.prototype.replaceChild Replaces `oldChild` with `newChild`. If `newChild` is a child of another `Node`
then `newChild` is removed from that other `Node` before appending to this `Node`.
@parameter newChild {object} The Leaf or Node object to insert.
@parameter oldChild {object} The child object to remove/replace.
@description var parent = new hijos.Node();
var child0 = new hijos.Leaf();
parent.appendChild(child0);
var child1 = new hijos.Node();
parent.replaceChild(child1, child0);
Replaces oldChild with newChild. If newChild is a child of another Node @param {Object} newChild The Leaf or Node object to insert.
then newChild is removed from that other Node before appending to this Node.
var parent = new hijos.Node(); @param {Object} oldChild The child object to remove/replace.
var child0 = new hijos.Leaf();
parent.appendChild(child0);
var child1 = new hijos.Node();
parent.replaceChild(child1, child0);
*/ */
hijos.Node.prototype.replaceChild = function(newChild, oldChild) { hijos.Node.prototype.replaceChild = function(newChild, oldChild) {
...@@ -838,18 +854,14 @@ hijos.Node.prototype.replaceChild = function(newChild, oldChild) { ...@@ -838,18 +854,14 @@ hijos.Node.prototype.replaceChild = function(newChild, oldChild) {
/** /**
@property hijos.Node.prototype.removeChild Removes `oldChild`.
@parameter oldChild {object} The child object to remove. var parent = new hijos.Node();
var child = new hijos.Leaf();
parent.appendChild(child);
parent.removeChild(child);
@description @param {Object} oldChild The child object to remove.
Removes oldChild.
var parent = new hijos.Node();
var child = new hijos.Leaf();
parent.appendChild(child);
parent.removeChild(child);
*/ */
hijos.Node.prototype.removeChild = function(oldChild) { hijos.Node.prototype.removeChild = function(oldChild) {
...@@ -884,25 +896,21 @@ hijos.Node.call(hijos.Node.prototype); ...@@ -884,25 +896,21 @@ hijos.Node.call(hijos.Node.prototype);
/** /**
@property hijos.Node.mixin
@parameter obj {object} The object to become a Node.
@description
Mixes in the Node methods into any object. Mixes in the Node methods into any object.
// Example 1 Example 1
app.MyView = function() { app.MyView = function() {
hijos.Node.call(this); hijos.Node.call(this);
}; };
hijos.Node.mixin(app.MyView.prototype); hijos.Node.mixin(app.MyView.prototype);
// Example 2 Example 2
var obj = {}; var obj = {};
hijos.Node.mixin(obj); hijos.Node.mixin(obj);
@param {Object} obj The object to become a `Node`.
*/ */
hijos.Node.mixin = function(obj) { hijos.Node.mixin = function(obj) {
...@@ -915,12 +923,20 @@ hijos.Node.mixin = function(obj) { ...@@ -915,12 +923,20 @@ hijos.Node.mixin = function(obj) {
hijos.Node.call(obj); hijos.Node.call(obj);
}; };
/* /*
Arbutus version 2 Arbutus version 4
Copyright (c) 2012, Peter Michaux Copyright (c) 2013, Peter Michaux
All rights reserved. All rights reserved.
Licensed under the Simplified BSD License. Licensed under the Simplified BSD License.
https://github.com/petermichaux/arbutus/blob/master/LICENSE https://github.com/petermichaux/arbutus/blob/master/LICENSE
*/var arbutus = {}; */
/**
The root namespace for the Arbutus library.
@namespace
*/
var arbutus = {};
(function() { (function() {
var trimLeft = /^\s+/, var trimLeft = /^\s+/,
...@@ -945,25 +961,12 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE ...@@ -945,25 +961,12 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE
return element.firstChild.firstChild.firstChild.firstChild; return element.firstChild.firstChild.firstChild.firstChild;
} }
function Parser(before, after, getFirstResult) { function makeParser(before, after, getFirstResult) {
if (before) { return function(html, doc) {
this.before = before;
}
if (after) {
this.after = after;
}
if (getFirstResult) {
this.getFirstResult = getFirstResult;
}
};
Parser.prototype = {
before: '',
after: '',
parse: function(html, doc) {
var parser = doc.createElement('div'); var parser = doc.createElement('div');
var fragment = doc.createDocumentFragment(); var fragment = doc.createDocumentFragment();
parser.innerHTML = this.before + html + this.after; parser.innerHTML = before + html + after;
var node = this.getFirstResult(parser); var node = getFirstResult(parser);
var nextNode; var nextNode;
while (node) { while (node) {
nextNode = node.nextSibling; nextNode = node.nextSibling;
...@@ -971,17 +974,18 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE ...@@ -971,17 +974,18 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE
node = nextNode; node = nextNode;
} }
return fragment; return fragment;
},
getFirstResult: getFirstChild
}; };
}
var defaultParser = makeParser('', '', getFirstChild);
var parsers = { var parsers = {
'td': new Parser('<table><tbody><tr>', '</tr></tbody></table>', getFirstGreatGreatGrandChild), 'td': makeParser('<table><tbody><tr>', '</tr></tbody></table>', getFirstGreatGreatGrandChild),
'tr': new Parser('<table><tbody>', '</tbody></table>', getFirstGreatGrandChild), 'tr': makeParser('<table><tbody>', '</tbody></table>', getFirstGreatGrandChild),
'tbody': new Parser('<table>', '</table>', getFirstGrandChild), 'tbody': makeParser('<table>', '</table>', getFirstGrandChild),
'col': new Parser('<table><colgroup>', '</colgroup></table>', getFirstGreatGrandChild), 'col': makeParser('<table><colgroup>', '</colgroup></table>', getFirstGreatGrandChild),
// Without the option in the next line, the parsed option will always be selected. // Without the option in the next line, the parsed option will always be selected.
'option': new Parser('<select><option>a</option>', '</select>', getSecondGrandChild) 'option': makeParser('<select><option>a</option>', '</select>', getSecondGrandChild)
}; };
parsers.th = parsers.td; parsers.th = parsers.td;
parsers.thead = parsers.tbody; parsers.thead = parsers.tbody;
...@@ -993,43 +997,51 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE ...@@ -993,43 +997,51 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE
/** /**
@property arbutus.parseHTML
@parameter html {string} The string of HTML to be parsed.
@parameter doc {Document} Optional document object to create the new DOM nodes.
@return {DocumentFragment}
@description
The html string will be trimmed. The html string will be trimmed.
Returns a document fragment that has the children defined by the html string. Returns a document fragment that has the children defined by the html string.
var fragment = arbutus.parseHTML('<p>alpha beta</p>'); var fragment = arbutus.parseHTML('<p>alpha beta</p>');
document.body.appendChild(fragment); document.body.appendChild(fragment);
Note that a call to this function is relatively expensive and you probably Note that a call to this function is relatively expensive and you probably
don't want to have a loop of thousands with calls to this function. don't want to have a loop of thousands with calls to this function.
@param {string} html The string of HTML to be parsed.
@param {Document} [doc] The document object to create the new DOM nodes.
@return {DocumentFragment}
*/ */
arbutus.parseHTML = function(html, doc) { arbutus.parseHTML = function(html, doc) {
// IE will trim when setting innerHTML so unify for all browsers // IE will trim when setting innerHTML so unify for all browsers
html = trim(html); html = trim(html);
var matches = html.match(tagRegExp), var parser = defaultParser;
parser = (matches && parsers[matches[1].toLowerCase()]) || var matches = html.match(tagRegExp);
Parser.prototype; if (matches) {
return parser.parse(html, doc || document); var name = matches[1].toLowerCase();
if (Object.prototype.hasOwnProperty.call(parsers, name)) {
parser = parsers[name];
}
}
return parser(html, doc || document);
}; };
}()); }());
/* /*
Grail version 3 Grail version 4
Copyright (c) 2012, Peter Michaux Copyright (c) 2012, Peter Michaux
All rights reserved. All rights reserved.
Licensed under the Simplified BSD License. Licensed under the Simplified BSD License.
https://github.com/petermichaux/grail/blob/master/LICENSE https://github.com/petermichaux/grail/blob/master/LICENSE
*/
/**
The root namespace for the Grail library.
@namespace
*/ */
var grail = {}; var grail = {};
(function() { (function() {
...@@ -1110,14 +1122,6 @@ var grail = {}; ...@@ -1110,14 +1122,6 @@ var grail = {};
/** /**
@property grail.findAll
@parameter selector {string} The CSS selector for the search.
@parameter root {Document|Element} Optional element to use as the search start point.
@description
Search for all elements matching the CSS selector. Returns an array of the elements. Search for all elements matching the CSS selector. Returns an array of the elements.
Acceptable simple selectors are of the following forms only. Acceptable simple selectors are of the following forms only.
...@@ -1131,13 +1135,19 @@ In the case of a #myId selector, the returned array will always have ...@@ -1131,13 +1135,19 @@ In the case of a #myId selector, the returned array will always have
zero or one elements. It is more likely that you want to call grail.find when zero or one elements. It is more likely that you want to call grail.find when
using an id selector. using an id selector.
If the root element is supplied it is used as the starting point for the search. If the root element is supplied then it is used as the starting point for the search.
The root element will be in the results if it matches the selector. The root element will be in the results if it matches the selector.
If the root element is not supplied then the current document is used If the root element is not supplied then the current document is used
as the search starting point. as the search starting point.
grail.findAll('#alpha'); grail.findAll('#alpha');
grail.findAll('div.gamma', document.body); grail.findAll('div.gamma', document.body);
@param {string} selector The CSS selector for the search.
@param {Document|Element} [root] The element to use as the search start point.
@return {Array} An array of matching `Element` objects.
*/ */
grail.findAll = function(selector, root) { grail.findAll = function(selector, root) {
...@@ -1173,20 +1183,18 @@ grail.findAll('div.gamma', document.body); ...@@ -1173,20 +1183,18 @@ grail.findAll('div.gamma', document.body);
/** /**
@property grail.find
@parameter selector {string} The CSS selector for the search.
@parameter root {Document|Element} Optional element to use as the search start point.
@description
Search for the first element matching the CSS selector. If the element is Search for the first element matching the CSS selector. If the element is
found then it is returned. If no matching element is found then found then it is returned. If no matching element is found then
null or undefined is returned. null or undefined is returned.
The rest of the details are the same as for grail.findAll. The rest of the details are the same as for grail.findAll.
@param {string} [selector] The CSS selector for the search.
@param {Document|Element} [root] The element to use as the search start point.
@return {Element} The found `Element`.
*/ */
grail.find = function(selector, root) { grail.find = function(selector, root) {
selector = trim(selector); selector = trim(selector);
...@@ -1211,11 +1219,18 @@ The rest of the details are the same as for grail.findAll. ...@@ -1211,11 +1219,18 @@ The rest of the details are the same as for grail.findAll.
}()); }());
/* /*
Hormigas version 3 Hormigas version 4
Copyright (c) 2012, Peter Michaux Copyright (c) 2012, Peter Michaux
All rights reserved. All rights reserved.
Licensed under the Simplified BSD License. Licensed under the Simplified BSD License.
https://github.com/petermichaux/hormigas/blob/master/LICENSE https://github.com/petermichaux/hormigas/blob/master/LICENSE
*/
/**
The root namespace for the Hormigas library.
@namespace
*/ */
var hormigas = {}; var hormigas = {};
(function() { (function() {
...@@ -1233,30 +1248,35 @@ var hormigas = {}; ...@@ -1233,30 +1248,35 @@ var hormigas = {};
/** /**
@property hormigas.ObjectSet A constructor function for creating set objects. A set can only contain
a particular object once. That means all objects in a set are unique. This
is different from an array where one object can be in the array in
multiple positions.
@description `ObjectSet` objects are designed
A constructor function for creating set objects. ObjectSets are designed
to hold JavaScript objects. They cache a marker on the objects. to hold JavaScript objects. They cache a marker on the objects.
Do not attempt to add primitives or host objects in a ObjectSet. This Do not attempt to add primitives or host objects in a `ObjectSet`. This
is a compromise to make ObjectSet objects efficient for use in the model is a compromise to make `ObjectSet` objects efficient for use in the model
layer of your application. layer of your MVC-style application.
When using the set iterators (e.g. `forEach`, `map`) do not depend
on the order of iteration of the set's elements. `ObjectSet` objects are unordered.
When using the set iterators (e.g. forEach, map) do not depend var set = new hormigas.ObjectSet(); // an empty set
on the order of iteration of the set's elements. ObjectSets are unordered.
var set = new hormigas.ObjectSet(); // an empty set `ObjectSet` objects have a `length` property that is the number of elements in the set.
ObjectSets have a length property that is the number of elements in the set. var alpha = {};
var beta = {};
var set = new hormigas.ObjectSet(alpha, beta, alpha);
set.length; // 2
var alpha = {}; The methods of an `ObjectSet` object are inspired by the incomplete
var beta = {}; Harmony Set proposal and the `Array.prototype` iterators.
var set = new hormigas.ObjectSet(alpha, beta, alpha);
set.length; // 2
The methods of an event target object are inspired by the incomplete @constructor
Harmony Set proposal and the Array.prototype iterators.
@param {...Object} [item] An object to add to the set.
*/ */
hormigas.ObjectSet = function() { hormigas.ObjectSet = function() {
...@@ -1268,17 +1288,22 @@ Harmony Set proposal and the Array.prototype iterators. ...@@ -1268,17 +1288,22 @@ Harmony Set proposal and the Array.prototype iterators.
/** /**
@property hormigas.ObjectSet.prototype.isEmpty The number of elements in the set.
*/
hormigas.ObjectSet.prototype.length = 0;
/**
@description Use to determine if the set has any elements or not.
Returns true if set is empty. Otherwise returns false. var alpha = {};
var set = new hormigas.ObjectSet(alpha);
set.isEmpty(); // false
set['delete'](alpha);
set.isEmpty(); // true
var alpha = {}; @return {boolean} `true` if set is empty. Otherwise `false`.
var set = new hormigas.ObjectSet(alpha);
set.isEmpty(); // false
set['delete'](alpha);
set.isEmpty(); // true
*/ */
hormigas.ObjectSet.prototype.isEmpty = function() { hormigas.ObjectSet.prototype.isEmpty = function() {
...@@ -1287,19 +1312,17 @@ set.isEmpty(); // true ...@@ -1287,19 +1312,17 @@ set.isEmpty(); // true
/** /**
@property hormigas.ObjectSet.prototype.has Is a particular object in the set or not?
@parameter element
@description var alpha = {};
var beta = {};
var set = new hormigas.ObjectSet(alpha);
set.has(alpha); // true
set.has(beta); // false
Returns true if element is in the set. Otherwise returns false. @param {Object} element The item in question.
var alpha = {}; @return `true` if `element` is in the set. Otherwise `false`.
var beta = {};
var set = new hormigas.ObjectSet(alpha);
set.has(alpha); // true
set.has(beta); // false
*/ */
hormigas.ObjectSet.prototype.has = function(element) { hormigas.ObjectSet.prototype.has = function(element) {
...@@ -1309,19 +1332,16 @@ set.has(beta); // false ...@@ -1309,19 +1332,16 @@ set.has(beta); // false
/** /**
@property hormigas.ObjectSet.prototype.add If `element` is not already in the set then adds element to the set.
@parameter element
@description var alpha = {};
var set = new hormigas.ObjectSet();
set.add(alpha); // true
set.has(alpha); // false
If element is not already in the set then adds element to the set @param {Object} element The item to add to the set.
and returns true. Otherwise returns false.
var alpha = {}; @return {boolean} `true` if `element` is added to the set as a result of this call. Otherwise `false` because `element` was already in the set.
var set = new hormigas.ObjectSet();
set.add(alpha); // true
set.has(alpha); // false
*/ */
hormigas.ObjectSet.prototype.add = function(element) { hormigas.ObjectSet.prototype.add = function(element) {
...@@ -1341,23 +1361,20 @@ set.has(alpha); // false ...@@ -1341,23 +1361,20 @@ set.has(alpha); // false
/** /**
@property hormigas.ObjectSet.prototype.delete If `element` is in the set then removes `element` from the set.
@parameter element `delete` is a reserved word and older implementations
did not allow bare reserved words in property name
position so quote `delete`.
@description var alpha = {};
var set = new hormigas.ObjectSet(alpha);
set['delete'](alpha); // true
set['delete'](alpha); // false
If element is in the set then removes element from the set @param {Object} element The item to delete from the set.
and returns true. Otherwise returns false.
"delete" is a reserved word and older implementations @return {boolean} `true` if `element` is deleted from the set as a result of this call. Otherwise `false` because `element` was not in the set.
did not allow bare reserved words in property name
position so quote "delete".
var alpha = {};
var set = new hormigas.ObjectSet(alpha);
set['delete'](alpha); // true
set['delete'](alpha); // false
*/ */
hormigas.ObjectSet.prototype['delete'] = function(element) { hormigas.ObjectSet.prototype['delete'] = function(element) {
...@@ -1373,17 +1390,14 @@ set['delete'](alpha); // false ...@@ -1373,17 +1390,14 @@ set['delete'](alpha); // false
/** /**
@property hormigas.ObjectSet.prototype.empty If the set has elements then removes all the elements.
@description
If the set has elements then removes all the elements and var alpha = {};
returns true. Otherwise returns false. var set = new hormigas.ObjectSet(alpha);
set.empty(); // true
set.empty(); // false
var alpha = {}; @return {boolean} `true` if elements were deleted from the set as the result of this call. Otherwise `false` because no elements were in the set.
var set = new hormigas.ObjectSet(alpha);
set.empty(); // true
set.empty(); // false
*/ */
hormigas.ObjectSet.prototype.empty = function() { hormigas.ObjectSet.prototype.empty = function() {
...@@ -1398,11 +1412,9 @@ set.empty(); // false ...@@ -1398,11 +1412,9 @@ set.empty(); // false
/** /**
@property hormigas.ObjectSet.prototype.toArray Convert the set to an array.
@description @return {Array} The elements of the set in a new array.
Returns the elements of the set in a new array.
*/ */
hormigas.ObjectSet.prototype.toArray = function() { hormigas.ObjectSet.prototype.toArray = function() {
...@@ -1417,23 +1429,19 @@ Returns the elements of the set in a new array. ...@@ -1417,23 +1429,19 @@ Returns the elements of the set in a new array.
/** /**
@property hormigas.ObjectSet.prototype.forEach Calls `callbackfn` for each element of the set.
@parameter callbackfn {function} The function to call for each element in the set.
@parameter thisArg {object} The optional object to use as the this object in calls to callbackfn. var alpha = {value: 0};
var beta = {value: 1};
var gamma = {value: 2};
var set = new hormigas.ObjectSet(alpha, beta, gamma);
set.forEach(function(element, set) {
console.log(element.value);
});
@description @param {function} callbackfn The function to call for each element in the set.
Calls callbackfn for each element of the set. @parameter {Object} [thisArg] The object to use as the `this` object in calls to `callbackfn`.
var alpha = {value: 0};
var beta = {value: 1};
var gamma = {value: 2};
var set = new hormigas.ObjectSet(alpha, beta, gamma);
set.forEach(function(element, set) {
console.log(element.value);
});
*/ */
hormigas.ObjectSet.prototype.forEach = function(callbackfn /*, thisArg */) { hormigas.ObjectSet.prototype.forEach = function(callbackfn /*, thisArg */) {
...@@ -1447,24 +1455,21 @@ set.forEach(function(element, set) { ...@@ -1447,24 +1455,21 @@ set.forEach(function(element, set) {
/** /**
@property hormigas.ObjectSet.prototype.every Calls `callbackfn` for each element of the set.
@parameter callbackfn {function} The function to call for each element in the set.
@parameter thisArg {object} The optional object to use as the this object in calls to callbackfn. var one = {value: 1};
var two = {value: 2};
var three = {value: 3};
var set = new hormigas.ObjectSet(one, two, three);
set.every(function(element, set) {
return element.value < 2;
}); // false
@description @param {function} callbackfn The function to call for each element in the set.
Calls callbackfn for each element of the set. If callbackfn returns a truthy value @param {Object} [thisArg] The object to use as the this object in calls to callbackfn.
for all elements then every returns true. Otherwise returns false.
var one = {value: 1}; @return {boolean} `true` if `callbackfn` returns a truthy value for all elements in the set. Otherwise `false`.
var two = {value: 2};
var three = {value: 3};
var set = new hormigas.ObjectSet(one, two, three);
set.every(function(element, set) {
return element.value < 2;
}); // false
*/ */
hormigas.ObjectSet.prototype.every = function(callbackfn /*, thisArg */) { hormigas.ObjectSet.prototype.every = function(callbackfn /*, thisArg */) {
...@@ -1480,24 +1485,21 @@ set.every(function(element, set) { ...@@ -1480,24 +1485,21 @@ set.every(function(element, set) {
/** /**
@property hormigas.ObjectSet.prototype.some Calls `callbackfn` for each element of the set.
@parameter callbackfn {function} The function to call for each element in the set. var one = {value: 1};
var two = {value: 2};
var three = {value: 3};
var set = new hormigas.ObjectSet(one, two, three);
set.some(function(element, set) {
return element.value < 2;
}); // true
@parameter thisArg {object} The optional object to use as the this object in calls to callbackfn. @param {function} callbackfn The function to call for each element in the set.
@description @param {Object} [thisArg] The object to use as the this object in calls to callbackfn.
Calls callbackfn for each element of the set. If callbackfn returns a truthy value @return {boolean} `true` if `callbackfn` returns a truthy value for at least one element in the set. Otherwise `false`.
for at least one element then some returns true. Otherwise returns false.
var one = {value: 1};
var two = {value: 2};
var three = {value: 3};
var set = new hormigas.ObjectSet(one, two, three);
set.some(function(element, set) {
return element.value < 2;
}); // true
*/ */
hormigas.ObjectSet.prototype.some = function(callbackfn /*, thisArg */) { hormigas.ObjectSet.prototype.some = function(callbackfn /*, thisArg */) {
...@@ -1513,36 +1515,34 @@ set.some(function(element, set) { ...@@ -1513,36 +1515,34 @@ set.some(function(element, set) {
/** /**
@property hormigas.ObjectSet.prototype.reduce Calls `callbackfn` for each element of the set.
@parameter callbackfn {function} The function to call for each element in the set.
@parameter initialValue {object} The optional starting value for accumulation.
@description
Calls callbackfn for each element of the set.
For the first call to callbackfn, if initialValue is supplied then initalValue is For the first call to `callbackfn`, if `initialValue` is supplied then `initalValue` is
the first argument passed to callbackfn and the second argument is the first the first argument passed to `callbackfn` and the second argument is the first
element in the set to be iterated. Otherwise the first argument is element in the set to be iterated. Otherwise the first argument is
the first element to be iterated in the set and the second argument is the first element to be iterated in the set and the second argument is
the next element to be iterated in the set. the next element to be iterated in the set.
For subsequent calls to callbackfn, the first argument is the value returned For subsequent calls to `callbackfn`, the first argument is the value returned
by the last call to callbackfn. The second argument is the next value to be by the last call to `callbackfn`. The second argument is the next value to be
iterated in the set. iterated in the set.
var one = {value: 1}; var one = {value: 1};
var two = {value: 2}; var two = {value: 2};
var three = {value: 3}; var three = {value: 3};
var set = new hormigas.ObjectSet(one, two, three); var set = new hormigas.ObjectSet(one, two, three);
set.reduce(function(accumulator, element) { set.reduce(function(accumulator, element) {
return {value: accumulator.value + element.value}; return {value: accumulator.value + element.value};
}); // {value:6} }); // {value:6}
set.reduce(function(accumulator, element) { set.reduce(function(accumulator, element) {
return accumulator + element.value; return accumulator + element.value;
}, 4); // 10 }, 4); // 10
@param {function} callbackfn The function to call for each element in the set.
@param {*} initialValue The optional starting value for accumulation.
@return {*} The value returned by the final call to `callbackfn`.
*/ */
hormigas.ObjectSet.prototype.reduce = function(callbackfn /*, initialValue */) { hormigas.ObjectSet.prototype.reduce = function(callbackfn /*, initialValue */) {
...@@ -1569,24 +1569,22 @@ set.reduce(function(accumulator, element) { ...@@ -1569,24 +1569,22 @@ set.reduce(function(accumulator, element) {
/** /**
@property hormigas.ObjectSet.prototype.map Calls `callbackfn` for each element of the set. The values returned by `callbackfn`
are added to a new array. This new array is the value returned by map.
@parameter callbackfn {function} The function to call for each element in the set.
@parameter thisArg {object} The optional object to use as the this object in calls to callbackfn. var alpha = {length: 5};
var beta = {length: 4};
var gamma = {length: 5};
var set = new hormigas.ObjectSet(alpha, beta, gamma);
set.map(function(element) {
return element.length;
}); // [5,5,4] or [5,4,5] or [4,5,5]
@description @param {function} callbackfn The function to call for each element in the set.
Calls callbackfn for each element of the set. The values returned by callbackfn @param {Object} [thisArg] The object to use as the this object in calls to `callbackfn`.
are added to a new array. This new array is the value returned by map.
var alpha = {length: 5}; @return {Array} The mapped values.
var beta = {length: 4};
var gamma = {length: 5};
var set = new hormigas.ObjectSet(alpha, beta, gamma);
set.map(function(element) {
return element.length;
}); // [5,5,4] or [5,4,5] or [4,5,5]
*/ */
hormigas.ObjectSet.prototype.map = function(callbackfn /*, thisArg */) { hormigas.ObjectSet.prototype.map = function(callbackfn /*, thisArg */) {
...@@ -1602,25 +1600,23 @@ set.map(function(element) { ...@@ -1602,25 +1600,23 @@ set.map(function(element) {
/** /**
@property hormigas.ObjectSet.prototype.filter
@parameter callbackfn {function} The function to call for each element in the set.
@parameter thisArg {object} The optional object to use as the this object in calls to callbackfn.
@description
Calls callbackfn for each element of the set. If callbackfn returns true Calls callbackfn for each element of the set. If callbackfn returns true
for an element then that element is added to a new array. This new array for an element then that element is added to a new array. This new array
is the value returned by filter. is the value returned by filter.
var alpha = {length: 5}; var alpha = {length: 5};
var beta = {length: 4}; var beta = {length: 4};
var gamma = {length: 5}; var gamma = {length: 5};
var set = new hormigas.ObjectSet(alpha, beta, gamma); var set = new hormigas.ObjectSet(alpha, beta, gamma);
set.filter(function(element) { set.filter(function(element) {
return element.length > 4; return element.length > 4;
}); // [alpha, gamma] or [gamma, alpha] }); // [alpha, gamma] or [gamma, alpha]
@param {function} callbackfn The function to call for each element in the set.
@param {object} [thisArg] The object to use as the this object in calls to `callbackfn`.
@return {Array} The filtered values.
*/ */
hormigas.ObjectSet.prototype.filter = function(callbackfn /*, thisArg */) { hormigas.ObjectSet.prototype.filter = function(callbackfn /*, thisArg */) {
...@@ -1644,25 +1640,21 @@ hormigas.ObjectSet.call(hormigas.ObjectSet.prototype); ...@@ -1644,25 +1640,21 @@ hormigas.ObjectSet.call(hormigas.ObjectSet.prototype);
/** /**
@property hormigas.ObjectSet.mixin Mixes in the `ObjectSet` methods into any object.
@parameter obj {object} The object to become a ObjectSet.
@description
Mixes in the ObjectSet methods into any object.
// Example 1 Example 1
app.MyModel = function() { app.MyModel = function() {
hormigas.ObjectSet.call(this); hormigas.ObjectSet.call(this);
}; };
hormigas.ObjectSet.mixin(app.MyModel.prototype); hormigas.ObjectSet.mixin(app.MyModel.prototype);
// Example 2 Example 2
var obj = {}; var obj = {};
hormigas.ObjectSet.mixin(obj); hormigas.ObjectSet.mixin(obj);
@param {Object} obj The object to become an `ObjectSet`.
*/ */
hormigas.ObjectSet.mixin = function(obj) { hormigas.ObjectSet.mixin = function(obj) {
...@@ -1674,15 +1666,32 @@ hormigas.ObjectSet.mixin = function(obj) { ...@@ -1674,15 +1666,32 @@ hormigas.ObjectSet.mixin = function(obj) {
} }
hormigas.ObjectSet.call(obj); hormigas.ObjectSet.call(obj);
}; };
/* /**
Maria release candidate 5 - an MVC framework for JavaScript applications @license
Copyright (c) 2012, Peter Michaux Maria release candidate 6 - an MVC framework for JavaScript applications
Copyright (c) 2013, Peter Michaux
All rights reserved. All rights reserved.
Licensed under the Simplified BSD License. Licensed under the Simplified BSD License.
https://github.com/petermichaux/maria/blob/master/LICENSE https://github.com/petermichaux/maria/blob/master/LICENSE
*/var maria = {};
// Not all browsers supported by Maria have Object.create
*/
/**
Root namespace
@namespace
*/
var maria = {};
/**
Not all browsers supported by Maria have the native `Object.create` from ECMAScript 5.
@method
@param {Object} obj The object to be the prototype of the new object
*/
maria.create = (function() { maria.create = (function() {
function F() {} function F() {}
return function(obj) { return function(obj) {
...@@ -1690,6 +1699,15 @@ maria.create = (function() { ...@@ -1690,6 +1699,15 @@ maria.create = (function() {
return new F(); return new F();
}; };
}()); }());
/**
Copy properties from the source to the sink.
@param {Object} sink The destination object.
@param {Object} source The source object.
*/
maria.borrow = function(sink, source) { maria.borrow = function(sink, source) {
for (var p in source) { for (var p in source) {
if (Object.prototype.hasOwnProperty.call(source, p)) { if (Object.prototype.hasOwnProperty.call(source, p)) {
...@@ -1697,9 +1715,19 @@ maria.borrow = function(sink, source) { ...@@ -1697,9 +1715,19 @@ maria.borrow = function(sink, source) {
} }
} }
}; };
// "this" must be a constructor function /**
// mix the "subclass" function into your constructor function
// When executing, `this` must be a constructor function.
Mix the "subclass" function into your constructor function.
@param {Object} namespace
@param {string} name
@param {Object} [options]
*/
maria.subclass = function(namespace, name, options) { maria.subclass = function(namespace, name, options) {
options = options || {}; options = options || {};
var properties = options.properties; var properties = options.properties;
...@@ -1719,23 +1747,40 @@ maria.subclass = function(namespace, name, options) { ...@@ -1719,23 +1747,40 @@ maria.subclass = function(namespace, name, options) {
SuperConstructor.subclass.apply(this, arguments); SuperConstructor.subclass.apply(this, arguments);
}; };
}; };
/**
Add an event listener.
See evento.on for description.
*/
maria.on = function() { maria.on = function() {
evento.on.apply(this, arguments); evento.on.apply(this, arguments);
}; };
/**
Remove an event listener.
See evento.off for description.
*/
maria.off = function() { maria.off = function() {
evento.off.apply(this, arguments); evento.off.apply(this, arguments);
}; };
/**
Purge an event listener of all its subscriptions.
See evento.purge for description.
*/
maria.purge = function() { maria.purge = function() {
evento.purge.apply(this, arguments); evento.purge.apply(this, arguments);
}; };
/** /**
@property maria.Model
@description
A constructor function to create new model objects. A constructor function to create new model objects.
var model = new maria.Model(); var model = new maria.Model();
...@@ -1823,6 +1868,10 @@ type will be notified. ...@@ -1823,6 +1868,10 @@ type will be notified.
(See evento.EventTarget for advanced information about event bubbling (See evento.EventTarget for advanced information about event bubbling
using "addParentEventTarget" and "removeParentEventTarget".) using "addParentEventTarget" and "removeParentEventTarget".)
@constructor
@extends evento.EventTarget
*/ */
maria.Model = function() { maria.Model = function() {
evento.EventTarget.call(this); evento.EventTarget.call(this);
...@@ -1831,15 +1880,18 @@ maria.Model = function() { ...@@ -1831,15 +1880,18 @@ maria.Model = function() {
maria.Model.prototype = maria.create(evento.EventTarget.prototype); maria.Model.prototype = maria.create(evento.EventTarget.prototype);
maria.Model.prototype.constructor = maria.Model; maria.Model.prototype.constructor = maria.Model;
/**
When a model is destroyed, it dispatches a `destroy` event to let
listeners (especially containing `maria.SetModel` objects) that
this particular model is no longer useful/reliable.
*/
maria.Model.prototype.destroy = function() { maria.Model.prototype.destroy = function() {
this.dispatchEvent({type: 'destroy'}); this.dispatchEvent({type: 'destroy'});
}; };
/** /**
@property maria.SetModel
@description
A constructor function to create new set model objects. A set model A constructor function to create new set model objects. A set model
object is a collection of elements. An element can only be included object is a collection of elements. An element can only be included
once in a set model object. once in a set model object.
...@@ -2011,6 +2063,11 @@ set model object. This makes it possible to observe only the set model ...@@ -2011,6 +2063,11 @@ set model object. This makes it possible to observe only the set model
object and still know when elements in the set are changing, for object and still know when elements in the set are changing, for
example. This can complement well the flyweight pattern used in a view. example. This can complement well the flyweight pattern used in a view.
@constructor
@extends maria.Model
@extends hormigas.ObjectSet
*/ */
maria.SetModel = function() { maria.SetModel = function() {
hormigas.ObjectSet.apply(this, arguments); hormigas.ObjectSet.apply(this, arguments);
...@@ -2024,8 +2081,25 @@ hormigas.ObjectSet.mixin(maria.SetModel.prototype); ...@@ -2024,8 +2081,25 @@ hormigas.ObjectSet.mixin(maria.SetModel.prototype);
// Wrap the set mutator methods to dispatch events. // Wrap the set mutator methods to dispatch events.
// takes multiple arguments so that only one event will be fired /**
//
Takes multiple arguments each to be added to the set.
setModel.add(item1)
setModel.add(item1, item2)
...
If the set is modified as a result of the add request then a `change`
event is dispatched on the set model object. If all of the arguments
are already in the set then this event will not be dispatched.
@param {Object} item The item to be added to the set.
@return {boolean} True if the set was modified. Otherwise false.
@override
*/
maria.SetModel.prototype.add = function() { maria.SetModel.prototype.add = function() {
var added = []; var added = [];
for (var i = 0, ilen = arguments.length; i < ilen; i++) { for (var i = 0, ilen = arguments.length; i < ilen; i++) {
...@@ -2050,8 +2124,25 @@ maria.SetModel.prototype.add = function() { ...@@ -2050,8 +2124,25 @@ maria.SetModel.prototype.add = function() {
return modified; return modified;
}; };
// takes multiple arguments so that only one event will be fired /**
//
Takes multiple arguments each to be deleted from the set.
setModel['delete'](item1)
setModel['delete'](item1, item2)
...
If the set is modified as a result of the delete request then a `change`
event is dispatched on the set model object. If all of the arguments
were already not in the set then this event will not be dispatched.
@param {Object} item The item to be removed from the set.
@return {boolean} True if the set was modified. Otherwise false.
@override
*/
maria.SetModel.prototype['delete'] = function() { maria.SetModel.prototype['delete'] = function() {
var deleted = []; var deleted = [];
for (var i = 0, ilen = arguments.length; i < ilen; i++) { for (var i = 0, ilen = arguments.length; i < ilen; i++) {
...@@ -2073,6 +2164,18 @@ maria.SetModel.prototype['delete'] = function() { ...@@ -2073,6 +2164,18 @@ maria.SetModel.prototype['delete'] = function() {
return modified; return modified;
}; };
/**
Deletes all elements of the set.
If the set is modified as a result of this empty request then a `change`
event is dispatched on the set model object.
@override
@return {boolean} True if the set was modified. Otherwise false.
*/
maria.SetModel.prototype.empty = function() { maria.SetModel.prototype.empty = function() {
var deleted = this.toArray(); var deleted = this.toArray();
var result = hormigas.ObjectSet.prototype.empty.call(this); var result = hormigas.ObjectSet.prototype.empty.call(this);
...@@ -2091,6 +2194,14 @@ maria.SetModel.prototype.empty = function() { ...@@ -2091,6 +2194,14 @@ maria.SetModel.prototype.empty = function() {
return result; return result;
}; };
/**
If a member of the set fires a `destroy` event then that member
must be deleted from this set. This handler will do the delete.
@param {Object} event The event object.
*/
maria.SetModel.prototype.handleEvent = function(ev) { maria.SetModel.prototype.handleEvent = function(ev) {
// If it is a destroy event being dispatched on the // If it is a destroy event being dispatched on the
...@@ -2104,14 +2215,6 @@ maria.SetModel.prototype.handleEvent = function(ev) { ...@@ -2104,14 +2215,6 @@ maria.SetModel.prototype.handleEvent = function(ev) {
}; };
/** /**
@property maria.View
@parameter model {Object} Optional
@parameter controller {Object} Optional
@description
A constructor function to create new view objects. A constructor function to create new view objects.
var view = new maria.View(); var view = new maria.View();
...@@ -2226,6 +2329,14 @@ accomplish the same. ...@@ -2226,6 +2329,14 @@ accomplish the same.
alert('another method'); alert('another method');
}; };
@constructor
@extends hijos.Node
@param {maria.Model} [model]
@param {maria.Controller} [controller]
*/ */
maria.View = function(model, controller) { maria.View = function(model, controller) {
hijos.Node.call(this); hijos.Node.call(this);
...@@ -2236,6 +2347,14 @@ maria.View = function(model, controller) { ...@@ -2236,6 +2347,14 @@ maria.View = function(model, controller) {
maria.View.prototype = maria.create(hijos.Node.prototype); maria.View.prototype = maria.create(hijos.Node.prototype);
maria.View.prototype.constructor = maria.View; maria.View.prototype.constructor = maria.View;
/*
Call before your application looses its last reference to this view.
This will unsubcribe this view from its model so that this view
does not become a zombie view.
*/
maria.View.prototype.destroy = function() { maria.View.prototype.destroy = function() {
maria.purge(this); maria.purge(this);
this._model = null; this._model = null;
...@@ -2246,27 +2365,77 @@ maria.View.prototype.destroy = function() { ...@@ -2246,27 +2365,77 @@ maria.View.prototype.destroy = function() {
hijos.Node.prototype.destroy.call(this); hijos.Node.prototype.destroy.call(this);
}; };
/**
By default, a view will observe its model for `change` events. When
a `change` event is dispatched on the model then this `update` method
is the handler. (The "change" and "update" names are inherited directly
from Smalltalk implementations.)
To be overridden by subclasses.
@param {object} event The event object.
*/
maria.View.prototype.update = function() { maria.View.prototype.update = function() {
// to be overridden by concrete view subclasses // to be overridden by concrete view subclasses
}; };
/**
Returns the current model object of this view.
@return {maria.Model} The model object.
*/
maria.View.prototype.getModel = function() { maria.View.prototype.getModel = function() {
return this._model; return this._model;
}; };
/**
Set the current model object of this view.
@param {maria.Model} model The model object.
*/
maria.View.prototype.setModel = function(model) { maria.View.prototype.setModel = function(model) {
this._setModelAndController(model, this._controller); this._setModelAndController(model, this._controller);
}; };
/**
Returns a controller constructor function to be used to create
a controller for this view.
@return {function} The controller constructor function.
*/
maria.View.prototype.getDefaultControllerConstructor = function() { maria.View.prototype.getDefaultControllerConstructor = function() {
return maria.Controller; return maria.Controller;
}; };
/**
Creates a new default controller for this view.
@return {maria.Controller} The controller object.
*/
maria.View.prototype.getDefaultController = function() { maria.View.prototype.getDefaultController = function() {
var constructor = this.getDefaultControllerConstructor(); var constructor = this.getDefaultControllerConstructor();
return new constructor(); return new constructor();
}; };
/**
If this view has not yet had its controller set then this method
creates a controller and sets it as this view's controller.
@return {maria.Controller} The controller object.
*/
maria.View.prototype.getController = function() { maria.View.prototype.getController = function() {
if (!this._controller) { if (!this._controller) {
this.setController(this.getDefaultController()); this.setController(this.getDefaultController());
...@@ -2274,10 +2443,33 @@ maria.View.prototype.getController = function() { ...@@ -2274,10 +2443,33 @@ maria.View.prototype.getController = function() {
return this._controller; return this._controller;
}; };
/**
Set the current controller for this view.
@param {maria.Controller} The controller object.
*/
maria.View.prototype.setController = function(controller) { maria.View.prototype.setController = function(controller) {
this._setModelAndController(this._model, controller); this._setModelAndController(this._model, controller);
}; };
/**
When the model is set for this view, the view will automatically
observe the events which are keys of the returned object. The values
for each key is the view's handler method to be called when the corresponding
event is dispatched on the model.
By default, a view will observe the model for `change` events and handle
those events with the view's `update` method.
You can override this method but, beware, doing so can lead to the dark side.
@return {Object} The map of model events and view handers.
*/
maria.View.prototype.getModelActions = function() { maria.View.prototype.getModelActions = function() {
return {'change': 'update'}; return {'change': 'update'};
}; };
...@@ -2312,16 +2504,6 @@ maria.View.prototype._setModelAndController = function(model, controller) { ...@@ -2312,16 +2504,6 @@ maria.View.prototype._setModelAndController = function(model, controller) {
}; };
/** /**
@property maria.ElementView
@parameter model {Object} Optional
@parameter controller {Object} Optional
@parameter document {Document} Optional
@description
A constructor function to create new element view objects. A constructor function to create new element view objects.
var elementView = new maria.ElementView(); var elementView = new maria.ElementView();
...@@ -2481,6 +2663,16 @@ the same. ...@@ -2481,6 +2663,16 @@ the same.
this.find('.ui-tooltip-top').style.display = 'none'; this.find('.ui-tooltip-top').style.display = 'none';
}; };
@constructor
@param {maria.Model} [model]
@param {maria.Controller} [controller]
@param {Document} [document]
@extends maria.View
*/ */
maria.ElementView = function(model, controller, doc) { maria.ElementView = function(model, controller, doc) {
maria.View.call(this, model, controller); maria.View.call(this, model, controller);
...@@ -2490,10 +2682,26 @@ maria.ElementView = function(model, controller, doc) { ...@@ -2490,10 +2682,26 @@ maria.ElementView = function(model, controller, doc) {
maria.ElementView.prototype = maria.create(maria.View.prototype); maria.ElementView.prototype = maria.create(maria.View.prototype);
maria.ElementView.prototype.constructor = maria.ElementView; maria.ElementView.prototype.constructor = maria.ElementView;
/**
Returns the web page document for the view. This document
is the one used to create elements to be added to the page,
for example.
@return {Document} The document object.
*/
maria.ElementView.prototype.getDocument = function() { maria.ElementView.prototype.getDocument = function() {
return this._doc || document; return this._doc || document;
}; };
/**
Set the web page document for the view. This document
is the one used to create elements to be added to the page,
for example.
*/
maria.ElementView.prototype.setDocument = function(doc) { maria.ElementView.prototype.setDocument = function(doc) {
this._doc = doc; this._doc = doc;
var childViews = this.childNodes; var childViews = this.childNodes;
...@@ -2502,14 +2710,43 @@ maria.ElementView.prototype.setDocument = function(doc) { ...@@ -2502,14 +2710,43 @@ maria.ElementView.prototype.setDocument = function(doc) {
} }
}; };
/**
Returns the template for this view used during the build process.
@return {string} The template HTML string.
*/
maria.ElementView.prototype.getTemplate = function() { maria.ElementView.prototype.getTemplate = function() {
return '<div></div>'; return '<div></div>';
}; };
/**
The UI actions object maps a UI action like a click
on a button with a handler method name. By default,
the handler will be called on the controller of the view.
@return {Object} The UI actions map.
*/
maria.ElementView.prototype.getUIActions = function() { maria.ElementView.prototype.getUIActions = function() {
return {}; return {};
}; };
/**
Builds the root DOM element for the view from the view's template
returned by `getTemplate`, attaches event handlers to the root
and its descendents as specified by the UI actions map returned
by `getUIActions`, calls the `buildData` method to allow model
values to be inserted into the root DOM element and its descendents,
and calls `buildChildViews`. This construction of the root DOM element
is lazy and only done when this method is called.
@return {Element} The root DOM Element of the view.
*/
maria.ElementView.prototype.build = function() { maria.ElementView.prototype.build = function() {
if (!this._rootEl) { if (!this._rootEl) {
this.buildTemplate(); this.buildTemplate();
...@@ -2520,6 +2757,14 @@ maria.ElementView.prototype.build = function() { ...@@ -2520,6 +2757,14 @@ maria.ElementView.prototype.build = function() {
return this._rootEl; return this._rootEl;
}; };
/**
Parses the HTML template string returned by `getTemplate` to create a
`DocumentFragment`. The first child of that `DocumentFragment` is set
as the root element of this view. All other sibling elements of the
`DocumentFragment` are discarded.
*/
maria.ElementView.prototype.buildTemplate = function() { maria.ElementView.prototype.buildTemplate = function() {
// parseHTML returns a DocumentFragment so take firstChild as the rootEl // parseHTML returns a DocumentFragment so take firstChild as the rootEl
this._rootEl = arbutus.parseHTML(this.getTemplate(), this.getDocument()).firstChild; this._rootEl = arbutus.parseHTML(this.getTemplate(), this.getDocument()).firstChild;
...@@ -2528,6 +2773,12 @@ maria.ElementView.prototype.buildTemplate = function() { ...@@ -2528,6 +2773,12 @@ maria.ElementView.prototype.buildTemplate = function() {
(function() { (function() {
var actionRegExp = /^(\S+)\s*(.*)$/; var actionRegExp = /^(\S+)\s*(.*)$/;
/**
Attaches event handlers to the root and its descendents as specified
by the UI actions map returned by `getUIActions`.
*/
maria.ElementView.prototype.buildUIActions = function() { maria.ElementView.prototype.buildUIActions = function() {
var uiActions = this.getUIActions(); var uiActions = this.getUIActions();
for (var key in uiActions) { for (var key in uiActions) {
...@@ -2546,10 +2797,25 @@ maria.ElementView.prototype.buildTemplate = function() { ...@@ -2546,10 +2797,25 @@ maria.ElementView.prototype.buildTemplate = function() {
}()); }());
/**
Does nothing by default. To be overridden by subclasses.
The intended use of this method is to populate the built root DOM element
and its descendents with model data.
*/
maria.ElementView.prototype.buildData = function() { maria.ElementView.prototype.buildData = function() {
// to be overridden by concrete ElementView subclasses // to be overridden by concrete ElementView subclasses
}; };
/*
Used as part of the initial building of the view. If child views have
been added to the view, then these children also built and appened
to the element returned by `getContainerEl`.
*/
maria.ElementView.prototype.buildChildViews = function() { maria.ElementView.prototype.buildChildViews = function() {
var childViews = this.childNodes; var childViews = this.childNodes;
for (var i = 0, ilen = childViews.length; i < ilen; i++) { for (var i = 0, ilen = childViews.length; i < ilen; i++) {
...@@ -2557,10 +2823,27 @@ maria.ElementView.prototype.buildChildViews = function() { ...@@ -2557,10 +2823,27 @@ maria.ElementView.prototype.buildChildViews = function() {
} }
}; };
/**
See `buildChildViews` for more details.
@return {Element} The DOM Element to which child view's should be attached.
*/
maria.ElementView.prototype.getContainerEl = function() { maria.ElementView.prototype.getContainerEl = function() {
return this.build(); return this.build();
}; };
/**
Add a new child view before an existing child view. If the `oldChild`
parameter is not supplied then the `newChild` is appened as the last child.
@param {maria.ElementView} newChild The child to be inserted.
@param {maria.ElementView} oldChild The child to insert before.
*/
maria.ElementView.prototype.insertBefore = function(newChild, oldChild) { maria.ElementView.prototype.insertBefore = function(newChild, oldChild) {
maria.View.prototype.insertBefore.call(this, newChild, oldChild); maria.View.prototype.insertBefore.call(this, newChild, oldChild);
if (this._rootEl) { if (this._rootEl) {
...@@ -2568,6 +2851,13 @@ maria.ElementView.prototype.insertBefore = function(newChild, oldChild) { ...@@ -2568,6 +2851,13 @@ maria.ElementView.prototype.insertBefore = function(newChild, oldChild) {
} }
}; };
/**
Remove an existing child view.
@param {maria.ElementView} oldChild The child to be removed.
*/
maria.ElementView.prototype.removeChild = function(oldChild) { maria.ElementView.prototype.removeChild = function(oldChild) {
maria.View.prototype.removeChild.call(this, oldChild); maria.View.prototype.removeChild.call(this, oldChild);
if (this._rootEl) { if (this._rootEl) {
...@@ -2575,24 +2865,53 @@ maria.ElementView.prototype.removeChild = function(oldChild) { ...@@ -2575,24 +2865,53 @@ maria.ElementView.prototype.removeChild = function(oldChild) {
} }
}; };
/**
Find the first element in this view that matches the CSS `selector`. The
view's root element can be the result.
By default Maria uses the Grail library as its DOM query engine. This is
to support older browsers that do not have `querySelector`. The Grail
engine only a limited set of simple selectors.
.class
tag
tag.class
#id
If your application only needs to work in newer browsers you can create
a Maria plugin to use `querySelector` but ensure the root element will
be returned if it matches `selector`.
If your application needs to work in older browsers but you need more
complex CSS `selector` strings then you can create a Maria plugin
to use some libray other than Grail.
@param {string} selector A CSS selector.
@return {Element} The first DOM element matching `selector`.
*/
maria.ElementView.prototype.find = function(selector) { maria.ElementView.prototype.find = function(selector) {
return grail.find(selector, this.build()); return grail.find(selector, this.build());
}; };
maria.ElementView.prototype.findAll = function(selector) {
return grail.findAll(selector, this.build());
};
/** /**
@property maria.SetView Find all the elements in this view that matches the CSS `selector`. The
view's root element can be in the result set.
@parameter model {Object} Optional See `find` for more details.
@parameter controller {Object} Optional @param {string} selector A CSS selector.
@parameter document {Document} Optional @return {Array} An array of the DOM elements matching `selector`.
@description */
maria.ElementView.prototype.findAll = function(selector) {
return grail.findAll(selector, this.build());
};
/**
A constructor function to create new set view objects. A constructor function to create new set view objects.
...@@ -2631,6 +2950,16 @@ maria.SetView.subclass for a more compact way to accomplish the same. ...@@ -2631,6 +2950,16 @@ maria.SetView.subclass for a more compact way to accomplish the same.
return new checkit.TodoView(todoModel); return new checkit.TodoView(todoModel);
}; };
@constructor
@param {maria.Model} [model]
@param {maria.Controller} [controller]
@param {Document} [document]
@extends maria.ElementView
*/ */
maria.SetView = function() { maria.SetView = function() {
maria.ElementView.apply(this, arguments); maria.ElementView.apply(this, arguments);
...@@ -2639,6 +2968,15 @@ maria.SetView = function() { ...@@ -2639,6 +2968,15 @@ maria.SetView = function() {
maria.SetView.prototype = maria.create(maria.ElementView.prototype); maria.SetView.prototype = maria.create(maria.ElementView.prototype);
maria.SetView.prototype.constructor = maria.SetView; maria.SetView.prototype.constructor = maria.SetView;
/**
The model of the view is a `maria.SetModel`. A new view will be created
for each model in that set model and the view will be appended as a child
view of this set view.
@override
*/
maria.SetView.prototype.buildChildViews = function() { maria.SetView.prototype.buildChildViews = function() {
var childModels = this.getModel().toArray(); var childModels = this.getModel().toArray();
for (var i = 0, ilen = childModels.length; i < ilen; i++) { for (var i = 0, ilen = childModels.length; i < ilen; i++) {
...@@ -2646,10 +2984,26 @@ maria.SetView.prototype.buildChildViews = function() { ...@@ -2646,10 +2984,26 @@ maria.SetView.prototype.buildChildViews = function() {
} }
}; };
/**
Creates a child view for a model. To be overridden by subclasses.
@param {maria.Model} model The model for the child view.
*/
maria.SetView.prototype.createChildView = function(model) { maria.SetView.prototype.createChildView = function(model) {
return new maria.ElementView(model); return new maria.ElementView(model);
}; };
/**
The handler for `change` events on this view's set model object.
@param {Object} event The event object.
@override
*/
maria.SetView.prototype.update = function(evt) { maria.SetView.prototype.update = function(evt) {
// Don't update for bubbling events. // Don't update for bubbling events.
if (evt.target === this.getModel()) { if (evt.target === this.getModel()) {
...@@ -2662,6 +3016,16 @@ maria.SetView.prototype.update = function(evt) { ...@@ -2662,6 +3016,16 @@ maria.SetView.prototype.update = function(evt) {
} }
}; };
/**
When a `change` event is fired on this view's set model because
some models were added to the set model, this method
will create child views and append them as children of this set view.
@param {Object} event The event object.
*/
maria.SetView.prototype.handleAdd = function(evt) { maria.SetView.prototype.handleAdd = function(evt) {
var childModels = evt.addedTargets; var childModels = evt.addedTargets;
for (var i = 0, ilen = childModels.length; i < ilen; i++) { for (var i = 0, ilen = childModels.length; i < ilen; i++) {
...@@ -2669,6 +3033,16 @@ maria.SetView.prototype.handleAdd = function(evt) { ...@@ -2669,6 +3033,16 @@ maria.SetView.prototype.handleAdd = function(evt) {
} }
}; };
/**
When a `change` event is fired on this view's set model because
some models were deleted from the set model, this method
will find, remove, and destroy the corresponding child views
of this set view.
@param {Object} event The event object.
*/
maria.SetView.prototype.handleDelete = function(evt) { maria.SetView.prototype.handleDelete = function(evt) {
var childModels = evt.deletedTargets; var childModels = evt.deletedTargets;
for (var i = 0, ilen = childModels.length; i < ilen; i++) { for (var i = 0, ilen = childModels.length; i < ilen; i++) {
...@@ -2686,10 +3060,6 @@ maria.SetView.prototype.handleDelete = function(evt) { ...@@ -2686,10 +3060,6 @@ maria.SetView.prototype.handleDelete = function(evt) {
}; };
/** /**
@property maria.Controller
@description
A constructor function to create new controller objects. A constructor function to create new controller objects.
Controller objects are usually created lazily on demand by a view Controller objects are usually created lazily on demand by a view
...@@ -2769,9 +3139,16 @@ to accomplish the same. ...@@ -2769,9 +3139,16 @@ to accomplish the same.
} }
}; };
@constructor
*/ */
maria.Controller = function() {}; maria.Controller = function() {};
/**
The destroy method.
*/
maria.Controller.prototype.destroy = function() { maria.Controller.prototype.destroy = function() {
this._model = null; this._model = null;
if (this._view) { if (this._view) {
...@@ -2780,33 +3157,55 @@ maria.Controller.prototype.destroy = function() { ...@@ -2780,33 +3157,55 @@ maria.Controller.prototype.destroy = function() {
} }
}; };
/**
Returns the current model object of the controller.
@return {maria.Model} The model object.
*/
maria.Controller.prototype.getModel = function() { maria.Controller.prototype.getModel = function() {
return this._model; return this._model;
}; };
// setModel is intended to be called *only* by /**
// the view _setModelAndController method.
// Do otherwise at your own risk. `setModel` is intended to be called **only** by
the view `_setModelAndController` method. **Do otherwise
at your own risk!**
@param {maria.Model} model The model object.
*/
maria.Controller.prototype.setModel = function(model) { maria.Controller.prototype.setModel = function(model) {
this._model = model; this._model = model;
}; };
/**
Returns the current view object of the controller.
@return {maria.View} The view object.
*/
maria.Controller.prototype.getView = function() { maria.Controller.prototype.getView = function() {
return this._view; return this._view;
}; };
// setView is intended to be called *only* by /**
// the view _setModelAndController method.
// Do otherwise at your own risk. `setView` is intended to be called **only** by
the view `_setModelAndController` method. **Do otherwise
at your own risk!**
@param {maria.View} view The view object.
*/
maria.Controller.prototype.setView = function(view) { maria.Controller.prototype.setView = function(view) {
this._view = view; this._view = view;
}; };
/** /**
@property maria.Model.subclass
@description
A function that makes subclassing maria.Model more compact. A function that makes subclassing maria.Model more compact.
The following example creates a checkit.TodoModel constructor function The following example creates a checkit.TodoModel constructor function
...@@ -2849,10 +3248,6 @@ maria.Model.subclass = function() { ...@@ -2849,10 +3248,6 @@ maria.Model.subclass = function() {
}; };
/** /**
@property maria.SetModel.subclass
@description
A function that makes subclassing maria.SetModel more compact. A function that makes subclassing maria.SetModel more compact.
The following example creates a checkit.TodosModel constructor function The following example creates a checkit.TodosModel constructor function
...@@ -2897,10 +3292,6 @@ maria.SetModel.subclass = function() { ...@@ -2897,10 +3292,6 @@ maria.SetModel.subclass = function() {
}; };
/** /**
@property maria.View.subclass
@description
A function that makes subclassing maria.View more compact. A function that makes subclassing maria.View more compact.
The following example creates a myapp.MyView constructor function The following example creates a myapp.MyView constructor function
...@@ -2959,10 +3350,6 @@ maria.View.subclass = function(namespace, name, options) { ...@@ -2959,10 +3350,6 @@ maria.View.subclass = function(namespace, name, options) {
}; };
/** /**
@property maria.ElementView.subclass
@description
A function that makes subclassing maria.ElementView more compact. A function that makes subclassing maria.ElementView more compact.
The following example creates a checkit.TodoView constructor function The following example creates a checkit.TodoView constructor function
...@@ -3074,10 +3461,6 @@ maria.ElementView.subclass = function(namespace, name, options) { ...@@ -3074,10 +3461,6 @@ maria.ElementView.subclass = function(namespace, name, options) {
}; };
/** /**
@property maria.SetView.subclass
@description
The same as maria.ElementView. The same as maria.ElementView.
You will likely want to specify a createChildView method. You will likely want to specify a createChildView method.
...@@ -3100,10 +3483,6 @@ maria.SetView.subclass = function() { ...@@ -3100,10 +3483,6 @@ maria.SetView.subclass = function() {
}; };
/** /**
@property maria.Controller.subclass
@description
A function that makes subclassing maria.Controller more compact. A function that makes subclassing maria.Controller more compact.
The following example creates a checkit.TodoController constructor The following example creates a checkit.TodoController constructor
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"spine": "~1.0.9", "spine": "~1.0.9",
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"handlebars": "~1.0.0-rc.3", "handlebars": "~1.0.0-rc.3",
"jquery": "~1.8.3" "jquery": "~1.8.3"
} }
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"backbone": "~0.9.10", "backbone": "~0.9.10",
"underscore": "~1.4.4", "underscore": "~1.4.4",
"jquery": "~1.9.1", "jquery": "~1.9.1",
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"backbone.localStorage": "~1.1.0", "backbone.localStorage": "~1.1.0",
"requirejs": "~2.1.5", "requirejs": "~2.1.5",
"requirejs-text": "~2.0.5" "requirejs-text": "~2.0.5"
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"es5-shim": "git://github.com/kriskowal/es5-shim.git#2.0.0", "es5-shim": "git://github.com/kriskowal/es5-shim.git#2.0.0",
"flight": "~1.0.3", "flight": "~1.0.3",
"jquery": "1.8.3", "jquery": "1.8.3",
"requirejs": "~2.1.5" "requirejs": "~2.1.5",
"todomvc-common": "~0.1.4"
} }
} }
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
label[for='toggle-all'] {
display: none;
}
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all:checked:before {
color: #737373;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.editing {
border-bottom: none;
padding: 0;
}
#todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list li label {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li .edit {
display: none;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: 1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
float: left;
text-align: left;
}
#filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
#filters li {
display: inline;
}
#filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
}
#filters li a.selected {
font-weight: bold;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
}
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
}
(function () {
'use strict';
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function getSourcePath() {
// If accessed via addyosmani.github.io/todomvc/, strip the project path.
if (location.hostname.indexOf('github.io') > 0) {
return location.pathname.replace(/todomvc\//, '');
}
return location.pathname;
}
function appendSourceLink() {
var sourceLink = document.createElement('a');
var paragraph = document.createElement('p');
var footer = document.getElementById('info');
var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';
if (footer) {
sourceLink.href = urlBase + getSourcePath();
sourceLink.appendChild(document.createTextNode('Check out the source'));
paragraph.appendChild(sourceLink);
footer.appendChild(paragraph);
}
}
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink();
redirect();
})();
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Flight • Todo</title> <title>Flight • Todo</title>
<link rel="stylesheet" href="../../assets/base.css"> <link rel="stylesheet" href="components/todomvc-common/base.css">
</head> </head>
<body> <body>
<section id="todoapp"> <section id="todoapp">
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<p>Created by <a href="http://github.com/mkuklis">Michal Kuklis</a></p> <p>Created by <a href="http://github.com/mkuklis">Michal Kuklis</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer> </footer>
<script src="../../assets/base.js"></script> <script src="components/todomvc-common/base.js"></script>
<script data-main="app/js/main" src="components/requirejs/requirejs.js"></script> <script data-main="app/js/main" src="components/requirejs/requirejs.js"></script>
</body> </body>
</html> </html>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-backbone-marionette", "name": "todomvc-backbone-marionette",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"underscore": "~1.4.4", "underscore": "~1.4.4",
"backbone.localStorage": "~1.1.0", "backbone.localStorage": "~1.1.0",
"backbone.marionette": "~1.0.0-rc6" "backbone.marionette": "~1.0.0-rc6"
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
"olives": "~1.4.0", "olives": "~1.4.0",
"emily": "~1.3.5", "emily": "~1.3.5",
"requirejs": "~2.1.5", "requirejs": "~2.1.5",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -29,9 +28,8 @@ ...@@ -29,9 +28,8 @@
} }
function redirect() { function redirect() {
if (location.hostname === 'addyosmani.github.com') { if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.com/todomvc', location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
'todomvc.com');
} }
} }
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
"dependencies": { "dependencies": {
"puremvc": "~1.0.1", "puremvc": "~1.0.1",
"director": "~1.2.0", "director": "~1.2.0",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -29,9 +28,8 @@ ...@@ -29,9 +28,8 @@
} }
function redirect() { function redirect() {
if (location.hostname === 'addyosmani.github.com') { if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.com/todomvc', location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
'todomvc.com');
} }
} }
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
"dependencies": { "dependencies": {
"sammy": "~0.7.4", "sammy": "~0.7.4",
"jquery": "~1.9.1", "jquery": "~1.9.1",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -29,9 +28,8 @@ ...@@ -29,9 +28,8 @@
} }
function redirect() { function redirect() {
if (location.hostname === 'addyosmani.github.com') { if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.com/todomvc', location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
'todomvc.com');
} }
} }
......
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"director": "~1.2.0", "director": "~1.2.0",
"todomvc-common": "~0.1.2" "todomvc-common": "~0.1.4"
} }
} }
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -29,9 +28,8 @@ ...@@ -29,9 +28,8 @@
} }
function redirect() { function redirect() {
if (location.hostname === 'addyosmani.github.com') { if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.com/todomvc', location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
'todomvc.com');
} }
} }
......
{
"directory" : "client/code/libs"
}
var http = require('http'), var http = require('http');
ss = require('socketstream'); var ss = require('socketstream');
// Define a single-page client // Define a single-page client
ss.client.define('main', { ss.client.define('main', {
view: 'app.html', view: 'app.html',
css: ['base.css'], css: ['base.css'],
code: [ 'libs', 'app' ], code: [
'libs/jquery/jquery.js',
'libs/todomvc-common/base.js',
'app'
],
tmpl: '*' tmpl: '*'
}); });
// Serve this client on the root URL // Serve this client on the root URL
ss.http.route( '/', function( req, res ) { ss.http.route('/', function (req, res) {
res.serveClient('main'); res.serveClient('main');
}); });
// Use server-side compiled Hogan (Mustache) templates. Others engines available // Use server-side compiled Hogan (Mustache) templates. Others engines available
ss.client.templateEngine.use( require('ss-hogan') ); ss.client.templateEngine.use(require('ss-hogan'));
// Minimize and pack assets if you type: SS_ENV=production node app.js // Minimize and pack assets if you type: SS_ENV=production node app.js
if ( ss.env === 'production' ) { if (ss.env === 'production') {
ss.client.packAssets(); ss.client.packAssets();
} }
// Start web server // Start web server
var server = http.Server( ss.http.middleware ); var server = http.Server(ss.http.middleware);
server.listen(3000); server.listen(3000);
// Start SocketStream // Start SocketStream
ss.start( server ); ss.start(server);
/*global $, ss */ /*global $, ss*/
'use strict'; (function () {
'use strict';
var Utils = { var Utils = {
// https://gist.github.com/1308368 // https://gist.github.com/1308368
uuid: function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b}, uuid: function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b},
pluralize: function( count, word ) { pluralize: function (count, word) {
return count === 1 ? word : word + 's'; return count === 1 ? word : word + 's';
} }
}; };
var App = { var App = {
init: function() { init: function () {
var self = this; var self = this;
this.ENTER_KEY = 13; this.ENTER_KEY = 13;
ss.rpc('todos.getAll', function( todos ) {
ss.rpc('todos.getAll', function (todos) {
self.todos = todos; self.todos = todos;
self.cacheElements(); self.cacheElements();
self.bindEvents(); self.bindEvents();
self.render(); self.render();
}); });
}, },
cacheElements: function() {
cacheElements: function () {
this.$todoApp = $('#todoapp'); this.$todoApp = $('#todoapp');
this.$newTodo = $('#new-todo'); this.$newTodo = $('#new-todo');
this.$toggleAll = $('#toggle-all'); this.$toggleAll = $('#toggle-all');
...@@ -30,130 +33,167 @@ var App = { ...@@ -30,130 +33,167 @@ var App = {
this.$count = $('#todo-count'); this.$count = $('#todo-count');
this.$clearBtn = $('#clear-completed'); this.$clearBtn = $('#clear-completed');
}, },
bindEvents: function() {
bindEvents: function () {
var list = this.$todoList; var list = this.$todoList;
this.$newTodo.on( 'keyup', this.create );
this.$toggleAll.on( 'change', this.toggleAll ); this.$newTodo.on('keyup', this.create);
this.$footer.on( 'click', '#clear-completed', this.destroyCompleted ); this.$toggleAll.on('change', this.toggleAll);
list.on( 'change', '.toggle', this.toggle ); this.$footer.on('click', '#clear-completed', this.destroyCompleted);
list.on( 'dblclick', 'label', this.edit );
list.on( 'keypress', '.edit', this.blurOnEnter ); list.on('change', '.toggle', this.toggle);
list.on( 'blur', '.edit', this.update ); list.on('dblclick', 'label', this.edit);
list.on( 'click', '.destroy', this.destroy ); list.on('keypress', '.edit', this.blurOnEnter);
ss.event.on( 'updateTodos', this.updateTodos ); list.on('blur', '.edit', this.update);
list.on('click', '.destroy', this.destroy);
ss.event.on('updateTodos', this.updateTodos);
}, },
updateTodos: function( todos ) {
updateTodos: function (todos) {
App.todos = todos; App.todos = todos;
App.render( true );
App.render(true);
}, },
render: function( preventRpc ) {
var html = this.todos.map(function( el ) { render: function (preventRpc) {
return ss.tmpl.todo.render( el ); var html = this.todos.map(function (el) {
return ss.tmpl.todo.render(el);
}).join(''); }).join('');
this.$todoList.html( html ); this.$todoList.html(html);
this.$main.toggle( !!this.todos.length ); this.$main.toggle(!!this.todos.length);
this.$toggleAll.prop( 'checked', !this.activeTodoCount() ); this.$toggleAll.prop('checked', !this.activeTodoCount());
this.renderFooter(); this.renderFooter();
if ( !preventRpc ) { if (!preventRpc) {
ss.rpc( 'todos.update', this.todos ); ss.rpc('todos.update', this.todos);
} }
}, },
renderFooter: function() {
var todoCount = this.todos.length, renderFooter: function () {
activeTodoCount = this.activeTodoCount(), var todoCount = this.todos.length;
footer = {
var activeTodoCount = this.activeTodoCount();
var footer = {
activeTodoCount: activeTodoCount, activeTodoCount: activeTodoCount,
activeTodoWord: Utils.pluralize( activeTodoCount, 'item' ), activeTodoWord: Utils.pluralize(activeTodoCount, 'item'),
completedTodos: todoCount - activeTodoCount completedTodos: todoCount - activeTodoCount
}; };
this.$footer.toggle( !!todoCount ); this.$footer.toggle(!!todoCount);
this.$footer.html( ss.tmpl.footer.render( footer ) );
this.$footer.html( ss.tmpl.footer.render(footer) );
}, },
toggleAll: function() {
var isChecked = $( this ).prop('checked'); toggleAll: function () {
$.each( App.todos, function( i, val ) { var isChecked = $(this).prop('checked');
$.each(App.todos, function (i, val) {
val.completed = isChecked; val.completed = isChecked;
}); });
App.render(); App.render();
}, },
activeTodoCount: function() {
activeTodoCount: function () {
var count = 0; var count = 0;
$.each( this.todos, function( i, val ) {
if ( !val.completed ) { $.each(this.todos, function (i, val) {
if (!val.completed) {
count++; count++;
} }
}); });
return count; return count;
}, },
destroyCompleted: function() {
var todos = App.todos, destroyCompleted: function () {
l = todos.length; var todos = App.todos;
while ( l-- ) { var l = todos.length;
if ( todos[l].completed ) {
todos.splice( l, 1 ); while (l--) {
if (todos[l].completed) {
todos.splice(l, 1);
} }
} }
App.render(); App.render();
}, },
// Accepts an element from inside the ".item" div and // Accepts an element from inside the ".item" div and
// returns the corresponding todo in the todos array // returns the corresponding todo in the todos array
getTodo: function( elem, callback ) { getTodo: function (elem, callback) {
var id = $( elem ).closest('li').data('id'); var id = $(elem).closest('li').data('id');
$.each( this.todos, function( i, val ) {
if ( val.id === id ) { $.each(this.todos, function (i, val) {
callback.apply( App, arguments ); if (val.id === id) {
callback.apply(App, arguments);
return false; return false;
} }
}); });
}, },
create: function(e) {
var $input = $(this), create: function (e) {
val = $.trim( $input.val() ); var $input = $(this);
if ( e.which !== App.ENTER_KEY || !val ) { var val = $.trim($input.val());
if (e.which !== App.ENTER_KEY || !val) {
return; return;
} }
App.todos.push({ App.todos.push({
id: Utils.uuid(), id: Utils.uuid(),
title: val, title: val,
completed: false completed: false
}); });
$input.val(''); $input.val('');
App.render(); App.render();
}, },
toggle: function() {
App.getTodo( this, function( i, val ) { toggle: function () {
App.getTodo(this, function (i, val) {
val.completed = !val.completed; val.completed = !val.completed;
}); });
App.render(); App.render();
}, },
edit: function() {
edit: function () {
$(this).closest('li').addClass('editing').find('.edit').focus(); $(this).closest('li').addClass('editing').find('.edit').focus();
}, },
blurOnEnter: function( e ) {
if ( e.keyCode === App.ENTER_KEY ) { blurOnEnter: function (e) {
if (e.keyCode === App.ENTER_KEY) {
e.target.blur(); e.target.blur();
} }
}, },
update: function() {
var val = $.trim( $(this).removeClass('editing').val() ); update: function () {
App.getTodo( this, function( i ) { var val = $.trim($(this).removeClass('editing').val());
if ( val ) { App.getTodo(this, function (i) {
this.todos[ i ].title = val; if (val) {
this.todos[i].title = val;
} else { } else {
this.todos.splice( i, 1 ); this.todos.splice(i, 1);
} }
this.render(); this.render();
}); });
}, },
destroy: function() {
App.getTodo( this, function( i ) { destroy: function () {
this.todos.splice( i, 1 ); App.getTodo(this, function (i) {
this.todos.splice(i, 1);
this.render(); this.render();
}); });
} }
}; };
App.init(); App.init();
})();
// This file automatically gets called first by SocketStream and must always exist /*global $, ss*/
(function () {
'use strict';
// This file automatically gets called first by SocketStream and must always exist
// Make 'ss' available to all modules and the browser console // Make 'ss' available to all modules and the browser console
window.ss = require('socketstream'); window.ss = require('socketstream');
ss.server.on('disconnect', function() { ss.server.on('disconnect', function () {
console.log('Connection down :-('); console.log('Connection down :-(');
}); });
ss.server.on('reconnect', function() { ss.server.on('reconnect', function () {
console.log('Connection back up :-)'); console.log('Connection back up :-)');
}); });
ss.server.on('ready', function() {
ss.server.on('ready', function () {
// Wait for the DOM to finish loading // Wait for the DOM to finish loading
$(function() { $(function () {
// Load app // Load app
require('/app'); require('/app');
}); });
});
}); })();
(function( window ) {
'use strict';
if ( location.hostname === 'todomvc.com' ) {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
})( window );
/*! HTML5 Shiv pre3.5 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
Uncompressed source: https://github.com/aFarkas/html5shiv */
(function(a,b){function h(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function i(){var a=l.elements;return typeof a=="string"?a.split(" "):a}function j(a){var b={},c=a.createElement,f=a.createDocumentFragment,g=f();a.createElement=function(a){l.shivMethods||c(a);var f;return b[a]?f=b[a].cloneNode():e.test(a)?f=(b[a]=c(a)).cloneNode():f=c(a),f.canHaveChildren&&!d.test(a)?g.appendChild(f):f},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+i().join().replace(/\w+/g,function(a){return b[a]=c(a),g.createElement(a),'c("'+a+'")'})+");return n}")(l,g)}function k(a){var b;return a.documentShived?a:(l.shivCSS&&!f&&(b=!!h(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),g||(b=!j(a)),b&&(a.documentShived=b),a)}function p(a){var b,c=a.getElementsByTagName("*"),d=c.length,e=RegExp("^(?:"+i().join("|")+")$","i"),f=[];while(d--)b=c[d],e.test(b.nodeName)&&f.push(b.applyElement(q(b)));return f}function q(a){var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(n+":"+a.nodeName);while(d--)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function r(a){var b,c=a.split("{"),d=c.length,e=RegExp("(^|[\\s,>+~])("+i().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),f="$1"+n+"\\:$2";while(d--)b=c[d]=c[d].split("}"),b[b.length-1]=b[b.length-1].replace(e,f),c[d]=b.join("}");return c.join("{")}function s(a){var b=a.length;while(b--)a[b].removeNode()}function t(a){var b,c,d=a.namespaces,e=a.parentWindow;return!o||a.printShived?a:(typeof d[n]=="undefined"&&d.add(n),e.attachEvent("onbeforeprint",function(){var d,e,f,g=a.styleSheets,i=[],j=g.length,k=Array(j);while(j--)k[j]=g[j];while(f=k.pop())if(!f.disabled&&m.test(f.media)){for(d=f.imports,j=0,e=d.length;j<e;j++)k.push(d[j]);try{i.push(f.cssText)}catch(l){}}i=r(i.reverse().join("")),c=p(a),b=h(a,i)}),e.attachEvent("onafterprint",function(){s(c),b.removeNode(!0)}),a.printShived=!0,a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea|object|iframe)$/i,e=/^<|^(?:a|b|button|code|div|fieldset|form|h1|h2|h3|h4|h5|h6|i|iframe|img|input|label|li|link|ol|option|p|param|q|script|select|span|strong|style|table|tbody|td|textarea|tfoot|th|thead|tr|ul)$/i,f,g;(function(){var c=b.createElement("a");c.innerHTML="<xyz></xyz>",f="hidden"in c,f&&typeof injectElementWithStyles=="function"&&injectElementWithStyles("#modernizr{}",function(b){b.hidden=!0,f=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle).display=="none"}),g=c.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var l={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:k};a.html5=l,k(b);var m=/^$|\b(?:all|print)\b/,n="html5shiv",o=!g&&function(){var c=b.documentElement;return typeof b.namespaces!="undefined"&&typeof b.parentWindow!="undefined"&&typeof c.applyElement!="undefined"&&typeof c.removeNode!="undefined"&&typeof a.attachEvent!="undefined"}();l.type+=" print",l.shivPrint=t,t(b)})(this,document);
/*! Copyright (c) 2009, 280 North Inc. http://280north.com/ MIT License. */
(function(n){"function"==typeof define?define(n):n()})(function(){function n(a){try{return Object.defineProperty(a,"sentinel",{}),"sentinel"in a}catch(d){}}if(!Function.prototype.bind)Function.prototype.bind=function(a){var d=this;if("function"!=typeof d)throw new TypeError;var b=p.call(arguments,1),c=function(){if(this instanceof c){var e=function(){};e.prototype=d.prototype;var e=new e,g=d.apply(e,b.concat(p.call(arguments)));return null!==g&&Object(g)===g?g:e}return d.apply(a,b.concat(p.call(arguments)))};
return c};var l=Function.prototype.call,f=Object.prototype,p=Array.prototype.slice,m=l.bind(f.toString),h=l.bind(f.hasOwnProperty),t,u,q,r,o;if(o=h(f,"__defineGetter__"))t=l.bind(f.__defineGetter__),u=l.bind(f.__defineSetter__),q=l.bind(f.__lookupGetter__),r=l.bind(f.__lookupSetter__);if(!Array.isArray)Array.isArray=function(a){return"[object Array]"==m(a)};if(!Array.prototype.forEach)Array.prototype.forEach=function(a,d){var b=i(this),c=0,e=b.length>>>0;if("[object Function]"!=m(a))throw new TypeError;
for(;c<e;)c in b&&a.call(d,b[c],c,b),c++};if(!Array.prototype.map)Array.prototype.map=function(a,d){var b=i(this),c=b.length>>>0,e=Array(c);if("[object Function]"!=m(a))throw new TypeError;for(var g=0;g<c;g++)g in b&&(e[g]=a.call(d,b[g],g,b));return e};if(!Array.prototype.filter)Array.prototype.filter=function(a,d){var b=i(this),c=b.length>>>0,e=[];if("[object Function]"!=m(a))throw new TypeError;for(var g=0;g<c;g++)g in b&&a.call(d,b[g],g,b)&&e.push(b[g]);return e};if(!Array.prototype.every)Array.prototype.every=
function(a,d){var b=i(this),c=b.length>>>0;if("[object Function]"!=m(a))throw new TypeError;for(var e=0;e<c;e++)if(e in b&&!a.call(d,b[e],e,b))return!1;return!0};if(!Array.prototype.some)Array.prototype.some=function(a,d){var b=i(this),c=b.length>>>0;if("[object Function]"!=m(a))throw new TypeError;for(var e=0;e<c;e++)if(e in b&&a.call(d,b[e],e,b))return!0;return!1};if(!Array.prototype.reduce)Array.prototype.reduce=function(a){var d=i(this),b=d.length>>>0;if("[object Function]"!=m(a))throw new TypeError;
if(!b&&1==arguments.length)throw new TypeError;var c=0,e;if(2<=arguments.length)e=arguments[1];else{do{if(c in d){e=d[c++];break}if(++c>=b)throw new TypeError;}while(1)}for(;c<b;c++)c in d&&(e=a.call(void 0,e,d[c],c,d));return e};if(!Array.prototype.reduceRight)Array.prototype.reduceRight=function(a){var d=i(this),b=d.length>>>0;if("[object Function]"!=m(a))throw new TypeError;if(!b&&1==arguments.length)throw new TypeError;var c,b=b-1;if(2<=arguments.length)c=arguments[1];else{do{if(b in d){c=d[b--];
break}if(0>--b)throw new TypeError;}while(1)}do b in this&&(c=a.call(void 0,c,d[b],b,d));while(b--);return c};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(a){var d=i(this),b=d.length>>>0;if(!b)return-1;var c=0;1<arguments.length&&(c=v(arguments[1]));for(c=0<=c?c:Math.max(0,b+c);c<b;c++)if(c in d&&d[c]===a)return c;return-1};if(!Array.prototype.lastIndexOf)Array.prototype.lastIndexOf=function(a){var d=i(this),b=d.length>>>0;if(!b)return-1;var c=b-1;1<arguments.length&&(c=Math.min(c,
v(arguments[1])));for(c=0<=c?c:b-Math.abs(c);0<=c;c--)if(c in d&&a===d[c])return c;return-1};if(!Object.getPrototypeOf)Object.getPrototypeOf=function(a){return a.__proto__||(a.constructor?a.constructor.prototype:f)};if(!Object.getOwnPropertyDescriptor)Object.getOwnPropertyDescriptor=function(a,d){if("object"!=typeof a&&"function"!=typeof a||null===a)throw new TypeError("Object.getOwnPropertyDescriptor called on a non-object: "+a);if(h(a,d)){var b,c,e;b={enumerable:!0,configurable:!0};if(o){var g=
a.__proto__;a.__proto__=f;c=q(a,d);e=r(a,d);a.__proto__=g;if(c||e){if(c)b.get=c;if(e)b.set=e;return b}}b.value=a[d];return b}};if(!Object.getOwnPropertyNames)Object.getOwnPropertyNames=function(a){return Object.keys(a)};if(!Object.create)Object.create=function(a,d){var b;if(null===a)b={__proto__:null};else{if("object"!=typeof a)throw new TypeError("typeof prototype["+typeof a+"] != 'object'");b=function(){};b.prototype=a;b=new b;b.__proto__=a}void 0!==d&&Object.defineProperties(b,d);return b};if(Object.defineProperty){var l=
n({}),y="undefined"==typeof document||n(document.createElement("div"));if(!l||!y)var s=Object.defineProperty}if(!Object.defineProperty||s)Object.defineProperty=function(a,d,b){if("object"!=typeof a&&"function"!=typeof a||null===a)throw new TypeError("Object.defineProperty called on non-object: "+a);if("object"!=typeof b&&"function"!=typeof b||null===b)throw new TypeError("Property description must be an object: "+b);if(s)try{return s.call(Object,a,d,b)}catch(c){}if(h(b,"value"))if(o&&(q(a,d)||r(a,
d))){var e=a.__proto__;a.__proto__=f;delete a[d];a[d]=b.value;a.__proto__=e}else a[d]=b.value;else{if(!o)throw new TypeError("getters & setters can not be defined on this javascript engine");h(b,"get")&&t(a,d,b.get);h(b,"set")&&u(a,d,b.set)}return a};if(!Object.defineProperties)Object.defineProperties=function(a,d){for(var b in d)h(d,b)&&Object.defineProperty(a,b,d[b]);return a};if(!Object.seal)Object.seal=function(a){return a};if(!Object.freeze)Object.freeze=function(a){return a};try{Object.freeze(function(){})}catch(D){Object.freeze=
function(a){return function(d){return"function"==typeof d?d:a(d)}}(Object.freeze)}if(!Object.preventExtensions)Object.preventExtensions=function(a){return a};if(!Object.isSealed)Object.isSealed=function(){return!1};if(!Object.isFrozen)Object.isFrozen=function(){return!1};if(!Object.isExtensible)Object.isExtensible=function(a){if(Object(a)!==a)throw new TypeError;for(var d="";h(a,d);)d+="?";a[d]=!0;var b=h(a,d);delete a[d];return b};if(!Object.keys){var w=!0,x="toString,toLocaleString,valueOf,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,constructor".split(","),
z=x.length,j;for(j in{toString:null})w=!1;Object.keys=function(a){if("object"!=typeof a&&"function"!=typeof a||null===a)throw new TypeError("Object.keys called on a non-object");var d=[],b;for(b in a)h(a,b)&&d.push(b);if(w)for(b=0;b<z;b++){var c=x[b];h(a,c)&&d.push(c)}return d}}if(!Date.prototype.toISOString||-1===(new Date(-621987552E5)).toISOString().indexOf("-000001"))Date.prototype.toISOString=function(){var a,d,b,c;if(!isFinite(this))throw new RangeError;a=[this.getUTCMonth()+1,this.getUTCDate(),
this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()];c=this.getUTCFullYear();c=(0>c?"-":9999<c?"+":"")+("00000"+Math.abs(c)).slice(0<=c&&9999>=c?-4:-6);for(d=a.length;d--;)b=a[d],10>b&&(a[d]="0"+b);return c+"-"+a.slice(0,2).join("-")+"T"+a.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"};if(!Date.now)Date.now=function(){return(new Date).getTime()};if(!Date.prototype.toJSON)Date.prototype.toJSON=function(){if("function"!=typeof this.toISOString)throw new TypeError;return this.toISOString()};
if(!Date.parse||864E13!==Date.parse("+275760-09-13T00:00:00.000Z"))Date=function(a){var d=function g(b,d,c,f,h,i,j){var k=arguments.length;return this instanceof a?(k=1==k&&""+b===b?new a(g.parse(b)):7<=k?new a(b,d,c,f,h,i,j):6<=k?new a(b,d,c,f,h,i):5<=k?new a(b,d,c,f,h):4<=k?new a(b,d,c,f):3<=k?new a(b,d,c):2<=k?new a(b,d):1<=k?new a(b):new a,k.constructor=g,k):a.apply(this,arguments)},b=RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(?:Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),
c;for(c in a)d[c]=a[c];d.now=a.now;d.UTC=a.UTC;d.prototype=a.prototype;d.prototype.constructor=d;d.parse=function(d){var c=b.exec(d);if(c){c.shift();for(var f=1;7>f;f++)c[f]=+(c[f]||(3>f?1:0)),1==f&&c[f]--;var h=+c.pop(),i=+c.pop(),j=c.pop(),f=0;if(j){if(23<i||59<h)return NaN;f=6E4*(60*i+h)*("+"==j?-1:1)}h=+c[0];return 0<=h&&99>=h?(c[0]=h+400,a.UTC.apply(this,c)+f-126227808E5):a.UTC.apply(this,c)+f}return a.parse.apply(this,arguments)};return d}(Date);j="\t\n\u000b\u000c\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";
if(!String.prototype.trim||j.trim()){j="["+j+"]";var A=RegExp("^"+j+j+"*"),B=RegExp(j+j+"*$");String.prototype.trim=function(){return(""+this).replace(A,"").replace(B,"")}}var v=function(a){a=+a;a!==a?a=0:0!==a&&a!==1/0&&a!==-(1/0)&&(a=(0<a||-1)*Math.floor(Math.abs(a)));return a},C="a"!="a"[0],i=function(a){if(null==a)throw new TypeError;return C&&"string"==typeof a&&a?a.split(""):Object(a)}});
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
/*! outerHTML - https://gist.github.com/1044128 */
"undefined"!==typeof document&&!("outerHTML"in document.createElementNS("http://www.w3.org/1999/xhtml","_"))&&function(a){var c=document.createElementNS("http://www.w3.org/1999/xhtml","_"),a=(a.HTMLElement||a.Element).prototype,e=new XMLSerializer,b=function(){var a;if(document.xmlVersion)return e.serializeToString(this);c.appendChild(this.cloneNode(!1));a=c.innerHTML.replace("><",">"+this.innerHTML+"<");c.innerHTML="";return a},d=function(a){var b=this.parentNode;if(null===b)throw DOMException.code=
DOMException.NOT_FOUND_ERR,DOMException;for(c.innerHTML=a;a=c.firstChild;)b.insertBefore(a,this);b.removeChild(this)};if(Object.defineProperty){b={get:b,set:d,enumerable:!0,configurable:!0};try{Object.defineProperty(a,"outerHTML",b)}catch(f){-2146823252===f.number&&(b.enumerable=!1,Object.defineProperty(a,"outerHTML",b))}}else Object.prototype.__defineGetter__&&Object.prototype.__defineSetter__&&(a.__defineGetter__("outerHTML",b),a.__defineSetter__("outerHTML",d))}(self);
/*! jQuery v1.7.2 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
This source diff could not be displayed because it is too large. You can view the blob instead.
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
label[for='toggle-all'] {
display: none;
}
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all:checked:before {
color: #737373;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.editing {
border-bottom: none;
padding: 0;
}
#todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list li label {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li .edit {
display: none;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: 1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
float: left;
text-align: left;
}
#filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
#filters li {
display: inline;
}
#filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
}
#filters li a.selected {
font-weight: bold;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
}
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
}
(function () {
'use strict';
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project
// path.
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, '');
}
return location.pathname;
}
function appendSourceLink() {
var sourceLink = document.createElement('a');
var paragraph = document.createElement('p');
var footer = document.getElementById('info');
var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';
if (footer) {
sourceLink.href = urlBase + getSourcePath();
sourceLink.appendChild(document.createTextNode('Check out the source'));
paragraph.appendChild(sourceLink);
footer.appendChild(paragraph);
}
}
function redirect() {
if (location.hostname === 'addyosmani.github.com') {
location.href = location.href.replace('addyosmani.github.com/todomvc',
'todomvc.com');
}
}
appendSourceLink();
redirect();
})();
...@@ -155,22 +155,11 @@ label[for='toggle-all'] { ...@@ -155,22 +155,11 @@ label[for='toggle-all'] {
#toggle-all { #toggle-all {
position: absolute; position: absolute;
top: -56px; top: -42px;
left: -15px; left: -4px;
width: 65px; width: 40px;
height: 41px;
text-align: center; text-align: center;
border: none; /* Mobile Safari */ border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
-webkit-transform: rotate(90deg);
/*-moz-transform: rotate(90deg);*/
-ms-transform: rotate(90deg);
/*-o-transform: rotate(90deg);*/
transform: rotate(90deg);
} }
#toggle-all:before { #toggle-all:before {
...@@ -219,7 +208,8 @@ label[for='toggle-all'] { ...@@ -219,7 +208,8 @@ label[for='toggle-all'] {
#todo-list li .toggle { #todo-list li .toggle {
text-align: center; text-align: center;
width: 40px; width: 40px;
height: 40px; /* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
...@@ -233,7 +223,6 @@ label[for='toggle-all'] { ...@@ -233,7 +223,6 @@ label[for='toggle-all'] {
} }
#todo-list li .toggle:after { #todo-list li .toggle:after {
font-size: 18px;
content: '✔'; content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */ line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px; font-size: 20px;
...@@ -250,8 +239,9 @@ label[for='toggle-all'] { ...@@ -250,8 +239,9 @@ label[for='toggle-all'] {
#todo-list li label { #todo-list li label {
word-break: break-word; word-break: break-word;
margin: 15px 15px 15px 60px; padding: 15px;
display: inline-block; margin-left: 45px;
display: block;
line-height: 1.2; line-height: 1.2;
-webkit-transition: color 0.4s; -webkit-transition: color 0.4s;
-moz-transition: color 0.4s; -moz-transition: color 0.4s;
...@@ -402,4 +392,23 @@ label[for='toggle-all'] { ...@@ -402,4 +392,23 @@ label[for='toggle-all'] {
#todo-list li .toggle { #todo-list li .toggle {
background: none; background: none;
} }
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
} }
<span id="todo-count"><strong>{{activeTodoCount}}</strong> {{activeTodoWord}} left</span> <span id="todo-count">
{{#completedTodos}}<button id="clear-completed">Clear completed ({{completedTodos}})</button>{{/completedTodos}} <strong>{{activeTodoCount}}</strong> {{activeTodoWord}} left
\ No newline at end of file </span>
{{#completedTodos}}
<button id="clear-completed">Clear completed ({{completedTodos}})</button>
{{/completedTodos}}
{
"name": "todomvc-socketstream",
"version": "0.0.0",
"dependencies": {
"jquery": "~1.9.1",
"todomvc-common": "~0.1.3"
}
}
...@@ -6,14 +6,14 @@ var todos = []; ...@@ -6,14 +6,14 @@ var todos = [];
// Define actions which can be called from the client using // Define actions which can be called from the client using
// ss.rpc('demo.ACTIONNAME', param1, param2...) // ss.rpc('demo.ACTIONNAME', param1, param2...)
exports.actions = function( req, res, ss ) { exports.actions = function(req, res, ss) {
return { return {
getAll: function() { getAll: function () {
res( todos ); res(todos);
}, },
update: function( clientTodos ) { update: function (clientTodos) {
todos = clientTodos; todos = clientTodos;
ss.publish.all( 'updateTodos', todos ); ss.publish.all('updateTodos', todos);
} }
}; };
}; };
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "~1.0.5", "angular": "~1.0.5",
"todomvc-common": "~0.1.2", "todomvc-common": "~0.1.4",
"requirejs": "~2.1.5" "requirejs": "~2.1.5"
} }
} }
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
'use strict'; 'use strict';
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
function getSourcePath() { function getSourcePath() {
// If accessed via addyosmani.github.com/todomvc/, strip the project // If accessed via addyosmani.github.io/todomvc/, strip the project path.
// path. if (location.hostname.indexOf('github.io') > 0) {
if (location.hostname.indexOf('github.com') > 0) {
return location.pathname.replace(/todomvc\//, ''); return location.pathname.replace(/todomvc\//, '');
} }
return location.pathname; return location.pathname;
...@@ -28,5 +27,12 @@ ...@@ -28,5 +27,12 @@
} }
} }
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink(); appendSourceLink();
redirect();
})(); })();
{
"name": "todomvc-common",
"version": "0.1.1",
"gitHead": "639b3e310c9fd6970e8ccda893ad564915e715f5",
"_id": "todomvc-common@0.1.1",
"readme": "ERROR: No README.md file found!",
"description": "ERROR: No README.md file found!",
"repository": {
"type": "git",
"url": "git://github.com/tastejs/todomvc-common.git"
}
}
\ No newline at end of file
...@@ -36,9 +36,8 @@ ...@@ -36,9 +36,8 @@
}; };
function redirect() { function redirect() {
if (location.hostname === 'addyosmani.github.com') { if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.com/todomvc', location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
'todomvc.com');
} }
} }
......
{
"name": "todomvc-template",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.4"
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
label[for='toggle-all'] {
display: none;
}
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all:checked:before {
color: #737373;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.editing {
border-bottom: none;
padding: 0;
}
#todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list li label {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li .edit {
display: none;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: 1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
float: left;
text-align: left;
}
#filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
#filters li {
display: inline;
}
#filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
}
#filters li a.selected {
font-weight: bold;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
}
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
}
(function () {
'use strict';
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function getSourcePath() {
// If accessed via addyosmani.github.io/todomvc/, strip the project path.
if (location.hostname.indexOf('github.io') > 0) {
return location.pathname.replace(/todomvc\//, '');
}
return location.pathname;
}
function appendSourceLink() {
var sourceLink = document.createElement('a');
var paragraph = document.createElement('p');
var footer = document.getElementById('info');
var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';
if (footer) {
sourceLink.href = urlBase + getSourcePath();
sourceLink.appendChild(document.createTextNode('Check out the source'));
paragraph.appendChild(sourceLink);
footer.appendChild(paragraph);
}
}
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink();
redirect();
})();
...@@ -4,12 +4,9 @@ ...@@ -4,12 +4,9 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Template • TodoMVC</title> <title>Template • TodoMVC</title>
<link rel="stylesheet" href="../assets/base.css"> <link rel="stylesheet" href="components/todomvc-common/base.css">
<!-- CSS overrides - remove if you don't need it --> <!-- CSS overrides - remove if you don't need it -->
<link rel="stylesheet" href="css/app.css"> <link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../assets/ie.js"></script>
<![endif]-->
</head> </head>
<body> <body>
<section id="todoapp"> <section id="todoapp">
...@@ -58,6 +55,7 @@ ...@@ -58,6 +55,7 @@
<a href="#/completed">Completed</a> <a href="#/completed">Completed</a>
</li> </li>
</ul> </ul>
<!-- Hidden if no completed items are left ↓ -->
<button id="clear-completed">Clear completed (1)</button> <button id="clear-completed">Clear completed (1)</button>
</footer> </footer>
</section> </section>
...@@ -70,7 +68,7 @@ ...@@ -70,7 +68,7 @@
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer> </footer>
<!-- Scripts here. Don't remove this ↓ --> <!-- Scripts here. Don't remove this ↓ -->
<script src="../assets/base.js"></script> <script src="components/todomvc-common/base.js"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
</body> </body>
</html> </html>
# Template • [TodoMVC](http://todomvc.com) # Framework Name TodoMVC Example
This is a todo app built using [framework](https://example.com/framework).
## Framework
## Getting Started Short description of the framework. Which components are used (Backbone,
Handlebars, ...)? What makes it different? What's the most awesome feature it
has? Where can I find more information on it?
Read the [App Specification](https://github.com/addyosmani/todomvc/wiki/App-Specification) before touching the template. ## Implementation
How is the app structured? Are there deviations from the spec? If so, why?
## Need help? ## Running
Feel free to [contact us](https://github.com/sindresorhus) if you have any questions or need help with the template. If there is a build step required to get the example working, explain it here.
To run the app, spin up an HTTP server and visit
## Credit http://localhost/.../myexample/.
Created by [Sindre Sorhus](http://sindresorhus.com)
# Template • [TodoMVC](http://todomvc.com)
## Getting Started
Read the [App Specification](https://github.com/addyosmani/todomvc/wiki/App-Specification) before touching the template.
## Need help?
Feel free to contact [Sindre](https://github.com/sindresorhus) or [Pascal](https://github.com/passy) if you have any questions or need help with the template.
## Credit
Created by [Sindre Sorhus](http://sindresorhus.com)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment