From 8698a276f937cb1cd6f67f7f213e2ea438500d7e Mon Sep 17 00:00:00 2001
From: Brandon Mathis <brandon@imathis.com>
Date: Mon, 30 May 2011 00:30:16 -0400
Subject: Cleaned out public from repository, updated gitignore, added syntax
 highlighting tests, improved syntax highlighting and styling of pre blocks.
 Overriding dynamic gist styling. Added a plugin for pygments caching which
 should speed things up terrifically. added ender.js as a lightweight way of
 scripting the DOM, events, etc. Some general typography and semantic html
 improvements.

---
 source/_includes/article.html                      |   35 +-
 source/_includes/footer.html                       |    6 +-
 source/_includes/head.html                         |   23 +-
 source/_includes/sidebar.html                      |    4 +-
 source/_layouts/archive_monthly.html               |   19 +
 source/_layouts/archive_yearly.html                |   25 +
 source/_layouts/default.html                       |   15 +-
 source/_layouts/page.html                          |    3 +
 source/_layouts/post.html                          |    1 +
 source/_posts/2009-11-13-hello-world.markdown      |    6 +-
 source/about.haml                                  |    1 +
 source/archive.html                                |   24 +
 source/index.html                                  |    1 -
 .../javascripts/libs/DOMAssistantCompressed-2.8.js |    4 -
 source/javascripts/libs/ender.js                   | 1497 +++++++++++++++++++
 source/javascripts/libs/ender.min.js               |    8 +
 .../libs/ie/DOMAssistantComplete-2.8.js            | 1529 ++++++++++++++++++++
 source/javascripts/libs/ie/respond.js              |  292 ++++
 source/javascripts/libs/ie/selectivizr-1.0.1.js    |    5 +
 .../libs/ios-viewport-scaling-bug-fix.js           |   28 +-
 source/javascripts/libs/jXHR.js                    |   85 ++
 source/javascripts/libs/json2.js                   |  481 ++++++
 source/javascripts/libs/modernizr-1.7.js           |  964 ++++++++++++
 source/javascripts/libs/modernizr-1.7.min.js       |    2 -
 source/javascripts/libs/respond.js                 |    8 -
 source/javascripts/libs/selectivizr-min.js         |    5 -
 source/javascripts/pinboard.js                     |    8 +-
 source/javascripts/syntax-helper.js                |   30 +
 source/javascripts/twitter.js                      |   14 +-
 source/test/syntax.html                            |  397 +++++
 source/test/syntax.markdown                        |  228 ---
 31 files changed, 5435 insertions(+), 313 deletions(-)
 create mode 100644 source/_layouts/archive_monthly.html
 create mode 100644 source/_layouts/archive_yearly.html
 create mode 100644 source/archive.html
 delete mode 100644 source/javascripts/libs/DOMAssistantCompressed-2.8.js
 create mode 100644 source/javascripts/libs/ender.js
 create mode 100644 source/javascripts/libs/ender.min.js
 create mode 100644 source/javascripts/libs/ie/DOMAssistantComplete-2.8.js
 create mode 100644 source/javascripts/libs/ie/respond.js
 create mode 100644 source/javascripts/libs/ie/selectivizr-1.0.1.js
 create mode 100644 source/javascripts/libs/jXHR.js
 create mode 100644 source/javascripts/libs/json2.js
 create mode 100644 source/javascripts/libs/modernizr-1.7.js
 delete mode 100644 source/javascripts/libs/modernizr-1.7.min.js
 delete mode 100644 source/javascripts/libs/respond.js
 delete mode 100755 source/javascripts/libs/selectivizr-min.js
 create mode 100644 source/javascripts/syntax-helper.js
 create mode 100644 source/test/syntax.html
 delete mode 100644 source/test/syntax.markdown

(limited to 'source')

diff --git a/source/_includes/article.html b/source/_includes/article.html
index 92f06720..3481cf21 100644
--- a/source/_includes/article.html
+++ b/source/_includes/article.html
@@ -1,18 +1,27 @@
 <header>
-  <h1><a href="{{ page.url }}">{{ page.title }}</a></h1>
-  <p>
-    {% if site.author or site.author == page.author %}
-      <span class="byline author vcard">By <span class="fn">{{ site.author }}</span></span>
-    {% elsif page.author %}
-      <span class="byline author vcard">By <span class="fn">{{ page.author }}</span></span>
+  {% if index %}
+    <h1><a href="{{ page.url }}">{{ page.title }}</a></h1>
+  {% else %}
+    <h1>{{ page.title }}</h1>
+  {% endif %}
+  {% unless page.nometa %}
+    {% if page.author %}
+      {% assign author = page.author %}
+    {% else %}
+      {% assign author = site.author %}
     {% endif %}
-    {% if page.date %}
-      <time datetime="{{ page.date | datetime }}" pubdate>{{ page.date | ordinalize }}</time>
-    {% endif %}
-    {% if page.updated %}
-      <time class="updated" datetime="{{ page.updated | datetime }}" pubdate>Updated {{ page.updated | ordinalize }}</time>
-    {% endif %}
-  </p>
+    <p>
+      {% if author %}
+        <span class="byline author vcard">By <span class="fn">{{ author }}</span></span>
+      {% endif %}
+      {% if page.date %}
+        <time datetime="{{ page.date | datetime }}" pubdate>{{ page.date | ordinalize }}</time>
+      {% endif %}
+      {% if page.updated %}
+        <time class="updated" datetime="{{ page.updated | datetime }}" pubdate>Updated {{ page.updated | ordinalize }}</time>
+      {% endif %}
+    </p>
+  {% endunless %}
 </header>
 {% if index %}
 <div class="entry">{{ content | exerpt(content, page.url, 'Continue reading &raquo;') | smart_quotes }}</div>
diff --git a/source/_includes/footer.html b/source/_includes/footer.html
index de560edc..5b40083e 100644
--- a/source/_includes/footer.html
+++ b/source/_includes/footer.html
@@ -3,9 +3,9 @@
   <span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>
 </p>
 {% if site.pinboard_user %}
+  <script language="javascript" src="/javascripts/pinboard.js"></script>
   <script language="javascript">
-    var pinboard_user = "{{ site.pinboard_user }}";
-    var pinboard_count = "{{ site.pinboard_count }}";
+    var linkroll = 'pinboard_linkroll'; //id target for pinboard list
+    pinboardNS_fetch_script("http://feeds.pinboard.in/json/v1/u:{{ site.pinboard_user }}/?cb=pinboardNS_show_bmarks\&count={{ site.pinboard_count }}");
   </script>
-  <script language="javascript" src="/javascripts/pinboard.js"></script>
 {% endif %}
diff --git a/source/_includes/head.html b/source/_includes/head.html
index 1d3329ba..b311ca69 100644
--- a/source/_includes/head.html
+++ b/source/_includes/head.html
@@ -1,7 +1,16 @@
+<!DOCTYPE html>
+<!--[if IEMobile 7 ]><html class="no-js iem7" manifest="default.appcache?v=1"><![endif]-->
+<!--[if lt IE 7 ]><html class="no-js ie6" lang="en"><![endif]-->
+<!--[if IE 7 ]><html class="no-js ie7" lang="en"><![endif]-->
+<!--[if IE 8 ]><html class="no-js ie8" lang="en"><![endif]-->
+<!--[if (gte IE 9)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" manifest="default.appcache?v=1" lang="en"><!--<![endif]-->
 <head>
   <meta charset="utf-8">
-
-  <title>{{page.title}} - {{site.title}}</title>
+  {% if page.title %}
+    <title>{{site.title}}: {{page.title}}{% if site.author %} - {{ site.author }}{% endif %}</title>
+  {% else %}
+    <title>{{site.title}}{% if site.author %} - {{ site.author }}{% endif %}</title>
+  {% endif %}
   <meta name="author" content="{{site.author}}">
   {% if page.description %}
     <meta name="description" content="{{page.description}}"/>
@@ -10,7 +19,7 @@
   <!-- http://t.co/dKP3o1e -->
   <meta name="HandheldFriendly" content="True">
   <meta name="MobileOptimized" content="320">
-  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
 
   {% if page.keywords %}
     <meta name="keywords" content="{{page.keywords}}"/>
@@ -18,8 +27,12 @@
 
   <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
   <!--<script src="/javascripts/octopress.js" type="text/javascript"></script>-->
-  <script src="javascripts/libs/modernizr-1.7.min.js"></script>
-  <script src="javascripts/libs/ios-viewport-scaling-bug-fix.js"></script>
+  <script src="/javascripts/libs/modernizr-1.7.js"></script>
+  <script src="/javascripts/libs/ios-viewport-scaling-bug-fix.js"></script>
+  <script src="/javascripts/libs/json2.js"></script>
+  <script src="/javascripts/libs/jXHR.js"></script>
+  <script src="/javascripts/libs/ender.js"></script>
+  <script src="/javascripts/syntax-helper.js"></script>
   {% if site.google_analytics_tracking_id %}
     {% include google_analytics.html %}
   {% endif %}
diff --git a/source/_includes/sidebar.html b/source/_includes/sidebar.html
index c5e3bd01..03890462 100644
--- a/source/_includes/sidebar.html
+++ b/source/_includes/sidebar.html
@@ -2,14 +2,13 @@
   <h1>About Me</h1>
   <p>Hi, I'm Octopress!</p>
 </section>
-{% if site.recent_posts %}
+{% if page.single and site.recent_posts %}
 <section>
   <h1>Recent Posts</h1>
   <ul id="recent_posts">
     {% for post in site.posts limit: site.recent_posts %}
       <li class="post">
         <a href="{{ post.url }}">{{ post.title }}</a>
-        <time>{{ post.date | date: "%B %d, %Y" }}</time>
       </li>
     {% endfor %}
   </ul>
@@ -24,3 +23,4 @@
 {% if site.pinboard_user %}
   <section>{% include pinboard.html %}</section>
 {% endif %}
+
diff --git a/source/_layouts/archive_monthly.html b/source/_layouts/archive_monthly.html
new file mode 100644
index 00000000..85ada6d8
--- /dev/null
+++ b/source/_layouts/archive_monthly.html
@@ -0,0 +1,19 @@
+---
+layout: default
+---
+<div id="content">
+  <div class="post">
+    <h1 class="post-title">{{ page.month | date_to_month }} {{ page.year }}</h1>
+    <p class="lead">Posts from {{ page.month | date_to_month }}, {{ page.year }}</p>
+    <ul>
+      {% for d in (1..31) reversed %}
+      {% if page.collated_posts[page.year][page.month][d] %}
+      {% for p in page.collated_posts[page.year][page.month][d] reversed %}
+      <li><a href='{{ p.url }}'>{{ p.title }}</a></li>
+      {% endfor %}
+      {% endif %}
+      {% endfor %}
+    </ul>
+  </div>
+</div>
+
diff --git a/source/_layouts/archive_yearly.html b/source/_layouts/archive_yearly.html
new file mode 100644
index 00000000..dabebebd
--- /dev/null
+++ b/source/_layouts/archive_yearly.html
@@ -0,0 +1,25 @@
+---
+layout: default
+---
+<div id="content">
+	<div class="post">
+		<h1 class="post-title">{{ page.year }}</h1>
+		<p class="lead">Posts from the year {{ page.year }}</p>
+		{% for m in (1..12) reversed %}
+			{% if page.collated_posts[page.year][m] %}
+				<h3>{{ m | date_to_month }}</h3>
+				{% for d in (1..31) reversed %}
+					{% if page.collated_posts[page.year][m][d] %}
+						{% for p in page.collated_posts[page.year][m][d] reversed %}
+							<div>
+								<strong>{{ p.date | date: "%d" }}</strong>
+								<a href='{{ p.url }}'>{{ p.title }}</a>
+							</div>
+						{% endfor %}
+					{% endif %}
+				{% endfor %}
+			{% endif %}
+		{% endfor %}
+	</div>
+</div>
+
diff --git a/source/_layouts/default.html b/source/_layouts/default.html
index f69043b7..06fdbd77 100644
--- a/source/_layouts/default.html
+++ b/source/_layouts/default.html
@@ -1,9 +1,6 @@
-<!DOCTYPE html>
-<!--[if IEMobile 7 ]><html class="no-js iem7" manifest="default.appcache?v=1"><![endif]-->
-<!--[if lt IE 7 ]><html class="no-js ie6" lang="en"><![endif]-->
-<!--[if IE 7 ]><html class="no-js ie7" lang="en"><![endif]-->
-<!--[if IE 8 ]><html class="no-js ie8" lang="en"><![endif]-->
-<!--[if (gte IE 9)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" manifest="default.appcache?v=1" lang="en"><!--<![endif]-->
+---
+permalink: /blog/:year/:month/:day/:title
+---
 {% include head.html %}
 <body {% if page.body_id %} id="{{ page.body_id }}" {% endif %} {% if page.no_sidebar %} class="no-sidebar" {% endif %}>
   <header><div>{% include header.html %}</div></header>
@@ -18,9 +15,9 @@
   </div>
   <footer><div>{% include footer.html %}</div></footer>
   <!--[if (lt IE 9) & (!IEMobile)]>
-  <script src="javascripts/libs/DOMAssistantCompressed-2.8.js"></script>
-  <script src="javascripts/libs/selectivizr-1.0.1.js"></script>
-  <script src="javascripts/libs/respond.min.js"></script>
+  <script src="javascripts/libs/ie/DOMAssistantCompressed-2.8.js"></script>
+  <script src="javascripts/libs/ie/selectivizr-1.0.1.js"></script>
+  <script src="javascripts/libs/ie/respond.min.js"></script>
   <![endif]-->
 </body>
 </html>
diff --git a/source/_layouts/page.html b/source/_layouts/page.html
index 3b568349..88d6e13a 100644
--- a/source/_layouts/page.html
+++ b/source/_layouts/page.html
@@ -1,5 +1,8 @@
 ---
 layout: default
+no_title_link: true
+permalink: pretty
+single: true
 ---
 
 <article>
diff --git a/source/_layouts/post.html b/source/_layouts/post.html
index 3b568349..d2c87ce3 100644
--- a/source/_layouts/post.html
+++ b/source/_layouts/post.html
@@ -1,5 +1,6 @@
 ---
 layout: default
+single: true
 ---
 
 <article>
diff --git a/source/_posts/2009-11-13-hello-world.markdown b/source/_posts/2009-11-13-hello-world.markdown
index 011368d3..af719856 100644
--- a/source/_posts/2009-11-13-hello-world.markdown
+++ b/source/_posts/2009-11-13-hello-world.markdown
@@ -7,9 +7,9 @@ updated: March 10th, 2010
 **Octopress is a blogging framework designed for hackers**, based on [Jekyll](http://github.com/mojombo/jekyll) the blog aware static site generator powering [Github pages](http://pages.github.com/).
 If you don't know what Jekyll is, [Jack Moffitt](http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/) wrote a good summary:
 
-> Jekyll is a static blog generator; it transforms a directory of input files into another directory of files suitable for a blog. The management of the blog is handled by standard, familiar tools like creating and renaming files, the text editor of your choice, and version control.
-
-<cite>**Jack Moffitt** [Blogging with Git Emacs and Jekyll](http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/)</cite>
+{% blockquote Jack Moffitt http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/ Blogging with Git Emacs and Jekyll %}
+  Jekyll is a static blog generator; it transforms a directory of input files into another directory of files suitable for a blog. The management of the blog is handled by standard, familiar tools like creating and renaming files, the text editor of your choice, and version control.
+{% endblockquote %}
 
 There's no database to set up, and you get to use tools like Emacs, Vim, or TextMate to write your posts, not some lame in-browser text editor. Just write, generate, deploy, using the same tools and patterns you already use for your daily work.
 
diff --git a/source/about.haml b/source/about.haml
index b0e9fd60..bbd5a9c6 100644
--- a/source/about.haml
+++ b/source/about.haml
@@ -2,6 +2,7 @@
 layout: default
 title: About Me
 layout: page
+description: this is about me
 date: May 14 2011
 ---
 / use the :mardown filter if you want to write pages with Markdown
diff --git a/source/archive.html b/source/archive.html
new file mode 100644
index 00000000..98518aa5
--- /dev/null
+++ b/source/archive.html
@@ -0,0 +1,24 @@
+---
+layout: page
+title: Blog Archive
+nometa: true
+---
+{% for post in site.posts reverse %}
+  {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
+  {% capture this_month %}{{ post.date | date: "%B" }}{% endcapture %}
+  {% unless year == this_year %}
+    {% unless forloop.first %}</ul>{% endunless %}
+    {% assign year = this_year %}
+    <h2>{{ year }}</h2>
+    <ul class="blog_archives">
+  {% endunless %}
+  {% unless month == this_month %}
+    {% assign month = this_month %}
+    <li><h4>{{ month }}</h4></li>
+  {% endunless %}
+  <li>
+    <time datetime="{{ post.date | datetime }}" pubdate>{{ post.date | date: "%d"}}</time>
+    <a href="{{ post.url }}">{{post.title}}</a>
+  </li>
+  {% if forloop.last %}</ul>{% endif %}
+{% endfor %}
diff --git a/source/index.html b/source/index.html
index 03b6b9c1..09eb8d13 100644
--- a/source/index.html
+++ b/source/index.html
@@ -1,6 +1,5 @@
 ---
 layout: default
-title: Octopress
 ---
 {% for page in site.posts limit:3 %}
 {% assign content = page.content %}
diff --git a/source/javascripts/libs/DOMAssistantCompressed-2.8.js b/source/javascripts/libs/DOMAssistantCompressed-2.8.js
deleted file mode 100644
index ff9ef9e0..00000000
--- a/source/javascripts/libs/DOMAssistantCompressed-2.8.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Developed by Robert Nyman/DOMAssistant team, code/licensing: http://domassistant.googlecode.com/, documentation: http://www.domassistant.com/documentation, version 2.8
-var DOMAssistant=function(){var j=function(){},o=window,g=o.$,k=o.$$,d=/*@cc_on!@*/false,i=d&&parseFloat(navigator.appVersion)<6,h,c={},q={},a=true,n=Array.prototype.slice,p={accesskey:"accessKey","class":"className",colspan:"colSpan","for":"htmlFor",maxlength:"maxLength",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",valign:"vAlign",cellspacing:"cellSpacing",cellpadding:"cellPadding"},m={rules:/\s*,\s*/g,selector:/^(\w+|\*)?(#[\w\u00C0-\uFFFF\-=$]+)?((\.[\w\u00C0-\uFFFF\-]+)*)?((\[\w+\s*([~^$*|])?(=\s*([-\w\u00C0-\uFFFF\s.]+|"[^"]*"|'[^']*'))?\]+)*)?((:\w[-\w]*(\((odd|even|\-?\d*n?([-+]\d+)?|[:#]?[-\w\u00C0-\uFFFF.]+|"[^"]*"|'[^']*'|((\w*\.[-\w\u00C0-\uFFFF]+)*)?|(\[#?\w+([~^$*|])?=?[-\w\u00C0-\uFFFF\s.'"]+\]+)|(:\w[-\w]*\(.+\)))\))?)*)?([+>~])?/,selectorSplit:/(?:\[.*\]|\(.*\)|[^\s+>~[(])+|[+>~]/g,id:/^#([-\w\u00C0-\uFFFF=$]+)$/,tag:/^\w+/,relation:/^[+>~]$/,pseudo:/^:(\w[-\w]*)(\((.+)\))?$/,pseudos:/:(\w[-\w]*)(\((([^(]+)|([^(]+\([^(]+)\))\))?/g,attribs:/\[(\w+)\s*([~^$*|])?(=)?\s*([^\[\]]*|"[^"]*"|'[^']*')?\](?=$|\[|:|\s)/g,classes:/\.([-\w\u00C0-\uFFFF]+)/g,quoted:/^["'](.*)["']$/,nth:/^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n([-+]\d+)?)|(-(([1-9]\d*)?)n\+(\d+)))$/,special:/(:check|:enabl|\bselect)ed\b/},f=function(t,u,r){var s=t.tagName;while((t=t[u+"Sibling"])&&(t.nodeType!==1||(r?t.tagName!==s:t.tagName==="!"))){}return t},b=function(r){return typeof r!=="undefined"},l=function(r){return(l=r[0].compareDocumentPosition?function(s){return s.sort(function(u,t){return 3-(u.compareDocumentPosition(t)&6)})}:d?function(s){return s.sort(function(u,t){return u.sourceIndex-t.sourceIndex})}:function(s){return s.sort(function(w,u){var v=document.createRange(),t=document.createRange();v.setStart(w,0);v.setEnd(w,0);t.setStart(u,0);t.setEnd(u,0);return v.compareBoundaryPoints(Range.START_TO_END,t)})})(r)};var e=function(s,r){s.push.apply(s,n.apply(r));return s};if(d){e=function(t,s){if(s.slice){return t.concat(s)}var r=0,u;while((u=s[r++])){t[t.length]=u}return t}}return{isIE:d,camel:p,def:b,allMethods:[],publicMethods:["prev","next","hasChild","cssSelect","elmsByClass","elmsByAttribute","elmsByTag"],harmonize:function(){o.$=g;o.$$=k;return this},initCore:function(){this.applyMethod.call(o,"$",this.$);this.applyMethod.call(o,"$$",this.$$);o.DOMAssistant=this;if(d){j=Array}j.prototype=[];(function(r){r.each=function(v,u){for(var t=0,s=this.length;t<s;t++){if(v.call(u||this[t],this[t],t,this)===false){break}}return this};r.first=function(){return b(this[0])?DOMAssistant.addMethodsToElm(this[0]):null};r.end=function(){return this.previousSet};r.indexOf=r.indexOf||function(u){for(var t=0,s=this.length;t<s;t++){if(t in this&&this[t]===u){return t}}return -1};r.map=function(w,v){var u=[];for(var t=0,s=this.length;t<s;t++){if(t in this){u[t]=w.call(v||this[t],this[t],t,this)}}return u};r.filter=function(w,v){var u=new j();u.previousSet=this;for(var t=0,s=this.length;t<s;t++){if(t in this&&w.call(v||this[t],this[t],t,this)){u.push(this[t])}}return u};r.every=function(v,u){for(var t=0,s=this.length;t<s;t++){if(t in this&&!v.call(u||this[t],this[t],t,this)){return false}}return true};r.some=function(v,u){for(var t=0,s=this.length;t<s;t++){if(t in this&&v.call(u||this[t],this[t],t,this)){return true}}return false}})(j.prototype);this.attach(this)},addMethods:function(r,s){if(!b(this.allMethods[r])){this.allMethods[r]=s;this.addHTMLArrayPrototype(r,s)}},addMethodsToElm:function(s){for(var r in this.allMethods){if(b(this.allMethods[r])){this.applyMethod.call(s,r,this.allMethods[r])}}return s},applyMethod:function(s,r){if(typeof this[s]!=="function"){this[s]=r}},attach:function(t){var r=t.publicMethods;if(!b(r)){for(var v in t){if(v!=="init"&&b(t[v])){this.addMethods(v,t[v])}}}else{if(r.constructor===Array){for(var s=0,u;(u=r[s]);s++){this.addMethods(u,t[u])}}}if(typeof t.init==="function"){t.init()}},addHTMLArrayPrototype:function(r,s){j.prototype[r]=function(){var v=new j();v.previousSet=this;for(var u=0,t=this.length;u<t;u++){v.push(s.apply(DOMAssistant.$$(this[u]),arguments))}return v}},cleanUp:function(u){var s=u.all||u.getElementsByTagName("*");for(var r=0,t;(t=s[r++]);){if(t.hasData&&t.hasData()){if(t.removeEvent){t.removeEvent()}t.unstore()}}u.innerHTML=""},setCache:function(r){a=r},$:function(){var u=arguments[0];if(arguments.length===1&&(typeof u==="object"||(typeof u==="function"&&!!u.nodeName))){return DOMAssistant.$$(u)}var w=!!u?new j():null;for(var s=0,r,v;(r=arguments[s]);s++){if(typeof r==="string"){r=r.replace(/^[^#\(]*(#)/,"$1");if(m.id.test(r)){if((v=DOMAssistant.$$(r.substr(1),false))){w.push(v)}}else{var t=(document.all||document.getElementsByTagName("*")).length;w=(!document.querySelectorAll&&a&&q.rule&&q.rule===r&&q.doc===t)?q.elms:e(w,DOMAssistant.cssSelection.call(document,r));q={rule:r,elms:w,doc:t}}}}return w},$$:function(x,u){var w=(typeof x==="object"||typeof x==="function"&&!!x.nodeName)?x:document.getElementById(x),v=b(u)?u:true,t=function(z){var y=z.id;return typeof y!=="object"?y:z.attributes.id.nodeValue};if(typeof x==="string"&&w&&t(w)!==x){w=null;for(var r=0,s;(s=document.all[r]);r++){if(t(s)===x){w=s;break}}}if(w&&v&&!w.next){DOMAssistant.addMethodsToElm(w)}return w},prev:function(){return DOMAssistant.$$(f(this,"previous"))},next:function(){return DOMAssistant.$$(f(this,"next"))},hasChild:function(r){return this===document||this!==r&&(this.contains?this.contains(r):!!(this.compareDocumentPosition(r)&16))},getSequence:function(v){var w,u=2,s=-1,r=-1,t=m.nth.exec(v.replace(/^0n\+/,"").replace(/^2n$/,"even").replace(/^2n+1$/,"odd"));if(!t){return null}if(t[2]){w=(t[2]==="odd")?1:2;r=(w===1)?1:0}else{if(t[3]){w=s=parseInt(t[3],10);u=0}else{if(t[4]){u=t[6]?parseInt(t[6],10):1;w=t[7]?parseInt(t[7],10):0;while(w<1){w+=u}r=(w>=u)?(w-u)%u:w}else{if(t[8]){u=t[10]?parseInt(t[10],10):1;w=s=parseInt(t[11],10);while(w>u){w-=u}r=(s>=u)?(s-u)%u:s}}}}return{start:w,add:u,max:s,modVal:r}},cssByDOM:function(v){var aU,I,D,N,av,x,ah,A,K,w,aq,aN,y,aI,at,aB=new j(),aR=aB.indexOf,ap=[],aG=[],aK=v.replace(m.rules,",").split(","),aF={};function aQ(s){s=s||ap;for(var r=s.length;r--;){s[r].added=null;s[r].removeAttribute("added")}}function C(){for(var r=aU.length;r--;){aU[r].childElms=null}}function am(t,r){for(var u=0,aX;(aX=t[u]);u++){var aW=false;for(var s=0,aV;(aV=r[s]);s++){if(aV===aX){aW=true;r.splice(s,1);break}}if(aW){t.splice(u--,1)}}return t}function E(s,r){return(d||m.special.test(r))?s[p[r.toLowerCase()]||r]:s.getAttribute(r,2)}function P(r,s){r=r?r.replace(m.quoted,"$1").replace(/(\.|\[|\])/g,"\\$1"):null;return{"^":"^"+r,"$":r+"$","*":r,"|":"^"+r+"(\\-\\w+)*$","~":"\\b"+r+"\\b"}[s]||(r!==null?"^"+r+"$":r)}function W(r){return(r||this).tagName!=="!"}function S(r,s){return i?(r==="*"?s.all:s.all.tags(r)):s.getElementsByTagName(r)}function aL(r,s){r=r||"*";s=s||document;return(s===document||s.lastModified)?c[r]||(c[r]=S(r,document)):S(r,s)}function ar(aX,bf,u){aU=[];var aV=bf.split("-"),a0=[],a5=0,be=/\-of\-type$/.test(bf),a4,aZ={first:function(bg){return !f(bg,"previous",be)},last:function(bg){return !f(bg,"next",be)},empty:function(bg){return !bg.firstChild},enabled:function(bg){return !bg.disabled&&bg.type!=="hidden"},disabled:function(bg){return bg.disabled},checked:function(bg){return bg.checked},contains:function(bg){return(bg.innerText||bg.textContent||"").indexOf(u.replace(m.quoted,"$1"))>-1},other:function(bg){return E(bg,bf)===u}};function t(bg){while((A=aX[a5++])){if(W(A)&&aZ[bg](A)){a0[a0.length]=A}}return a0}var bb=aV[0]||null;if(bb&&aZ[bb]){return t(bb)}switch(bb){case"only":var a1,aW;while((A=aX[a5++])){K=A.parentNode;var a6=A.nodeName;if(K!==a1||a6!==aW){if(aZ.first(A)&&aZ.last(A)){a0[a0.length]=A}a1=K;aW=a6}}break;case"nth":if(u==="n"){a0=aX}else{var bd=(aV[1]==="last")?["lastChild","previousSibling"]:["firstChild","nextSibling"];aI=DOMAssistant.getSequence(u);if(aI){while((A=aX[a5++])){K=A.parentNode;K.childElms=K.childElms||{};var a7=A.nodeName;if(!K.childElms[a7]){var ba=0;aN=aI.start;y=K[bd[0]];while(y&&(aI.max<0||aN<=aI.max)){var bc=y.nodeName;if((be&&bc===a7)||(!be&&y.nodeType===1&&bc!=="!")){if(++ba===aN){if(bc===a7){a0[a0.length]=y}aN+=aI.add}}y=y[bd[1]]}if(at){h++}K.childElms[a7]=true;aU[aU.length]=K}}C()}}break;case"target":var s=document.location.hash.slice(1);if(s){while((A=aX[a5++])){if(E(A,"name")===s||E(A,"id")===s){a0[a0.length]=A;break}}}break;case"not":if((a4=m.pseudo.exec(u))){a0=am(aX,ar(aX,a4[1]?a4[1].toLowerCase():null,a4[3]||null))}else{for(var a8 in m){if(m[a8].lastIndex){m[a8].lastIndex=0}}u=u.replace(m.id,"[id=$1]");var a3=m.tag.exec(u);var aY=m.classes.exec(u);var a2=m.attribs.exec(u);var r=new RegExp(a2?P(a2[4],a2[2]):"(^|\\s)"+(a3?a3[0]:aY?aY[1]:"")+"(\\s|$)","i");while((w=aX[a5++])){aq=null;if(a3&&!r.test(w.nodeName)||aY&&!r.test(w.className)){aq=w}else{if(a2){var a9=E(w,a2[1]);if(!b(a9)||a9===false||typeof a9==="string"&&!r.test(a9)){aq=w}}}if(aq&&!aq.added){aq.added=true;a0[a0.length]=aq}}}break;default:return t("other")}return a0}function Z(aV,t){var r=0,u=aV,aW;while((aW=t[r++])){if(!u.length||u.indexOf(aW)<0){aV.push(aW)}}return aV}h=-1;for(var ak=0,aJ=[];(I=aK[ak]);ak++){if(!(D=I.match(m.selectorSplit))||ak&&aR.call(aK.slice(0,ak),I)>-1){continue}ap=[this];for(var ai=0,G;(G=D[ai]);ai++){aG=[];if((N=m.relation.exec(G))){var an=null,aS=D[ai+1];if((av=m.tag.exec(aS))){av=av[0];x=new RegExp("(^|\\s)"+av+"(\\s|$)","i")}else{if(m.id.test(aS)){an=DOMAssistant.$(aS)||null}}for(var ag=0,M;(M=ap[ag]);ag++){switch(N[0]){case">":var aD=an||aL(av,M);for(var ae=0,ay;(ay=aD[ae]);ae++){if(ay.parentNode===M){aG[aG.length]=ay}}break;case"+":if((M=f(M,"next"))){if((an&&an[0]===M)||(!an&&(!av||x.test(M.nodeName)))){aG[aG.length]=M}}break;case"~":while((M=M.nextSibling)&&!M.added){if((an&&an[0]===M)||(!an&&(!av||x.test(M.nodeName)))){M.added=true;aG[aG.length]=M}}break}}ap=aG;aQ();G=D[++ai];if(/^\w+$/.test(G)||m.id.test(G)){continue}ap.skipTag=true}var au=m.selector.exec(G);aF={tag:au[1]?au[1]:"*",id:au[2],allClasses:au[3],allAttr:au[5],allPseudos:au[10]};at=(aF.tag==="*");if(aF.id){var O=0,al=document.getElementById(aF.id.slice(1));if(al){while(ap[O]&&!DOMAssistant.hasChild.call(ap[O],al)){O++}aG=(O<ap.length&&(at||aF.tag===al.tagName.toLowerCase()))?[al]:[]}ap=aG}else{if(aF.tag&&!ap.skipTag){if(ai===0&&!aG.length&&ap.length===1){ap=aG=e([],aL(aF.tag,ap[0]))}else{for(var ad=0,aO=ap.length,az,aw;ad<aO;ad++){az=aL(aF.tag,ap[ad]);for(var aa=0;(aw=az[aa]);aa++){if(!aw.added){aw.added=true;aG[aG.length]=aw}}}ap=aG;aQ()}}}if(!aG.length){break}ap.skipTag=false;if(aF.allClasses){var Y=0,ab=[],J=aF.allClasses.split(".").slice(1);while((ah=ap[Y++])){var af=true,ax=ah.className;if(ax&&ax.length){ax=ax.split(" ");for(var X=J.length;X--;){if(ax.indexOf(J[X])<0){af=false;break}}if(af){ab[ab.length]=ah}}}ap=aG=ab}if(aF.allAttr){var B,T=0,aC=[],ac=[],aH=aF.allAttr.match(m.attribs);for(var H=/^\[(selected|readonly)(\s*=.+)?\]$/,V=0,z=aH.length,U,aP;V<z;V++){m.attribs.lastIndex=0;U=m.attribs.exec(aH[V].replace(H,"[$1]"));aP=P(U[4],U[2]||null);aC[V]=[(aP?new RegExp(aP):null),U[1]]}while((ah=aG[T++])){for(var R=0,aE=aC.length;R<aE;R++){var aA=aC[R][0],aj=E(ah,aC[R][1]);B=true;if(!aA&&aj===true){continue}if((!aA&&(!aj||typeof aj!=="string"||!aj.length))||(!!aA&&!aA.test(aj))){B=false;break}}if(B){ac[ac.length]=ah}}ap=aG=ac}if(aF.allPseudos){var F=aF.allPseudos.match(m.pseudos);for(var Q=0,ao=F.length;Q<ao;Q++){m.pseudos.lastIndex=0;var aT=m.pseudos.exec(F[Q]);var L=aT[1]?aT[1].toLowerCase():null;var aM=aT[3]||null;aG=ar(aG,L,aM);aQ(aG)}ap=aG}}aB=((aJ.length&&(at||aR.call(aJ,aF.tag)>=0||aR.call(aJ,"*")>=0))?Z:e)(aB,ap);aJ.push(aF.tag);if(d&&at){aB=aB.filter(W)}}return((aB.length>1&&aK.length>1)||h>0)?l(aB):aB},cssByXpath:function(s){var t={xhtml:"http://www.w3.org/1999/xhtml"},u=(document.documentElement.namespaceURI===t.xhtml)?"xhtml:":"",r=function v(w){return t[w]||null};DOMAssistant.cssByXpath=function(N){var R,T,J,z,A,E,B=new j(),C=N.replace(m.rules,",").split(",");function M(W){var X=W?"[":"",V=W?"]":"";return function(Y,ac,ab,aa,Z){Z=(Z||"").replace(m.quoted,"$1");if(ac===Z&&ac==="readonly"){aa=null}return X+({"^":"starts-with(@"+ac+', "'+Z+'")',"$":"substring(@"+ac+", (string-length(@"+ac+") - "+(Z.length-1)+"), "+Z.length+') = "'+Z+'"',"*":'contains(concat(" ", @'+ac+', " "), "'+Z+'")',"|":"@"+ac+'="'+Z+'" or starts-with(@'+ac+', "'+Z+'-")',"~":'contains(concat(" ", @'+ac+', " "), " '+Z+' ")'}[ab]||("@"+ac+(aa?'="'+Z+'"':"")))+V}}function P(W,Y,X){W=/\-child$/.test(Y)?"*":W;var aa=Y.split("-"),V=((aa[1]==="last")?"(count(following-sibling::":"(count(preceding-sibling::")+W+") + 1)",Z,ab;switch(aa[0]){case"nth":return(X!=="n"&&(E=DOMAssistant.getSequence(X)))?((E.start===E.max)?V+" = "+E.start:V+" mod "+E.add+" = "+E.modVal+((E.start>1)?" and "+V+" >= "+E.start:"")+((E.max>0)?" and "+V+" <= "+E.max:"")):"";case"not":return"not("+((Z=m.pseudo.exec(X))?P(W,Z[1]?Z[1].toLowerCase():null,Z[3]||null):X.replace(m.id,"[id=$1]").replace(m.tag,"self::$0").replace(m.classes,'contains(concat(" ", @class, " "), " $1 ")').replace(m.attribs,M()))+")";case"first":return"not(preceding-sibling::"+W+")";case"last":return"not(following-sibling::"+W+")";case"only":return"not(preceding-sibling::"+W+" or following-sibling::"+W+")";case"empty":return"not(child::*) and not(text())";case"contains":return'contains(., "'+X.replace(m.quoted,"$1")+'")';case"enabled":return'not(@disabled) and not(@type="hidden")';case"disabled":return"@disabled";case"target":return'@name="'+(ab=document.location.hash.slice(1))+'" or @id="'+ab+'"';default:return"@"+Y+'="'+X+'"'}}for(var O=0;(R=C[O]);O++){if(!(T=R.match(m.selectorSplit))||O&&B.indexOf.call(C.slice(0,O),R)>-1){continue}J=J?J+" | .":".";for(var L=0,Q=T.length;L<Q;L++){z=m.selector.exec(T[L]);A={tag:u+(z[1]?z[1]:"*"),id:z[2],allClasses:z[3],allAttr:z[5],allPseudos:z[10],tagRelation:z[20]};J+=(A.tagRelation?({">":"/","+":"/following-sibling::*[1]/self::","~":"/following-sibling::"}[A.tagRelation]||""):((L>0&&m.relation.test(T[L-1]))?A.tag:("//"+A.tag)))+(A.id||"").replace(m.id,'[@id = "$1"]')+(A.allClasses||"").replace(m.classes,'[contains(concat(" ", @class, " "), " $1 ")]')+(A.allAttr||"").replace(m.attribs,M(true));if(A.allPseudos){var D=A.allPseudos.match(m.pseudos);for(var K=0,x=D.length;K<x;K++){m.pseudos.lastIndex=0;var y=m.pseudos.exec(D[K]),U=y[1]?y[1].toLowerCase():null,w=y[3]||null,G=P(A.tag,U,w);if(G.length){J+="["+G+"]"}}}}}try{var I=document.evaluate(J,this,r,7,null),H,F=0;while((H=I.snapshotItem(F++))){B.push(H)}}catch(S){}return B};return DOMAssistant.cssByXpath.call(this,s)},cssSelection:function(s){if(!s){return null}var r=m.special.test(s);try{if(document.querySelectorAll&&!r){return e(new j(),this.querySelectorAll(s))}}catch(t){}return((document.evaluate&&!r&&!/-of-type/.test(s))?DOMAssistant.cssByXpath:DOMAssistant.cssByDOM).call(this,s)},cssSelect:function(r){return DOMAssistant.cssSelection.call(this,r)},elmsByClass:function(t,r){var s=(r||"")+"."+t;return DOMAssistant.cssSelection.call(this,s)},elmsByAttribute:function(s,t,r,v){var u=(r||"")+"["+s+((t&&t!=="*")?((v||"")+"="+t+"]"):"]");return DOMAssistant.cssSelection.call(this,u)},elmsByTag:function(r){return DOMAssistant.cssSelection.call(this,r)}}}();DOMAssistant.initCore();DOMAssistant.Storage=function(){var c=1,a=[],b="_da"+ +new Date();return{hasData:function(){var d=this[b];return !!d&&!!a[d]},retrieve:function(d){if(!DOMAssistant.def(d)){return this[b]||(this[b]=c++)}if(!this[b]||!a[this[b]]){return}return a[this[b]][d]},store:function(f,g){var e=this[b]||(this[b]=c++);a[e]=a[e]||{};if(typeof f==="object"){for(var d in f){if(typeof d==="string"){a[e][d]=f[d]}}}else{a[e][f]=g}return this},unstore:function(e){var d=this[b]||(this[b]=c++);if(a[d]){if(DOMAssistant.def(e)){delete a[d][e]}else{a[d]=null}}return this}}}();DOMAssistant.attach(DOMAssistant.Storage);DOMAssistant.AJAX=function(){var globalXMLHttp=null,readyState=0,status=-1,statusText="",requestPool=[],createAjaxObj=function(url,method,callback,addToContent){var params=null;if(/POST/i.test(method)){url=url.split("?");params=url[1];url=url[0]}return{url:url,method:method,callback:callback,params:params,headers:{},responseType:"text",addToContent:addToContent||false}};return{publicMethods:["ajax","get","post","load"],initRequest:function(){var XMLHttp=null;if(!!window.XMLHttpRequest&&!DOMAssistant.isIE){XMLHttp=new XMLHttpRequest();DOMAssistant.AJAX.initRequest=function(){return requestPool.length?requestPool.pop():new XMLHttpRequest()}}else{if(!!window.ActiveXObject){var XMLHttpMS=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];for(var i=0;i<XMLHttpMS.length;i++){try{XMLHttp=new window.ActiveXObject(XMLHttpMS[i]);DOMAssistant.AJAX.initRequest=function(){return requestPool.length?requestPool.pop():new window.ActiveXObject(XMLHttpMS[i])};break}catch(e){XMLHttp=null}}}}return XMLHttp},ajax:function(ajaxObj){if(!ajaxObj.noParse&&ajaxObj.url&&/\?/.test(ajaxObj.url)&&ajaxObj.method&&/POST/i.test(ajaxObj.method)){var url=ajaxObj.url.split("?");ajaxObj.url=url[0];ajaxObj.params=url[1]+((url[1].length>0&&ajaxObj.params)?("&"+ajaxObj.params):"")}return DOMAssistant.AJAX.makeCall.call(this,ajaxObj)},get:function(url,callback,addToContent){return DOMAssistant.AJAX.makeCall.call(this,createAjaxObj(url,"GET",callback,addToContent))},post:function(url,callback){return DOMAssistant.AJAX.makeCall.call(this,createAjaxObj(url,"POST",callback))},load:function(url,addToContent){this.get(url,DOMAssistant.AJAX.replaceWithAJAXContent,addToContent)},makeCall:function(ajaxObj){var XMLHttp=DOMAssistant.AJAX.initRequest();if(XMLHttp){globalXMLHttp=XMLHttp;(function(elm){var url=ajaxObj.url,method=ajaxObj.method||"GET",callback=ajaxObj.callback,params=ajaxObj.params,headers=ajaxObj.headers,responseType=ajaxObj.responseType||"text",addToContent=ajaxObj.addToContent,timeout=ajaxObj.timeout||null,ex=ajaxObj.exception,timeoutId=null,done=false;XMLHttp.open(method,url,true);XMLHttp.setRequestHeader("AJAX","true");XMLHttp.setRequestHeader("X-Requested-With","XMLHttpRequest");if(method==="POST"){XMLHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");XMLHttp.setRequestHeader("Content-length",params?params.length:0);if(XMLHttp.overrideMimeType){XMLHttp.setRequestHeader("Connection","close")}}if(responseType==="json"){XMLHttp.setRequestHeader("Accept","application/json, text/javascript, */*")}for(var i in headers){if(typeof i==="string"){XMLHttp.setRequestHeader(i,headers[i])}}if(typeof callback==="function"){XMLHttp.onreadystatechange=function(){try{if(XMLHttp.readyState===4&&!done){window.clearTimeout(timeoutId);done=true;status=XMLHttp.status;statusText=XMLHttp.statusText;readyState=4;if((status||location.protocol!=="file:")&&(status<200||status>=300)){throw new Error(statusText)}var response=/xml/i.test(responseType)?XMLHttp.responseXML:XMLHttp.responseText;if(/json/i.test(responseType)&&!!response){response=(typeof JSON==="object"&&typeof JSON.parse==="function")?JSON.parse(response):eval("("+response+")")}globalXMLHttp=null;XMLHttp.onreadystatechange=function(){};requestPool.push(XMLHttp);callback.call(elm,response,addToContent)}}catch(e){globalXMLHttp=XMLHttp=null;if(typeof ex==="function"){ex.call(elm,e);ex=null}}}}XMLHttp.send(params);if(timeout){timeoutId=window.setTimeout(function(){if(!done){XMLHttp.abort();done=true;if(typeof ex==="function"){readyState=0;status=408;statusText="Request timeout";globalXMLHttp=XMLHttp=null;ex.call(elm,new Error(statusText));ex=null}}},timeout)}})(this)}return this},replaceWithAJAXContent:function(content,add){if(add){this.innerHTML+=content}else{DOMAssistant.cleanUp(this);this.innerHTML=content}},getReadyState:function(){return(globalXMLHttp&&DOMAssistant.def(globalXMLHttp.readyState))?globalXMLHttp.readyState:readyState},getStatus:function(){return status},getStatusText:function(){return statusText}}}();DOMAssistant.attach(DOMAssistant.AJAX);DOMAssistant.CSS=function(){var a=DOMAssistant.def,b={display:true};return{addClass:function(d){if(!this.hasClass(d)){var c=this.className;this.className=c+(c.length?" ":"")+d}return this},removeClass:function(c){return this.replaceClass(c)},replaceClass:function(d,e){var c=new RegExp(("(^|\\s)"+d+"(\\s|$)"),"i");this.className=this.className.replace(c,function(f,h,g){return e?(h+e+g):" "}).replace(/^\s+|\s+$/g,"");return this},hasClass:function(c){return(" "+this.className+" ").indexOf(" "+c+" ")>-1},setStyle:function(f,g){var e=this.style;if("filters" in this&&(typeof f==="string"?/opacity/i.test(f):a(f.opacity))){e.zoom=1;e.filter=(e.filter||"").replace(/alpha\([^)]*\)/,"")+"alpha(opacity="+(a(f.opacity)?f.opacity:g)*100+")"}if(a(e.cssText)){var c=e.cssText;if(typeof f==="object"){for(var d in f){if(typeof d==="string"){if(b[d]){e[d]=f[d]}c+=";"+d+":"+f[d]}}}else{if(b[f]){e[f]=g}c+=";"+f+":"+g}e.cssText=c}return this},getStyle:function(c){var e="",d;c=c.toLowerCase();if(document.defaultView&&document.defaultView.getComputedStyle){e=document.defaultView.getComputedStyle(this,"").getPropertyValue(c)}else{if(this.currentStyle){if("filters" in this&&c==="opacity"){e=(d=this.style.filter||this.currentStyle.filter)&&d.indexOf("opacity=")>=0?parseFloat(d.match(/opacity=([^)]*)/)[1])/100:1}else{c=c.replace(/^float$/,"styleFloat").replace(/\-(\w)/g,function(f,g){return g.toUpperCase()});e=this.currentStyle[c]}if(e==="auto"&&/^(width|height)$/.test(c)&&this.currentStyle.display!=="none"){e=this["offset"+c.charAt(0).toUpperCase()+c.substr(1)]+"px"}}}return e}}}();DOMAssistant.attach(DOMAssistant.CSS);DOMAssistant.Content=function(){var a=DOMAssistant.$$;return{init:function(){DOMAssistant.setCache(false)},create:function(d,c,b,e){var f=a(document.createElement(d));if(c){f=f.setAttributes(c)}if(DOMAssistant.def(e)){f.addContent(e)}if(b){this.appendChild(f)}return f},setAttributes:function(b){if(DOMAssistant.isIE){var c=function(g,e,f){var d=e.toLowerCase();switch(d){case"name":case"type":case"multiple":return a(document.createElement(g.outerHTML.replace(new RegExp(d+"(=[a-zA-Z]+)?")," ").replace(">"," "+d+"="+f+">")));case"style":g.style.cssText=f;return g;default:g[DOMAssistant.camel[d]||e]=f;return g}};DOMAssistant.Content.setAttributes=function(d){var h=this;var g=this.parentNode;for(var f in d){if(typeof d[f]==="string"||typeof d[f]==="number"){var e=c(h,f,d[f]);if(g&&/(name|type)/i.test(f)){if(h.innerHTML){e.innerHTML=h.innerHTML}g.replaceChild(e,h)}h=e}}return h}}else{DOMAssistant.Content.setAttributes=function(d){for(var e in d){if(/class/i.test(e)){this.className=d[e]}else{this.setAttribute(e,d[e])}}return this}}return DOMAssistant.Content.setAttributes.call(this,b)},addContent:function(f){var d=typeof f;if(d==="string"||d==="number"){if(!this.firstChild){this.innerHTML=f}else{var c=document.createElement("div");c.innerHTML=f;for(var b=c.childNodes.length-1,e=null;b>=0;b--){e=this.insertBefore(c.childNodes[b],e)}}}else{if(d==="object"||(d==="function"&&!!f.nodeName)){this.appendChild(f)}}return this},replaceContent:function(b){DOMAssistant.cleanUp(this);return this.addContent(b)},replace:function(g,b){var f=typeof g;if(f==="string"||f==="number"){var e=this.parentNode;var d=DOMAssistant.Content.create.call(e,"div",null,false,g);for(var c=d.childNodes.length;c--;){e.insertBefore(d.childNodes[c],this.nextSibling)}g=this.nextSibling;e.removeChild(this)}else{if(f==="object"||(f==="function"&&!!g.nodeName)){this.parentNode.replaceChild(g,this)}}return b?g:this},remove:function(){DOMAssistant.cleanUp(this);if(this.hasData()){if(this.removeEvent){this.removeEvent()}this.unstore()}this.parentNode.removeChild(this);return null}}}();DOMAssistant.attach(DOMAssistant.Content);DOMAssistant.Events=function(){var i,g="_events",c=!!document.addEventListener,a={focus:true,blur:true},b=DOMAssistant.isIE?{focus:"activate",blur:"deactivate",mouseenter:"mouseover",mouseleave:"mouseout"}:{mouseenter:"mouseover",mouseleave:"mouseout"},f={special:/^submit|reset|change|select$/i,mouseenterleave:/^mouse(enter|leave)$/i,dom:/^DOM/,on:/^on/i},e=function(j){return DOMAssistant.isIE&&f.special.test(j)},d=function(j){return b[j]||j},h=function(n,k,m){n=n||window.event||{};if(n.event){return n}var l={event:n,type:k||n.type,bubbles:n.bubbles||true,cancelable:n.cancelable||false,target:m||n.target||n.srcElement,clientX:n.clientX||0,clientY:n.clientY||0,altKey:n.altKey||false,ctrlKey:n.ctrlKey||false,shiftKey:n.shiftKey||false,button:n.button||null,timeStamp:+new Date(),preventDefault:function(){if(n.preventDefault){n.preventDefault()}this.returnValue=n.returnValue=false},stopPropagation:function(){if(n.stopPropagation){n.stopPropagation()}this.cancelBubble=n.cancelBubble=true}};if(l.target&&3===l.target.nodeType){l.target=l.target.parentNode}l.currentTarget=l.target;l.relatedTarget=n.relatedTarget||(n.fromElement===l.target?n.toElement:n.fromElement)||null;var o=document.documentElement,j=document.body;l.pageX=DOMAssistant.def(n.pageX)?n.pageX:(l.clientX+(o.scrollLeft||j.scrollLeft)-(o.clientLeft||0));l.pageY=DOMAssistant.def(n.pageY)?n.pageY:(l.clientY+(o.scrollTop||j.scrollTop)-(o.clientTop||0));if("number"===typeof n.which){l.keyCode=n.keyCode;l.charCode=l.which=n.which}else{if(n.keyCode){l.keyCode=l.charCode=n.keyCode}}return l};return{publicMethods:["triggerEvent","addEvent","removeEvent","relayEvent","unrelayEvent","preventDefault","cancelBubble"],init:function(){DOMAssistant.preventDefault=this.preventDefault;DOMAssistant.cancelBubble=this.cancelBubble;i=this.handleEvent},triggerEvent:function(r,o,q){var m=d(r),s=this.retrieve(g),j=q||h(q,m,o||this);j.currentTarget=this;if(s&&s[m]){for(var n=0,l=s[m].length;n<l;n++){if(s[m][n].call(this,j)===false){j.stopPropagation()}}}else{if(typeof this["on"+m]==="function"){this["on"+m].call(this,j)}}var k=DOMAssistant.$$(this.parentNode);if(!j.cancelBubble&&k&&k.nodeType===1){k.triggerEvent(m,o,j)}return this},addEvent:function(r,l,k,q,n){var j,m=d(r),p=m+this.retrieve(),o="on"+m;if(!(l.attachedElements&&l.attachedElements[p])){var s=this.retrieve(g)||{};if(!s[m]){s[m]=[];j=this[o];this[o]=null}if(typeof this.window==="object"){this.window[o]=i}else{if(!s[m].length){if(c){this.addEventListener(m,i,a[m])}else{this[o]=i}}}if(j){s[m].push(j)}if(m!==r){l.evt=r}l.relay=k;l.proxy=q;l.selector=n;l.attachedElements=l.attachedElements||{};l.attachedElements[p]=true;s[m].push(l);this.store(g,s)}return this},handleEvent:function(r){var q=(r&&f.dom.test(r.type)&&c)?r:h(r),o=d(q.type),p=q.target,l=q.relatedTarget,n=this.retrieve(g)[o].slice(0),t,j,s;if((t=n.length)){for(var m=0;m<t;m++){if(typeof n[m]==="function"){if((s=n[m].evt)&&s!==o){q.type=s;if(l&&f.mouseenterleave.test(s)){if(n[m].relay){var k=n[m].elms||(n[m].elms=this.cssSelect(n[m].selector));if(k.indexOf(p)<0||!DOMAssistant.hasChild.call(l,p)){continue}}else{if(this===l||this.hasChild(l)){continue}}}}j=n[m].call(this,q)}}if(j===false){q.stopPropagation()}return j}},removeEvent:function(w,l,k,s){var q=(w=d(w))+this.retrieve(),x=this.retrieve(g),p="on"+w;if(x&&!w){for(var v in x){if(x[v].length){this.removeEvent(v)}}var r=this.attributes;for(var t,m=r.length;m--;){t=r[m].nodeName.toLowerCase();if(f.on.test(t)&&typeof this[t]==="function"){this[t]=null}}}else{if(x&&x[w]){var o=x[w];for(var u,n=o.length;n--;){u=l||o[n];if(o[n]===u&&k===u.relay&&s===u.proxy){o.splice(n,1);if(!!s&&u.selector){this.cssSelect(u.selector).removeEvent(s)}if(u.attachedElements){u.attachedElements[q]=null}}}if(!x[w].length){if(c){this.removeEventListener(w,i,a[w])}else{this[p]=null}}}else{if(this[p]&&!l&&!k){this[p]=null}}}return this},relayEvent:function(k,j,m,l){if(e(k)){this.relayEvent("focus",j,function(){DOMAssistant.$$(this).removeEvent(k).addEvent(k,function(n){return m.call(this,h(n))})},k).relayEvent("blur",j,function(){DOMAssistant.$$(this).removeEvent(k)},k);return this}return this.addEvent(k,function(s){s=h(s);var r=s.target,n=arguments,o=0,t,p=this.cssSelect(j);while((t=p[o++])){if((t===r||DOMAssistant.hasChild.call(t,r))&&!t.disabled){s.currentTarget=t;var q=m.apply(t,n);if(!q){s.preventDefault()}return q}}},true,l,j)},unrelayEvent:function(j){if(e(j)){return this.removeEvent("focus",null,true,j).removeEvent("blur",null,true,j)}return this.removeEvent(j,null,true)},preventDefault:function(j){if(j.preventDefault){j.preventDefault()}j.returnValue=false},cancelBubble:function(j){if(j.stopPropagation){j.stopPropagation()}j.cancelBubble=true}}}();DOMAssistant.attach(DOMAssistant.Events);DOMAssistant.DOMLoad=function(){var g=false,a=null,f=[],b={},c=null,d=function(){for(var j=0,h=f.length;j<h;j++){try{f[j]()}catch(k){if(c&&typeof c==="function"){c(k)}}}f=[]},e=function(){if(g){return}g=true;d()};
-/*@cc_on @if(@_win32||@_win64)document.write("<script id=\"ieScriptLoad\" defer src=\"//:\"><\/script>");document.getElementById("ieScriptLoad").onreadystatechange=function(){if(this.readyState==="complete"){e()}}@end@*/
-if(document.addEventListener){document.addEventListener("DOMContentLoaded",e,false)}if(/KHTML|WebKit|iCab/i.test(navigator.userAgent)){a=setInterval(function(){if(/loaded|complete/i.test(document.readyState)){e();clearInterval(a)}},10)}window.onload=e;return{DOMReady:function(){for(var j=0,h=arguments.length,k;j<h;j++){k=arguments[j];if(!k.DOMReady&&!b[k]){if(typeof k==="string"){b[k]=true;k=new Function(k)}k.DOMReady=true;f.push(k)}}if(g){d()}},setErrorHandling:function(h){c=h}}}();DOMAssistant.DOMReady=DOMAssistant.DOMLoad.DOMReady;
\ No newline at end of file
diff --git a/source/javascripts/libs/ender.js b/source/javascripts/libs/ender.js
new file mode 100644
index 00000000..5e56fd89
--- /dev/null
+++ b/source/javascripts/libs/ender.js
@@ -0,0 +1,1497 @@
+/*!
+  * Ender: open module JavaScript framework
+  * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat)
+  * https://ender.no.de
+  * License MIT
+  * Build: ender -b jeesh
+  */
+!function (context) {
+
+  function aug(o, o2) {
+    for (var k in o2) {
+      k != 'noConflict' && k != '_VERSION' && (o[k] = o2[k]);
+    }
+    return o;
+  }
+
+  function boosh(s, r) {
+    var els;
+    if (ender._select && typeof s == 'string' || s.nodeName || s.length && 'item' in s || s == window) { //string || node || nodelist || window
+      els = ender._select(s, r);
+      els.selector = s;
+    } else {
+      els = isFinite(s.length) ? s : [s];
+    }
+    return aug(els, boosh);
+  }
+
+  function ender(s, r) {
+    return boosh(s, r);
+  }
+
+  aug(ender, {
+    _VERSION: '0.2.0',
+    ender: function (o, chain) {
+      aug(chain ? boosh : ender, o);
+    }
+  });
+
+  aug(boosh, {
+    forEach: function (fn, scope) {
+      // opt out of native forEach so we can intentionally call our own scope
+      // defaulting to the current item
+      for (var i = 0, l = this.length; i < l; ++i) {
+        i in this && fn.call(scope || this[i], this[i], i, this);
+      }
+      // return self for chaining
+      return this;
+    }
+  });
+
+  var old = context.$;
+  ender.noConflict = function () {
+    context.$ = old;
+    return this;
+  };
+
+  (typeof module !== 'undefined') && module.exports && (module.exports = ender);
+  // use subscript notation as extern for Closure compilation
+  context['ender'] = context['$'] = ender;
+
+}(this);
+/*!
+  * bean.js - copyright Jacob Thornton 2011
+  * https://github.com/fat/bean
+  * MIT License
+  * special thanks to:
+  * dean edwards: http://dean.edwards.name/
+  * dperini: https://github.com/dperini/nwevents
+  * the entire mootools team: github.com/mootools/mootools-core
+  */
+!function (context) {
+  var __uid = 1, registry = {}, collected = {},
+      overOut = /over|out/,
+      namespace = /[^\.]*(?=\..*)\.|.*/,
+      stripName = /\..*/,
+      addEvent = 'addEventListener',
+      attachEvent = 'attachEvent',
+      removeEvent = 'removeEventListener',
+      detachEvent = 'detachEvent',
+      doc = context.document || {},
+      root = doc.documentElement || {},
+      W3C_MODEL = root[addEvent],
+      eventSupport = W3C_MODEL ? addEvent : attachEvent,
+
+  isDescendant = function (parent, child) {
+    var node = child.parentNode;
+    while (node != null) {
+      if (node == parent) {
+        return true;
+      }
+      node = node.parentNode;
+    }
+  },
+
+  retrieveUid = function (obj, uid) {
+    return (obj.__uid = uid || obj.__uid || __uid++);
+  },
+
+  retrieveEvents = function (element) {
+    var uid = retrieveUid(element);
+    return (registry[uid] = registry[uid] || {});
+  },
+
+  listener = W3C_MODEL ? function (element, type, fn, add) {
+    element[add ? addEvent : removeEvent](type, fn, false);
+  } : function (element, type, fn, add, custom) {
+    custom && add && (element['_on' + custom] = element['_on' + custom] || 0);
+    element[add ? attachEvent : detachEvent]('on' + type, fn);
+  },
+
+  nativeHandler = function (element, fn, args) {
+    return function (event) {
+      event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || context).event);
+      return fn.apply(element, [event].concat(args));
+    };
+  },
+
+  customHandler = function (element, fn, type, condition, args) {
+    return function (event) {
+      if (condition ? condition.call(this, event) : W3C_MODEL ? true : event && event.propertyName == '_on' + type || !event) {
+        fn.apply(element, [event].concat(args));
+      }
+    };
+  },
+
+  addListener = function (element, orgType, fn, args) {
+    var type = orgType.replace(stripName, ''),
+        events = retrieveEvents(element),
+        handlers = events[type] || (events[type] = {}),
+        uid = retrieveUid(fn, orgType.replace(namespace, ''));
+    if (handlers[uid]) {
+      return element;
+    }
+    var custom = customEvents[type];
+    if (custom) {
+      fn = custom.condition ? customHandler(element, fn, type, custom.condition) : fn;
+      type = custom.base || type;
+    }
+    var isNative = nativeEvents[type];
+    fn = isNative ? nativeHandler(element, fn, args) : customHandler(element, fn, type, false, args);
+    isNative = W3C_MODEL || isNative;
+    if (type == 'unload') {
+      var org = fn;
+      fn = function () {
+        removeListener(element, type, fn) && org();
+      };
+    }
+    element[eventSupport] && listener(element, isNative ? type : 'propertychange', fn, true, !isNative && type);
+    handlers[uid] = fn;
+    fn.__uid = uid;
+    return type == 'unload' ? element : (collected[retrieveUid(element)] = element);
+  },
+
+  removeListener = function (element, orgType, handler) {
+    var uid, names, uids, i, events = retrieveEvents(element), type = orgType.replace(stripName, '');
+    if (!events || !events[type]) {
+      return element;
+    }
+    names = orgType.replace(namespace, '');
+    uids = names ? names.split('.') : [handler.__uid];
+    for (i = uids.length; i--;) {
+      uid = uids[i];
+      handler = events[type][uid];
+      delete events[type][uid];
+      if (element[eventSupport]) {
+        type = customEvents[type] ? customEvents[type].base : type;
+        var isNative = W3C_MODEL || nativeEvents[type];
+        listener(element, isNative ? type : 'propertychange', handler, false, !isNative && type);
+      }
+    }
+    return element;
+  },
+
+  del = function (selector, fn, $) {
+    return function (e) {
+      var array = typeof selector == 'string' ? $(selector, this) : selector;
+      for (var target = e.target; target && target != this; target = target.parentNode) {
+        for (var i = array.length; i--;) {
+          if (array[i] == target) {
+            return fn.apply(target, arguments);
+          }
+        }
+      }
+    };
+  },
+
+  add = function (element, events, fn, delfn, $) {
+    if (typeof events == 'object' && !fn) {
+      for (var type in events) {
+        events.hasOwnProperty(type) && add(element, type, events[type]);
+      }
+    } else {
+      var isDel = typeof fn == 'string', types = (isDel ? fn : events).split(' ');
+      fn = isDel ? del(events, delfn, $) : fn;
+      for (var i = types.length; i--;) {
+        addListener(element, types[i], fn, Array.prototype.slice.call(arguments, isDel ? 4 : 3));
+      }
+    }
+    return element;
+  },
+
+  remove = function (element, orgEvents, fn) {
+    var k, type, events,
+        isString = typeof(orgEvents) == 'string',
+        names = isString && orgEvents.replace(namespace, ''),
+        rm = removeListener,
+        attached = retrieveEvents(element);
+    if (isString && /\s/.test(orgEvents)) {
+      orgEvents = orgEvents.split(' ');
+      var i = orgEvents.length - 1;
+      while (remove(element, orgEvents[i]) && i--) {}
+      return element;
+    }
+    events = isString ? orgEvents.replace(stripName, '') : orgEvents;
+    if (!attached || (isString && !attached[events])) {
+      return element;
+    }
+    if (typeof fn == 'function') {
+      rm(element, events, fn);
+    } else if (names) {
+      rm(element, orgEvents);
+    } else {
+      rm = events ? rm : remove;
+      type = isString && events;
+      events = events ? (fn || attached[events] || events) : attached;
+      for (k in events) {
+        events.hasOwnProperty(k) && rm(element, type || k, events[k]);
+      }
+    }
+    return element;
+  },
+
+  fire = function (element, type, args) {
+    var evt, k, i, types = type.split(' ');
+    for (i = types.length; i--;) {
+      type = types[i].replace(stripName, '');
+      var isNative = nativeEvents[type],
+          isNamespace = types[i].replace(namespace, ''),
+          handlers = retrieveEvents(element)[type];
+      if (isNamespace) {
+        isNamespace = isNamespace.split('.');
+        for (k = isNamespace.length; k--;) {
+          handlers[isNamespace[k]] && handlers[isNamespace[k]].apply(element, args);
+        }
+      } else if (!args && element[eventSupport]) {
+        fireListener(isNative, type, element);
+      } else {
+        for (k in handlers) {
+          handlers.hasOwnProperty(k) && handlers[k].apply(element, args);
+        }
+      }
+    }
+    return element;
+  },
+
+  fireListener = W3C_MODEL ? function (isNative, type, element) {
+    evt = document.createEvent(isNative ? "HTMLEvents" : "UIEvents");
+    evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, context, 1);
+    element.dispatchEvent(evt);
+  } : function (isNative, type, element) {
+    isNative ? element.fireEvent('on' + type, document.createEventObject()) : element['_on' + type]++;
+  },
+
+  clone = function (element, from, type) {
+    var events = retrieveEvents(from), obj, k;
+    obj = type ? events[type] : events;
+    for (k in obj) {
+      obj.hasOwnProperty(k) && (type ? add : clone)(element, type || from, type ? obj[k] : k);
+    }
+    return element;
+  },
+
+  fixEvent = function (e) {
+    var result = {};
+    if (!e) {
+      return result;
+    }
+    var type = e.type, target = e.target || e.srcElement;
+    result.preventDefault = fixEvent.preventDefault(e);
+    result.stopPropagation = fixEvent.stopPropagation(e);
+    result.target = target && target.nodeType == 3 ? target.parentNode : target;
+    if (~type.indexOf('key')) {
+      result.keyCode = e.which || e.keyCode;
+    } else if ((/click|mouse|menu/i).test(type)) {
+      result.rightClick = e.which == 3 || e.button == 2;
+      result.pos = { x: 0, y: 0 };
+      if (e.pageX || e.pageY) {
+        result.clientX = e.pageX;
+        result.clientY = e.pageY;
+      } else if (e.clientX || e.clientY) {
+        result.clientX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
+        result.clientY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
+      }
+      overOut.test(type) && (result.relatedTarget = e.relatedTarget || e[(type == 'mouseover' ? 'from' : 'to') + 'Element']);
+    }
+    for (var k in e) {
+      if (!(k in result)) {
+        result[k] = e[k];
+      }
+    }
+    return result;
+  };
+
+  fixEvent.preventDefault = function (e) {
+    return function () {
+      if (e.preventDefault) {
+        e.preventDefault();
+      }
+      else {
+        e.returnValue = false;
+      }
+    };
+  };
+
+  fixEvent.stopPropagation = function (e) {
+    return function () {
+      if (e.stopPropagation) {
+        e.stopPropagation();
+      } else {
+        e.cancelBubble = true;
+      }
+    };
+  };
+
+  var nativeEvents = { click: 1, dblclick: 1, mouseup: 1, mousedown: 1, contextmenu: 1, //mouse buttons
+    mousewheel: 1, DOMMouseScroll: 1, //mouse wheel
+    mouseover: 1, mouseout: 1, mousemove: 1, selectstart: 1, selectend: 1, //mouse movement
+    keydown: 1, keypress: 1, keyup: 1, //keyboard
+    orientationchange: 1, // mobile
+    touchstart: 1, touchmove: 1, touchend: 1, touchcancel: 1, // touch
+    gesturestart: 1, gesturechange: 1, gestureend: 1, // gesture
+    focus: 1, blur: 1, change: 1, reset: 1, select: 1, submit: 1, //form elements
+    load: 1, unload: 1, beforeunload: 1, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
+    error: 1, abort: 1, scroll: 1 }; //misc
+
+  function check(event) {
+    var related = event.relatedTarget;
+    if (!related) {
+      return related == null;
+    }
+    return (related != this && related.prefix != 'xul' && !/document/.test(this.toString()) && !isDescendant(this, related));
+  }
+
+  var customEvents = {
+    mouseenter: { base: 'mouseover', condition: check },
+    mouseleave: { base: 'mouseout', condition: check },
+    mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' }
+  };
+
+  var bean = { add: add, remove: remove, clone: clone, fire: fire };
+
+  var clean = function (el) {
+    var uid = remove(el).__uid;
+    if (uid) {
+      delete collected[uid];
+      delete registry[uid];
+    }
+  };
+
+  if (context[attachEvent]) {
+    add(context, 'unload', function () {
+      for (var k in collected) {
+        collected.hasOwnProperty(k) && clean(collected[k]);
+      }
+      context.CollectGarbage && CollectGarbage();
+    });
+  }
+
+  var oldBean = context.bean;
+  bean.noConflict = function () {
+    context.bean = oldBean;
+    return this;
+  };
+
+  (typeof module !== 'undefined' && module.exports) ?
+    (module.exports = bean) :
+    (context['bean'] = bean);
+
+}(this);!function ($) {
+  var b = bean.noConflict(),
+      integrate = function (method, type, method2) {
+        var _args = type ? [type] : [];
+        return function () {
+          for (var args, i = 0, l = this.length; i < l; i++) {
+            args = [this[i]].concat(_args, Array.prototype.slice.call(arguments, 0));
+            args.length == 4 && args.push($);
+            !arguments.length && method == 'add' && type && (method = 'fire');
+            b[method].apply(this, args);
+          }
+          return this;
+        };
+      };
+
+  var add = integrate('add'),
+      remove = integrate('remove'),
+      fire = integrate('fire');
+
+  var methods = {
+
+    on: add,
+    addListener: add,
+    bind: add,
+    listen: add,
+    delegate: add,
+
+    unbind: remove,
+    unlisten: remove,
+    removeListener: remove,
+    undelegate: remove,
+
+    emit: fire,
+    trigger: fire,
+
+    cloneEvents: integrate('clone'),
+
+    hover: function (enter, leave) {
+      for (var i = 0, l = this.length; i < l; i++) {
+        b.add.call(this, this[i], 'mouseenter', enter);
+        b.add.call(this, this[i], 'mouseleave', leave);
+      }
+      return this;
+    }
+  };
+
+  var shortcuts = [
+    'blur', 'change', 'click', 'dblclick', 'error', 'focus', 'focusin',
+    'focusout', 'keydown', 'keypress', 'keyup', 'load', 'mousedown',
+    'mouseenter', 'mouseleave', 'mouseout', 'mouseover', 'mouseup',
+    'resize', 'scroll', 'select', 'submit', 'unload'
+  ];
+
+  for (var i = shortcuts.length; i--;) {
+    var shortcut = shortcuts[i];
+    methods[shortcut] = integrate('add', shortcut);
+  }
+
+  $.ender(methods, true);
+}(ender);
+/*!
+  * bonzo.js - copyright @dedfat 2011
+  * https://github.com/ded/bonzo
+  * Follow our software http://twitter.com/dedfat
+  * MIT License
+  */
+!function (context) {
+
+  var doc = context.document,
+      html = doc.documentElement,
+      query = null,
+      byTag = 'getElementsByTagName',
+      specialAttributes = /^checked|value|selected$/,
+      specialTags = /select|map|fieldset|table|tbody|tr|colgroup/i,
+      tagMap = { select: 'option', table: 'tbody', tr: 'td' },
+      stateAttributes = /^checked|selected$/,
+      ie = /msie/i.test(navigator.userAgent),
+      uidList = [],
+      uuids = 0,
+      digit = /^-?[\d\.]+$/,
+      px = 'px',
+      // commonly used methods
+      setAttribute = 'setAttribute',
+      getAttribute = 'getAttribute',
+      trimReplace = /(^\s*|\s*$)/g,
+      unitless = { lineHeight: 1, zoom: 1, zIndex: 1, opacity: 1 };
+
+  function classReg(c) {
+    return new RegExp("(^|\\s+)" + c + "(\\s+|$)");
+  }
+
+  function each(ar, fn, scope) {
+    for (var i = 0, l = ar.length; i < l; i++) {
+      fn.call(scope || ar[i], ar[i], i, ar);
+    }
+    return ar;
+  }
+
+  var trim = String.prototype.trim ?
+    function (s) {
+      return s.trim();
+    } :
+    function (s) {
+      return s.replace(trimReplace, '');
+    };
+
+  function camelize(s) {
+    return s.replace(/-(.)/g, function (m, m1) {
+      return m1.toUpperCase();
+    });
+  }
+
+  function is(node) {
+    return node && node.nodeName && node.nodeType == 1;
+  }
+
+  function some(ar, fn, scope) {
+    for (var i = 0, j = ar.length; i < j; ++i) {
+      if (fn.call(scope, ar[i], i, ar)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  var getStyle = doc.defaultView && doc.defaultView.getComputedStyle ?
+    function (el, property) {
+      var value = null;
+      if (property == 'float') {
+        property = 'cssFloat';
+      }
+      var computed = doc.defaultView.getComputedStyle(el, '');
+      computed && (value = computed[camelize(property)]);
+      return el.style[property] || value;
+
+    } : (ie && html.currentStyle) ?
+
+    function (el, property) {
+      property = camelize(property);
+      property = property == 'float' ? 'styleFloat' : property;
+
+      if (property == 'opacity') {
+        var val = 100;
+        try {
+          val = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;
+        } catch (e1) {
+          try {
+            val = el.filters('alpha').opacity;
+          } catch (e2) {}
+        }
+        return val / 100;
+      }
+      var value = el.currentStyle ? el.currentStyle[property] : null;
+      return el.style[property] || value;
+    } :
+
+    function (el, property) {
+      return el.style[camelize(property)];
+    };
+
+  function insert(target, host, fn) {
+    var i = 0, self = host || this, r = [];
+    each(normalize(query ? query(target) : target), function (t) {
+      each(self, function (el) {
+        var n = el.cloneNode(true);
+        fn(t, n);
+        r[i] = n;
+        i++;
+      });
+    }, this);
+    each(r, function (e, i) {
+      self[i] = e;
+    });
+    self.length = i;
+    return self;
+  }
+
+  function xy(el, x, y) {
+    var $el = bonzo(el),
+        style = $el.css('position'),
+        offset = $el.offset(),
+        rel = 'relative',
+        isRel = style == rel,
+        delta = [parseInt($el.css('left'), 10), parseInt($el.css('top'), 10)];
+
+    if (style == 'static') {
+      $el.css('position', rel);
+      style = rel;
+    }
+
+    isNaN(delta[0]) && (delta[0] = isRel ? 0 : el.offsetLeft);
+    isNaN(delta[1]) && (delta[1] = isRel ? 0 : el.offsetTop);
+
+    x !== null && (el.style.left = x - offset.left + delta[0] + 'px');
+    y !== null && (el.style.top = y - offset.top + delta[1] + 'px');
+
+  }
+
+  function Bonzo(elements) {
+    this.length = 0;
+    this.original = elements;
+    if (elements) {
+      elements = typeof elements !== 'string' &&
+        !elements.nodeType &&
+        typeof elements.length !== 'undefined' ?
+          elements :
+          [elements];
+      this.length = elements.length;
+      for (var i = 0; i < elements.length; i++) {
+        this[i] = elements[i];
+      }
+    }
+  }
+
+  Bonzo.prototype = {
+
+    each: function (fn, scope) {
+      return each(this, fn, scope);
+    },
+
+    map: function (fn, reject) {
+      var m = [], n, i;
+      for (i = 0; i < this.length; i++) {
+        n = fn.call(this, this[i]);
+        reject ? (reject(n) && m.push(n)) : m.push(n);
+      }
+      return m;
+    },
+
+    first: function () {
+      return bonzo(this[0]);
+    },
+
+    last: function () {
+      return bonzo(this[this.length - 1]);
+    },
+
+    html: function (h, text) {
+      var method = text ?
+        html.textContent == null ?
+          'innerText' :
+          'textContent' :
+        'innerHTML', m;
+      function append(el, tag) {
+        while (el.firstChild) {
+          el.removeChild(el.firstChild);
+        }
+        each(normalize(h, tag), function (node) {
+          el.appendChild(node);
+        });
+      }
+      return typeof h !== 'undefined' ?
+          this.each(function (el) {
+            (m = el.tagName.match(specialTags)) ?
+              append(el, m[0]) :
+              (el[method] = h);
+          }) :
+        this[0] ? this[0][method] : '';
+    },
+
+    text: function (text) {
+      return this.html(text, 1);
+    },
+
+    addClass: function (c) {
+      return this.each(function (el) {
+        this.hasClass(el, c) || (el.className = trim(el.className + ' ' + c));
+      }, this);
+    },
+
+    removeClass: function (c) {
+      return this.each(function (el) {
+        this.hasClass(el, c) && (el.className = trim(el.className.replace(classReg(c), ' ')));
+      }, this);
+    },
+
+    hasClass: function (el, c) {
+      return typeof c == 'undefined' ?
+        some(this, function (i) {
+          return classReg(el).test(i.className);
+        }) :
+        classReg(c).test(el.className);
+    },
+
+    toggleClass: function (c, condition) {
+      if (typeof condition !== 'undefined' && !condition) {
+        return this;
+      }
+      return this.each(function (el) {
+        this.hasClass(el, c) ?
+          (el.className = trim(el.className.replace(classReg(c), ' '))) :
+          (el.className = trim(el.className + ' ' + c));
+      }, this);
+    },
+
+    show: function (type) {
+      return this.each(function (el) {
+        el.style.display = type || '';
+      });
+    },
+
+    hide: function (elements) {
+      return this.each(function (el) {
+        el.style.display = 'none';
+      });
+    },
+
+    append: function (node) {
+      return this.each(function (el) {
+        each(normalize(node), function (i) {
+          el.appendChild(i);
+        });
+      });
+    },
+
+    prepend: function (node) {
+      return this.each(function (el) {
+        var first = el.firstChild;
+        each(normalize(node), function (i) {
+          el.insertBefore(i, first);
+        });
+      });
+    },
+
+    appendTo: function (target, host) {
+      return insert.call(this, target, host, function (t, el) {
+        t.appendChild(el);
+      });
+    },
+
+    prependTo: function (target, host) {
+      return insert.call(this, target, host, function (t, el) {
+        t.insertBefore(el, t.firstChild);
+      });
+    },
+
+    next: function () {
+      return this.related('nextSibling');
+    },
+
+    previous: function () {
+      return this.related('previousSibling');
+    },
+
+    related: function (method) {
+      return this.map(
+        function (el) {
+          el = el[method];
+          while (el && el.nodeType !== 1) {
+            el = el[method];
+          }
+          return el || 0;
+        },
+        function (el) {
+          return el;
+        }
+      );
+    },
+
+    before: function (node) {
+      return this.each(function (el) {
+        each(bonzo.create(node), function (i) {
+          el.parentNode.insertBefore(i, el);
+        });
+      });
+    },
+
+    after: function (node) {
+      return this.each(function (el) {
+        each(bonzo.create(node), function (i) {
+          el.parentNode.insertBefore(i, el.nextSibling);
+        });
+      });
+    },
+
+    insertBefore: function (target, host) {
+      return insert.call(this, target, host, function (t, el) {
+        t.parentNode.insertBefore(el, t);
+      });
+    },
+
+    insertAfter: function (target, host) {
+      return insert.call(this, target, host, function (t, el) {
+        var sibling = t.nextSibling;
+        if (sibling) {
+          t.parentNode.insertBefore(el, sibling);
+        }
+        else {
+          t.parentNode.appendChild(el);
+        }
+      });
+    },
+
+    css: function (o, v) {
+      // is this a request for just getting a style?
+      if (v === undefined && typeof o == 'string') {
+        return getStyle(this[0], o);
+      }
+      var iter = o;
+      if (typeof o == 'string') {
+        iter = {};
+        iter[o] = v;
+      }
+
+      if (ie && iter.opacity) {
+        // oh this 'ol gamut
+        iter.filter = 'alpha(opacity=' + (iter.opacity * 100) + ')';
+        // give it layout
+        iter.zoom = o.zoom || 1;
+        delete iter.opacity;
+      }
+
+      if (v = iter['float']) {
+        // float is a reserved style word. w3 uses cssFloat, ie uses styleFloat
+        ie ? (iter.styleFloat = v) : (iter.cssFloat = v);
+        delete iter['float'];
+      }
+
+      var fn = function (el, p, v) {
+        for (var k in iter) {
+          if (iter.hasOwnProperty(k)) {
+            v = iter[k];
+            // change "5" to "5px" - unless you're line-height, which is allowed
+            (p = camelize(k)) && digit.test(v) && !(p in unitless) && (v += px);
+            el.style[p] = v;
+          }
+        }
+      };
+      return this.each(fn);
+    },
+
+    offset: function (x, y) {
+      if (x || y) {
+        return this.each(function (el) {
+          xy(el, x, y);
+        });
+      }
+      var el = this[0];
+      var width = el.offsetWidth;
+      var height = el.offsetHeight;
+      var top = el.offsetTop;
+      var left = el.offsetLeft;
+      while (el = el.offsetParent) {
+        top = top + el.offsetTop;
+        left = left + el.offsetLeft;
+      }
+
+      return {
+        top: top,
+        left: left,
+        height: height,
+        width: width
+      };
+    },
+
+    attr: function (k, v) {
+      var el = this[0];
+      return typeof v == 'undefined' ?
+        specialAttributes.test(k) ?
+          stateAttributes.test(k) && typeof el[k] == 'string' ?
+            true : el[k] : el[getAttribute](k) :
+        this.each(function (el) {
+          k == 'value' ? (el.value = v) : el[setAttribute](k, v);
+        });
+    },
+
+    val: function (s) {
+      return (typeof s == 'string') ? this.attr('value', s) : this[0].value;
+    },
+
+    removeAttr: function (k) {
+      return this.each(function (el) {
+        el.removeAttribute(k);
+      });
+    },
+
+    data: function (k, v) {
+      var el = this[0];
+      if (typeof v === 'undefined') {
+        el[getAttribute]('data-node-uid') || el[setAttribute]('data-node-uid', ++uuids);
+        var uid = el[getAttribute]('data-node-uid');
+        uidList[uid] || (uidList[uid] = {});
+        return uidList[uid][k];
+      } else {
+        return this.each(function (el) {
+          el[getAttribute]('data-node-uid') || el[setAttribute]('data-node-uid', ++uuids);
+          var uid = el[getAttribute]('data-node-uid');
+          var o = {};
+          o[k] = v;
+          uidList[uid] = o;
+        });
+      }
+    },
+
+    remove: function () {
+      return this.each(function (el) {
+        el.parentNode && el.parentNode.removeChild(el);
+      });
+    },
+
+    empty: function () {
+      return this.each(function (el) {
+        while (el.firstChild) {
+          el.removeChild(el.firstChild);
+        }
+      });
+    },
+
+    detach: function () {
+      return this.map(function (el) {
+        return el.parentNode.removeChild(el);
+      });
+    },
+
+    scrollTop: function (y) {
+      return scroll.call(this, null, y, 'y');
+    },
+
+    scrollLeft: function (x) {
+      return scroll.call(this, x, null, 'x');
+    }
+  };
+
+  function normalize(node, tag) {
+    return typeof node == 'string' ? bonzo.create(node, tag) : is(node) ? [node] : node;
+  }
+
+  function scroll(x, y, type) {
+    var el = this[0];
+    if (x == null && y == null) {
+      return (isBody(el) ? getWindowScroll() : { x: el.scrollLeft, y: el.scrollTop })[type];
+    }
+    if (isBody(el)) {
+      window.scrollTo(x, y);
+    } else {
+      x != null && (el.scrollLeft = x);
+      y != null && (el.scrollTop = y);
+    }
+    return this;
+  }
+
+  function isBody(element) {
+    return element === window || (/^(?:body|html)$/i).test(element.tagName);
+  }
+
+  function getWindowScroll() {
+    return { x: window.pageXOffset || html.scrollLeft, y: window.pageYOffset || html.scrollTop };
+  }
+
+  function bonzo(els, host) {
+    return new Bonzo(els, host);
+  }
+
+  bonzo.setQueryEngine = function (q) {
+    query = q;
+    delete bonzo.setQueryEngine;
+  };
+
+  bonzo.aug = function (o, target) {
+    for (var k in o) {
+      o.hasOwnProperty(k) && ((target || Bonzo.prototype)[k] = o[k]);
+    }
+  };
+
+  bonzo.create = function (node, tag) {
+    return typeof node == 'string' ?
+      function () {
+        var t = tag ? tagMap[tag.toLowerCase()] : null;
+        var el = doc.createElement(t || 'div'), els = [];
+        if (tag) {
+          var bitches = node.match(new RegExp("<" + t + ">.+?<\\/" + t + ">", "g"));
+          each(bitches, function (m) {
+            m = m.replace(/<(.+)>(.+?)<\/\1>/, '$2');
+            var bah = doc.createElement(t);
+            bah.appendChild(doc.createDocumentFragment(m));
+            el.appendChild(bah);
+          });
+        } else {
+          el.innerHTML = node;
+        }
+        var nodes = el.childNodes;
+        el = el.firstChild;
+        els.push(el);
+        while (el = el.nextSibling) {
+          (el.nodeType == 1) && els.push(el);
+        }
+        return els;
+
+      }() : is(node) ? [node.cloneNode(true)] : [];
+  };
+
+  bonzo.doc = function () {
+    var w = html.scrollWidth,
+        h = html.scrollHeight,
+        vp = this.viewport();
+    return {
+      width: Math.max(w, vp.width),
+      height: Math.max(h, vp.height)
+    };
+  };
+
+  bonzo.firstChild = function (el) {
+    for (var c = el.childNodes, i = 0, j = (c && c.length) || 0, e; i < j; i++) {
+      if (c[i].nodeType === 1) {
+        e = c[j = i];
+      }
+    }
+    return e;
+  };
+
+  bonzo.viewport = function () {
+    var h = self.innerHeight,
+        w = self.innerWidth;
+    ie && (h = html.clientHeight) && (w = html.clientWidth);
+    return {
+      width: w,
+      height: h
+    };
+  };
+
+  bonzo.isAncestor = 'compareDocumentPosition' in html ?
+    function (container, element) {
+      return (container.compareDocumentPosition(element) & 16) == 16;
+    } : 'contains' in html ?
+    function (container, element) {
+      return container !== element && container.contains(element);
+    } :
+    function (container, element) {
+      while (element = element.parentNode) {
+        if (element === container) {
+          return true;
+        }
+      }
+      return false;
+    };
+
+  var old = context.bonzo;
+  bonzo.noConflict = function () {
+    context.bonzo = old;
+    return this;
+  };
+  context['bonzo'] = bonzo;
+
+}(this);!function ($) {
+
+  var b = bonzo;
+  b.setQueryEngine($);
+  $.ender(b);
+  $.ender(b(), true);
+  $.ender({
+    create: function (node) {
+      return $(b.create(node));
+    }
+  });
+
+  $.id = function (id) {
+    return $([document.getElementById(id)]);
+  };
+
+  function indexOf(ar, val) {
+    for (var i = 0; i < ar.length; i++) {
+      if (ar[i] === val) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  function uniq(ar) {
+    var a = [], i, j;
+    label:
+    for (i = 0; i < ar.length; i++) {
+      for (j = 0; j < a.length; j++) {
+        if (a[j] == ar[i]) {
+          continue label;
+        }
+      }
+      a[a.length] = ar[i];
+    }
+    return a;
+  }
+
+  $.ender({
+    parents: function (selector, closest) {
+      var collection = $(selector), j, k, p, r = [];
+      for (j = 0, k = this.length; j < k; j++) {
+        p = this[j];
+        while (p = p.parentNode) {
+          if (indexOf(collection, p) !== -1) {
+            r.push(p);
+            if (closest) break;
+          }
+        }
+      }
+      return $(uniq(r));
+    },
+
+    closest: function (selector) {
+      return this.parents(selector, true);
+    },
+
+    first: function () {
+      return $(this[0]);
+    },
+
+    last: function () {
+      return $(this[this.length - 1]);
+    },
+
+    next: function () {
+      return $(b(this).next());
+    },
+
+    previous: function () {
+      return $(b(this).previous());
+    },
+
+    appendTo: function (t) {
+      return b(this.selector).appendTo(t, this);
+    },
+
+    prependTo: function (t) {
+      return b(this.selector).prependTo(t, this);
+    },
+
+    insertAfter: function (t) {
+      return b(this.selector).insertAfter(t, this);
+    },
+
+    insertBefore: function (t) {
+      return b(this.selector).insertBefore(t, this);
+    },
+
+    siblings: function () {
+      var i, l, p, r = [];
+      for (i = 0, l = this.length; i < l; i++) {
+        p = this[i];
+        while (p = p.previousSibling) {
+          p.nodeType == 1 && r.push(p);
+        }
+        p = this[i];
+        while (p = p.nextSibling) {
+          p.nodeType == 1 && r.push(p);
+        }
+      }
+      return $(r);
+    },
+
+    children: function () {
+      var el, r = [];
+      for (i = 0, l = this.length; i < l; i++) {
+        if (!(el = b.firstChild(this[i]))) {
+          continue;
+        }
+        r.push(el);
+        while (el = el.nextSibling) {
+          el.nodeType == 1 && r.push(el);
+        }
+      }
+      return $(uniq(r));
+    },
+
+    height: function (v) {
+      return v ? this.css('height', v) : parseInt(this.css('height'), 10);
+    },
+
+    width: function (v) {
+      return v ? this.css('width', v) : parseInt(this.css('width'), 10);
+    }
+  }, true);
+
+}(ender || $);
+
+!function () { var exports = {}, module = { exports: exports }; !function (doc) {
+  var loaded = 0, fns = [], ol, f = false,
+      testEl = doc.createElement('a'),
+      domContentLoaded = 'DOMContentLoaded',
+      addEventListener = 'addEventListener',
+      onreadystatechange = 'onreadystatechange';
+
+  /^loade|c/.test(doc.readyState) && (loaded = 1);
+
+  function flush() {
+    loaded = 1;
+    for (var i = 0, l = fns.length; i < l; i++) {
+      fns[i]();
+    }
+  }
+  doc[addEventListener] && doc[addEventListener](domContentLoaded, function fn() {
+    doc.removeEventListener(domContentLoaded, fn, f);
+    flush();
+  }, f);
+
+
+  testEl.doScroll && doc.attachEvent(onreadystatechange, (ol = function ol() {
+    if (/^c/.test(doc.readyState)) {
+      doc.detachEvent(onreadystatechange, ol);
+      flush();
+    }
+  }));
+
+  var domReady = testEl.doScroll ?
+    function (fn) {
+      self != top ?
+        !loaded ?
+          fns.push(fn) :
+          fn() :
+        !function () {
+          try {
+            testEl.doScroll('left');
+          } catch (e) {
+            return setTimeout(function() {
+              domReady(fn);
+            }, 50);
+          }
+          fn();
+        }();
+    } :
+    function (fn) {
+      loaded ? fn() : fns.push(fn);
+    };
+
+    (typeof module !== 'undefined') && module.exports ?
+      (module.exports = {domReady: domReady}) :
+      (window.domReady = domReady);
+
+}(document); $.ender(module.exports); }.call($);
+/*!
+  * qwery.js - copyright @dedfat
+  * https://github.com/ded/qwery
+  * Follow our software http://twitter.com/dedfat
+  * MIT License
+  */
+
+!function (context, doc) {
+
+  var c, i, j, k, l, m, o, p, r, v,
+      el, node, len, found, classes, item, items, token,
+      id = /#([\w\-]+)/,
+      clas = /\.[\w\-]+/g,
+      idOnly = /^#([\w\-]+$)/,
+      classOnly = /^\.([\w\-]+)$/,
+      tagOnly = /^([\w\-]+)$/,
+      tagAndOrClass = /^([\w]+)?\.([\w\-]+)$/,
+      html = doc.documentElement,
+      tokenizr = /\s(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\])/,
+      specialChars = /([.*+?\^=!:${}()|\[\]\/\\])/g,
+      simple = /^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,
+      attr = /\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,
+      chunker = new RegExp(simple.source + '(' + attr.source + ')?');
+
+  function array(ar) {
+    r = [];
+    for (i = 0, len = ar.length; i < len; i++) {
+      r[i] = ar[i];
+    }
+    return r;
+  }
+
+  var cache = function () {
+    this.c = {};
+  };
+  cache.prototype = {
+    g: function (k) {
+      return this.c[k] || undefined;
+    },
+    s: function (k, v) {
+      this.c[k] = v;
+      return v;
+    }
+  };
+
+  var classCache = new cache(),
+      cleanCache = new cache(),
+      attrCache = new cache(),
+      tokenCache = new cache();
+
+  function q(query) {
+    return query.match(chunker);
+  }
+
+  function interpret(whole, tag, idsAndClasses, wholeAttribute, attribute, qualifier, value) {
+    var m, c, k;
+    if (tag && this.tagName.toLowerCase() !== tag) {
+      return false;
+    }
+    if (idsAndClasses && (m = idsAndClasses.match(id)) && m[1] !== this.id) {
+      return false;
+    }
+    if (idsAndClasses && (classes = idsAndClasses.match(clas))) {
+      for (i = classes.length; i--;) {
+        c = classes[i].slice(1);
+        if (!(classCache.g(c) || classCache.s(c, new RegExp('(^|\\s+)' + c + '(\\s+|$)'))).test(this.className)) {
+          return false;
+        }
+      }
+    }
+    if (wholeAttribute && !value) {
+      o = this.attributes;
+      for (k in o) {
+        if (Object.prototype.hasOwnProperty.call(o, k) && (o[k].name || k) == attribute) {
+          return this;
+        }
+      }
+    }
+    if (wholeAttribute && !checkAttr(qualifier, this.getAttribute(attribute) || '', value)) {
+      return false;
+    }
+    return this;
+  }
+
+  function loopAll(tokens) {
+    var r = [], token = tokens.pop(), intr = q(token), tag = intr[1] || '*', i, l, els,
+        root = tokens.length && (m = tokens[0].match(idOnly)) ? doc.getElementById(m[1]) : doc;
+    if (!root) {
+      return r;
+    }
+    els = root.getElementsByTagName(tag);
+    for (i = 0, l = els.length; i < l; i++) {
+      el = els[i];
+      if (item = interpret.apply(el, intr)) {
+        r.push(item);
+      }
+    }
+    return r;
+  }
+
+  function clean(s) {
+    return cleanCache.g(s) || cleanCache.s(s, s.replace(specialChars, '\\$1'));
+  }
+
+  function checkAttr(qualify, actual, val) {
+    switch (qualify) {
+    case '=':
+      return actual == val;
+    case '^=':
+      return actual.match(attrCache.g('^=' + val) || attrCache.s('^=' + val, new RegExp('^' + clean(val))));
+    case '$=':
+      return actual.match(attrCache.g('$=' + val) || attrCache.s('$=' + val, new RegExp(clean(val) + '$')));
+    case '*=':
+      return actual.match(attrCache.g(val) || attrCache.s(val, new RegExp(clean(val))));
+    case '~=':
+      return actual.match(attrCache.g('~=' + val) || attrCache.s('~=' + val, new RegExp('(?:^|\\s+)' + clean(val) + '(?:\\s+|$)')));
+    case '|=':
+      return actual.match(attrCache.g('|=' + val) || attrCache.s('|=' + val, new RegExp('^' + clean(val) + '(-|$)')));
+    }
+    return false;
+  }
+
+  function _qwery(selector) {
+    var r = [], ret = [], i, l,
+        tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr));
+    tokens = tokens.slice(0);
+    if (!tokens.length) {
+      return r;
+    }
+    r = loopAll(tokens);
+    if (!tokens.length) {
+      return r;
+    }
+    // loop through all descendent tokens
+    for (j = 0, l = r.length, k = 0; j < l; j++) {
+      node = r[j];
+      p = node;
+      // loop through each token
+      for (i = tokens.length; i--;) {
+        z: // loop through parent nodes
+        while (p !== html && (p = p.parentNode)) {
+          if (found = interpret.apply(p, q(tokens[i]))) {
+            break z;
+          }
+        }
+      }
+      found && (ret[k++] = node);
+    }
+    return ret;
+  }
+
+  function boilerPlate(selector, _root, fn) {
+    var root = (typeof _root == 'string') ? fn(_root)[0] : (_root || doc);
+    if (selector === window || isNode(selector)) {
+      return !_root || (selector !== window && isNode(root) && isAncestor(selector, root)) ? [selector] : [];
+    }
+    if (selector && typeof selector === 'object' && isFinite(selector.length)) {
+      return array(selector);
+    }
+    if (m = selector.match(idOnly)) {
+      return (el = doc.getElementById(m[1])) ? [el] : [];
+    }
+    if (m = selector.match(tagOnly)) {
+      return array(root.getElementsByTagName(m[1]));
+    }
+    return false;
+  }
+
+  function isNode(el) {
+    return (el && el.nodeType && (el.nodeType == 1 || el.nodeType == 9));
+  }
+
+  function uniq(ar) {
+    var a = [], i, j;
+    label:
+    for (i = 0; i < ar.length; i++) {
+      for (j = 0; j < a.length; j++) {
+        if (a[j] == ar[i]) {
+          continue label;
+        }
+      }
+      a[a.length] = ar[i];
+    }
+    return a;
+  }
+
+  function qwery(selector, _root) {
+    var root = (typeof _root == 'string') ? qwery(_root)[0] : (_root || doc);
+    if (!root || !selector) {
+      return [];
+    }
+    if (m = boilerPlate(selector, _root, qwery)) {
+      return m;
+    }
+    return select(selector, root);
+  }
+
+  var isAncestor = 'compareDocumentPosition' in html ?
+    function (element, container) {
+      return (container.compareDocumentPosition(element) & 16) == 16;
+    } : 'contains' in html ?
+    function (element, container) {
+      container = container == doc || container == window ? html : container;
+      return container !== element && container.contains(element);
+    } :
+    function (element, container) {
+      while (element = element.parentNode) {
+        if (element === container) {
+          return 1;
+        }
+      }
+      return 0;
+    },
+
+  select = (doc.querySelector && doc.querySelectorAll) ?
+    function (selector, root) {
+      if (doc.getElementsByClassName && (m = selector.match(classOnly))) {
+        return array((root).getElementsByClassName(m[1]));
+      }
+      return array((root).querySelectorAll(selector));
+    } :
+    function (selector, root) {
+      var result = [], collection, collections = [], i;
+      if (m = selector.match(tagAndOrClass)) {
+        items = root.getElementsByTagName(m[1] || '*');
+        r = classCache.g(m[2]) || classCache.s(m[2], new RegExp('(^|\\s+)' + m[2] + '(\\s+|$)'));
+        for (i = 0, l = items.length, j = 0; i < l; i++) {
+          r.test(items[i].className) && (result[j++] = items[i]);
+        }
+        return result;
+      }
+      for (i = 0, items = selector.split(','), l = items.length; i < l; i++) {
+        collections[i] = _qwery(items[i]);
+      }
+      for (i = 0, l = collections.length; i < l && (collection = collections[i]); i++) {
+        var ret = collection;
+        if (root !== doc) {
+          ret = [];
+          for (j = 0, m = collection.length; j < m && (element = collection[j]); j++) {
+            // make sure element is a descendent of root
+            isAncestor(element, root) && ret.push(element);
+          }
+        }
+        result = result.concat(ret);
+      }
+      return uniq(result);
+    };
+
+  qwery.uniq = uniq;
+  var oldQwery = context.qwery;
+  qwery.noConflict = function () {
+    context.qwery = oldQwery;
+    return this;
+  };
+  context['qwery'] = qwery;
+
+}(this, document);!function (doc) {
+  var q = qwery.noConflict();
+  function create(node, root) {
+    var el = (root || doc).createElement('div'), els = [];
+    el.innerHTML = node;
+    var nodes = el.childNodes;
+    el = el.firstChild;
+    els.push(el);
+    while (el = el.nextSibling) {
+      (el.nodeType == 1) && els.push(el);
+    }
+    return els;
+  };
+  $._select = function (s, r) {
+    return /^\s*</.test(s) ? create(s, r) : q(s, r);
+  };
+  $.ender({
+    find: function (s) {
+      var r = [], i, l, j, k, els;
+      for (i = 0, l = this.length; i < l; i++) {
+        els = q(s, this[i]);
+        for (j = 0, k = els.length; j < k; j++) {
+          r.push(els[j]);
+        }
+      }
+      return $(q.uniq(r));
+    }
+    , and: function (s) {
+      var plus = $(s);
+      for (var i = this.length, j = 0, l = this.length + plus.length; i < l; i++, j++) {
+        this[i] = plus[j];
+      }
+      return this;
+    }
+  }, true);
+}(document);
diff --git a/source/javascripts/libs/ender.min.js b/source/javascripts/libs/ender.min.js
new file mode 100644
index 00000000..7b5a6700
--- /dev/null
+++ b/source/javascripts/libs/ender.min.js
@@ -0,0 +1,8 @@
+/*!
+  * Ender: open module JavaScript framework
+  * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat)
+  * https://ender.no.de
+  * License MIT
+  * Build: ender -b jeesh
+  */
+!function(a){function d(a,b){return c(a,b)}function c(a,e){var f;d._select&&typeof a=="string"||a.nodeName||a.length&&"item"in a||a==window?(f=d._select(a,e),f.selector=a):f=isFinite(a.length)?a:[a];return b(f,c)}function b(a,b){for(var c in b)c!="noConflict"&&c!="_VERSION"&&(a[c]=b[c]);return a}b(d,{_VERSION:"0.2.0",ender:function(a,e){b(e?c:d,a)}}),b(c,{forEach:function(a,b){for(var c=0,d=this.length;c<d;++c)c in this&&a.call(b||this[c],this[c],c,this);return this}});var e=a.$;d.noConflict=function(){a.$=e;return this},typeof module!="undefined"&&module.exports&&(module.exports=d),a.ender=a.$=d}(this),!function(a){function F(a){var b=a.relatedTarget;if(!b)return b==null;return b!=this&&b.prefix!="xul"&&!/document/.test(this.toString())&&!p(this,b)}var b=1,c={},d={},e=/over|out/,f=/[^\.]*(?=\..*)\.|.*/,g=/\..*/,h="addEventListener",i="attachEvent",j="removeEventListener",k="detachEvent",l=a.document||{},m=l.documentElement||{},n=m[h],o=n?h:i,p=function(a,b){var c=b.parentNode;while(c!=null){if(c==a)return!0;c=c.parentNode}},q=function(a,c){return a.__uid=c||a.__uid||b++},r=function(a){var b=q(a);return c[b]=c[b]||{}},s=n?function(a,b,c,d){a[d?h:j](b,c,!1)}:function(a,b,c,d,e){e&&d&&(a["_on"+e]=a["_on"+e]||0),a[d?i:k]("on"+b,c)},t=function(b,c,d){return function(e){e=D(e||((this.ownerDocument||this.document||this).parentWindow||a).event);return c.apply(b,[e].concat(d))}},u=function(a,b,c,d,e){return function(f){(d?d.call(this,f):n?!0:f&&f.propertyName=="_on"+c||!f)&&b.apply(a,[f].concat(e))}},v=function(a,b,c,e){var h=b.replace(g,""),i=r(a),j=i[h]||(i[h]={}),k=q(c,b.replace(f,""));if(j[k])return a;var l=G[h];l&&(c=l.condition?u(a,c,h,l.condition):c,h=l.base||h);var m=E[h];c=m?t(a,c,e):u(a,c,h,!1,e),m=n||m;if(h=="unload"){var p=c;c=function(){w(a,h,c)&&p()}}a[o]&&s(a,m?h:"propertychange",c,!0,!m&&h),j[k]=c,c.__uid=k;return h=="unload"?a:d[q(a)]=a},w=function(a,b,c){var d,e,h,i,j=r(a),k=b.replace(g,"");if(!j||!j[k])return a;e=b.replace(f,""),h=e?e.split("."):[c.__uid];for(i=h.length;i--;){d=h[i],c=j[k][d],delete j[k][d];if(a[o]){k=G[k]?G[k].base:k;var l=n||E[k];s(a,l?k:"propertychange",c,!1,!l&&k)}}return a},x=function(a,b,c){return function(d){var e=typeof a=="string"?c(a,this):a;for(var f=d.target;f&&f!=this;f=f.parentNode)for(var g=e.length;g--;)if(e[g]==f)return b.apply(f,arguments)}},y=function(a,b,c,d,e){if(typeof b=="object"&&!c)for(var f in b)b.hasOwnProperty(f)&&y(a,f,b[f]);else{var g=typeof c=="string",h=(g?c:b).split(" ");c=g?x(b,d,e):c;for(var i=h.length;i--;)v(a,h[i],c,Array.prototype.slice.call(arguments,g?4:3))}return a},z=function(a,b,c){var d,e,h,i=typeof b=="string",j=i&&b.replace(f,""),k=w,l=r(a);if(i&&/\s/.test(b)){b=b.split(" ");var m=b.length-1;while(z(a,b[m])&&m--);return a}h=i?b.replace(g,""):b;if(!l||i&&!l[h])return a;if(typeof c=="function")k(a,h,c);else if(j)k(a,b);else{k=h?k:z,e=i&&h,h=h?c||l[h]||h:l;for(d in h)h.hasOwnProperty(d)&&k(a,e||d,h[d])}return a},A=function(a,b,c){var d,e,h,i=b.split(" ");for(h=i.length;h--;){b=i[h].replace(g,"");var j=E[b],k=i[h].replace(f,""),l=r(a)[b];if(k){k=k.split(".");for(e=k.length;e--;)l[k[e]]&&l[k[e]].apply(a,c)}else if(!c&&a[o])B(j,b,a);else for(e in l)l.hasOwnProperty(e)&&l[e].apply(a,c)}return a},B=n?function(b,c,d){evt=document.createEvent(b?"HTMLEvents":"UIEvents"),evt[b?"initEvent":"initUIEvent"](c,!0,!0,a,1),d.dispatchEvent(evt)}:function(a,b,c){a?c.fireEvent("on"+b,document.createEventObject()):c["_on"+b]++},C=function(a,b,c){var d=r(b),e,f;e=c?d[c]:d;for(f in e)e.hasOwnProperty(f)&&(c?y:C)(a,c||b,c?e[f]:f);return a},D=function(a){var b={};if(!a)return b;var c=a.type,d=a.target||a.srcElement;b.preventDefault=D.preventDefault(a),b.stopPropagation=D.stopPropagation(a),b.target=d&&d.nodeType==3?d.parentNode:d;if(~c.indexOf("key"))b.keyCode=a.which||a.keyCode;else if(/click|mouse|menu/i.test(c)){b.rightClick=a.which==3||a.button==2,b.pos={x:0,y:0};if(a.pageX||a.pageY)b.clientX=a.pageX,b.clientY=a.pageY;else if(a.clientX||a.clientY)b.clientX=a.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,b.clientY=a.clientY+document.body.scrollTop+document.documentElement.scrollTop;e.test(c)&&(b.relatedTarget=a.relatedTarget||a[(c=="mouseover"?"from":"to")+"Element"])}for(var f in a)f in b||(b[f]=a[f]);return b};D.preventDefault=function(a){return function(){a.preventDefault?a.preventDefault():a.returnValue=!1}},D.stopPropagation=function(a){return function(){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}};var E={click:1,dblclick:1,mouseup:1,mousedown:1,contextmenu:1,mousewheel:1,DOMMouseScroll:1,mouseover:1,mouseout:1,mousemove:1,selectstart:1,selectend:1,keydown:1,keypress:1,keyup:1,orientationchange:1,touchstart:1,touchmove:1,touchend:1,touchcancel:1,gesturestart:1,gesturechange:1,gestureend:1,focus:1,blur:1,change:1,reset:1,select:1,submit:1,load:1,unload:1,beforeunload:1,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1},G={mouseenter:{base:"mouseover",condition:F},mouseleave:{base:"mouseout",condition:F},mousewheel:{base:/Firefox/.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel"}},H={add:y,remove:z,clone:C,fire:A},I=function(a){var b=z(a).__uid;b&&(delete d[b],delete c[b])};a[i]&&y(a,"unload",function(){for(var b in d)d.hasOwnProperty(b)&&I(d[b]);a.CollectGarbage&&CollectGarbage()});var J=a.bean;H.noConflict=function(){a.bean=J;return this},typeof module!="undefined"&&module.exports?module.exports=H:a.bean=H}(this),!function(a){var b=bean.noConflict(),c=function(c,d,e){var f=d?[d]:[];return function(){for(var e,g=0,h=this.length;g<h;g++)e=[this[g]].concat(f,Array.prototype.slice.call(arguments,0)),e.length==4&&e.push(a),!arguments.length&&c=="add"&&d&&(c="fire"),b[c].apply(this,e);return this}},d=c("add"),e=c("remove"),f=c("fire"),g={on:d,addListener:d,bind:d,listen:d,delegate:d,unbind:e,unlisten:e,removeListener:e,undelegate:e,emit:f,trigger:f,cloneEvents:c("clone"),hover:function(a,c){for(var d=0,e=this.length;d<e;d++)b.add.call(this,this[d],"mouseenter",a),b.add.call(this,this[d],"mouseleave",c);return this}},h=["blur","change","click","dblclick","error","focus","focusin","focusout","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mouseout","mouseover","mouseup","resize","scroll","select","submit","unload"];for(var i=h.length;i--;){var j=h[i];g[j]=c("add",j)}a.ender(g,!0)}(ender),!function(a){function G(a,b){return new B(a,b)}function F(){return{x:window.pageXOffset||c.scrollLeft,y:window.pageYOffset||c.scrollTop}}function E(a){return a===window||/^(?:body|html)$/i.test(a.tagName)}function D(a,b,c){var d=this[0];if(a==null&&b==null)return(E(d)?F():{x:d.scrollLeft,y:d.scrollTop})[c];E(d)?window.scrollTo(a,b):(a!=null&&(d.scrollLeft=a),b!=null&&(d.scrollTop=b));return this}function C(a,b){return typeof a=="string"?G.create(a,b):w(a)?[a]:a}function B(a){this.length=0,this.original=a;if(a){a=typeof a!="string"&&!a.nodeType&&typeof a.length!="undefined"?a:[a],this.length=a.length;for(var b=0;b<a.length;b++)this[b]=a[b]}}function A(a,b,c){var d=G(a),e=d.css("position"),f=d.offset(),g="relative",h=e==g,i=[parseInt(d.css("left"),10),parseInt(d.css("top"),10)];e=="static"&&(d.css("position",g),e=g),isNaN(i[0])&&(i[0]=h?0:a.offsetLeft),isNaN(i[1])&&(i[1]=h?0:a.offsetTop),b!==null&&(a.style.left=b-f.left+i[0]+"px"),c!==null&&(a.style.top=c-f.top+i[1]+"px")}function z(a,b,c){var e=0,f=b||this,g=[];t(C(d?d(a):a),function(a){t(f,function(b){var d=b.cloneNode(!0);c(a,d),g[e]=d,e++})},this),t(g,function(a,b){f[b]=a}),f.length=e;return f}function x(a,b,c){for(var d=0,e=a.length;d<e;++d)if(b.call(c,a[d],d,a))return!0;return!1}function w(a){return a&&a.nodeName&&a.nodeType==1}function v(a){return a.replace(/-(.)/g,function(a,b){return b.toUpperCase()})}function t(a,b,c){for(var d=0,e=a.length;d<e;d++)b.call(c||a[d],a[d],d,a);return a}function s(a){return new RegExp("(^|\\s+)"+a+"(\\s+|$)")}var b=a.document,c=b.documentElement,d=null,e="getElementsByTagName",f=/^checked|value|selected$/,g=/select|map|fieldset|table|tbody|tr|colgroup/i,h={select:"option",table:"tbody",tr:"td"},i=/^checked|selected$/,j=/msie/i.test(navigator.userAgent),k=[],l=0,m=/^-?[\d\.]+$/,n="px",o="setAttribute",p="getAttribute",q=/(^\s*|\s*$)/g,r={lineHeight:1,zoom:1,zIndex:1,opacity:1},u=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(q,"")},y=b.defaultView&&b.defaultView.getComputedStyle?function(a,c){var d=null;c=="float"&&(c="cssFloat");var e=b.defaultView.getComputedStyle(a,"");e&&(d=e[v(c)]);return a.style[c]||d}:j&&c.currentStyle?function(a,b){b=v(b),b=b=="float"?"styleFloat":b;if(b=="opacity"){var c=100;try{c=a.filters["DXImageTransform.Microsoft.Alpha"].opacity}catch(d){try{c=a.filters("alpha").opacity}catch(e){}}return c/100}var f=a.currentStyle?a.currentStyle[b]:null;return a.style[b]||f}:function(a,b){return a.style[v(b)]};B.prototype={each:function(a,b){return t(this,a,b)},map:function(a,b){var c=[],d,e;for(e=0;e<this.length;e++)d=a.call(this,this[e]),b?b(d)&&c.push(d):c.push(d);return c},first:function(){return G(this[0])},last:function(){return G(this[this.length-1])},html:function(a,b){function f(b,c){while(b.firstChild)b.removeChild(b.firstChild);t(C(a,c),function(a){b.appendChild(a)})}var d=b?c.textContent==null?"innerText":"textContent":"innerHTML",e;return typeof a!="undefined"?this.each(function(b){(e=b.tagName.match(g))?f(b,e[0]):b[d]=a}):this[0]?this[0][d]:""},text:function(a){return this.html(a,1)},addClass:function(a){return this.each(function(b){this.hasClass(b,a)||(b.className=u(b.className+" "+a))},this)},removeClass:function(a){return this.each(function(b){this.hasClass(b,a)&&(b.className=u(b.className.replace(s(a)," ")))},this)},hasClass:function(a,b){return typeof b=="undefined"?x(this,function(b){return s(a).test(b.className)}):s(b).test(a.className)},toggleClass:function(a,b){if(typeof b!="undefined"&&!b)return this;return this.each(function(b){this.hasClass(b,a)?b.className=u(b.className.replace(s(a)," ")):b.className=u(b.className+" "+a)},this)},show:function(a){return this.each(function(b){b.style.display=a||""})},hide:function(a){return this.each(function(a){a.style.display="none"})},append:function(a){return this.each(function(b){t(C(a),function(a){b.appendChild(a)})})},prepend:function(a){return this.each(function(b){var c=b.firstChild;t(C(a),function(a){b.insertBefore(a,c)})})},appendTo:function(a,b){return z.call(this,a,b,function(a,b){a.appendChild(b)})},prependTo:function(a,b){return z.call(this,a,b,function(a,b){a.insertBefore(b,a.firstChild)})},next:function(){return this.related("nextSibling")},previous:function(){return this.related("previousSibling")},related:function(a){return this.map(function(b){b=b[a];while(b&&b.nodeType!==1)b=b[a];return b||0},function(a){return a})},before:function(a){return this.each(function(b){t(G.create(a),function(a){b.parentNode.insertBefore(a,b)})})},after:function(a){return this.each(function(b){t(G.create(a),function(a){b.parentNode.insertBefore(a,b.nextSibling)})})},insertBefore:function(a,b){return z.call(this,a,b,function(a,b){a.parentNode.insertBefore(b,a)})},insertAfter:function(a,b){return z.call(this,a,b,function(a,b){var c=a.nextSibling;c?a.parentNode.insertBefore(b,c):a.parentNode.appendChild(b)})},css:function(a,b){if(b===undefined&&typeof a=="string")return y(this[0],a);var c=a;typeof a=="string"&&(c={},c[a]=b),j&&c.opacity&&(c.filter="alpha(opacity="+c.opacity*100+")",c.zoom=a.zoom||1,delete c.opacity);if(b=c["float"])j?c.styleFloat=b:c.cssFloat=b,delete c["float"];var d=function(a,b,d){for(var e in c)c.hasOwnProperty(e)&&(d=c[e],(b=v(e))&&m.test(d)&&!(b in r)&&(d+=n),a.style[b]=d)};return this.each(d)},offset:function(a,b){if(a||b)return this.each(function(c){A(c,a,b)});var c=this[0],d=c.offsetWidth,e=c.offsetHeight,f=c.offsetTop,g=c.offsetLeft;while(c=c.offsetParent)f=f+c.offsetTop,g=g+c.offsetLeft;return{top:f,left:g,height:e,width:d}},attr:function(a,b){var c=this[0];return typeof b=="undefined"?f.test(a)?i.test(a)&&typeof c[a]=="string"?!0:c[a]:c[p](a):this.each(function(c){a=="value"?c.value=b:c[o](a,b)})},val:function(a){return typeof a=="string"?this.attr("value",a):this[0].value},removeAttr:function(a){return this.each(function(b){b.removeAttribute(a)})},data:function(a,b){var c=this[0];if(typeof b=="undefined"){c[p]("data-node-uid")||c[o]("data-node-uid",++l);var d=c[p]("data-node-uid");k[d]||(k[d]={});return k[d][a]}return this.each(function(c){c[p]("data-node-uid")||c[o]("data-node-uid",++l);var d=c[p]("data-node-uid"),e={};e[a]=b,k[d]=e})},remove:function(){return this.each(function(a){a.parentNode&&a.parentNode.removeChild(a)})},empty:function(){return this.each(function(a){while(a.firstChild)a.removeChild(a.firstChild)})},detach:function(){return this.map(function(a){return a.parentNode.removeChild(a)})},scrollTop:function(a){return D.call(this,null,a,"y")},scrollLeft:function(a){return D.call(this,a,null,"x")}},G.setQueryEngine=function(a){d=a,delete G.setQueryEngine},G.aug=function(a,b){for(var c in a)a.hasOwnProperty(c)&&((b||B.prototype)[c]=a[c])},G.create=function(a,c){return typeof a=="string"?function(){var d=c?h[c.toLowerCase()]:null,e=b.createElement(d||"div"),f=[];if(c){var g=a.match(new RegExp("<"+d+">.+?<\\/"+d+">","g"));t(g,function(a){a=a.replace(/<(.+)>(.+?)<\/\1>/,"$2");var c=b.createElement(d);c.appendChild(b.createDocumentFragment(a)),e.appendChild(c)})}else e.innerHTML=a;var i=e.childNodes;e=e.firstChild,f.push(e);while(e=e.nextSibling)e.nodeType==1&&f.push(e);return f}():w(a)?[a.cloneNode(!0)]:[]},G.doc=function(){var a=c.scrollWidth,b=c.scrollHeight,d=this.viewport();return{width:Math.max(a,d.width),height:Math.max(b,d.height)}},G.firstChild=function(a){for(var b=a.childNodes,c=0,d=b&&b.length||0,e;c<d;c++)b[c].nodeType===1&&(e=b[d=c]);return e},G.viewport=function(){var a=self.innerHeight,b=self.innerWidth;j&&(a=c.clientHeight)&&(b=c.clientWidth);return{width:b,height:a}},G.isAncestor="compareDocumentPosition"in c?function(a,b){return(a.compareDocumentPosition(b)&16)==16}:"contains"in c?function(a,b){return a!==b&&a.contains(b)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1};var H=a.bonzo;G.noConflict=function(){a.bonzo=H;return this},a.bonzo=G}(this),!function(a){function d(a){var b=[],c,d;label:for(c=0;c<a.length;c++){for(d=0;d<b.length;d++)if(b[d]==a[c])continue label;b[b.length]=a[c]}return b}function c(a,b){for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1}var b=bonzo;b.setQueryEngine(a),a.ender(b),a.ender(b(),!0),a.ender({create:function(c){return a(b.create(c))}}),a.id=function(b){return a([document.getElementById(b)])},a.ender({parents:function(b,e){var f=a(b),g,h,i,j=[];for(g=0,h=this.length;g<h;g++){i=this[g];while(i=i.parentNode)if(c(f,i)!==-1){j.push(i);if(e)break}}return a(d(j))},closest:function(a){return this.parents(a,!0)},first:function(){return a(this[0])},last:function(){return a(this[this.length-1])},next:function(){return a(b(this).next())},previous:function(){return a(b(this).previous())},appendTo:function(a){return b(this.selector).appendTo(a,this)},prependTo:function(a){return b(this.selector).prependTo(a,this)},insertAfter:function(a){return b(this.selector).insertAfter(a,this)},insertBefore:function(a){return b(this.selector).insertBefore(a,this)},siblings:function(){var b,c,d,e=[];for(b=0,c=this.length;b<c;b++){d=this[b];while(d=d.previousSibling)d.nodeType==1&&e.push(d);d=this[b];while(d=d.nextSibling)d.nodeType==1&&e.push(d)}return a(e)},children:function(){var c,e=[];for(i=0,l=this.length;i<l;i++){if(!(c=b.firstChild(this[i])))continue;e.push(c);while(c=c.nextSibling)c.nodeType==1&&e.push(c)}return a(d(e))},height:function(a){return a?this.css("height",a):parseInt(this.css("height"),10)},width:function(a){return a?this.css("width",a):parseInt(this.css("width"),10)}},!0)}(ender||$),!function(){var a={},b={exports:a};!function(a){function k(){c=1;for(var a=0,b=d.length;a<b;a++)d[a]()}var c=0,d=[],e,f=!1,g=a.createElement("a"),h="DOMContentLoaded",i="addEventListener",j="onreadystatechange";/^loade|c/.test(a.readyState)&&(c=1),a[i]&&a[i](h,function b(){a.removeEventListener(h,b,f),k()},f),g.doScroll&&a.attachEvent(j,e=function b(){/^c/.test(a.readyState)&&(a.detachEvent(j,b),k())});var l=g.doScroll?function(a){self!=top?c?a():d.push(a):!function(){try{g.doScroll("left")}catch(b){return setTimeout(function(){l(a)},50)}a()}()}:function(a){c?a():d.push(a)};typeof b!="undefined"&&b.exports?b.exports={domReady:l}:window.domReady=l}(document),$.ender(b.exports)}.call($),!function(a,b){function V(a,c){var d=typeof c=="string"?V(c)[0]:c||b;if(!d||!a)return[];if(h=S(a,c,V))return h;return X(a,d)}function U(a){var b=[],c,d;label:for(c=0;c<a.length;c++){for(d=0;d<b.length;d++)if(b[d]==a[c])continue label;b[b.length]=a[c]}return b}function T(a){return a&&a.nodeType&&(a.nodeType==1||a.nodeType==9)}function S(a,c,d){var e=typeof c=="string"?d(c)[0]:c||b;if(a===window||T(a))return!c||a!==window&&T(e)&&W(a,e)?[a]:[];if(a&&typeof a=="object"&&isFinite(a.length))return G(a);if(h=a.match(w))return(m=b.getElementById(h[1]))?[m]:[];if(h=a.match(y))return G(e.getElementsByTagName(h[1]));return!1}function R(a){var b=[],c=[],d,g,h=L.g(a)||L.s(a,a.split(B));h=h.slice(0);if(!h.length)return b;b=O(h);if(!h.length)return b;for(e=0,g=b.length,f=0;e<g;e++){n=b[e],j=n;for(d=h.length;d--;)z:while(j!==A&&(j=j.parentNode))if(p=N.apply(j,M(h[d])))break z;p&&(c[f++]=n)}return c}function Q(a,b,c){switch(a){case"=":return b==c;case"^=":return b.match(K.g("^="+c)||K.s("^="+c,new RegExp("^"+P(c))));case"$=":return b.match(K.g("$="+c)||K.s("$="+c,new RegExp(P(c)+"$")));case"*=":return b.match(K.g(c)||K.s(c,new RegExp(P(c))));case"~=":return b.match(K.g("~="+c)||K.s("~="+c,new RegExp("(?:^|\\s+)"+P(c)+"(?:\\s+|$)")));case"|=":return b.match(K.g("|="+c)||K.s("|="+c,new RegExp("^"+P(c)+"(-|$)")))}return!1}function P(a){return J.g(a)||J.s(a,a.replace(C,"\\$1"))}function O(a){var c=[],d=a.pop(),e=M(d),f=e[1]||"*",g,i,j,k=a.length&&(h=a[0].match(w))?b.getElementById(h[1]):b;if(!k)return c;j=k.getElementsByTagName(f);for(g=0,i=j.length;g<i;g++)m=j[g],(r=N.apply(m,e))&&c.push(r);return c}function N(a,b,c,e,f,g,h){var j,k,l;if(b&&this.tagName.toLowerCase()!==b)return!1;if(c&&(j=c.match(u))&&j[1]!==this.id)return!1;if(c&&(q=c.match(v)))for(d=q.length;d--;){k=q[d].slice(1);if(!(I.g(k)||I.s(k,new RegExp("(^|\\s+)"+k+"(\\s+|$)"))).test(this.className))return!1}if(e&&!h){i=this.attributes;for(l in i)if(Object.prototype.hasOwnProperty.call(i,l)&&(i[l].name||l)==f)return this}if(e&&!Q(g,this.getAttribute(f)||"",h))return!1;return this}function M(a){return a.match(F)}function G(a){k=[];for(d=0,o=a.length;d<o;d++)k[d]=a[d];return k}var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=/#([\w\-]+)/,v=/\.[\w\-]+/g,w=/^#([\w\-]+$)/,x=/^\.([\w\-]+)$/,y=/^([\w\-]+)$/,z=/^([\w]+)?\.([\w\-]+)$/,A=b.documentElement,B=/\s(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\])/,C=/([.*+?\^=!:${}()|\[\]\/\\])/g,D=/^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,E=/\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,F=new RegExp(D.source+"("+E.source+")?"),H=function(){this.c={}};H.prototype={g:function(a){return this.c[a]||undefined},s:function(a,b){this.c[a]=b;return b}};var I=new H,J=new H,K=new H,L=new H,W="compareDocumentPosition"in A?function(a,b){return(b.compareDocumentPosition(a)&16)==16}:"contains"in A?function(a,c){c=c==b||c==window?A:c;return c!==a&&c.contains(a)}:function(a,b){while(a=a.parentNode)if(a===b)return 1;return 0},X=b.querySelector&&b.querySelectorAll?function(a,c){if(b.getElementsByClassName&&(h=a.match(x)))return G(c.getElementsByClassName(h[1]));return G(c.querySelectorAll(a))}:function(a,c){var d=[],f,i=[],j;if(h=a.match(z)){s=c.getElementsByTagName(h[1]||"*"),k=I.g(h[2])||I.s(h[2],new RegExp("(^|\\s+)"+h[2]+"(\\s+|$)"));for(j=0,g=s.length,e=0;j<g;j++)k.test(s[j].className)&&(d[e++]=s[j]);return d}for(j=0,s=a.split(","),g=s.length;j<g;j++)i[j]=R(s[j]);for(j=0,g=i.length;j<g&&(f=i[j]);j++){var l=f;if(c!==b){l=[];for(e=0,h=f.length;e<h&&(element=f[e]);e++)W(element,c)&&l.push(element)}d=d.concat(l)}return U(d)};V.uniq=U;var Y=a.qwery;V.noConflict=function(){a.qwery=Y;return this},a.qwery=V}(this,document),!function(a){function c(b,c){var d=(c||a).createElement("div"),e=[];d.innerHTML=b;var f=d.childNodes;d=d.firstChild,e.push(d);while(d=d.nextSibling)d.nodeType==1&&e.push(d);return e}var b=qwery.noConflict();$._select=function(a,d){return/^\s*</.test(a)?c(a,d):b(a,d)},$.ender({find:function(a){var c=[],d,e,f,g,h;for(d=0,e=this.length;d<e;d++){h=b(a,this[d]);for(f=0,g=h.length;f<g;f++)c.push(h[f])}return $(b.uniq(c))},and:function(a){var b=$(a);for(var c=this.length,d=0,e=this.length+b.length;c<e;c++,d++)this[c]=b[d];return this}},!0)}(document)
\ No newline at end of file
diff --git a/source/javascripts/libs/ie/DOMAssistantComplete-2.8.js b/source/javascripts/libs/ie/DOMAssistantComplete-2.8.js
new file mode 100644
index 00000000..ddca30ed
--- /dev/null
+++ b/source/javascripts/libs/ie/DOMAssistantComplete-2.8.js
@@ -0,0 +1,1529 @@
+// Developed by Robert Nyman/DOMAssistant team, code/licensing: http://domassistant.googlecode.com/, documentation: http://www.domassistant.com/documentation, version 2.8
+var DOMAssistant = function () {
+	var HTMLArray = function () {
+		// Constructor
+	},
+	w = window, _$ = w.$, _$$ = w.$$,
+	isIE = /*@cc_on!@*/false,
+	isIE5 = isIE && parseFloat(navigator.appVersion) < 6,
+	sort, tagCache = {}, lastCache = {}, useCache = true,
+	slice = Array.prototype.slice,
+	camel = {
+		"accesskey": "accessKey",
+		"class": "className",
+		"colspan": "colSpan",
+		"for": "htmlFor",
+		"maxlength": "maxLength",
+		"readonly": "readOnly",
+		"rowspan": "rowSpan",
+		"tabindex": "tabIndex",
+		"valign": "vAlign",
+		"cellspacing": "cellSpacing",
+		"cellpadding": "cellPadding"
+	},
+	regex = {
+		rules: /\s*,\s*/g,
+		selector: /^(\w+|\*)?(#[\w\u00C0-\uFFFF\-=$]+)?((\.[\w\u00C0-\uFFFF\-]+)*)?((\[\w+\s*([~^$*|])?(=\s*([-\w\u00C0-\uFFFF\s.]+|"[^"]*"|'[^']*'))?\]+)*)?((:\w[-\w]*(\((odd|even|\-?\d*n?([-+]\d+)?|[:#]?[-\w\u00C0-\uFFFF.]+|"[^"]*"|'[^']*'|((\w*\.[-\w\u00C0-\uFFFF]+)*)?|(\[#?\w+([~^$*|])?=?[-\w\u00C0-\uFFFF\s.'"]+\]+)|(:\w[-\w]*\(.+\)))\))?)*)?([+>~])?/,
+		selectorSplit: /(?:\[.*\]|\(.*\)|[^\s+>~[(])+|[+>~]/g,
+		id: /^#([-\w\u00C0-\uFFFF=$]+)$/,
+		tag: /^\w+/,
+		relation: /^[+>~]$/,
+		pseudo: /^:(\w[-\w]*)(\((.+)\))?$/,
+		pseudos: /:(\w[-\w]*)(\((([^(]+)|([^(]+\([^(]+)\))\))?/g,
+		attribs: /\[(\w+)\s*([~^$*|])?(=)?\s*([^\[\]]*|"[^"]*"|'[^']*')?\](?=$|\[|:|\s)/g,
+		classes: /\.([-\w\u00C0-\uFFFF]+)/g,
+		quoted: /^["'](.*)["']$/,
+		nth: /^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n([-+]\d+)?)|(-(([1-9]\d*)?)n\+(\d+)))$/,
+		special: /(:check|:enabl|\bselect)ed\b/
+	},
+	navigate = function (node, direction, checkTagName) {
+		var oldName = node.tagName;
+		while ((node = node[direction + "Sibling"]) && (node.nodeType !== 1 || (checkTagName? node.tagName !== oldName : node.tagName === "!"))) {}
+		return node;
+	},
+	def = function (obj) {
+		return typeof obj !== "undefined";
+	},
+	sortDocumentOrder = function (elmArray) {
+		return (sortDocumentOrder = elmArray[0].compareDocumentPosition? function (elmArray) { return elmArray.sort( function (a, b) { return 3 - (a.compareDocumentPosition(b) & 6); } ); } :
+			isIE? function (elmArray) { return elmArray.sort( function (a, b) { return a.sourceIndex - b.sourceIndex; } ); } :
+			function (elmArray) { return elmArray.sort( function (a, b) {
+				var range1 = document.createRange(), range2 = document.createRange();
+				range1.setStart(a, 0);
+				range1.setEnd(a, 0);
+				range2.setStart(b, 0);
+				range2.setEnd(b, 0);
+				return range1.compareBoundaryPoints(Range.START_TO_END, range2);
+			} ); })(elmArray);
+	};
+	var pushAll = function (set1, set2) {
+		set1.push.apply(set1, slice.apply(set2));
+		return set1;
+	};
+	if (isIE) {
+		pushAll = function (set1, set2) {
+			if (set2.slice) {
+				return set1.concat(set2);
+			}
+			var i=0, item;
+			while ((item = set2[i++])) {
+				set1[set1.length] = item;
+			}
+			return set1;
+		};
+	}
+	return {
+		isIE : isIE,
+		camel : camel,
+		def : def,
+		allMethods : [],
+		publicMethods : [
+			"prev",
+			"next",
+			"hasChild",
+			"cssSelect",
+			"elmsByClass",
+			"elmsByAttribute",
+			"elmsByTag"
+		],
+		
+		harmonize : function () {
+			w.$ = _$;
+			w.$$ = _$$;
+			return this;
+		},
+		
+		initCore : function () {
+			this.applyMethod.call(w, "$", this.$);
+			this.applyMethod.call(w, "$$", this.$$);
+			w.DOMAssistant = this;
+			if (isIE) {
+				HTMLArray = Array;
+			}
+			HTMLArray.prototype = [];
+			(function (H) {
+				H.each = function (fn, context) {
+					for (var i=0, il=this.length; i<il; i++) {
+						if (fn.call(context || this[i], this[i], i, this) === false) {
+							break;
+						}
+					}
+					return this;
+				};
+				H.first = function () {
+					return def(this[0])? DOMAssistant.addMethodsToElm(this[0]) : null;
+				};
+				H.end = function () {
+					return this.previousSet;
+				};
+				H.indexOf = H.indexOf || function (elm) {
+					for (var i=0, il=this.length; i<il; i++) {
+						if (i in this && this[i] === elm) {
+							return i;
+						}
+					}
+					return -1;
+				};
+				H.map = function (fn, context) {
+					var res = [];
+					for (var i=0, il=this.length; i<il; i++) {
+						if (i in this) {
+							res[i] = fn.call(context || this[i], this[i], i, this);
+						}
+					}
+					return res;
+				};
+				H.filter = function (fn, context) {
+					var res = new HTMLArray();
+					res.previousSet = this;
+					for (var i=0, il=this.length; i<il; i++) {
+						if (i in this && fn.call(context || this[i], this[i], i, this)) {
+							res.push(this[i]);
+						}
+					}
+					return res;
+				};
+				H.every = function (fn, context) {
+					for (var i=0, il=this.length; i<il; i++) {
+						if (i in this && !fn.call(context || this[i], this[i], i, this)) {
+							return false;
+						}
+					}
+					return true;
+				};
+				H.some = function (fn, context) {
+					for (var i=0, il=this.length; i<il; i++) {
+						if (i in this && fn.call(context || this[i], this[i], i, this)) {
+							return true;
+						}
+					}
+					return false;
+				};
+			})(HTMLArray.prototype);
+			this.attach(this);
+		},
+		
+		addMethods : function (name, method) {
+			if (!def(this.allMethods[name])) {
+				this.allMethods[name] = method;
+				this.addHTMLArrayPrototype(name, method);
+			}
+		},
+		
+		addMethodsToElm : function (elm) {
+			for (var method in this.allMethods) {
+				if (def(this.allMethods[method])) {
+					this.applyMethod.call(elm, method, this.allMethods[method]);
+				}
+			}
+			return elm;
+		},
+		
+		applyMethod : function (method, func) {
+			if (typeof this[method] !== "function") {
+				this[method] = func;
+			}
+		},
+		
+		attach : function (plugin) {
+			var publicMethods = plugin.publicMethods;
+			if (!def(publicMethods)) {
+				for (var method in plugin) {
+					if (method !== "init" && def(plugin[method])) {
+						this.addMethods(method, plugin[method]);
+					}
+				}
+			}
+			else if (publicMethods.constructor === Array) {
+				for (var i=0, current; (current=publicMethods[i]); i++) {
+					this.addMethods(current, plugin[current]);
+				}
+			}
+			if (typeof plugin.init === "function") {
+				plugin.init();
+			}
+		},
+		
+		addHTMLArrayPrototype : function (name, method) {
+			HTMLArray.prototype[name] = function () {
+				var elmsToReturn = new HTMLArray();
+				elmsToReturn.previousSet = this;
+				for (var i=0, il=this.length; i<il; i++) {
+					elmsToReturn.push(method.apply(DOMAssistant.$$(this[i]), arguments));
+				}
+				return elmsToReturn;
+			};
+		},
+		
+		cleanUp : function (elm) {
+			var children = elm.all || elm.getElementsByTagName("*");
+			for (var i=0, child; (child=children[i++]);) {
+				if (child.hasData && child.hasData()) {
+					if (child.removeEvent) { child.removeEvent(); }
+					child.unstore();
+				}
+			}
+			elm.innerHTML = "";
+		},
+		
+		setCache : function (cache) {
+			useCache = cache;
+		},
+		
+		$ : function () {
+			var obj = arguments[0];
+			if (arguments.length === 1 && (typeof obj === "object" || (typeof obj === "function" && !!obj.nodeName))) {
+				return DOMAssistant.$$(obj);
+			}
+			var elm = !!obj? new HTMLArray() : null;
+			for (var i=0, arg, idMatch; (arg=arguments[i]); i++) {
+				if (typeof arg === "string") {
+					arg = arg.replace(/^[^#\(]*(#)/, "$1");
+					if (regex.id.test(arg)) {
+						if ((idMatch = DOMAssistant.$$(arg.substr(1), false))) {
+							elm.push(idMatch);
+						}
+					}
+					else {
+						var doc = (document.all || document.getElementsByTagName("*")).length;
+						elm = (!document.querySelectorAll && useCache && lastCache.rule && lastCache.rule === arg && lastCache.doc === doc)? lastCache.elms : pushAll(elm, DOMAssistant.cssSelection.call(document, arg));
+						lastCache = { rule: arg, elms: elm, doc: doc };
+					}
+				}
+			}
+			return elm;
+		},
+		
+		$$ : function (id, addMethods) {
+			var elm = (typeof id === "object" || typeof id === "function" && !!id.nodeName)? id : document.getElementById(id),
+				applyMethods = def(addMethods)? addMethods : true,
+				getId = function(el) { var eid = el.id; return typeof eid !== "object"? eid : el.attributes.id.nodeValue; };
+			if (typeof id === "string" && elm && getId(elm) !== id) {
+				elm = null;
+				for (var i=0, item; (item=document.all[i]); i++) {
+					if (getId(item) === id) {
+						elm = item;
+						break;
+					}
+				}
+			}
+			if (elm && applyMethods && !elm.next) {
+				DOMAssistant.addMethodsToElm(elm);
+			}
+			return elm;
+		},
+		
+		prev : function () {
+			return DOMAssistant.$$(navigate(this, "previous"));
+		},
+
+		next : function () {
+			return DOMAssistant.$$(navigate(this, "next"));
+		},
+		
+		hasChild: function (elm) {
+			return this === document || this !== elm && (this.contains? this.contains(elm) : !!(this.compareDocumentPosition(elm) & 16));
+		},
+
+		getSequence : function (expression) {
+			var start, add = 2, max = -1, modVal = -1,
+				pseudoVal = regex.nth.exec(expression.replace(/^0n\+/, "").replace(/^2n$/, "even").replace(/^2n+1$/, "odd"));
+			if (!pseudoVal) {
+				return null;
+			}
+			if (pseudoVal[2]) {	// odd or even
+				start = (pseudoVal[2] === "odd")? 1 : 2;
+				modVal = (start === 1)? 1 : 0;
+			}
+			else if (pseudoVal[3]) {	// single digit
+				start = max = parseInt(pseudoVal[3], 10);
+				add = 0;
+			}
+			else if (pseudoVal[4]) {	// an+b
+				add = pseudoVal[6]? parseInt(pseudoVal[6], 10) : 1;
+				start = pseudoVal[7]? parseInt(pseudoVal[7], 10) : 0;
+				while (start < 1) {
+					start += add;
+				}
+				modVal = (start >= add)? (start - add) % add : start;
+			}
+			else if (pseudoVal[8]) {	// -an+b
+				add = pseudoVal[10]? parseInt(pseudoVal[10], 10) : 1;
+				start = max = parseInt(pseudoVal[11], 10);
+				while (start > add) {
+					start -= add;
+				}
+				modVal = (max >= add)? (max - add) % add : max;
+			}
+			return { start: start, add: add, max: max, modVal: modVal };
+		},
+		
+		cssByDOM : function (cssRule) {
+			var prevParents, currentRule, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, current, previous, prevParent, notElm, addElm, iteratorNext, childElm, sequence, anyTag,
+				elm = new HTMLArray(), index = elm.indexOf, prevElm = [], matchingElms = [], cssRules = cssRule.replace(regex.rules, ",").split(","), splitRule = {};
+			function clearAdded (elm) {
+				elm = elm || prevElm;
+				for (var n=elm.length; n--;) {
+					elm[n].added = null;
+					elm[n].removeAttribute("added");
+				}
+			}
+			function clearChildElms () {
+				for (var n=prevParents.length; n--;) {
+					prevParents[n].childElms = null;
+				}
+			}
+			function subtractArray (arr1, arr2) {
+				for (var i=0, src1; (src1=arr1[i]); i++) {
+					var found = false;
+					for (var j=0, src2; (src2=arr2[j]); j++) {
+						if (src2 === src1) {
+							found = true;
+							arr2.splice(j, 1);
+							break;
+						}
+					}
+					if (found) {
+						arr1.splice(i--, 1);
+					}
+				}
+				return arr1;
+			}
+			function getAttr (elm, attr) {
+				return (isIE || regex.special.test(attr))? elm[camel[attr.toLowerCase()] || attr] : elm.getAttribute(attr, 2);
+			}
+			function attrToRegExp (attrVal, substrOperator) {
+				attrVal = attrVal? attrVal.replace(regex.quoted, "$1").replace(/(\.|\[|\])/g, "\\$1") : null;
+				return {
+					"^": "^" + attrVal,
+					"$": attrVal + "$",
+					"*": attrVal,
+					"|": "^" + attrVal + "(\\-\\w+)*$",
+					"~": "\\b" + attrVal + "\\b"
+				}[substrOperator] || (attrVal !== null? "^" + attrVal + "$" : attrVal);
+			}
+			function notComment(el) {
+				return (el || this).tagName !== "!";
+			}
+			function getTags (tag, context) {
+				return isIE5? (tag === "*"? context.all : context.all.tags(tag)) : context.getElementsByTagName(tag);
+			}
+			function getElementsByTagName (tag, parent) {
+				tag = tag || "*";
+				parent = parent || document;
+				return (parent === document || parent.lastModified)? tagCache[tag] || (tagCache[tag] = getTags(tag, document)) : getTags(tag, parent);
+			}
+			function getElementsByPseudo (previousMatch, pseudoClass, pseudoValue) {
+				prevParents = [];
+				var pseudo = pseudoClass.split("-"), matchingElms = [], idx = 0, checkNodeName = /\-of\-type$/.test(pseudoClass), recur,
+				match = {
+					first: function(el) { return !navigate(el, "previous", checkNodeName); },
+					last: function(el) { return !navigate(el, "next", checkNodeName); },
+					empty: function(el) { return !el.firstChild; },
+					enabled: function(el) { return !el.disabled && el.type !== "hidden"; },
+					disabled: function(el) { return el.disabled; },
+					checked: function(el) { return el.checked; },
+					contains: function(el) { return (el.innerText || el.textContent || "").indexOf(pseudoValue.replace(regex.quoted, "$1")) > -1; },
+					other: function(el) { return getAttr(el, pseudoClass) === pseudoValue; }
+				};
+				function basicMatch(key) {
+					while ((previous=previousMatch[idx++])) {
+						if (notComment(previous) && match[key](previous)) {
+							matchingElms[matchingElms.length] = previous;
+						}
+					}
+					return matchingElms;
+				}
+				var word = pseudo[0] || null;
+				if (word && match[word]) {
+					return basicMatch(word);
+				}
+				switch (word) {
+					case "only":
+						var kParent, kTag;
+						while ((previous=previousMatch[idx++])) {
+							prevParent = previous.parentNode;
+							var q = previous.nodeName;
+							if (prevParent !== kParent || q !== kTag) {
+								if (match.first(previous) && match.last(previous)) {
+									matchingElms[matchingElms.length] = previous;
+								}
+								kParent = prevParent;
+								kTag = q;
+							}
+						}
+						break;
+					case "nth":
+						if (pseudoValue === "n") {
+							matchingElms = previousMatch;
+						}
+						else {
+							var direction = (pseudo[1] === "last")? ["lastChild", "previousSibling"] : ["firstChild", "nextSibling"];
+							sequence = DOMAssistant.getSequence(pseudoValue);
+							if (sequence) {
+								while ((previous=previousMatch[idx++])) {
+									prevParent = previous.parentNode;
+									prevParent.childElms = prevParent.childElms || {};
+									var p = previous.nodeName;
+									if (!prevParent.childElms[p]) {
+										var childCount = 0;
+										iteratorNext = sequence.start;
+										childElm = prevParent[direction[0]];
+										while (childElm && (sequence.max < 0 || iteratorNext <= sequence.max)) {
+											var c = childElm.nodeName;
+											if ((checkNodeName && c === p) || (!checkNodeName && childElm.nodeType === 1 && c !== "!")) {
+												if (++childCount === iteratorNext) {
+													if (c === p) { matchingElms[matchingElms.length] = childElm; }
+													iteratorNext += sequence.add;
+												}
+											}
+											childElm = childElm[direction[1]];
+										}
+										if (anyTag) { sort++; }
+										prevParent.childElms[p] = true;
+										prevParents[prevParents.length] = prevParent;
+									}
+								}
+								clearChildElms();
+							}
+						}
+						break;
+					case "target":
+						var hash = document.location.hash.slice(1);
+						if (hash) {
+							while ((previous=previousMatch[idx++])) {
+								if (getAttr(previous, "name") === hash || getAttr(previous, "id") === hash) {
+									matchingElms[matchingElms.length] = previous;
+									break;
+								}
+							}
+						}
+						break;
+					case "not":
+						if ((recur = regex.pseudo.exec(pseudoValue))) {
+							matchingElms = subtractArray(previousMatch, getElementsByPseudo(previousMatch, recur[1]? recur[1].toLowerCase() : null, recur[3] || null));
+						}
+						else {
+							for (var re in regex) {
+								if (regex[re].lastIndex) {
+									regex[re].lastIndex = 0;
+								}
+							}
+							pseudoValue = pseudoValue.replace(regex.id, "[id=$1]");
+							var notTag = regex.tag.exec(pseudoValue);
+							var notClass = regex.classes.exec(pseudoValue);
+							var notAttr = regex.attribs.exec(pseudoValue);
+							var notRegExp = new RegExp(notAttr? attrToRegExp(notAttr[4], notAttr[2]) : "(^|\\s)" + (notTag? notTag[0] : notClass? notClass[1] : "") + "(\\s|$)", "i");
+							while ((notElm=previousMatch[idx++])) {
+								addElm = null;
+								if (notTag && !notRegExp.test(notElm.nodeName) || notClass && !notRegExp.test(notElm.className)) {
+									addElm = notElm;
+								}
+								else if (notAttr) {
+									var att = getAttr(notElm, notAttr[1]);
+									if (!def(att) || att === false || typeof att === "string" && !notRegExp.test(att)) {
+										addElm = notElm;
+									}
+								}
+								if (addElm && !addElm.added) {
+									addElm.added = true;
+									matchingElms[matchingElms.length] = addElm;
+								}
+							}
+						}
+						break;
+					default: return basicMatch("other");
+				}
+				return matchingElms;
+			}
+			function pushUnique(set1, set2) {
+				var i=0, s=set1, item;
+				while ((item = set2[i++])) {
+					if (!s.length || s.indexOf(item) < 0) {
+						set1.push(item);
+					}
+				}
+				return set1;
+			}
+			sort = -1;
+			for (var a=0, tagBin=[]; (currentRule=cssRules[a]); a++) {
+				if (!(cssSelectors = currentRule.match(regex.selectorSplit)) || a && index.call(cssRules.slice(0, a), currentRule) > -1) { continue; }
+				prevElm = [this];
+				for (var i=0, rule; (rule=cssSelectors[i]); i++) {
+					matchingElms = [];
+					if ((childOrSiblingRef = regex.relation.exec(rule))) {
+						var idElm = null, nextWord = cssSelectors[i+1];
+						if ((nextTag = regex.tag.exec(nextWord))) {
+							nextTag = nextTag[0];
+							nextRegExp = new RegExp("(^|\\s)" + nextTag + "(\\s|$)", "i");
+						}
+						else if (regex.id.test(nextWord)) {
+							idElm = DOMAssistant.$(nextWord) || null;
+						}
+						for (var j=0, prevRef; (prevRef=prevElm[j]); j++) {
+							switch (childOrSiblingRef[0]) {
+								case ">":
+									var children = idElm || getElementsByTagName(nextTag, prevRef);
+									for (var k=0, child; (child=children[k]); k++) {
+										if (child.parentNode === prevRef) {
+											matchingElms[matchingElms.length] = child;
+										}
+									}
+									break;
+								case "+":
+									if ((prevRef = navigate(prevRef, "next"))) {
+										if ((idElm && idElm[0] === prevRef) || (!idElm && (!nextTag || nextRegExp.test(prevRef.nodeName)))) {
+											matchingElms[matchingElms.length] = prevRef;
+										}
+									}
+									break;
+								case "~":
+									while ((prevRef = prevRef.nextSibling) && !prevRef.added) {
+										if ((idElm && idElm[0] === prevRef) || (!idElm && (!nextTag || nextRegExp.test(prevRef.nodeName)))) {
+											prevRef.added = true;
+											matchingElms[matchingElms.length] = prevRef;
+										}
+									}
+									break;
+							}
+						}
+						prevElm = matchingElms;
+						clearAdded();
+						rule = cssSelectors[++i];
+						if (/^\w+$/.test(rule) || regex.id.test(rule)) {
+							continue;
+						}
+						prevElm.skipTag = true;
+					}
+					var cssSelector = regex.selector.exec(rule);
+					splitRule = {
+						tag : cssSelector[1]? cssSelector[1] : "*",
+						id : cssSelector[2],
+						allClasses : cssSelector[3],
+						allAttr : cssSelector[5],
+						allPseudos : cssSelector[10]
+					};
+					anyTag = (splitRule.tag === "*");
+					if (splitRule.id) {
+						var u = 0, DOMElm = document.getElementById(splitRule.id.slice(1));
+						if (DOMElm) {
+							while (prevElm[u] && !DOMAssistant.hasChild.call(prevElm[u], DOMElm)) { u++; }
+							matchingElms = (u < prevElm.length && (anyTag || splitRule.tag === DOMElm.tagName.toLowerCase()))? [DOMElm] : [];
+						}
+						prevElm = matchingElms;
+					}
+					else if (splitRule.tag && !prevElm.skipTag) {
+						if (i===0 && !matchingElms.length && prevElm.length === 1) {
+							prevElm = matchingElms = pushAll([], getElementsByTagName(splitRule.tag, prevElm[0]));
+						}
+						else {
+							for (var l=0, ll=prevElm.length, tagCollectionMatches, tagMatch; l<ll; l++) {
+								tagCollectionMatches = getElementsByTagName(splitRule.tag, prevElm[l]);
+								for (var m=0; (tagMatch=tagCollectionMatches[m]); m++) {
+									if (!tagMatch.added) {
+										tagMatch.added = true;
+										matchingElms[matchingElms.length] = tagMatch;
+									}
+								}
+							}
+							prevElm = matchingElms;
+							clearAdded();
+						}
+					}
+					if (!matchingElms.length) {
+						break;
+					}
+					prevElm.skipTag = false;
+					if (splitRule.allClasses) {
+						var n = 0, matchingClassElms = [], allClasses = splitRule.allClasses.split(".").slice(1);
+						while ((current = prevElm[n++])) {
+							var matchCls = true, elmClass = current.className;
+							if (elmClass && elmClass.length) {
+								elmClass = elmClass.split(" ");
+								for (var o=allClasses.length; o--;) {
+									if (elmClass.indexOf(allClasses[o]) < 0) {
+										matchCls = false;
+										break;
+									}
+								}
+								if (matchCls) {
+									matchingClassElms[matchingClassElms.length] = current;
+								}
+							}
+						}
+						prevElm = matchingElms = matchingClassElms;
+					}
+					if (splitRule.allAttr) {
+						var matchAttr, r = 0, regExpAttributes = [], matchingAttributeElms = [], allAttr = splitRule.allAttr.match(regex.attribs);
+						for (var specialStrip = /^\[(selected|readonly)(\s*=.+)?\]$/, q=0, ql=allAttr.length, attributeMatch, attrVal; q<ql; q++) {
+							regex.attribs.lastIndex = 0;
+							attributeMatch = regex.attribs.exec(allAttr[q].replace(specialStrip, "[$1]"));
+							attrVal = attrToRegExp(attributeMatch[4], attributeMatch[2] || null);
+							regExpAttributes[q] = [(attrVal? new RegExp(attrVal) : null), attributeMatch[1]];
+						}
+						while ((current = matchingElms[r++])) {
+							for (var s=0, sl=regExpAttributes.length; s<sl; s++) {
+								var attributeRegExp = regExpAttributes[s][0], currentAttr = getAttr(current, regExpAttributes[s][1]);
+								matchAttr = true;
+								if (!attributeRegExp && currentAttr === true) { continue; }
+								if ((!attributeRegExp && (!currentAttr || typeof currentAttr !== "string" || !currentAttr.length)) || (!!attributeRegExp && !attributeRegExp.test(currentAttr))) {
+									matchAttr = false;
+									break;
+								}
+							}
+							if (matchAttr) {
+								matchingAttributeElms[matchingAttributeElms.length] = current;
+							}
+						}
+						prevElm = matchingElms = matchingAttributeElms;
+					}
+					if (splitRule.allPseudos) {
+						var allPseudos = splitRule.allPseudos.match(regex.pseudos);
+						for (var t=0, tl=allPseudos.length; t<tl; t++) {
+							regex.pseudos.lastIndex = 0;
+							var pseudo = regex.pseudos.exec(allPseudos[t]);
+							var pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null;
+							var pseudoValue = pseudo[3] || null;
+							matchingElms = getElementsByPseudo(matchingElms, pseudoClass, pseudoValue);
+							clearAdded(matchingElms);
+						}
+						prevElm = matchingElms;
+					}
+				}
+				elm = ((tagBin.length && (anyTag || index.call(tagBin, splitRule.tag) >= 0 || index.call(tagBin, "*") >= 0))? pushUnique : pushAll)(elm, prevElm);
+				tagBin.push(splitRule.tag);
+				if (isIE && anyTag) { elm = elm.filter(notComment); }
+			}
+			return ((elm.length > 1 && cssRules.length > 1) || sort > 0)? sortDocumentOrder(elm) : elm;
+		},
+		
+		cssByXpath : function (cssRule) {
+			var ns = { xhtml: "http://www.w3.org/1999/xhtml" },
+				prefix = (document.documentElement.namespaceURI === ns.xhtml)? "xhtml:" : "",
+				nsResolver = function lookupNamespaceURI (prefix) {
+					return ns[prefix] || null;
+				};
+			DOMAssistant.cssByXpath = function (cssRule) {
+				var currentRule, cssSelectors, xPathExpression, cssSelector, splitRule, sequence,
+					elm = new HTMLArray(), cssRules = cssRule.replace(regex.rules, ",").split(",");
+				function attrToXPath (wrap) {
+					var pre = wrap? "[" : "", post = wrap? "]" : "";
+					return function (match, p1, p2, p3, p4) {
+						p4 = (p4 || "").replace(regex.quoted, "$1");
+						if (p1 === p4 && p1 === "readonly") { p3 = null; }
+						return pre + ({
+							"^": "starts-with(@" + p1 + ", \"" + p4 + "\")",
+							"$": "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p4.length - 1) + "), " + p4.length + ") = \"" + p4 + "\"",
+							"*": "contains(concat(\" \", @" + p1 + ", \" \"), \"" + p4 + "\")",
+							"|": "@" + p1 + "=\"" + p4 + "\" or starts-with(@" + p1 + ", \"" + p4 + "-\")",
+							"~": "contains(concat(\" \", @" + p1 + ", \" \"), \" " + p4 + " \")"
+						}[p2] || ("@" + p1 + (p3? "=\"" + p4 + "\"" : ""))) + post;
+					};
+				}
+				function pseudoToXPath (tag, pseudoClass, pseudoValue) {
+					tag = /\-child$/.test(pseudoClass)? "*" : tag;
+					var pseudo = pseudoClass.split("-"), position = ((pseudo[1] === "last")? "(count(following-sibling::" : "(count(preceding-sibling::") + tag + ") + 1)", recur, hash;
+					switch (pseudo[0]) {
+						case "nth": return (pseudoValue !== "n" && (sequence = DOMAssistant.getSequence(pseudoValue)))? ((sequence.start === sequence.max)? position + " = " + sequence.start : position + " mod " + sequence.add + " = " + sequence.modVal + ((sequence.start > 1)? " and " + position + " >= " + sequence.start : "") + ((sequence.max > 0)? " and " + position + " <= " + sequence.max: "")) : "";
+						case "not": return "not(" + ((recur = regex.pseudo.exec(pseudoValue))? pseudoToXPath(tag, recur[1]? recur[1].toLowerCase() : null, recur[3] || null) : pseudoValue.replace(regex.id, "[id=$1]").replace(regex.tag, "self::$0").replace(regex.classes, "contains(concat(\" \", @class, \" \"), \" $1 \")").replace(regex.attribs, attrToXPath())) + ")";
+						case "first": return "not(preceding-sibling::" + tag + ")";
+						case "last": return "not(following-sibling::" + tag + ")";
+						case "only": return "not(preceding-sibling::" + tag + " or following-sibling::" + tag + ")";
+						case "empty": return "not(child::*) and not(text())";
+						case "contains": return "contains(., \"" + pseudoValue.replace(regex.quoted, "$1") + "\")";
+						case "enabled": return "not(@disabled) and not(@type=\"hidden\")";
+						case "disabled": return "@disabled";
+						case "target": return "@name=\"" + (hash = document.location.hash.slice(1)) + "\" or @id=\"" + hash + "\"";
+						default: return "@" + pseudoClass + "=\"" + pseudoValue + "\"";
+					}
+				}
+				for (var i=0; (currentRule=cssRules[i]); i++) {
+					if (!(cssSelectors = currentRule.match(regex.selectorSplit)) || i && elm.indexOf.call(cssRules.slice(0, i), currentRule) > -1) { continue; }
+					xPathExpression = xPathExpression? xPathExpression + " | ." : ".";
+					for (var j=0, jl=cssSelectors.length; j<jl; j++) {
+						cssSelector = regex.selector.exec(cssSelectors[j]);
+						splitRule = {
+							tag: prefix + (cssSelector[1]? cssSelector[1] : "*"),
+							id: cssSelector[2],
+							allClasses: cssSelector[3],
+							allAttr: cssSelector[5],
+							allPseudos: cssSelector[10],
+							tagRelation: cssSelector[20]
+						};
+						xPathExpression +=
+							(splitRule.tagRelation? ({ ">": "/", "+": "/following-sibling::*[1]/self::", "~": "/following-sibling::" }[splitRule.tagRelation] || "") : ((j > 0 && regex.relation.test(cssSelectors[j-1]))? splitRule.tag : ("//" + splitRule.tag))) +
+							(splitRule.id || "").replace(regex.id, "[@id = \"$1\"]") +
+							(splitRule.allClasses || "").replace(regex.classes, "[contains(concat(\" \", @class, \" \"), \" $1 \")]") +
+							(splitRule.allAttr || "").replace(regex.attribs, attrToXPath(true));
+						if (splitRule.allPseudos) {
+							var allPseudos = splitRule.allPseudos.match(regex.pseudos);
+							for (var k=0, kl=allPseudos.length; k<kl; k++) {
+								regex.pseudos.lastIndex = 0;
+								var pseudo = regex.pseudos.exec(allPseudos[k]),
+									pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null,
+									pseudoValue = pseudo[3] || null,
+									xpath = pseudoToXPath(splitRule.tag, pseudoClass, pseudoValue);
+								if (xpath.length) {
+									xPathExpression += "[" + xpath + "]";
+								}
+							}
+						}
+					}
+				}
+				try {
+					var xPathNodes = document.evaluate(xPathExpression, this, nsResolver, 7, null), node, p=0;
+					while ((node = xPathNodes.snapshotItem(p++))) { elm.push(node); }
+				} catch (e) {}
+				return elm;
+			};
+			return DOMAssistant.cssByXpath.call(this, cssRule);
+		},
+		
+		cssSelection : function (cssRule) {
+			if (!cssRule) { return null; }
+			var special = regex.special.test(cssRule);
+			try {
+				if (document.querySelectorAll && !special) {
+					return pushAll(new HTMLArray(), this.querySelectorAll(cssRule));
+				}
+			} catch (e) {}
+			return ((document.evaluate && !special && !/-of-type/.test(cssRule))? DOMAssistant.cssByXpath : DOMAssistant.cssByDOM).call(this, cssRule);
+		},
+		
+		cssSelect : function (cssRule) {
+			return DOMAssistant.cssSelection.call(this, cssRule);
+		},
+		
+		elmsByClass : function (className, tag) {
+			var cssRule = (tag || "") + "." + className;
+			return DOMAssistant.cssSelection.call(this, cssRule);
+		},
+		
+		elmsByAttribute : function (attr, attrVal, tag, substrMatchSelector) {
+			var cssRule = (tag || "") + "[" + attr + ((attrVal && attrVal !== "*")? ((substrMatchSelector || "") + "=" + attrVal + "]") : "]");
+			return DOMAssistant.cssSelection.call(this, cssRule);
+		},
+		
+		elmsByTag : function (tag) {
+			return DOMAssistant.cssSelection.call(this, tag);
+		}
+	};
+}();
+DOMAssistant.initCore();
+DOMAssistant.Storage = function () {
+	var uniqueId = 1, data = [], expando = "_da" + +new Date();
+	return {
+		hasData : function () {
+			var uid = this[expando];
+			return !!uid && !!data[uid];
+		},
+		retrieve : function (key) {
+			if (!DOMAssistant.def(key)) {
+				return this[expando] || (this[expando] = uniqueId++);
+			}
+			if (!this[expando] || !data[this[expando]]) { return; }
+			return data[this[expando]][key];
+		},
+		
+		store : function (key, val) {
+			var uid = this[expando] || (this[expando] = uniqueId++);
+			data[uid] = data[uid] || {};
+			if (typeof key === "object") {
+				for (var i in key) {
+					if (typeof i === "string") {
+						data[uid][i] = key[i];
+					}
+				}
+			}
+			else {
+				data[uid][key] = val;
+			}
+			return this;
+		},
+		
+		unstore : function (key) {
+			var uid = this[expando] || (this[expando] = uniqueId++);
+			if (data[uid]) {
+				if (DOMAssistant.def(key)) {
+					delete data[uid][key];
+				}
+				else {
+					data[uid] = null;
+				}
+			}
+			return this;
+		}
+	};
+}();
+DOMAssistant.attach(DOMAssistant.Storage);
+DOMAssistant.AJAX = function () {
+	var globalXMLHttp = null,
+	readyState = 0,
+	status = -1,
+	statusText = "",
+	requestPool = [],
+	createAjaxObj = function (url, method, callback, addToContent) {
+		var params = null;
+		if (/POST/i.test(method)) {
+			url = url.split("?");
+			params = url[1];
+			url = url[0];
+		}
+		return {
+			url : url,
+			method : method,
+			callback : callback,
+			params : params,
+			headers : {},
+			responseType : "text",
+			addToContent : addToContent || false
+		};
+	};
+	return {
+		publicMethods : [
+			"ajax",
+			"get",
+			"post",
+			"load"
+		],
+		
+		initRequest : function () {
+			var XMLHttp = null;
+			if (!!window.XMLHttpRequest && !DOMAssistant.isIE) {
+				XMLHttp = new XMLHttpRequest();
+				DOMAssistant.AJAX.initRequest = function () {
+					return requestPool.length? requestPool.pop() : new XMLHttpRequest();
+				};
+			}
+			else if (!!window.ActiveXObject) {
+				var XMLHttpMS = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
+				for (var i=0; i<XMLHttpMS.length; i++) {
+					try {
+						XMLHttp = new window.ActiveXObject(XMLHttpMS[i]);
+						DOMAssistant.AJAX.initRequest = function () {
+							return requestPool.length? requestPool.pop() : new window.ActiveXObject(XMLHttpMS[i]);
+						};
+						break;
+					}
+					catch (e) {
+						XMLHttp = null;
+					}
+				}
+			}
+			return XMLHttp;
+		},
+		
+		ajax : function (ajaxObj) {
+			if (!ajaxObj.noParse && ajaxObj.url && /\?/.test(ajaxObj.url) && ajaxObj.method && /POST/i.test(ajaxObj.method)) {
+				var url = ajaxObj.url.split("?");
+				ajaxObj.url = url[0];
+				ajaxObj.params = url[1] + ((url[1].length > 0 && ajaxObj.params)? ("&" + ajaxObj.params) : "");
+			}
+			return DOMAssistant.AJAX.makeCall.call(this, ajaxObj);
+		},
+		
+		get : function (url, callback, addToContent) {
+			return DOMAssistant.AJAX.makeCall.call(this, createAjaxObj(url, "GET", callback, addToContent));
+		},
+		
+		post : function (url, callback) {
+			return DOMAssistant.AJAX.makeCall.call(this, createAjaxObj(url, "POST", callback));
+		},
+		
+		load : function (url, addToContent) {
+			this.get(url, DOMAssistant.AJAX.replaceWithAJAXContent, addToContent);
+		},
+		
+		makeCall : function (ajaxObj) {
+			var XMLHttp = DOMAssistant.AJAX.initRequest();
+			if (XMLHttp) {
+				globalXMLHttp = XMLHttp;
+				(function (elm) {
+					var url = ajaxObj.url,
+						method = ajaxObj.method || "GET",
+						callback = ajaxObj.callback,
+						params = ajaxObj.params,
+						headers = ajaxObj.headers,
+						responseType = ajaxObj.responseType || "text",
+						addToContent = ajaxObj.addToContent,
+						timeout = ajaxObj.timeout || null,
+						ex = ajaxObj.exception,
+						timeoutId = null,
+						done = false;
+					XMLHttp.open(method, url, true);
+					XMLHttp.setRequestHeader("AJAX", "true");
+					XMLHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+					if (method === "POST") {
+						XMLHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+						XMLHttp.setRequestHeader("Content-length", params? params.length : 0);
+						if (XMLHttp.overrideMimeType) {
+							XMLHttp.setRequestHeader("Connection", "close");
+						}
+					}
+					if (responseType === "json") {
+						XMLHttp.setRequestHeader("Accept", "application/json, text/javascript, */*");
+					}
+					for (var i in headers) {
+						if (typeof i === "string") {
+							XMLHttp.setRequestHeader(i, headers[i]);
+						}
+					}
+					if (typeof callback === "function") {
+						XMLHttp.onreadystatechange = function () {
+							try {
+								if (XMLHttp.readyState === 4 && !done) {
+									window.clearTimeout(timeoutId);
+									done = true;
+									status = XMLHttp.status;
+									statusText = XMLHttp.statusText;
+									readyState = 4;
+									if ((status || location.protocol !== "file:") && (status < 200 || status >= 300)) {
+										throw new Error(statusText);
+									}
+									var response = /xml/i.test(responseType)? XMLHttp.responseXML : XMLHttp.responseText;
+									if (/json/i.test(responseType) && !!response) {
+										response = (typeof JSON === "object" && typeof JSON.parse === "function")? JSON.parse(response) : eval("(" + response + ")");
+									}
+									globalXMLHttp = null;
+									XMLHttp.onreadystatechange = function () {};
+									requestPool.push(XMLHttp);
+									callback.call(elm, response, addToContent);
+								}
+							}
+							catch (e) {
+								globalXMLHttp = XMLHttp = null;
+								if (typeof ex === "function") {
+									ex.call(elm, e);
+									ex = null;
+								}
+							}
+						};
+					}
+					XMLHttp.send(params);
+					if (timeout) {
+						timeoutId = window.setTimeout( function () {
+							if (!done) {
+								XMLHttp.abort();
+								done = true;
+								if (typeof ex === "function") {
+									readyState = 0;
+									status = 408;
+									statusText = "Request timeout";
+									globalXMLHttp = XMLHttp = null;
+									ex.call(elm, new Error(statusText));
+									ex = null;
+								}
+							}
+						}, timeout);
+					}
+				})(this);
+			}
+			return this;
+		},
+		
+		replaceWithAJAXContent : function (content, add) {
+			if (add) {
+				this.innerHTML += content;
+			}
+			else {
+				DOMAssistant.cleanUp(this);
+				this.innerHTML = content;
+			}
+		},
+		
+		getReadyState : function () {
+			return (globalXMLHttp && DOMAssistant.def(globalXMLHttp.readyState))? globalXMLHttp.readyState : readyState;
+		},
+		
+		getStatus : function () {
+			return status;
+		},
+		
+		getStatusText : function () {
+			return statusText;
+		}
+	};
+}();
+DOMAssistant.attach(DOMAssistant.AJAX);
+DOMAssistant.CSS = function () {
+	var def = DOMAssistant.def,
+		direct = { display: true };
+	return {
+		addClass : function (className) {
+			if (!this.hasClass(className)) {
+				var currentClass = this.className;
+				this.className = currentClass + (currentClass.length? " " : "") + className;
+			}
+			return this;
+		},
+
+		removeClass : function (className) {
+			return this.replaceClass(className);
+		},
+
+		replaceClass : function (className, newClass) {
+			var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i");
+			this.className = this.className.replace(classToRemove, function (match, p1, p2) {
+				return newClass? (p1 + newClass + p2) : " ";
+			}).replace(/^\s+|\s+$/g, "");
+			return this;
+		},
+
+		hasClass : function (className) {
+			return (" " + this.className + " ").indexOf(" " + className + " ") > -1;
+		},
+
+		setStyle : function (style, value) {
+			var css = this.style;
+			if ("filters" in this && (typeof style === "string"? /opacity/i.test(style) : def(style.opacity))) {
+				css.zoom = 1;
+				css.filter = (css.filter || "").replace(/alpha\([^)]*\)/, "") + "alpha(opacity=" + (def(style.opacity)? style.opacity : value) * 100 + ")";
+			}
+			if (def(css.cssText)) {
+				var styleToSet = css.cssText;
+				if (typeof style === "object") {
+					for (var i in style) {
+						if (typeof i === "string") {
+							if (direct[i]) { css[i] = style[i]; }
+							styleToSet += ";" + i + ":" + style[i];
+						}
+					}
+				}
+				else {
+					if (direct[style]) { css[style] = value; }
+					styleToSet += ";" + style + ":" + value;
+				}
+				css.cssText = styleToSet;
+			}
+			return this;
+		},
+
+		getStyle : function (cssRule) {
+			var val = "", f;
+			cssRule = cssRule.toLowerCase();
+			if (document.defaultView && document.defaultView.getComputedStyle) {
+				val = document.defaultView.getComputedStyle(this, "").getPropertyValue(cssRule);
+			}
+			else if (this.currentStyle) {
+				if ("filters" in this && cssRule === "opacity") {
+					val = (f = this.style.filter || this.currentStyle.filter) && f.indexOf("opacity=") >= 0? parseFloat(f.match(/opacity=([^)]*)/)[1]) / 100 : 1;
+				}
+				else {
+					cssRule = cssRule.replace(/^float$/, "styleFloat").replace(/\-(\w)/g, function (match, p1) {
+						return p1.toUpperCase();
+					});
+					val = this.currentStyle[cssRule];
+				}
+				if (val === "auto" && /^(width|height)$/.test(cssRule) && this.currentStyle.display !== "none") {
+					val = this["offset" + cssRule.charAt(0).toUpperCase() + cssRule.substr(1)] + "px";
+				}
+			}
+			return val;
+		}
+	};
+}();
+DOMAssistant.attach(DOMAssistant.CSS);
+DOMAssistant.Content = function () {
+	var D$ = DOMAssistant.$$;
+	return {
+		init : function () {
+			DOMAssistant.setCache(false);
+		},
+
+		create : function (name, attr, append, content) {
+			var elm = D$(document.createElement(name));
+			if (attr) {
+				elm = elm.setAttributes(attr);
+			}
+			if (DOMAssistant.def(content)) {
+				elm.addContent(content);
+			}
+			if (append) {
+				this.appendChild(elm);
+			}
+			return elm;
+		},
+
+		setAttributes : function (attr) {
+			if (DOMAssistant.isIE) {
+				var setAttr = function (elm, att, val) {
+					var attLower = att.toLowerCase();
+					switch (attLower) {
+						case "name":
+						case "type":
+						case "multiple":
+							return D$(document.createElement(elm.outerHTML.replace(new RegExp(attLower + "(=[a-zA-Z]+)?"), " ").replace(">", " " + attLower + "=" + val + ">")));
+						case "style":
+							elm.style.cssText = val;
+							return elm;
+						default:
+							elm[DOMAssistant.camel[attLower] || att] = val;
+							return elm;
+					}
+				};
+				DOMAssistant.Content.setAttributes = function (attr) {
+					var elem = this;
+					var parent = this.parentNode;
+					for (var i in attr) {
+						if (typeof attr[i] === "string" || typeof attr[i] === "number") {
+							var newElem = setAttr(elem, i, attr[i]);
+							if (parent && /(name|type)/i.test(i)) {
+								if (elem.innerHTML) {
+									newElem.innerHTML = elem.innerHTML;
+								}
+								parent.replaceChild(newElem, elem);
+							}
+							elem = newElem;
+						}
+					}
+					return elem;
+				};
+			}
+			else {
+				DOMAssistant.Content.setAttributes = function (attr) {
+					for (var i in attr) {
+						if (/class/i.test(i)) {
+							this.className = attr[i];
+						}
+						else {
+							this.setAttribute(i, attr[i]);
+						}
+					}
+					return this;
+				};
+			}
+			return DOMAssistant.Content.setAttributes.call(this, attr); 
+		},
+
+		addContent : function (content) {
+			var type = typeof content;
+			if (type === "string" || type === "number") {
+				if (!this.firstChild) {
+					this.innerHTML = content;
+				}
+				else {
+					var tmp = document.createElement("div");
+					tmp.innerHTML = content;
+					for (var i=tmp.childNodes.length-1, last=null; i>=0; i--) {
+						last = this.insertBefore(tmp.childNodes[i], last);
+					}
+				}
+			}
+			else if (type === "object" || (type === "function" && !!content.nodeName)) {
+				this.appendChild(content);
+			}
+			return this;
+		},
+
+		replaceContent : function (content) {
+			DOMAssistant.cleanUp(this);
+			return this.addContent(content);
+		},
+
+		replace : function (content, returnNew) {
+			var type = typeof content;
+			if (type === "string" || type === "number") {
+				var parent = this.parentNode;
+				var tmp = DOMAssistant.Content.create.call(parent, "div", null, false, content);
+				for (var i=tmp.childNodes.length; i--;) {
+					parent.insertBefore(tmp.childNodes[i], this.nextSibling);
+				}
+				content = this.nextSibling;
+				parent.removeChild(this);
+			}
+			else if (type === "object" || (type === "function" && !!content.nodeName)) {
+				this.parentNode.replaceChild(content, this);
+			}
+			return returnNew? content : this;
+		},
+
+		remove : function () {
+			DOMAssistant.cleanUp(this);
+			if (this.hasData()) {
+				if (this.removeEvent) { this.removeEvent(); }
+				this.unstore();
+			}
+			this.parentNode.removeChild(this);
+			return null;
+		}
+	};
+}();
+DOMAssistant.attach(DOMAssistant.Content);
+DOMAssistant.Events = function () {
+	var handler,
+		key = "_events",
+		w3cMode = !!document.addEventListener,
+		useCapture = { focus: true, blur: true },
+		translate = DOMAssistant.isIE? { focus: "activate", blur: "deactivate", mouseenter: "mouseover", mouseleave: "mouseout" } : { mouseenter: "mouseover", mouseleave: "mouseout" },
+		regex = {
+			special: /^submit|reset|change|select$/i,
+			mouseenterleave: /^mouse(enter|leave)$/i,
+			dom: /^DOM/,
+			on: /^on/i
+		},
+		special = function (e) {
+			return DOMAssistant.isIE && regex.special.test(e);
+		},
+		fix = function (e) {
+			return translate[e] || e;
+		},
+		createEvent = function (e, type, target) {
+			e = e || window.event || {};
+			if (e.event) { return e; }
+			var event = {
+				event: e,
+				type: type || e.type,
+				bubbles: e.bubbles || true,
+				cancelable: e.cancelable || false,
+				target: target || e.target || e.srcElement,
+				clientX: e.clientX || 0,
+				clientY: e.clientY || 0,
+				altKey: e.altKey || false,
+				ctrlKey: e.ctrlKey || false,
+				shiftKey: e.shiftKey || false,
+				button: e.button || null,
+				timeStamp: +new Date(),
+				preventDefault: function() {
+					if (e.preventDefault) { e.preventDefault(); }
+					this.returnValue = e.returnValue = false;
+				},
+				stopPropagation: function() {
+					if (e.stopPropagation) { e.stopPropagation(); }
+					this.cancelBubble = e.cancelBubble = true;
+				}
+			};
+			if (event.target && 3 === event.target.nodeType) { // Safari textnode bug
+				event.target = event.target.parentNode;	
+			}
+			event.currentTarget = event.target;
+			event.relatedTarget = e.relatedTarget || (e.fromElement === event.target? e.toElement : e.fromElement) || null;
+			var de = document.documentElement, b = document.body;
+			event.pageX = DOMAssistant.def(e.pageX)? e.pageX : (event.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0));
+			event.pageY = DOMAssistant.def(e.pageY)? e.pageY : (event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0));
+			if ("number" === typeof e.which) {
+				event.keyCode = e.keyCode;
+				event.charCode = event.which = e.which;
+			}
+			else if (e.keyCode) {
+				event.keyCode = event.charCode = e.keyCode;
+			}
+			return event;
+		};
+
+	return {
+		publicMethods : [
+			"triggerEvent",
+			"addEvent",
+			"removeEvent",
+			"relayEvent",
+			"unrelayEvent",
+			"preventDefault",
+			"cancelBubble"
+		],
+
+		init : function () {
+			DOMAssistant.preventDefault = this.preventDefault;
+			DOMAssistant.cancelBubble = this.cancelBubble;
+			handler = this.handleEvent;
+		},
+
+		triggerEvent : function (evt, target, e) {
+			var fevt = fix(evt),
+				events = this.retrieve(key),
+				event = e || createEvent(e, fevt, target || this);
+			event.currentTarget = this;
+			if (events && events[fevt]) {
+				for (var i=0, iL=events[fevt].length; i<iL; i++) {
+					if (events[fevt][i].call(this, event) === false) { event.stopPropagation(); }
+				}
+			}
+			else if (typeof this["on" + fevt] === "function") {
+				this["on" + fevt].call(this, event);
+			}
+			var p = DOMAssistant.$$(this.parentNode);
+			if (!event.cancelBubble && p && p.nodeType === 1) {
+				p.triggerEvent(fevt, target, event);
+			}
+			return this;
+		},
+
+		addEvent : function (evt, func, relay, proxy, selector) {
+			var existingEvent,
+				fevt = fix(evt),
+				uid = fevt + this.retrieve(),
+				onevt = "on" + fevt;
+			if (!(func.attachedElements && func.attachedElements[uid])) {
+				var events = this.retrieve(key) || {};
+				if (!events[fevt]) {
+					events[fevt] = [];
+					existingEvent = this[onevt];
+					this[onevt] = null;
+				}
+				if (typeof this.window === "object") { this.window[onevt] = handler; }
+				else if (!events[fevt].length) {
+					if (w3cMode) { this.addEventListener(fevt, handler, useCapture[fevt]); }
+					else { this[onevt] = handler; }
+				}
+				if (existingEvent) {
+					events[fevt].push(existingEvent);
+				}
+				if (fevt !== evt) { func.evt = evt; }
+				func.relay = relay;
+				func.proxy = proxy;
+				func.selector = selector;
+				func.attachedElements = func.attachedElements || {};
+				func.attachedElements[uid] = true;
+				events[fevt].push(func);
+				this.store(key, events);
+			}
+			return this;
+		},
+
+		handleEvent : function (evt) {
+			var currentEvt = (evt && regex.dom.test(evt.type) && w3cMode)? evt : createEvent(evt),
+				type = fix(currentEvt.type),
+				targ = currentEvt.target,
+				relatedTarg = currentEvt.relatedTarget,
+				eventColl = this.retrieve(key)[type].slice(0), eventCollLength, eventReturn, oevt;
+			if ((eventCollLength = eventColl.length)) {
+				for (var i=0; i<eventCollLength; i++) {
+					if (typeof eventColl[i] === "function") {
+						if ((oevt = eventColl[i].evt) && oevt !== type) {
+							currentEvt.type = oevt;
+							if (relatedTarg && regex.mouseenterleave.test(oevt)) {
+								if (eventColl[i].relay) {
+									var elms = eventColl[i].elms || (eventColl[i].elms = this.cssSelect(eventColl[i].selector));
+									if (elms.indexOf(targ) < 0 || !DOMAssistant.hasChild.call(relatedTarg, targ)) { continue; }
+								}
+								else if (this === relatedTarg || this.hasChild(relatedTarg)) { continue; }
+							}
+						}
+						eventReturn = eventColl[i].call(this, currentEvt);
+					}
+				}
+				if (eventReturn === false) { currentEvt.stopPropagation(); }
+				return eventReturn;
+			}
+		},
+
+		removeEvent : function (evt, func, relay, proxy) {
+			var uid = (evt = fix(evt)) + this.retrieve(),
+				events = this.retrieve(key),
+				onevt = "on" + evt;
+			if (events && !evt) {
+				for (var ev in events) {
+					if (events[ev].length) { this.removeEvent(ev); }
+				}
+				var attr = this.attributes;
+				for (var att, j=attr.length; j--;) {
+					att = attr[j].nodeName.toLowerCase();
+					if (regex.on.test(att) && typeof this[att] === "function") {
+						this[att] = null;
+					}
+				}
+			}
+			else if (events && events[evt]) {
+				var eventColl = events[evt];
+				for (var fn, i=eventColl.length; i--;) {
+					fn = func || eventColl[i];
+					if (eventColl[i] === fn && relay === fn.relay && proxy === fn.proxy) {
+						eventColl.splice(i, 1);
+						if (!!proxy && fn.selector) {
+							this.cssSelect(fn.selector).removeEvent(proxy);
+						}
+						if (fn.attachedElements) {
+							fn.attachedElements[uid] = null;
+						}
+					}
+				}
+				if (!events[evt].length) {
+					if (w3cMode) { this.removeEventListener(evt, handler, useCapture[evt]); }
+					else { this[onevt] = null; }
+				}
+			}
+			else if (this[onevt] && !func && !relay) {
+				this[onevt] = null;
+			}
+			return this;
+		},
+
+		relayEvent: function (evt, selector, fn, proxy) {
+			if (special(evt)) {
+				this.relayEvent("focus", selector, function() {
+					DOMAssistant.$$(this).removeEvent(evt).addEvent(evt, function(e) {
+						return fn.call(this, createEvent(e));
+					});
+				}, evt).relayEvent("blur", selector, function() {
+					DOMAssistant.$$(this).removeEvent(evt);
+				}, evt);
+				return this;
+			}
+			return this.addEvent(evt, function(e) {
+				e = createEvent(e);
+				var target = e.target, args = arguments, i = 0, elm, elms = this.cssSelect(selector);
+				while ((elm = elms[i++])) {
+					if ((elm === target || DOMAssistant.hasChild.call(elm, target)) && !elm.disabled) {
+						e.currentTarget = elm;
+						var retVal = fn.apply(elm, args);
+						if (!retVal) { e.preventDefault(); }
+						return retVal;
+					}
+				}
+			}, true, proxy, selector);
+		},
+
+		unrelayEvent: function (evt) {
+			if (special(evt)) {
+				return this.removeEvent("focus", null, true, evt).removeEvent("blur", null, true, evt);
+			}
+			return this.removeEvent(evt, null, true);
+		},
+
+		preventDefault : function (evt) {
+			if (evt.preventDefault) { evt.preventDefault(); }
+			evt.returnValue = false;
+		},
+
+		cancelBubble : function (evt) {
+			if (evt.stopPropagation) { evt.stopPropagation(); }
+			evt.cancelBubble = true;
+		}
+	};
+}();
+DOMAssistant.attach(DOMAssistant.Events);
+DOMAssistant.DOMLoad = function () {
+	var DOMLoaded = false,
+	DOMLoadTimer = null,
+	functionsToCall = [],
+	addedStrings = {},
+	errorHandling = null,
+	execFunctions = function () {
+		for (var i=0, il=functionsToCall.length; i<il; i++) {
+			try {
+				functionsToCall[i]();
+			}
+			catch (e) {
+				if (errorHandling && typeof errorHandling === "function") {
+					errorHandling(e);
+				}
+			}
+		}
+		functionsToCall = [];
+	},
+	DOMHasLoaded = function () {
+		if (DOMLoaded) {
+			return;
+		}
+		DOMLoaded = true;
+		execFunctions();
+	};
+	/* Internet Explorer */
+	/*@cc_on
+	@if (@_win32 || @_win64)
+		document.write("<script id=\"ieScriptLoad\" defer src=\"//:\"><\/script>");
+		document.getElementById("ieScriptLoad").onreadystatechange = function() {
+			if (this.readyState === "complete") {
+				DOMHasLoaded();
+			}
+		};
+	@end @*/
+	/* Mozilla, Chrome, Opera */
+	if (document.addEventListener) {
+		document.addEventListener("DOMContentLoaded", DOMHasLoaded, false);
+	}
+	/* Safari, iCab, Konqueror */
+	if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
+		DOMLoadTimer = setInterval(function () {
+			if (/loaded|complete/i.test(document.readyState)) {
+				DOMHasLoaded();
+				clearInterval(DOMLoadTimer);
+			}
+		}, 10);
+	}
+	/* Other web browsers */
+	window.onload = DOMHasLoaded;
+	
+	return {
+		DOMReady : function () {
+			for (var i=0, il=arguments.length, funcRef; i<il; i++) {
+				funcRef = arguments[i];
+				if (!funcRef.DOMReady && !addedStrings[funcRef]) {
+					if (typeof funcRef === "string") {
+						addedStrings[funcRef] = true;
+						funcRef = new Function(funcRef);
+					}
+					funcRef.DOMReady = true;
+					functionsToCall.push(funcRef);
+				}
+			}
+			if (DOMLoaded) {
+				execFunctions();
+			}
+		},
+		
+		setErrorHandling : function (funcRef) {
+			errorHandling = funcRef;
+		}
+	};
+}();
+DOMAssistant.DOMReady = DOMAssistant.DOMLoad.DOMReady;
\ No newline at end of file
diff --git a/source/javascripts/libs/ie/respond.js b/source/javascripts/libs/ie/respond.js
new file mode 100644
index 00000000..e7a5bba3
--- /dev/null
+++ b/source/javascripts/libs/ie/respond.js
@@ -0,0 +1,292 @@
+/*
+ * respond.js - A small and fast polyfill for min/max-width CSS3 Media Queries
+ * Copyright 2011, Scott Jehl, scottjehl.com
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Usage: Check out the readme file or github.com/scottjehl/respond
+*/
+(function( win, mqSupported ){
+	//exposed namespace
+	win.respond		= {};
+
+	//define update even in native-mq-supporting browsers, to avoid errors
+	respond.update	= function(){};
+
+	//expose media query support flag for external use
+	respond.mediaQueriesSupported	= mqSupported;
+
+	//if media queries are supported, exit here
+	if( mqSupported ){ return; }
+
+	//define vars
+	var doc 			= win.document,
+		docElem 		= doc.documentElement,
+		mediastyles		= [],
+		rules			= [],
+		appendedEls 	= [],
+		parsedSheets 	= {},
+		resizeThrottle	= 30,
+		head 			= doc.getElementsByTagName( "head" )[0] || docElem,
+		links			= head.getElementsByTagName( "link" ),
+		requestQueue	= [],
+
+		//loop stylesheets, send text content to translate
+		ripCSS			= function(){
+			var sheets 	= links,
+				sl 		= sheets.length,
+				i		= 0,
+				//vars for loop:
+				sheet, href, media, isCSS;
+
+			for( ; i < sl; i++ ){
+				sheet	= sheets[ i ],
+				href	= sheet.href,
+				media	= sheet.media,
+				isCSS	= sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
+
+				//only links plz and prevent re-parsing
+				if( !!href && isCSS && !parsedSheets[ href ] ){
+					if( !/^([a-zA-Z]+?:(\/\/)?(www\.)?)/.test( href )
+						|| href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
+						requestQueue.push( {
+							href: href,
+							media: media
+						} );
+					}
+					else{
+						parsedSheets[ href ] = true;
+					}
+				}
+			}
+			makeRequests();
+
+		},
+
+		//recurse through request queue, get css text
+		makeRequests	= function(){
+			if( requestQueue.length ){
+				var thisRequest = requestQueue.shift();
+
+				ajax( thisRequest.href, function( styles ){
+					translate( styles, thisRequest.href, thisRequest.media );
+					parsedSheets[ thisRequest.href ] = true;
+					makeRequests();
+				} );
+			}
+		},
+
+		//find media blocks in css text, convert to style blocks
+		translate			= function( styles, href, media ){
+			var qs			= styles.match( /@media ([^\{]+)\{((?!@media)[\s\S])*(?=\}[\s]*\/\*\/mediaquery\*\/)/gmi ),
+				ql			= qs && qs.length || 0,
+				//try to get CSS path
+				href		= href.substring( 0, href.lastIndexOf( "/" )),
+				repUrls		= function( css ){
+					return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
+				},
+				useMedia	= !ql && media,
+				//vars used in loop
+				i			= 0,
+				j, fullq, thisq, eachq, eql;
+
+			//if path exists, tack on trailing slash
+			if( href.length ){ href += "/"; }
+
+			//if no internal queries exist, but media attr does, use that
+			//note: this currently lacks support for situations where a media attr is specified on a link AND
+				//its associated stylesheet has internal CSS media queries.
+				//In those cases, the media attribute will currently be ignored.
+			if( useMedia ){
+				ql = 1;
+			}
+
+
+			for( ; i < ql; i++ ){
+				j	= 0;
+
+				//media attr
+				if( useMedia ){
+					fullq = media;
+					rules.push( repUrls( styles ) );
+				}
+				//parse for styles
+				else{
+					fullq	= qs[ i ].match( /@media ([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
+					rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
+				}
+
+				eachq	= fullq.split( "," );
+				eql		= eachq.length;
+
+
+				for( ; j < eql; j++ ){
+					thisq	= eachq[ j ];
+					mediastyles.push( {
+						media	: thisq.match( /(only\s+)?([a-zA-Z]+)(\sand)?/ ) && RegExp.$2,
+						rules	: rules.length - 1,
+						minw	: thisq.match( /\(min\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/ ) && parseFloat( RegExp.$1 ),
+						maxw	: thisq.match( /\(max\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/ ) && parseFloat( RegExp.$1 )
+					} );
+				}
+			}
+
+			applyMedia();
+		},
+
+		lastCall,
+
+		resizeDefer,
+
+		//enable/disable styles
+		applyMedia			= function( fromResize ){
+			var name		= "clientWidth",
+				docElemProp	= docElem[ name ],
+				currWidth 	= doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
+				styleBlocks	= {},
+				dFrag		= doc.createDocumentFragment(),
+				lastLink	= links[ links.length-1 ],
+				now 		= (new Date()).getTime();
+
+			//throttle resize calls
+			if( fromResize && lastCall && now - lastCall < resizeThrottle ){
+				clearTimeout( resizeDefer );
+				resizeDefer = setTimeout( applyMedia, resizeThrottle );
+				return;
+			}
+			else {
+				lastCall	= now;
+			}
+
+			for( var i in mediastyles ){
+				var thisstyle = mediastyles[ i ];
+				if( !thisstyle.minw && !thisstyle.maxw ||
+					( !thisstyle.minw || thisstyle.minw && currWidth >= thisstyle.minw ) &&
+					(!thisstyle.maxw || thisstyle.maxw && currWidth <= thisstyle.maxw ) ){
+						if( !styleBlocks[ thisstyle.media ] ){
+							styleBlocks[ thisstyle.media ] = [];
+						}
+						styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
+				}
+			}
+
+			//remove any existing respond style element(s)
+			for( var i in appendedEls ){
+				if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){
+					head.removeChild( appendedEls[ i ] );
+				}
+			}
+
+			//inject active styles, grouped by media type
+			for( var i in styleBlocks ){
+				var ss		= doc.createElement( "style" ),
+					css		= styleBlocks[ i ].join( "\n" );
+
+				ss.type = "text/css";
+				ss.media	= i;
+
+				if ( ss.styleSheet ){
+		        	ss.styleSheet.cssText = css;
+		        }
+		        else {
+					ss.appendChild( doc.createTextNode( css ) );
+		        }
+		        dFrag.appendChild( ss );
+				appendedEls.push( ss );
+			}
+
+			//append to DOM at once
+			head.insertBefore( dFrag, lastLink.nextSibling );
+		},
+		//tweaked Ajax functions from Quirksmode
+		ajax = function( url, callback ) {
+			var req = xmlHttp();
+			if (!req){
+				return;
+			}
+			req.open( "GET", url, true );
+			req.onreadystatechange = function () {
+				if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){
+					return;
+				}
+				callback( req.responseText );
+			}
+			if ( req.readyState == 4 ){
+				return;
+			}
+			req.send();
+		},
+		//define ajax obj
+		xmlHttp = (function() {
+			var xmlhttpmethod = false,
+				attempts = [
+					function(){ return new ActiveXObject("Microsoft.XMLHTTP") },
+					function(){ return new XMLHttpRequest() }
+				],
+				al = attempts.length;
+
+			while( al-- ){
+				try {
+					xmlhttpmethod = attempts[ al ]();
+				}
+				catch(e) {
+					continue;
+				}
+				break;
+			}
+			return function(){
+				return xmlhttpmethod;
+			};
+		})();
+
+	//translate CSS
+	ripCSS();
+
+	//expose update for re-running respond later on
+	respond.update = ripCSS;
+
+	//adjust on resize
+	function callMedia(){
+		applyMedia( true );
+	}
+	if( win.addEventListener ){
+		win.addEventListener( "resize", callMedia, false );
+	}
+	else if( win.attachEvent ){
+		win.attachEvent( "onresize", callMedia );
+	}
+})(
+	this,
+	(function( win ){
+
+		//for speed, flag browsers with window.matchMedia support and IE 9 as supported
+		if( win.matchMedia ){ return true; }
+
+		var bool,
+			doc			= document,
+			docElem		= doc.documentElement,
+			refNode		= docElem.firstElementChild || docElem.firstChild,
+			// fakeBody required for <FF4 when executed in <head>
+			fakeUsed	= !doc.body,
+			fakeBody	= doc.body || doc.createElement( "body" ),
+			div			= doc.createElement( "div" ),
+			q			= "only all";
+
+		div.id = "mq-test-1";
+		div.style.cssText = "position:absolute;top:-99em";
+		fakeBody.appendChild( div );
+
+		div.innerHTML = '_<style media="'+q+'"> #mq-test-1 { width: 9px; }</style>';
+		if( fakeUsed ){
+			docElem.insertBefore( fakeBody, refNode );
+		}
+		div.removeChild( div.firstChild );
+		bool = div.offsetWidth == 9;
+		if( fakeUsed ){
+			docElem.removeChild( fakeBody );
+		}
+		else{
+			fakeBody.removeChild( div );
+		}
+		return bool;
+	})( this )
+);
+
diff --git a/source/javascripts/libs/ie/selectivizr-1.0.1.js b/source/javascripts/libs/ie/selectivizr-1.0.1.js
new file mode 100644
index 00000000..0846b919
--- /dev/null
+++ b/source/javascripts/libs/ie/selectivizr-1.0.1.js
@@ -0,0 +1,5 @@
+/*!
+ * selectivizr v1.0.1 - (c) Keith Clark, freely distributable under the terms of the MIT license.
+ * selectivizr.com
+ */
+var k=true,p=false;(function(A){function N(a){return a.replace(O,q).replace(P,function(b,e,c){b=c.split(",");c=0;for(var g=b.length;c<g;c++){var h=Q(b[c].replace(R,q).replace(S,q))+w,f=[];b[c]=h.replace(T,function(d,l,m,j,i){if(l){if(f.length>0){d=f;var x;i=h.substring(0,i).replace(U,o);if(i==o||i.charAt(i.length-1)==w)i+="*";try{x=y(i)}catch(ha){}if(x){i=0;for(m=x.length;i<m;i++){j=x[i];for(var B=j.className,C=0,V=d.length;C<V;C++){var r=d[C];if(!RegExp("(^|\\s)"+r.className+"(\\s|$)").test(j.className))if(r.b&&(r.b===k||r.b(j)===k))B=E(B,r.className,k)}j.className=B}}f=[]}return l}else{if(l=m?W(m):!F||F.test(j)?{className:G(j),b:k}:null){f.push(l);return"."+l.className}return d}})}return e+b.join(",")})}function W(a){var b=k,e=G(a.slice(1)),c=a.substring(0,5)==":not(",g,h;if(c)a=a.slice(5,-1);var f=a.indexOf("(");if(f>-1)a=a.substring(0,f);if(a.charAt(0)==":")switch(a.slice(1)){case "root":b=function(d){return c?d!=H:d==H};break;case "target":if(s==8){b=function(d){function l(){var m=location.hash,j=m.slice(1);return c?m==""||d.id!=j:m!=""&&d.id==j}t(A,"hashchange",function(){u(d,e,l())});return l()};break}return p;case "checked":b=function(d){X.test(d.type)&&t(d,"propertychange",function(){event.propertyName=="checked"&&u(d,e,d.checked!==c)});return d.checked!==c};break;case "disabled":c=!c;case "enabled":b=function(d){if(Y.test(d.tagName)){t(d,"propertychange",function(){event.propertyName=="$disabled"&&u(d,e,d.a===c)});z.push(d);d.a=d.disabled;return d.disabled===c}return a==":enabled"?c:!c};break;case "focus":g="focus";h="blur";case "hover":if(!g){g="mouseenter";h="mouseleave"}b=function(d){t(d,c?h:g,function(){u(d,e,k)});t(d,c?g:h,function(){u(d,e,p)});return c};break;default:if(!Z.test(a))return p}return{className:e,b:b}}function G(a){return I+"-"+(s==6&&$?aa++:a.replace(ba,function(b){return b.charCodeAt(0)}))}function Q(a){return a.replace(J,q).replace(ca,w)}function u(a,b,e){var c=a.className;b=E(c,b,e);if(b!=c){a.className=b;a.parentNode.className+=o}}function E(a,b,e){var c=RegExp("(^|\\s)"+b+"(\\s|$)"),g=c.test(a);return e?g?a:a+w+b:g?a.replace(c,q).replace(J,q):a}function t(a,b,e){a.attachEvent("on"+b,e)}function D(a,b){if(/^https?:\/\//i.test(a))return b.substring(0,b.indexOf("/",8))==a.substring(0,a.indexOf("/",8))?a:null;if(a.charAt(0)=="/")return b.substring(0,b.indexOf("/",8))+a;var e=b.split("?")[0];if(a.charAt(0)!="?"&&e.charAt(e.length-1)!="/")e=e.substring(0,e.lastIndexOf("/")+1);return e+a}function K(a){if(a){v.open("GET",a,p);v.send();return(v.status==200?v.responseText:o).replace(da,o).replace(ea,function(b,e,c,g,h){return K(D(c||h,a))}).replace(fa,function(b,e,c){e=e||"";return" url("+e+D(c,a)+e+") "})}return o}function ga(){var a,b;a=n.getElementsByTagName("BASE");for(var e=a.length>0?a[0].href:n.location.href,c=0;c<n.styleSheets.length;c++){b=n.styleSheets[c];if(b.href!=o)if(a=D(b.href,e))b.cssText=N(K(a))}z.length>0&&setInterval(function(){for(var g=0,h=z.length;g<h;g++){var f=z[g];if(f.disabled!==f.a)if(f.disabled){f.disabled=p;f.a=k;f.disabled=k}else f.a=f.disabled}},250)}if(!/*@cc_on!@*/true){var n=document,H=n.documentElement,v=function(){if(A.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){return null}}(),s=/MSIE ([\d])/.exec(navigator.userAgent)[1];if(!(n.compatMode!="CSS1Compat"||s<6||s>8||!v)){var L={NW:"*.Dom.select",DOMAssistant:"*.$",Prototype:"$$",YAHOO:"*.util.Selector.query",MooTools:"$$",Sizzle:"*",jQuery:"*",dojo:"*.query"},y,z=[],aa=0,$=k,I="slvzr",M=I+"DOMReady",da=/(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g,ea=/@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g,fa=/\burl\(\s*(["']?)([^"')]+)\1\s*\)/g,Z=/^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/,O=/:(:first-(?:line|letter))/g,P=/(^|})\s*([^\{]*?[\[:][^{]+)/g,T=/([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g,U=/(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g,ba=/[^\w-]/g,Y=/^(INPUT|SELECT|TEXTAREA|BUTTON)$/,X=/^(checkbox|radio)$/,F=s>6?/[\$\^*]=(['"])\1/:null,R=/([(\[+~])\s+/g,S=/\s+([)\]+~])/g,ca=/\s+/g,J=/^\s*((?:[\S\s]*\S)?)\s*$/,o="",w=" ",q="$1";n.write("<script id="+M+" defer src='//:'><\/script>");n.getElementById(M).onreadystatechange=function(){if(this.readyState=="complete"){a:{var a,b;for(b in L)if(A[b]&&(a=eval(L[b].replace("*",b)))){y=a;break a}y=p}if(y){ga();this.parentNode.removeChild(this)}}}}}})(this);
\ No newline at end of file
diff --git a/source/javascripts/libs/ios-viewport-scaling-bug-fix.js b/source/javascripts/libs/ios-viewport-scaling-bug-fix.js
index 49f0d443..0e8d701d 100644
--- a/source/javascripts/libs/ios-viewport-scaling-bug-fix.js
+++ b/source/javascripts/libs/ios-viewport-scaling-bug-fix.js
@@ -2,19 +2,19 @@
 // By @mathias, @cheeaun and @jdalton
 
 (function(doc) {
-	var addEvent = 'addEventListener',
-	    type = 'gesturestart',
-	    qsa = 'querySelectorAll',
-	    scales = [1, 1],
-	    meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : [];
-	function fix() {
-		meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1];
-		doc.removeEventListener(type, fix, true);
-	}
-	if ((meta = meta[meta.length - 1]) && addEvent in doc) {
-		fix();
-		scales = [.25, 1.6];
-		doc[addEvent](type, fix, true);
-	}
+  var addEvent = 'addEventListener',
+  type = 'gesturestart',
+  qsa = 'querySelectorAll',
+  scales = [1, 1],
+  meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : [];
+  function fix() {
+    meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1];
+    doc.removeEventListener(type, fix, true);
+  }
+  if ((meta = meta[meta.length - 1]) && addEvent in doc) {
+    fix();
+    scales = [.25, 1.6];
+    doc[addEvent](type, fix, true);
+  }
 }(document));
 
diff --git a/source/javascripts/libs/jXHR.js b/source/javascripts/libs/jXHR.js
new file mode 100644
index 00000000..6775655c
--- /dev/null
+++ b/source/javascripts/libs/jXHR.js
@@ -0,0 +1,85 @@
+// jXHR.js (JSON-P XHR)
+// v0.1 (c) Kyle Simpson
+// MIT License
+
+(function(global){
+	var SETTIMEOUT = global.setTimeout, // for better compression
+		doc = global.document,
+		callback_counter = 0;
+
+	global.jXHR = function() {
+		var script_url,
+			script_loaded,
+			jsonp_callback,
+			scriptElem,
+			publicAPI = null;
+
+		function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }
+
+		function reset() {
+			script_loaded = false;
+			script_url = "";
+			removeScript();
+			scriptElem = null;
+			fireReadyStateChange(0);
+		}
+
+		function ThrowError(msg) {
+			try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }
+		}
+
+		function handleScriptLoad() {
+			if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; }
+			this.onload = this.onreadystatechange = null; // prevent memory leak
+			script_loaded = true;
+			if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");
+			removeScript();
+		}
+
+		function fireReadyStateChange(rs,args) {
+			args = args || [];
+			publicAPI.readyState = rs;
+			if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);
+		}
+
+		publicAPI = {
+			onerror:null,
+			onreadystatechange:null,
+			readyState:0,
+			open:function(method,url){
+				reset();
+				internal_callback = "cb"+(callback_counter++);
+				(function(icb){
+					global.jXHR[icb] = function() {
+						try { fireReadyStateChange.call(publicAPI,4,arguments); }
+						catch(err) {
+							publicAPI.readyState = -1;
+							ThrowError("Script failed to run ["+script_url+"].");
+						}
+						global.jXHR[icb] = null;
+					};
+				})(internal_callback);
+				script_url = url.replace(/=\?/,"=jXHR."+internal_callback);
+				fireReadyStateChange(1);
+			},
+			send:function(){
+				SETTIMEOUT(function(){
+					scriptElem = doc.createElement("script");
+					scriptElem.setAttribute("type","text/javascript");
+					scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);};
+					scriptElem.setAttribute("src",script_url);
+					doc.getElementsByTagName("head")[0].appendChild(scriptElem);
+				},0);
+				fireReadyStateChange(2);
+			},
+			setRequestHeader:function(){}, // noop
+			getResponseHeader:function(){return "";}, // basically noop
+			getAllResponseHeaders:function(){return [];} // ditto
+		};
+
+		reset();
+
+		return publicAPI;
+	};
+})(window);
+
diff --git a/source/javascripts/libs/json2.js b/source/javascripts/libs/json2.js
new file mode 100644
index 00000000..5e61c56f
--- /dev/null
+++ b/source/javascripts/libs/json2.js
@@ -0,0 +1,481 @@
+/*
+    http://www.JSON.org/json2.js
+    2011-02-23
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, strict: false, regexp: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+var JSON;
+if (!JSON) {
+    JSON = {};
+}
+
+(function () {
+    "use strict";
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return isFinite(this.valueOf()) ?
+                this.getUTCFullYear()     + '-' +
+                f(this.getUTCMonth() + 1) + '-' +
+                f(this.getUTCDate())      + 'T' +
+                f(this.getUTCHours())     + ':' +
+                f(this.getUTCMinutes())   + ':' +
+                f(this.getUTCSeconds())   + 'Z' : null;
+        };
+
+        String.prototype.toJSON      =
+            Number.prototype.toJSON  =
+            Boolean.prototype.toJSON = function (key) {
+                return this.valueOf();
+            };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+            var c = meta[a];
+            return typeof c === 'string' ? c :
+                '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+        }) + '"' : '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' : gap ?
+                    '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
+                    '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    if (typeof rep[i] === 'string') {
+                        k = rep[i];
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' : gap ?
+                '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
+                '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                    typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.prototype.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/
+                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+}());
+
diff --git a/source/javascripts/libs/modernizr-1.7.js b/source/javascripts/libs/modernizr-1.7.js
new file mode 100644
index 00000000..a7f86db1
--- /dev/null
+++ b/source/javascripts/libs/modernizr-1.7.js
@@ -0,0 +1,964 @@
+/*!
+ * Modernizr v1.7
+ * http://www.modernizr.com
+ *
+ * Developed by: 
+ * - Faruk Ates  http://farukat.es/
+ * - Paul Irish  http://paulirish.com/
+ *
+ * Copyright (c) 2009-2011
+ * Dual-licensed under the BSD or MIT licenses.
+ * http://www.modernizr.com/license/
+ */
+
+ 
+/*
+ * Modernizr is a script that detects native CSS3 and HTML5 features
+ * available in the current UA and provides an object containing all
+ * features with a true/false value, depending on whether the UA has
+ * native support for it or not.
+ * 
+ * Modernizr will also add classes to the <html> element of the page,
+ * one for each feature it detects. If the UA supports it, a class
+ * like "cssgradients" will be added. If not, the class name will be
+ * "no-cssgradients". This allows for simple if-conditionals in your
+ * CSS, giving you fine control over the look & feel of your website.
+ * 
+ * @author        Faruk Ates
+ * @author        Paul Irish
+ * @copyright     (c) 2009-2011 Faruk Ates.
+ * @contributor   Ben Alman
+ */
+
+window.Modernizr = (function(window,document,undefined){
+    
+    var version = '1.7',
+
+    ret = {},
+
+    /**
+     * !! DEPRECATED !!
+     * 
+     * enableHTML5 is a private property for advanced use only. If enabled,
+     * it will make Modernizr.init() run through a brief while() loop in
+     * which it will create all HTML5 elements in the DOM to allow for
+     * styling them in Internet Explorer, which does not recognize any
+     * non-HTML4 elements unless created in the DOM this way.
+     * 
+     * enableHTML5 is ON by default.
+     * 
+     * The enableHTML5 toggle option is DEPRECATED as per 1.6, and will be
+     * replaced in 2.0 in lieu of the modular, configurable nature of 2.0.
+     */
+    enableHTML5 = true,
+    
+    
+    docElement = document.documentElement,
+    docHead = document.head || document.getElementsByTagName('head')[0],
+
+    /**
+     * Create our "modernizr" element that we do most feature tests on.
+     */
+    mod = 'modernizr',
+    modElem = document.createElement( mod ),
+    m_style = modElem.style,
+
+    /**
+     * Create the input element for various Web Forms feature tests.
+     */
+    inputElem = document.createElement( 'input' ),
+    
+    smile = ':)',
+    
+    tostring = Object.prototype.toString,
+    
+    // List of property values to set for css tests. See ticket #21
+    prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
+
+    // Following spec is to expose vendor-specific style properties as:
+    //   elem.style.WebkitBorderRadius
+    // and the following would be incorrect:
+    //   elem.style.webkitBorderRadius
+    
+    // Webkit ghosts their properties in lowercase but Opera & Moz do not.
+    // Microsoft foregoes prefixes entirely <= IE8, but appears to 
+    //   use a lowercase `ms` instead of the correct `Ms` in IE9
+    
+    // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
+    domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
+
+    ns = {'svg': 'http://www.w3.org/2000/svg'},
+
+    tests = {},
+    inputs = {},
+    attrs = {},
+    
+    classes = [],
+    
+    featurename, // used in testing loop
+    
+    
+    
+    // todo: consider using http://javascript.nwbox.com/CSSSupport/css-support.js instead
+    testMediaQuery = function(mq){
+
+      var st = document.createElement('style'),
+          div = document.createElement('div'),
+          ret;
+
+      st.textContent = mq + '{#modernizr{height:3px}}';
+      docHead.appendChild(st);
+      div.id = 'modernizr';
+      docElement.appendChild(div);
+
+      ret = div.offsetHeight === 3;
+
+      st.parentNode.removeChild(st);
+      div.parentNode.removeChild(div);
+
+      return !!ret;
+
+    },
+    
+    
+    /**
+      * isEventSupported determines if a given element supports the given event
+      * function from http://yura.thinkweb2.com/isEventSupported/
+      */
+    isEventSupported = (function(){
+
+      var TAGNAMES = {
+        'select':'input','change':'input',
+        'submit':'form','reset':'form',
+        'error':'img','load':'img','abort':'img'
+      };
+
+      function isEventSupported(eventName, element) {
+
+        element = element || document.createElement(TAGNAMES[eventName] || 'div');
+        eventName = 'on' + eventName;
+
+        // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
+        var isSupported = (eventName in element);
+
+        if (!isSupported) {
+          // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
+          if (!element.setAttribute) {
+            element = document.createElement('div');
+          }
+          if (element.setAttribute && element.removeAttribute) {
+            element.setAttribute(eventName, '');
+            isSupported = is(element[eventName], 'function');
+
+            // If property was created, "remove it" (by setting value to `undefined`)
+            if (!is(element[eventName], undefined)) {
+              element[eventName] = undefined;
+            }
+            element.removeAttribute(eventName);
+          }
+        }
+
+        element = null;
+        return isSupported;
+      }
+      return isEventSupported;
+    })();
+    
+    
+    // hasOwnProperty shim by kangax needed for Safari 2.0 support
+    var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
+    if (!is(_hasOwnProperty, undefined) && !is(_hasOwnProperty.call, undefined)) {
+      hasOwnProperty = function (object, property) {
+        return _hasOwnProperty.call(object, property);
+      };
+    }
+    else {
+      hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
+        return ((property in object) && is(object.constructor.prototype[property], undefined));
+      };
+    }
+    
+    /**
+     * set_css applies given styles to the Modernizr DOM node.
+     */
+    function set_css( str ) {
+        m_style.cssText = str;
+    }
+
+    /**
+     * set_css_all extrapolates all vendor-specific css strings.
+     */
+    function set_css_all( str1, str2 ) {
+        return set_css(prefixes.join(str1 + ';') + ( str2 || '' ));
+    }
+
+    /**
+     * is returns a boolean for if typeof obj is exactly type.
+     */
+    function is( obj, type ) {
+        return typeof obj === type;
+    }
+
+    /**
+     * contains returns a boolean for if substr is found within str.
+     */
+    function contains( str, substr ) {
+        return (''+str).indexOf( substr ) !== -1;
+    }
+
+    /**
+     * test_props is a generic CSS / DOM property test; if a browser supports
+     *   a certain property, it won't return undefined for it.
+     *   A supported CSS property returns empty string when its not yet set.
+     */
+    function test_props( props, callback ) {
+        for ( var i in props ) {
+            if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], modElem ) ) ) {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * test_props_all tests a list of DOM properties we want to check against.
+     *   We specify literally ALL possible (known and/or likely) properties on 
+     *   the element including the non-vendor prefixed one, for forward-
+     *   compatibility.
+     */
+    function test_props_all( prop, callback ) {
+      
+        var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1),
+            props   = (prop + ' ' + domPrefixes.join(uc_prop + ' ') + uc_prop).split(' ');
+
+        return !!test_props( props, callback );
+    }
+    
+
+    /**
+     * Tests
+     * -----
+     */
+
+    tests['flexbox'] = function() {
+        /**
+         * set_prefixed_value_css sets the property of a specified element
+         * adding vendor prefixes to the VALUE of the property.
+         * @param {Element} element
+         * @param {string} property The property name. This will not be prefixed.
+         * @param {string} value The value of the property. This WILL be prefixed.
+         * @param {string=} extra Additional CSS to append unmodified to the end of
+         * the CSS string.
+         */
+        function set_prefixed_value_css(element, property, value, extra) {
+            property += ':';
+            element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
+        }
+
+        /**
+         * set_prefixed_property_css sets the property of a specified element
+         * adding vendor prefixes to the NAME of the property.
+         * @param {Element} element
+         * @param {string} property The property name. This WILL be prefixed.
+         * @param {string} value The value of the property. This will not be prefixed.
+         * @param {string=} extra Additional CSS to append unmodified to the end of
+         * the CSS string.
+         */
+        function set_prefixed_property_css(element, property, value, extra) {
+            element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
+        }
+
+        var c = document.createElement('div'),
+            elem = document.createElement('div');
+
+        set_prefixed_value_css(c, 'display', 'box', 'width:42px;padding:0;');
+        set_prefixed_property_css(elem, 'box-flex', '1', 'width:10px;');
+
+        c.appendChild(elem);
+        docElement.appendChild(c);
+
+        var ret = elem.offsetWidth === 42;
+
+        c.removeChild(elem);
+        docElement.removeChild(c);
+
+        return ret;
+    };
+    
+    // On the S60 and BB Storm, getContext exists, but always returns undefined
+    // http://github.com/Modernizr/Modernizr/issues/issue/97/ 
+    
+    tests['canvas'] = function() {
+        var elem = document.createElement( 'canvas' );
+        return !!(elem.getContext && elem.getContext('2d'));
+    };
+    
+    tests['canvastext'] = function() {
+        return !!(ret['canvas'] && is(document.createElement( 'canvas' ).getContext('2d').fillText, 'function'));
+    };
+    
+    // This WebGL test false positives in FF depending on graphics hardware. But really it's quite impossible to know
+    // wether webgl will succeed until after you create the context. You might have hardware that can support
+    // a 100x100 webgl canvas, but will not support a 1000x1000 webgl canvas. So this feature inference is weak, 
+    // but intentionally so.
+    tests['webgl'] = function(){
+        return !!window.WebGLRenderingContext;
+    };
+    
+    /*
+     * The Modernizr.touch test only indicates if the browser supports
+     *    touch events, which does not necessarily reflect a touchscreen
+     *    device, as evidenced by tablets running Windows 7 or, alas,
+     *    the Palm Pre / WebOS (touch) phones.
+     *    
+     * Additionally, Chrome (desktop) used to lie about its support on this,
+     *    but that has since been rectified: http://crbug.com/36415
+     *    
+     * We also test for Firefox 4 Multitouch Support.
+     *
+     * For more info, see: http://modernizr.github.com/Modernizr/touch.html
+     */
+     
+    tests['touch'] = function() {
+
+        return ('ontouchstart' in window) || testMediaQuery('@media ('+prefixes.join('touch-enabled),(')+'modernizr)');
+
+    };
+
+
+    /**
+     * geolocation tests for the new Geolocation API specification.
+     *   This test is a standards compliant-only test; for more complete
+     *   testing, including a Google Gears fallback, please see:
+     *   http://code.google.com/p/geo-location-javascript/
+     * or view a fallback solution using google's geo API:
+     *   http://gist.github.com/366184
+     */
+    tests['geolocation'] = function() {
+        return !!navigator.geolocation;
+    };
+
+    // Per 1.6: 
+    // This used to be Modernizr.crosswindowmessaging but the longer
+    // name has been deprecated in favor of a shorter and property-matching one.
+    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
+    // and in the first release thereafter disappear entirely.
+    tests['postmessage'] = function() {
+      return !!window.postMessage;
+    };
+
+    // Web SQL database detection is tricky:
+
+    // In chrome incognito mode, openDatabase is truthy, but using it will 
+    //   throw an exception: http://crbug.com/42380
+    // We can create a dummy database, but there is no way to delete it afterwards. 
+    
+    // Meanwhile, Safari users can get prompted on any database creation.
+    //   If they do, any page with Modernizr will give them a prompt:
+    //   http://github.com/Modernizr/Modernizr/issues/closed#issue/113
+    
+    // We have chosen to allow the Chrome incognito false positive, so that Modernizr
+    //   doesn't litter the web with these test databases. As a developer, you'll have
+    //   to account for this gotcha yourself.
+    tests['websqldatabase'] = function() {
+      var result = !!window.openDatabase;
+      /*  if (result){
+            try {
+              result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
+            } catch(e) {
+            }
+          }  */
+      return result;
+    };
+    
+    // Vendors have inconsistent prefixing with the experimental Indexed DB:
+    // - Firefox is shipping indexedDB in FF4 as moz_indexedDB
+    // - Webkit's implementation is accessible through webkitIndexedDB
+    // We test both styles.
+    tests['indexedDB'] = function(){
+      for (var i = -1, len = domPrefixes.length; ++i < len; ){ 
+        var prefix = domPrefixes[i].toLowerCase();
+        if (window[prefix + '_indexedDB'] || window[prefix + 'IndexedDB']){
+          return true;
+        } 
+      }
+      return false;
+    };
+
+    // documentMode logic from YUI to filter out IE8 Compat Mode
+    //   which false positives.
+    tests['hashchange'] = function() {
+      return isEventSupported('hashchange', window) && ( document.documentMode === undefined || document.documentMode > 7 );
+    };
+
+    // Per 1.6: 
+    // This used to be Modernizr.historymanagement but the longer
+    // name has been deprecated in favor of a shorter and property-matching one.
+    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
+    // and in the first release thereafter disappear entirely.
+    tests['history'] = function() {
+      return !!(window.history && history.pushState);
+    };
+
+    tests['draganddrop'] = function() {
+        return isEventSupported('dragstart') && isEventSupported('drop');
+    };
+    
+    tests['websockets'] = function(){
+        return ('WebSocket' in window);
+    };
+    
+    
+    // http://css-tricks.com/rgba-browser-support/
+    tests['rgba'] = function() {
+        // Set an rgba() color and check the returned value
+        
+        set_css(  'background-color:rgba(150,255,150,.5)' );
+        
+        return contains( m_style.backgroundColor, 'rgba' );
+    };
+    
+    tests['hsla'] = function() {
+        // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
+        //   except IE9 who retains it as hsla
+        
+        set_css('background-color:hsla(120,40%,100%,.5)' );
+        
+        return contains( m_style.backgroundColor, 'rgba' ) || contains( m_style.backgroundColor, 'hsla' );
+    };
+    
+    tests['multiplebgs'] = function() {
+        // Setting multiple images AND a color on the background shorthand property
+        //  and then querying the style.background property value for the number of
+        //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
+        
+        set_css( 'background:url(//:),url(//:),red url(//:)' );
+        
+        // If the UA supports multiple backgrounds, there should be three occurrences
+        //   of the string "url(" in the return value for elem_style.background
+
+        return new RegExp("(url\\s*\\(.*?){3}").test(m_style.background);
+    };
+    
+    
+    // In testing support for a given CSS property, it's legit to test:
+    //    `elem.style[styleName] !== undefined`
+    // If the property is supported it will return an empty string,
+    // if unsupported it will return undefined.
+    
+    // We'll take advantage of this quick test and skip setting a style 
+    // on our modernizr element, but instead just testing undefined vs
+    // empty string.
+    
+
+    tests['backgroundsize'] = function() {
+        return test_props_all( 'backgroundSize' );
+    };
+    
+    tests['borderimage'] = function() {
+        return test_props_all( 'borderImage' );
+    };
+    
+    
+    // Super comprehensive table about all the unique implementations of 
+    // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
+    
+    tests['borderradius'] = function() {
+        return test_props_all( 'borderRadius', '', function( prop ) {
+            return contains( prop, 'orderRadius' );
+        });
+    };
+    
+    // WebOS unfortunately false positives on this test.
+    tests['boxshadow'] = function() {
+        return test_props_all( 'boxShadow' );
+    };
+    
+    // FF3.0 will false positive on this test 
+    tests['textshadow'] = function(){
+        return document.createElement('div').style.textShadow === '';
+    };
+    
+    
+    tests['opacity'] = function() {
+        // Browsers that actually have CSS Opacity implemented have done so
+        //  according to spec, which means their return values are within the
+        //  range of [0.0,1.0] - including the leading zero.
+        
+        set_css_all( 'opacity:.55' );
+        
+        // The non-literal . in this regex is intentional:
+        //   German Chrome returns this value as 0,55
+        // https://github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
+        return /^0.55$/.test(m_style.opacity);
+    };
+    
+    
+    tests['cssanimations'] = function() {
+        return test_props_all( 'animationName' );
+    };
+    
+    
+    tests['csscolumns'] = function() {
+        return test_props_all( 'columnCount' );
+    };
+    
+    
+    tests['cssgradients'] = function() {
+        /**
+         * For CSS Gradients syntax, please see:
+         * http://webkit.org/blog/175/introducing-css-gradients/
+         * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
+         * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
+         * http://dev.w3.org/csswg/css3-images/#gradients-
+         */
+        
+        var str1 = 'background-image:',
+            str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
+            str3 = 'linear-gradient(left top,#9f9, white);';
+        
+        set_css(
+            (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length)
+        );
+        
+        return contains( m_style.backgroundImage, 'gradient' );
+    };
+    
+    
+    tests['cssreflections'] = function() {
+        return test_props_all( 'boxReflect' );
+    };
+    
+    
+    tests['csstransforms'] = function() {
+        return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
+    };
+    
+    
+    tests['csstransforms3d'] = function() {
+        
+        var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]);
+        
+        // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
+        //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
+        //   some conditions. As a result, Webkit typically recognizes the syntax but 
+        //   will sometimes throw a false positive, thus we must do a more thorough check:
+        if (ret && 'webkitPerspective' in docElement.style){
+          
+          // Webkit allows this media query to succeed only if the feature is enabled.    
+          // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }`    
+          ret = testMediaQuery('@media ('+prefixes.join('transform-3d),(')+'modernizr)');
+        }
+        return ret;
+    };
+    
+    
+    tests['csstransitions'] = function() {
+        return test_props_all( 'transitionProperty' );
+    };
+
+
+    // @font-face detection routine by Diego Perini
+    // http://javascript.nwbox.com/CSSSupport/
+    tests['fontface'] = function(){
+
+        var 
+        sheet, bool,
+        head = docHead || docElement,
+        style = document.createElement("style"),
+        impl = document.implementation || { hasFeature: function() { return false; } };
+        
+        style.type = 'text/css';
+        head.insertBefore(style, head.firstChild);
+        sheet = style.sheet || style.styleSheet;
+
+        var supportAtRule = impl.hasFeature('CSS2', '') ?
+                function(rule) {
+                    if (!(sheet && rule)) return false;
+                    var result = false;
+                    try {
+                        sheet.insertRule(rule, 0);
+                        result = (/src/i).test(sheet.cssRules[0].cssText);
+                        sheet.deleteRule(sheet.cssRules.length - 1);
+                    } catch(e) { }
+                    return result;
+                } :
+                function(rule) {
+                    if (!(sheet && rule)) return false;
+                    sheet.cssText = rule;
+                    
+                    return sheet.cssText.length !== 0 && (/src/i).test(sheet.cssText) &&
+                      sheet.cssText
+                            .replace(/\r+|\n+/g, '')
+                            .indexOf(rule.split(' ')[0]) === 0;
+                };
+        
+        bool = supportAtRule('@font-face { font-family: "font"; src: url(data:,); }');
+        head.removeChild(style);
+        return bool;
+    };
+    
+
+    // These tests evaluate support of the video/audio elements, as well as
+    // testing what types of content they support.
+    //
+    // We're using the Boolean constructor here, so that we can extend the value
+    // e.g.  Modernizr.video     // true
+    //       Modernizr.video.ogg // 'probably'
+    //
+    // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
+    //                     thx to NielsLeenheer and zcorpan
+    
+    // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
+    //   Modernizr does not normalize for that.
+    
+    tests['video'] = function() {
+        var elem = document.createElement('video'),
+            bool = !!elem.canPlayType;
+        
+        if (bool){  
+            bool      = new Boolean(bool);  
+            bool.ogg  = elem.canPlayType('video/ogg; codecs="theora"');
+            
+            // Workaround required for IE9, which doesn't report video support without audio codec specified.
+            //   bug 599718 @ msft connect
+            var h264 = 'video/mp4; codecs="avc1.42E01E';
+            bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
+            
+            bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
+        }
+        return bool;
+    };
+    
+    tests['audio'] = function() {
+        var elem = document.createElement('audio'),
+            bool = !!elem.canPlayType;
+        
+        if (bool){  
+            bool      = new Boolean(bool);  
+            bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"');
+            bool.mp3  = elem.canPlayType('audio/mpeg;');
+            
+            // Mimetypes accepted: 
+            //   https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
+            //   http://bit.ly/iphoneoscodecs
+            bool.wav  = elem.canPlayType('audio/wav; codecs="1"');
+            bool.m4a  = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
+        }
+        return bool;
+    };
+
+
+    // Firefox has made these tests rather unfun.
+
+    // In FF4, if disabled, window.localStorage should === null.
+
+    // Normally, we could not test that directly and need to do a 
+    //   `('localStorage' in window) && ` test first because otherwise Firefox will
+    //   throw http://bugzil.la/365772 if cookies are disabled
+
+    // However, in Firefox 4 betas, if dom.storage.enabled == false, just mentioning
+    //   the property will throw an exception. http://bugzil.la/599479
+    // This looks to be fixed for FF4 Final.
+
+    // Because we are forced to try/catch this, we'll go aggressive.
+
+    // FWIW: IE8 Compat mode supports these features completely:
+    //   http://www.quirksmode.org/dom/html5.html
+    // But IE8 doesn't support either with local files
+
+    tests['localstorage'] = function() {
+        try {
+            return !!localStorage.getItem;
+        } catch(e) {
+            return false;
+        }
+    };
+
+    tests['sessionstorage'] = function() {
+        try {
+            return !!sessionStorage.getItem;
+        } catch(e){
+            return false;
+        }
+    };
+
+
+    tests['webWorkers'] = function () {
+        return !!window.Worker;
+    };
+
+
+    tests['applicationcache'] =  function() {
+        return !!window.applicationCache;
+    };
+
+ 
+    // Thanks to Erik Dahlstrom
+    tests['svg'] = function(){
+        return !!document.createElementNS && !!document.createElementNS(ns.svg, "svg").createSVGRect;
+    };
+
+    tests['inlinesvg'] = function() {
+      var div = document.createElement('div');
+      div.innerHTML = '<svg/>';
+      return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
+    };
+
+    // Thanks to F1lt3r and lucideer
+    // http://github.com/Modernizr/Modernizr/issues#issue/35
+    tests['smil'] = function(){
+        return !!document.createElementNS && /SVG/.test(tostring.call(document.createElementNS(ns.svg,'animate')));
+    };
+
+    tests['svgclippaths'] = function(){
+        // Possibly returns a false positive in Safari 3.2?
+        return !!document.createElementNS && /SVG/.test(tostring.call(document.createElementNS(ns.svg,'clipPath')));
+    };
+
+
+    // input features and input types go directly onto the ret object, bypassing the tests loop.
+    // Hold this guy to execute in a moment.
+    function webforms(){
+    
+        // Run through HTML5's new input attributes to see if the UA understands any.
+        // We're using f which is the <input> element created early on
+        // Mike Taylr has created a comprehensive resource for testing these attributes
+        //   when applied to all input types: 
+        //   http://miketaylr.com/code/input-type-attr.html
+        // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
+        ret['input'] = (function(props) {
+            for (var i = 0, len = props.length; i<len; i++) {
+                attrs[ props[i] ] = !!(props[i] in inputElem);
+            }
+            return attrs;
+        })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
+
+        // Run through HTML5's new input types to see if the UA understands any.
+        //   This is put behind the tests runloop because it doesn't return a
+        //   true/false like all the other tests; instead, it returns an object
+        //   containing each input type with its corresponding true/false value 
+        
+        // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
+        ret['inputtypes'] = (function(props) {
+          
+            for (var i = 0, bool, inputElemType, defaultView, len=props.length; i < len; i++) {
+              
+                inputElem.setAttribute('type', inputElemType = props[i]);
+                bool = inputElem.type !== 'text';
+                
+                // We first check to see if the type we give it sticks.. 
+                // If the type does, we feed it a textual value, which shouldn't be valid.
+                // If the value doesn't stick, we know there's input sanitization which infers a custom UI
+                if (bool){  
+                  
+                    inputElem.value         = smile;
+                    inputElem.style.cssText = 'position:absolute;visibility:hidden;';
+     
+                    if (/^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined){
+                      
+                      docElement.appendChild(inputElem);
+                      defaultView = document.defaultView;
+                      
+                      // Safari 2-4 allows the smiley as a value, despite making a slider
+                      bool =  defaultView.getComputedStyle && 
+                              defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&                  
+                              // Mobile android web browser has false positive, so must
+                              // check the height to see if the widget is actually there.
+                              (inputElem.offsetHeight !== 0);
+                              
+                      docElement.removeChild(inputElem);
+                              
+                    } else if (/^(search|tel)$/.test(inputElemType)){
+                      // Spec doesnt define any special parsing or detectable UI 
+                      //   behaviors so we pass these through as true
+                      
+                      // Interestingly, opera fails the earlier test, so it doesn't
+                      //  even make it here.
+                      
+                    } else if (/^(url|email)$/.test(inputElemType)) {
+                      // Real url and email support comes with prebaked validation.
+                      bool = inputElem.checkValidity && inputElem.checkValidity() === false;
+                      
+                    } else if (/^color$/.test(inputElemType)) {
+                        // chuck into DOM and force reflow for Opera bug in 11.00
+                        // github.com/Modernizr/Modernizr/issues#issue/159
+                        docElement.appendChild(inputElem);
+                        docElement.offsetWidth; 
+                        bool = inputElem.value != smile;
+                        docElement.removeChild(inputElem);
+
+                    } else {
+                      // If the upgraded input compontent rejects the :) text, we got a winner
+                      bool = inputElem.value != smile;
+                    }
+                }
+                
+                inputs[ props[i] ] = !!bool;
+            }
+            return inputs;
+        })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
+
+    }
+
+
+
+    // End of test definitions
+    // -----------------------
+
+
+
+    // Run through all tests and detect their support in the current UA.
+    // todo: hypothetically we could be doing an array of tests and use a basic loop here.
+    for ( var feature in tests ) {
+        if ( hasOwnProperty( tests, feature ) ) {
+            // run the test, throw the return value into the Modernizr,
+            //   then based on that boolean, define an appropriate className
+            //   and push it into an array of classes we'll join later.
+            featurename  = feature.toLowerCase();
+            ret[ featurename ] = tests[ feature ]();
+
+            classes.push( ( ret[ featurename ] ? '' : 'no-' ) + featurename );
+        }
+    }
+    
+    // input tests need to run.
+    if (!ret.input) webforms();
+    
+
+   
+    // Per 1.6: deprecated API is still accesible for now:
+    ret.crosswindowmessaging = ret.postmessage;
+    ret.historymanagement = ret.history;
+
+
+
+    /**
+     * Addtest allows the user to define their own feature tests
+     * the result will be added onto the Modernizr object,
+     * as well as an appropriate className set on the html element
+     * 
+     * @param feature - String naming the feature
+     * @param test - Function returning true if feature is supported, false if not
+     */
+    ret.addTest = function (feature, test) {
+      feature = feature.toLowerCase();
+      
+      if (ret[ feature ]) {
+        return; // quit if you're trying to overwrite an existing test
+      } 
+      test = !!(test());
+      docElement.className += ' ' + (test ? '' : 'no-') + feature; 
+      ret[ feature ] = test;
+      return ret; // allow chaining.
+    };
+
+    /**
+     * Reset m.style.cssText to nothing to reduce memory footprint.
+     */
+    set_css( '' );
+    modElem = inputElem = null;
+
+    //>>BEGIN IEPP
+    // Enable HTML 5 elements for styling in IE. 
+    // fyi: jscript version does not reflect trident version
+    //      therefore ie9 in ie7 mode will still have a jScript v.9
+    if ( enableHTML5 && window.attachEvent && (function(){ var elem = document.createElement("div");
+                                      elem.innerHTML = "<elem></elem>";
+                                      return elem.childNodes.length !== 1; })()) {
+        // iepp v1.6.2 by @jon_neal : code.google.com/p/ie-print-protector
+        (function(win, doc) {
+          var elems = 'abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video',
+            elemsArr = elems.split('|'),
+            elemsArrLen = elemsArr.length,
+            elemRegExp = new RegExp('(^|\\s)('+elems+')', 'gi'), 
+            tagRegExp = new RegExp('<(\/*)('+elems+')', 'gi'),
+            ruleRegExp = new RegExp('(^|[^\\n]*?\\s)('+elems+')([^\\n]*)({[\\n\\w\\W]*?})', 'gi'),
+            docFrag = doc.createDocumentFragment(),
+            html = doc.documentElement,
+            head = html.firstChild,
+            bodyElem = doc.createElement('body'),
+            styleElem = doc.createElement('style'),
+            body;
+          function shim(doc) {
+            var a = -1;
+            while (++a < elemsArrLen)
+              // Use createElement so IE allows HTML5-named elements in a document
+              doc.createElement(elemsArr[a]);
+          }
+          function getCSS(styleSheetList, mediaType) {
+            var a = -1,
+              len = styleSheetList.length,
+              styleSheet,
+              cssTextArr = [];
+            while (++a < len) {
+              styleSheet = styleSheetList[a];
+              // Get css from all non-screen stylesheets and their imports
+              if ((mediaType = styleSheet.media || mediaType) != 'screen') cssTextArr.push(getCSS(styleSheet.imports, mediaType), styleSheet.cssText);
+            }
+            return cssTextArr.join('');
+          }
+          // Shim the document and iepp fragment
+          shim(doc);
+          shim(docFrag);
+          // Add iepp custom print style element
+          head.insertBefore(styleElem, head.firstChild);
+          styleElem.media = 'print';
+          win.attachEvent(
+            'onbeforeprint',
+            function() {
+              var a = -1,
+                cssText = getCSS(doc.styleSheets, 'all'),
+                cssTextArr = [],
+                rule;
+              body = body || doc.body;
+              // Get only rules which reference HTML5 elements by name
+              while ((rule = ruleRegExp.exec(cssText)) != null)
+                // Replace all html5 element references with iepp substitute classnames
+                cssTextArr.push((rule[1]+rule[2]+rule[3]).replace(elemRegExp, '$1.iepp_$2')+rule[4]);
+              // Write iepp custom print CSS
+              styleElem.styleSheet.cssText = cssTextArr.join('\n');
+              while (++a < elemsArrLen) {
+                var nodeList = doc.getElementsByTagName(elemsArr[a]),
+                  nodeListLen = nodeList.length,
+                  b = -1;
+                while (++b < nodeListLen)
+                  if (nodeList[b].className.indexOf('iepp_') < 0)
+                    // Append iepp substitute classnames to all html5 elements
+                    nodeList[b].className += ' iepp_'+elemsArr[a];
+              }
+              docFrag.appendChild(body);
+              html.appendChild(bodyElem);
+              // Write iepp substitute print-safe document
+              bodyElem.className = body.className;
+              // Replace HTML5 elements with <font> which is print-safe and shouldn't conflict since it isn't part of html5
+              bodyElem.innerHTML = body.innerHTML.replace(tagRegExp, '<$1font');
+            }
+          );
+          win.attachEvent(
+            'onafterprint',
+            function() {
+              // Undo everything done in onbeforeprint
+              bodyElem.innerHTML = '';
+              html.removeChild(bodyElem);
+              html.appendChild(body);
+              styleElem.styleSheet.cssText = '';
+            }
+          );
+        })(window, document);
+    }
+    //>>END IEPP
+
+    // Assign private properties to the return object with prefix
+    ret._enableHTML5     = enableHTML5;
+    ret._version         = version;
+
+    // Remove "no-js" class from <html> element, if it exists:
+    docElement.className = docElement.className.replace(/\bno-js\b/,'') 
+                            + ' js '
+
+                            // Add the new classes to the <html> element.
+                            + classes.join( ' ' );
+    
+    return ret;
+
+})(this,this.document);
\ No newline at end of file
diff --git a/source/javascripts/libs/modernizr-1.7.min.js b/source/javascripts/libs/modernizr-1.7.min.js
deleted file mode 100644
index 6f54850c..00000000
--- a/source/javascripts/libs/modernizr-1.7.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// Modernizr v1.7  www.modernizr.com
-window.Modernizr=function(a,b,c){function G(){e.input=function(a){for(var b=0,c=a.length;b<c;b++)t[a[b]]=!!(a[b]in l);return t}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)l.setAttribute("type",f=a[d]),e=l.type!=="text",e&&(l.value=m,l.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&l.style.WebkitAppearance!==c?(g.appendChild(l),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(l,null).WebkitAppearance!=="textfield"&&l.offsetHeight!==0,g.removeChild(l)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=l.checkValidity&&l.checkValidity()===!1:/^color$/.test(f)?(g.appendChild(l),g.offsetWidth,e=l.value!=m,g.removeChild(l)):e=l.value!=m)),s[a[d]]=!!e;return s}("search tel url email datetime date month week time datetime-local number range color".split(" "))}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return!!E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c&&(!b||b(a[d],j)))return!0}function D(a,b){return(""+a).indexOf(b)!==-1}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="1.7",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v,w=function(a){var c=b.createElement("style"),d=b.createElement("div"),e;c.textContent=a+"{#modernizr{height:3px}}",h.appendChild(c),d.id="modernizr",g.appendChild(d),e=d.offsetHeight===3,c.parentNode.removeChild(c),d.parentNode.removeChild(d);return!!e},x=function(){function d(d,e){e=e||b.createElement(a[d]||"div");var f=(d="on"+d)in e;f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=C(e[d],"function"),C(e[d],c)||(e[d]=c),e.removeAttribute(d))),e=null;return f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),y=({}).hasOwnProperty,z;C(y,c)||C(y.call,c)?z=function(a,b){return b in a&&C(a.constructor.prototype[b],c)}:z=function(a,b){return y.call(a,b)},r.flexbox=function(){function c(a,b,c,d){a.style.cssText=o.join(b+":"+c+";")+(d||"")}function a(a,b,c,d){b+=":",a.style.cssText=(b+o.join(c+";"+b)).slice(0,-b.length)+(d||"")}var d=b.createElement("div"),e=b.createElement("div");a(d,"display","box","width:42px;padding:0;"),c(e,"box-flex","1","width:10px;"),d.appendChild(e),g.appendChild(d);var f=e.offsetWidth===42;d.removeChild(e),g.removeChild(d);return f},r.canvas=function(){var a=b.createElement("canvas");return a.getContext&&a.getContext("2d")},r.canvastext=function(){return e.canvas&&C(b.createElement("canvas").getContext("2d").fillText,"function")},r.webgl=function(){return!!a.WebGLRenderingContext},r.touch=function(){return"ontouchstart"in a||w("@media ("+o.join("touch-enabled),(")+"modernizr)")},r.geolocation=function(){return!!navigator.geolocation},r.postmessage=function(){return!!a.postMessage},r.websqldatabase=function(){var b=!!a.openDatabase;return b},r.indexedDB=function(){for(var b=-1,c=p.length;++b<c;){var d=p[b].toLowerCase();if(a[d+"_indexedDB"]||a[d+"IndexedDB"])return!0}return!1},r.hashchange=function(){return x("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},r.history=function(){return !!(a.history&&history.pushState)},r.draganddrop=function(){return x("dragstart")&&x("drop")},r.websockets=function(){return"WebSocket"in a},r.rgba=function(){A("background-color:rgba(150,255,150,.5)");return D(k.backgroundColor,"rgba")},r.hsla=function(){A("background-color:hsla(120,40%,100%,.5)");return D(k.backgroundColor,"rgba")||D(k.backgroundColor,"hsla")},r.multiplebgs=function(){A("background:url(//:),url(//:),red url(//:)");return(new RegExp("(url\\s*\\(.*?){3}")).test(k.background)},r.backgroundsize=function(){return F("backgroundSize")},r.borderimage=function(){return F("borderImage")},r.borderradius=function(){return F("borderRadius","",function(a){return D(a,"orderRadius")})},r.boxshadow=function(){return F("boxShadow")},r.textshadow=function(){return b.createElement("div").style.textShadow===""},r.opacity=function(){B("opacity:.55");return/^0.55$/.test(k.opacity)},r.cssanimations=function(){return F("animationName")},r.csscolumns=function(){return F("columnCount")},r.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";A((a+o.join(b+a)+o.join(c+a)).slice(0,-a.length));return D(k.backgroundImage,"gradient")},r.cssreflections=function(){return F("boxReflect")},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])},r.csstransforms3d=function(){var a=!!E(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);a&&"webkitPerspective"in g.style&&(a=w("@media ("+o.join("transform-3d),(")+"modernizr)"));return a},r.csstransitions=function(){return F("transitionProperty")},r.fontface=function(){var a,c,d=h||g,e=b.createElement("style"),f=b.implementation||{hasFeature:function(){return!1}};e.type="text/css",d.insertBefore(e,d.firstChild),a=e.sheet||e.styleSheet;var i=f.hasFeature("CSS2","")?function(b){if(!a||!b)return!1;var c=!1;try{a.insertRule(b,0),c=/src/i.test(a.cssRules[0].cssText),a.deleteRule(a.cssRules.length-1)}catch(d){}return c}:function(b){if(!a||!b)return!1;a.cssText=b;return a.cssText.length!==0&&/src/i.test(a.cssText)&&a.cssText.replace(/\r+|\n+/g,"").indexOf(b.split(" ")[0])===0};c=i('@font-face { font-family: "font"; src: url(data:,); }'),d.removeChild(e);return c},r.video=function(){var a=b.createElement("video"),c=!!a.canPlayType;if(c){c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"');var d='video/mp4; codecs="avc1.42E01E';c.h264=a.canPlayType(d+'"')||a.canPlayType(d+', mp4a.40.2"'),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return c},r.audio=function(){var a=b.createElement("audio"),c=!!a.canPlayType;c&&(c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"'),c.mp3=a.canPlayType("audio/mpeg;"),c.wav=a.canPlayType('audio/wav; codecs="1"'),c.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;"));return c},r.localstorage=function(){try{return!!localStorage.getItem}catch(a){return!1}},r.sessionstorage=function(){try{return!!sessionStorage.getItem}catch(a){return!1}},r.webWorkers=function(){return!!a.Worker},r.applicationcache=function(){return!!a.applicationCache},r.svg=function(){return!!b.createElementNS&&!!b.createElementNS(q.svg,"svg").createSVGRect},r.inlinesvg=function(){var a=b.createElement("div");a.innerHTML="<svg/>";return(a.firstChild&&a.firstChild.namespaceURI)==q.svg},r.smil=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"animate")))},r.svgclippaths=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"clipPath")))};for(var H in r)z(r,H)&&(v=H.toLowerCase(),e[v]=r[H](),u.push((e[v]?"":"no-")+v));e.input||G(),e.crosswindowmessaging=e.postmessage,e.historymanagement=e.history,e.addTest=function(a,b){a=a.toLowerCase();if(!e[a]){b=!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b;return e}},A(""),j=l=null,f&&a.attachEvent&&function(){var a=b.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}()&&function(a,b){function p(a,b){var c=-1,d=a.length,e,f=[];while(++c<d)e=a[c],(b=e.media||b)!="screen"&&f.push(p(e.imports,b),e.cssText);return f.join("")}function o(a){var b=-1;while(++b<e)a.createElement(d[b])}var c="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",d=c.split("|"),e=d.length,f=new RegExp("(^|\\s)("+c+")","gi"),g=new RegExp("<(/*)("+c+")","gi"),h=new RegExp("(^|[^\\n]*?\\s)("+c+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),i=b.createDocumentFragment(),j=b.documentElement,k=j.firstChild,l=b.createElement("body"),m=b.createElement("style"),n;o(b),o(i),k.insertBefore(m,k.firstChild),m.media="print",a.attachEvent("onbeforeprint",function(){var a=-1,c=p(b.styleSheets,"all"),k=[],o;n=n||b.body;while((o=h.exec(c))!=null)k.push((o[1]+o[2]+o[3]).replace(f,"$1.iepp_$2")+o[4]);m.styleSheet.cssText=k.join("\n");while(++a<e){var q=b.getElementsByTagName(d[a]),r=q.length,s=-1;while(++s<r)q[s].className.indexOf("iepp_")<0&&(q[s].className+=" iepp_"+d[a])}i.appendChild(n),j.appendChild(l),l.className=n.className,l.innerHTML=n.innerHTML.replace(g,"<$1font")}),a.attachEvent("onafterprint",function(){l.innerHTML="",j.removeChild(l),j.appendChild(n),m.styleSheet.cssText=""})}(a,b),e._enableHTML5=f,e._version=d,g.className=g.className.replace(/\bno-js\b/,"")+" js "+u.join(" ");return e}(this,this.document)
\ No newline at end of file
diff --git a/source/javascripts/libs/respond.js b/source/javascripts/libs/respond.js
deleted file mode 100644
index 99b19825..00000000
--- a/source/javascripts/libs/respond.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * respond.js - A small and fast polyfill for min/max-width CSS3 Media Queries
- * Copyright 2011, Scott Jehl, scottjehl.com
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * Usage: Check out the readme file or github.com/scottjehl/respond
-*/
-(function(e,h){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=h;if(h){return}var u=e.document,r=u.documentElement,i=[],k=[],p=[],o={},g=30,f=u.getElementsByTagName("head")[0]||r,b=f.getElementsByTagName("link"),d=[],a=function(){var B=b,w=B.length;for(var z=0;z<w;z++){var y=B[z],x=y.href,A=y.media,v=y.rel&&y.rel.toLowerCase()==="stylesheet";if(!!x&&v&&!o[x]){if(!/^([a-zA-Z]+?:(\/\/)?(www\.)?)/.test(x)||x.replace(RegExp.$1,"").split("/")[0]===e.location.host){d.push({href:x,media:A})}else{o[x]=true}}}t()},t=function(){if(d.length){var v=d.shift();n(v.href,function(w){m(w,v.href,v.media);o[v.href]=true;t()})}},m=function(G,v,x){var E=G.match(/@media ([^\{]+)\{((?!@media)[\s\S])*(?=\}[\s]*\/\*\/mediaquery\*\/)/gmi),H=E&&E.length||0,v=v.substring(0,v.lastIndexOf("/")),w=function(I){return I.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+v+"$2$3")},y=!H&&x;if(v.length){v+="/"}if(y){H=1}for(var B=0;B<H;B++){var C;if(y){C=x;k.push(w(G))}else{C=E[B].match(/@media ([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1;k.push(RegExp.$2&&w(RegExp.$2))}var z=C.split(","),F=z.length;for(var A=0;A<F;A++){var D=z[A];i.push({media:D.match(/(only\s+)?([a-zA-Z]+)(\sand)?/)&&RegExp.$2,rules:k.length-1,minw:D.match(/\(min\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/)&&parseFloat(RegExp.$1),maxw:D.match(/\(max\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/)&&parseFloat(RegExp.$1)})}}j()},l,q,j=function(E){var v="clientWidth",x=r[v],D=u.compatMode==="CSS1Compat"&&x||u.body[v]||x,z={},C=u.createDocumentFragment(),B=b[b.length-1],w=(new Date()).getTime();if(E&&l&&w-l<g){clearTimeout(q);q=setTimeout(j,g);return}else{l=w}for(var y in i){var F=i[y];if(!F.minw&&!F.maxw||(!F.minw||F.minw&&D>=F.minw)&&(!F.maxw||F.maxw&&D<=F.maxw)){if(!z[F.media]){z[F.media]=[]}z[F.media].push(k[F.rules])}}for(var y in p){if(p[y]&&p[y].parentNode===f){f.removeChild(p[y])}}for(var y in z){var G=u.createElement("style"),A=z[y].join("\n");G.type="text/css";G.media=y;if(G.styleSheet){G.styleSheet.cssText=A}else{G.appendChild(u.createTextNode(A))}C.appendChild(G);p.push(G)}f.insertBefore(C,B.nextSibling)},n=function(v,x){var w=c();if(!w){return}w.open("GET",v,true);w.onreadystatechange=function(){if(w.readyState!=4||w.status!=200&&w.status!=304){return}x(w.responseText)};if(w.readyState==4){return}w.send()},c=(function(){var v=false,w=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml3.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new XMLHttpRequest()}],y=w.length;while(y--){try{v=w[y]()}catch(x){continue}break}return function(){return v}})();a();respond.update=a;function s(){j(true)}if(e.addEventListener){e.addEventListener("resize",s,false)}else{if(e.attachEvent){e.attachEvent("onresize",s)}}})(this,(function(f){if(f.matchMedia){return true}var e,i=document,c=i.documentElement,g=c.firstElementChild||c.firstChild,h=!i.body,d=i.body||i.createElement("body"),b=i.createElement("div"),a="only all";b.id="mq-test-1";b.style.cssText="position:absolute;top:-99em";d.appendChild(b);b.innerHTML='_<style media="'+a+'"> #mq-test-1 { width: 9px; }</style>';if(h){c.insertBefore(d,g)}b.removeChild(b.firstChild);e=b.offsetWidth==9;if(h){c.removeChild(d)}else{d.removeChild(b)}return e})(this));
-
diff --git a/source/javascripts/libs/selectivizr-min.js b/source/javascripts/libs/selectivizr-min.js
deleted file mode 100755
index 5adda2fa..00000000
--- a/source/javascripts/libs/selectivizr-min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*!
- * selectivizr v1.0.2 - (c) Keith Clark, freely distributable under the terms of the MIT license.
- * selectivizr.com
- */
-(function(j){function A(a){return a.replace(B,h).replace(C,function(a,d,b){for(var a=b.split(","),b=0,e=a.length;b<e;b++){var s=D(a[b].replace(E,h).replace(F,h))+o,l=[];a[b]=s.replace(G,function(a,b,c,d,e){if(b){if(l.length>0){var a=l,f,e=s.substring(0,e).replace(H,i);if(e==i||e.charAt(e.length-1)==o)e+="*";try{f=t(e)}catch(k){}if(f){e=0;for(c=f.length;e<c;e++){for(var d=f[e],h=d.className,j=0,m=a.length;j<m;j++){var g=a[j];if(!RegExp("(^|\\s)"+g.className+"(\\s|$)").test(d.className)&&g.b&&(g.b===!0||g.b(d)===!0))h=u(h,g.className,!0)}d.className=h}}l=[]}return b}else{if(b=c?I(c):!v||v.test(d)?{className:w(d),b:!0}:null)return l.push(b),"."+b.className;return a}})}return d+a.join(",")})}function I(a){var c=!0,d=w(a.slice(1)),b=a.substring(0,5)==":not(",e,f;b&&(a=a.slice(5,-1));var l=a.indexOf("(");l>-1&&(a=a.substring(0,l));if(a.charAt(0)==":")switch(a.slice(1)){case "root":c=function(a){return b?a!=p:a==p};break;case "target":if(m==8){c=function(a){function c(){var d=location.hash,e=d.slice(1);return b?d==i||a.id!=e:d!=i&&a.id==e}k(j,"hashchange",function(){g(a,d,c())});return c()};break}return!1;case "checked":c=function(a){J.test(a.type)&&k(a,"propertychange",function(){event.propertyName=="checked"&&g(a,d,a.checked!==b)});return a.checked!==b};break;case "disabled":b=!b;case "enabled":c=function(c){if(K.test(c.tagName))return k(c,"propertychange",function(){event.propertyName=="$disabled"&&g(c,d,c.a===b)}),q.push(c),c.a=c.disabled,c.disabled===b;return a==":enabled"?b:!b};break;case "focus":e="focus",f="blur";case "hover":e||(e="mouseenter",f="mouseleave");c=function(a){k(a,b?f:e,function(){g(a,d,!0)});k(a,b?e:f,function(){g(a,d,!1)});return b};break;default:if(!L.test(a))return!1}return{className:d,b:c}}function w(a){return M+"-"+(m==6&&N?O++:a.replace(P,function(a){return a.charCodeAt(0)}))}function D(a){return a.replace(x,h).replace(Q,o)}function g(a,c,d){var b=a.className,c=u(b,c,d);if(c!=b)a.className=c,a.parentNode.className+=i}function u(a,c,d){var b=RegExp("(^|\\s)"+c+"(\\s|$)"),e=b.test(a);return d?e?a:a+o+c:e?a.replace(b,h).replace(x,h):a}function k(a,c,d){a.attachEvent("on"+c,d)}function r(a,c){if(/^https?:\/\//i.test(a))return c.substring(0,c.indexOf("/",8))==a.substring(0,a.indexOf("/",8))?a:null;if(a.charAt(0)=="/")return c.substring(0,c.indexOf("/",8))+a;var d=c.split(/[?#]/)[0];a.charAt(0)!="?"&&d.charAt(d.length-1)!="/"&&(d=d.substring(0,d.lastIndexOf("/")+1));return d+a}function y(a){if(a)return n.open("GET",a,!1),n.send(),(n.status==200?n.responseText:i).replace(R,i).replace(S,function(c,d,b,e,f){return y(r(b||f,a))}).replace(T,function(c,d,b){d=d||i;return" url("+d+r(b,a)+d+") "});return i}function U(){var a,c;a=f.getElementsByTagName("BASE");for(var d=a.length>0?a[0].href:f.location.href,b=0;b<f.styleSheets.length;b++)if(c=f.styleSheets[b],c.href!=i&&(a=r(c.href,d)))c.cssText=A(y(a));q.length>0&&setInterval(function(){for(var a=0,c=q.length;a<c;a++){var b=q[a];if(b.disabled!==b.a)b.disabled?(b.disabled=!1,b.a=!0,b.disabled=!0):b.a=b.disabled}},250)}if(!/*@cc_on!@*/true){var f=document,p=f.documentElement,n=function(){if(j.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){return null}}(),m=/MSIE (\d+)/.exec(navigator.userAgent)[1];if(!(f.compatMode!="CSS1Compat"||m<6||m>8||!n)){var z={NW:"*.Dom.select",MooTools:"$$",DOMAssistant:"*.$",Prototype:"$$",YAHOO:"*.util.Selector.query",Sizzle:"*",jQuery:"*",dojo:"*.query"},t,q=[],O=0,N=!0,M="slvzr",R=/(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g,S=/@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g,T=/\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g,L=/^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/,B=/:(:first-(?:line|letter))/g,C=/(^|})\s*([^\{]*?[\[:][^{]+)/g,G=/([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g,H=/(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g,P=/[^\w-]/g,K=/^(INPUT|SELECT|TEXTAREA|BUTTON)$/,J=/^(checkbox|radio)$/,v=m>6?/[\$\^*]=(['"])\1/:null,E=/([(\[+~])\s+/g,F=/\s+([)\]+~])/g,Q=/\s+/g,x=/^\s*((?:[\S\s]*\S)?)\s*$/,i="",o=" ",h="$1";(function(a,c){function d(){try{p.doScroll("left")}catch(a){setTimeout(d,50);return}b("poll")}function b(d){if(!(d.type=="readystatechange"&&f.readyState!="complete")&&((d.type=="load"?a:f).detachEvent("on"+d.type,b,!1),!e&&(e=!0)))c.call(a,d.type||d)}var e=!1,g=!0;if(f.readyState=="complete")c.call(a,i);else{if(f.createEventObject&&p.doScroll){try{g=!a.frameElement}catch(h){}g&&d()}k(f,"readystatechange",b);k(a,"load",b)}})(j,function(){for(var a in z){var c,d,b=j;if(j[a]){for(c=z[a].replace("*",a).split(".");(d=c.shift())&&(b=b[d]););if(typeof b=="function"){t=b;U();break}}}})}}})(this);
\ No newline at end of file
diff --git a/source/javascripts/pinboard.js b/source/javascripts/pinboard.js
index 9a69e0a6..cff7ccc4 100644
--- a/source/javascripts/pinboard.js
+++ b/source/javascripts/pinboard.js
@@ -1,6 +1,5 @@
-var count = pinboard_count;
-var linkroll = 'pinboard_linkroll';
 function pinboardNS_fetch_script(url) {
+  console.log(url);
   document.writeln('<s'+'cript type="text/javascript" src="' + url + '"></s'+'cript>');
 }
 
@@ -10,9 +9,6 @@ function pinboardNS_show_bmarks(r) {
   lr.show_bmarks();
 }
 
-var json_URL = "http://feeds.pinboard.in/json/v1/u:"+pinboard_user+"/?cb=pinboardNS_show_bmarks\&count=" + count;
-pinboardNS_fetch_script(json_URL);
-
 function Pinboard_Linkroll() {
   var items;
 
@@ -42,7 +38,7 @@ function Pinboard_Linkroll() {
     if (it.t.length > 0) {
       for (var i = 0; i < it.t.length; i++) {
         var tag = it.t[i];
-        str += " <a class=\"pin-tag\" href=\"http://pinboard.in/u:"+ this.cook(it.a) + "/t:" + this.cook(tag) + "\">" + this.cook(tag) + "</a>  ";
+        str += " <a class=\"pin-tag\" href=\"http://pinboard.in/u:"+ this.cook(it.a) + "/t:" + this.cook(tag) + "\">" + this.cook(tag).replace(/^\s+|\s+$/g, '') + "</a> ";
       }
     }
     str += "</p></li>\n";
diff --git a/source/javascripts/syntax-helper.js b/source/javascripts/syntax-helper.js
new file mode 100644
index 00000000..e1a6889b
--- /dev/null
+++ b/source/javascripts/syntax-helper.js
@@ -0,0 +1,30 @@
+function addDivLines(){
+  $('div.highlight pre code').each(function(el){
+    var content = bonzo(el).html();
+    var lines = content.split('\n');
+    var count = lines.length;
+    bonzo(lines).each(function(line, index){
+      if(line == '') line = ' ';
+      lines[index] = '<div class="line">' + line + '</div>';
+    });
+    $(el).html(lines.join(''));
+  });
+}
+function preToTable(){
+  $('div.highlight').each(function(code){
+    var tableStart = '<table cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter">';
+    var lineNumbers = '<pre class="line-numbers">';
+    var tableMiddle = '</pre></td><td class="code" width="100%">';
+    var tableEnd = '</td></tr></tbody></table>';
+    var count = $('div.line', code).length;
+    for (i=1;i<=count; i++){
+      lineNumbers += '<span class="line">'+i+'</span>\n';
+    }
+    table = tableStart + lineNumbers + tableMiddle + '<pre>'+$('pre', code).html()+'</pre>' + tableEnd;
+    $(code).html(table);
+  });
+}
+$.domReady(function () {
+  addDivLines();
+  preToTable();
+});
diff --git a/source/javascripts/twitter.js b/source/javascripts/twitter.js
index d50efe1c..2dad2882 100644
--- a/source/javascripts/twitter.js
+++ b/source/javascripts/twitter.js
@@ -1,9 +1,3 @@
-/* http://www.JSON.org/json2.js 2009-09-29 Public Domain. NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. See http://www.JSON.org/js.html */
-if(!this.JSON){this.JSON={}}(function(){function l(c){return c<10?'0'+c:c}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(c){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+l(this.getUTCMonth()+1)+'-'+l(this.getUTCDate())+'T'+l(this.getUTCHours())+':'+l(this.getUTCMinutes())+':'+l(this.getUTCSeconds())+'Z':null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(c){return this.valueOf()}}var o=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,p=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,h,m,r={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},j;function q(a){p.lastIndex=0;return p.test(a)?'"'+a.replace(p,function(c){var f=r[c];return typeof f==='string'?f:'\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function n(c,f){var a,e,d,i,k=h,g,b=f[c];if(b&&typeof b==='object'&&typeof b.toJSON==='function'){b=b.toJSON(c)}if(typeof j==='function'){b=j.call(f,c,b)}switch(typeof b){case'string':return q(b);case'number':return isFinite(b)?String(b):'null';case'boolean':case'null':return String(b);case'object':if(!b){return'null'}h+=m;g=[];if(Object.prototype.toString.apply(b)==='[object Array]'){i=b.length;for(a=0;a<i;a+=1){g[a]=n(a,b)||'null'}d=g.length===0?'[]':h?'[\n'+h+g.join(',\n'+h)+'\n'+k+']':'['+g.join(',')+']';h=k;return d}if(j&&typeof j==='object'){i=j.length;for(a=0;a<i;a+=1){e=j[a];if(typeof e==='string'){d=n(e,b);if(d){g.push(q(e)+(h?': ':':')+d)}}}}else{for(e in b){if(Object.hasOwnProperty.call(b,e)){d=n(e,b);if(d){g.push(q(e)+(h?': ':':')+d)}}}}d=g.length===0?'{}':h?'{\n'+h+g.join(',\n'+h)+'\n'+k+'}':'{'+g.join(',')+'}';h=k;return d}}if(typeof JSON.stringify!=='function'){JSON.stringify=function(c,f,a){var e;h='';m='';if(typeof a==='number'){for(e=0;e<a;e+=1){m+=' '}}else if(typeof a==='string'){m=a}j=f;if(f&&typeof f!=='function'&&(typeof f!=='object'||typeof f.length!=='number')){throw new Error('JSON.stringify');}return n('',{'':c})}}if(typeof JSON.parse!=='function'){JSON.parse=function(i,k){var g;function b(c,f){var a,e,d=c[f];if(d&&typeof d==='object'){for(a in d){if(Object.hasOwnProperty.call(d,a)){e=b(d,a);if(e!==undefined){d[a]=e}else{delete d[a]}}}}return k.call(c,f,d)}o.lastIndex=0;if(o.test(i)){i=i.replace(o,function(c){return'\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(i.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){g=eval('('+i+')');return typeof k==='function'?b({'':g},''):g}throw new SyntaxError('JSON.parse');}}}());
-
-// jXHR.js (JSON-P XHR) | v0.1 (c) Kyle Simpson | MIT License
-(function(c){var b=c.setTimeout,d=c.document,a=0;c.jXHR=function(){var e,g,n,h,m=null;function l(){try{h.parentNode.removeChild(h)}catch(o){}}function k(){g=false;e="";l();h=null;i(0)}function f(p){try{m.onerror.call(m,p,e)}catch(o){throw new Error(p)}}function j(){if((this.readyState&&this.readyState!=="complete"&&this.readyState!=="loaded")||g){return}this.onload=this.onreadystatechange=null;g=true;if(m.readyState!==4){f("Script failed to load ["+e+"].")}l()}function i(o,p){p=p||[];m.readyState=o;if(typeof m.onreadystatechange==="function"){m.onreadystatechange.apply(m,p)}}m={onerror:null,onreadystatechange:null,readyState:0,open:function(p,o){k();internal_callback="cb"+(a++);(function(q){c.jXHR[q]=function(){try{i.call(m,4,arguments)}catch(r){m.readyState=-1;f("Script failed to run ["+e+"].")}c.jXHR[q]=null}})(internal_callback);e=o.replace(/=\?/,"=jXHR."+internal_callback);i(1)},send:function(){b(function(){h=d.createElement("script");h.setAttribute("type","text/javascript");h.onload=h.onreadystatechange=function(){j.call(h)};h.setAttribute("src",e);d.getElementsByTagName("head")[0].appendChild(h)},0);i(2)},setRequestHeader:function(){},getResponseHeader:function(){return""},getAllResponseHeaders:function(){return[]}};k();return m}})(window);
-
 function getTwitterFeed(success, user, count, replies) {
   feed = new jXHR();
   feed.onerror = function (msg,url) { alert(msg); }
@@ -30,18 +24,18 @@ function showTwitterFeed(tweets){
   var timeline = document.getElementById('tweets');
   timeline.innerHTML='';
   for (t in tweets){
-    timeline.innerHTML+='<li>'+'<p>'+linkifyTweet(tweets[t].text)+'<a href="http://twitter.com/'+twitter_user+'/status/'+tweets[t].id_str+'">'+prettyDate(tweets[t].created_at)+'</a></p>'+'</li>';
+    timeline.innerHTML+='<li>'+'<p>'+'<a href="http://twitter.com/'+twitter_user+'/status/'+tweets[t].id_str+'"><span>&infin;</span><span>'+prettyDate(tweets[t].created_at)+'</span></a>'+linkifyTweet(tweets[t].text)+'</p>'+'</li>';
   }
 }
 function linkifyTweet(text){
-  return text.replace(/(https?:\/\/[\w\-:;?&=+.%#\/]+)/gi, '<a href="$1">$1</a>')
+  return text.replace(/(https?:\/\/)([\w\-:;?&=+.%#\/]+)/gi, '<a href="$1$2">$2</a>')
     .replace(/(^|\W)@(\w+)/g, '$1<a href="http://twitter.com/$2">@$2</a>')
-    .replace(/(^|\W)#(\w+)/g, '$1#<a href="http://search.twitter.com/search?q=%23$2">$2</a>');
+    .replace(/(^|\W)#(\w+)/g, '$1<a href="http://search.twitter.com/search?q=%23$2">#$2</a>');
 }
 
 function prettyDate(date_str){
   var time_formats = [
-    [60, 'just now', 1], // 60
+    [60, 'now', 1], // 60
     [120, '1 min', '1 minute from now'], // 60*2
     [3600, 'mins', 60], // 60*60, 60
     [7200, '1 hour', '1 hour from now'], // 60*60*2
diff --git a/source/test/syntax.html b/source/test/syntax.html
new file mode 100644
index 00000000..ac26554f
--- /dev/null
+++ b/source/test/syntax.html
@@ -0,0 +1,397 @@
+---
+layout: default
+layout: page
+nometa: true
+title: Syntax Highlighting Debug
+---
+
+<h3 class="filename">gist_syntax_test.rb</h3>
+{% gist 996818 test.rb %}
+
+<h3 class="filename">syntax_test.diff</h3>
+{% highlight diff %}
+@@ -590,7 +590,7 @@ class SpritesTest < Test::Unit::TestCase
+   it "should generate a sprite from nested folders" do
+     css = render <<-SCSS
+-      @import "nested/*.png";
++      @import "nested/**/*.png";
+       @include all-nested-sprites;
+     SCSS
+     assert_correct css, <<-CSS
+
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.html</h3>
+{% highlight html %}
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title>A Tiny Page</title>
+<style type="text/css">
+<!--
+      p { font-size:15pt; color:#000 }
+    -->
+</style></head><!-- real comment -->
+<body bgcolor="#FFFFFF" text="#000000" link="#0000CC">
+<script language="javascript" type="text/javascript">
+      function changeHeight(h) {
+        var tds = document.getElementsByTagName("td");
+        for(var i = 0; i < tds.length; i++) {
+          tds[i].setAttribute("height", h + "px");
+      }}
+</script>
+<h1>abc</h1>
+<h2>def</h2>
+<p>Testing page</p>
+</body></html>
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.js</h3>
+{% highlight js %}
+
+/**
+sample javascript from xui
+*/
+
+var undefined,
+    xui,
+    window     = this,
+    string     = new String('string'),
+    document   = window.document,
+    simpleExpr = /^#?([\w-]+)$/,
+    idExpr     = /^#/,
+    tagExpr    = /<([\w:]+)/,
+    slice      = function (e) { return [].slice.call(e, 0); };
+    try { var a = slice(document.documentElement.childNodes)[0].nodeType; }
+    catch(e){ slice = function (e) { var ret=[]; for (var i=0; e[i]; i++)
+        ret.push(e[i]); return ret; }; }
+
+window.x$ = window.xui = xui = function(q, context) {
+    return new xui.fn.find(q, context);
+};
+
+
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.rb</h3>
+{% highlight ruby %}
+
+include Enumerable
+
+def initialize(rbconfig)
+@rbconfig = rbconfig
+@no_harm = false
+end
+
+def load_savefile
+begin
+    File.foreach(savefile()) do |line|
+    k, v = *line.split(/=/, 2)
+    self[k] = v.strip
+    end
+rescue Errno::ENOENT
+    setup_rb_error $!.message + "\n#{File.basename($0)} config first"
+end
+end
+
+if c['rubylibdir']
+    # V > 1.6.3
+    libruby         = "#{c['prefix']}/lib/ruby"
+    siterubyverarch = c['sitearchdir']
+end
+parameterize = lambda {|path|
+    path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
+}
+
+if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
+    makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
+else
+    makeprog = 'make'
+end
+
+def setup_rb_error(msg)
+  raise SetupError, msg
+end
+
+if $0 == __FILE__
+  begin
+    ToplevelInstaller.invoke
+  rescue SetupError
+    raise if $DEBUG
+    $stderr.puts $!.message
+    $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
+    exit 1
+  end
+end
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.php</h3>
+{% highlight php %}
+<?php
+require_once($GLOBALS['g_campsiteDir']. "/$ADMIN_DIR/country/common.php");
+require_once($GLOBALS['g_campsiteDir']. "/classes/SimplePager.php");
+camp_load_translation_strings("api");
+
+$f_country_language_selected = camp_session_get('f_language_selected', '');
+$f_country_offset = camp_session_get('f_country_offset', 0);
+if (empty($f_country_language_selected)) {
+	$f_country_language_selected = null;
+}
+$ItemsPerPage = 20;
+$languages = Language::GetLanguages(null, null, null, array(), array(), true);
+$numCountries = Country::GetNumCountries($f_country_language_selected);
+
+$pager = new SimplePager($numCountries, $ItemsPerPage, "index.php?");
+
+$crumbs = array();
+$crumbs[] = array(getGS("Configure"), "");
+$crumbs[] = array(getGS("Countries"), "");
+echo camp_html_breadcrumbs($crumbs);
+
+?>
+
+<?php  if ($g_user->hasPermission("ManageCountries")) { ?>
+<table BORDER="0" CELLSPACING="0" CELLPADDING="1">
+    <tr>
+        <td><a href="add.php"><?php putGS("Add new"); ?></a></td>
+    </tr>
+</table>
+{% endhighlight %}
+
+
+<h3 class="filename">syntax_test.hs</h3>
+{% highlight hs %}
+{-# LANGUAGE OverloadedStrings #-}
+module Main where
+
+--import Prelude hiding (id)
+--import Control.Category (id)
+import Control.Arrow ((>>>), (***), arr)
+import Control.Monad (forM_)
+-- import Data.Monoid (mempty, mconcat)
+
+-- import System.FilePath
+
+import Hakyll
+
+
+main :: IO ()
+main = hakyll $ do
+
+    route   "css/*" $ setExtension "css"
+    compile "css/*" $ byExtension (error "Not a (S)CSS file")
+        [ (".css",  compressCssCompiler)
+        , (".scss", sass)
+        ]
+
+    route   "js/**" idRoute
+    compile "js/**" copyFileCompiler
+
+    route   "img/*" idRoute
+    compile "img/*" copyFileCompiler
+
+    compile "templates/*" templateCompiler
+
+    forM_ ["test.md", "index.md"] $ \page -> do
+        route   page $ setExtension "html"
+        compile page $ pageCompiler
+            >>> applyTemplateCompiler "templates/default.html"
+            >>> relativizeUrlsCompiler
+
+sass :: Compiler Resource String
+sass = getResourceString >>> unixFilter "sass" ["-s", "--scss"]
+                         >>> arr compressCss
+
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.sh</h3>
+{% highlight sh %}
+#!/bin/bash
+
+cd $ROOT_DIR
+DOT_FILES="lastpass weechat ssh Xauthority"
+for dotfile in $DOT_FILES; do conform_link "$DATA_DIR/$dotfile" ".$dotfile"; done
+
+# TODO: refactor with suffix variables (or common cron values)
+
+case "$PLATFORM" in
+	linux)
+        #conform_link "$CONF_DIR/shell/zshenv" ".zshenv"
+        crontab -l > $ROOT_DIR/tmp/crontab-conflict-arch
+        cd $ROOT_DIR/$CONF_DIR/cron
+        if [[ "$(diff ~/tmp/crontab-conflict-arch crontab-current-arch)" == ""
+            ]];
+            then # no difference with current backup
+                logger "$LOG_PREFIX: crontab live settings match stored "\
+                    "settings; no restore required"
+                rm ~/tmp/crontab-conflict-arch
+            else # current crontab settings in file do not match live settings
+                crontab $ROOT_DIR/$CONF_DIR/cron/crontab-current-arch
+                logger "$LOG_PREFIX: crontab stored settings conflict with "\
+                    "live settings; stored settings restored. "\
+                    "Previous settings recorded in ~/tmp/crontab-conflict-arch."
+        fi
+    ;;
+
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.py</h3>
+{% highlight py %}
+# test python (sample from offlineimap)
+
+class ExitNotifyThread(Thread):
+    """This class is designed to alert a "monitor" to the fact that a thread has
+    exited and to provide for the ability for it to find out why."""
+    def run(self):
+        global exitthreads, profiledir
+        self.threadid = thread.get_ident()
+        try:
+            if not profiledir:          # normal case
+                Thread.run(self)
+            else:
+                try:
+                    import cProfile as profile
+                except ImportError:
+                    import profile
+                prof = profile.Profile()
+                try:
+                    prof = prof.runctx("Thread.run(self)", globals(), locals())
+                except SystemExit:
+                    pass
+                prof.dump_stats( \
+                            profiledir + "/" + str(self.threadid) + "_" + \
+                            self.getName() + ".prof")
+        except:
+            self.setExitCause('EXCEPTION')
+            if sys:
+                self.setExitException(sys.exc_info()[1])
+                tb = traceback.format_exc()
+                self.setExitStackTrace(tb)
+        else:
+            self.setExitCause('NORMAL')
+        if not hasattr(self, 'exitmessage'):
+            self.setExitMessage(None)
+
+        if exitthreads:
+            exitthreads.put(self, True)
+
+    def setExitCause(self, cause):
+        self.exitcause = cause
+    def getExitCause(self):
+        """Returns the cause of the exit, one of:
+        'EXCEPTION' -- the thread aborted because of an exception
+        'NORMAL' -- normal termination."""
+        return self.exitcause
+    def setExitException(self, exc):
+        self.exitexception = exc
+    def getExitException(self):
+        """If getExitCause() is 'EXCEPTION', holds the value from
+        sys.exc_info()[1] for this exception."""
+        return self.exitexception
+    def setExitStackTrace(self, st):
+        self.exitstacktrace = st
+    def getExitStackTrace(self):
+        """If getExitCause() is 'EXCEPTION', returns a string representing
+        the stack trace for this exception."""
+        return self.exitstacktrace
+    def setExitMessage(self, msg):
+        """Sets the exit message to be fetched by a subsequent call to
+        getExitMessage.  This message may be any object or type except
+        None."""
+        self.exitmessage = msg
+    def getExitMessage(self):
+        """For any exit cause, returns the message previously set by
+        a call to setExitMessage(), or None if there was no such message
+        set."""
+        return self.exitmessage
+
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.pl</h3>
+{% highlight perl %}
+#!perl -w
+
+# Time-stamp: <2002/04/06, 13:12:13 (EST), maverick, csvformat.pl>
+# Two pass CSV file to table formatter
+
+$delim = $#ARGV >= 1 ? $ARGV[1] : ',';
+print STDERR "Split pattern: $delim\n";
+
+# first pass
+open F, "<$ARGV[0]" or die;
+while(<F>)
+{
+  chomp;
+  $i = 0;
+  map { $max[$_->[1]] = $_->[0] if $_->[0] > ($max[$_->[1]] || 0) }
+    (map {[length $_, $i++]} split($delim));
+}
+close F;
+
+print STDERR 'Field width:   ', join(', ', @max), "\n";
+print STDERR join(' ', map {'-' x $_} @max);
+
+# second pass
+open F, "<$ARGV[0]" or die;
+while(<F>)
+  {
+  chomp;
+  $i = 0;
+  map { printf("%-$max[$_->[1]]s ", $_->[0]) }
+    (map {[$_, $i++]} split($delim));
+  print "\n";
+}
+close F;
+
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.java</h3>
+{% highlight java %}
+import java.util.Map;
+import java.util.TreeSet;
+
+public class GetEnv {
+  /**
+   * let's test generics
+   * @param args the command line arguments
+   */
+  public static void main(String[] args) {
+    // get a map of environment variables
+    Map<String, String> env = System.getenv();
+    // build a sorted set out of the keys and iterate
+    for(String k: new TreeSet<String>(env.keySet())) {
+      System.out.printf("%s = %s\n", k, env.get(k));
+    }
+  }    }
+{% endhighlight %}
+
+<h3 class="filename">syntax_test.c</h3>
+{% highlight c %}
+#define UNICODE
+#include <windows.h>
+
+int main(int argc, char **argv) {
+  int speed = 0, speed1 = 0, speed2 = 0; // 1-20
+  printf("Set Mouse Speed by Maverick\n");
+
+  SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
+  printf("Current speed: %2d\n", speed);
+
+  if (argc == 1) return 0;
+  if (argc >= 2) sscanf(argv[1], "%d", &speed1);
+  if (argc >= 3) sscanf(argv[2], "%d", &speed2);
+
+  if (argc == 2) // set speed to first value
+    speed = speed1;
+  else if (speed == speed1 || speed == speed2) // alternate
+    speed = speed1 + speed2 - speed;
+  else
+    speed = speed1;  // start with first value
+
+  SystemParametersInfo(SPI_SETMOUSESPEED, 0,  speed, 0);
+  SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
+  printf("New speed:     %2d\n", speed);
+  return 0;
+}
+
+{% endhighlight %}
+
diff --git a/source/test/syntax.markdown b/source/test/syntax.markdown
deleted file mode 100644
index ec5bab50..00000000
--- a/source/test/syntax.markdown
+++ /dev/null
@@ -1,228 +0,0 @@
---- 
-layout: default
-title: Syntax Highlighting Debug
----
-<div class="code_window">
-<em>Ruby</em>
-{% highlight ruby %}
-def rebuild_site(relative)
-  puts ">>> Change Detected to: #{relative} <<<"
-  IO.popen('rake generate') do |io|
-    print(io.readpartial(512)) until io.eof?
-  end
-  puts '>>> Update Complete <<<'
-end
-{% endhighlight %}
-</div>
-
-So that's a small example. What about a big one?
-
-<div class="code_window">
-<em>Ruby</em>
-{% highlight ruby %}
-require 'active_support/core_ext/array'
-require 'active_support/core_ext/hash/except'
-require 'active_support/core_ext/object/metaclass'
-
-module ActiveRecord
-  module NamedScope
-    extend ActiveSupport::Concern
-
-    # All subclasses of ActiveRecord::Base have one named scope:
-    # * <tt>scoped</tt> - which allows for the creation of anonymous \scopes, on the fly: <tt>Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)</tt>
-    #
-    # These anonymous \scopes tend to be useful when procedurally generating complex queries, where passing
-    # intermediate values (scopes) around as first-class objects is convenient.
-    #
-    # You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.
-    included do
-      named_scope :scoped, lambda { |scope| scope }
-    end
-
-    module ClassMethods
-      def scopes
-        read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
-      end
-
-      # Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
-      # such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :red, :conditions => {:color => 'red'}
-      #     named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
-      #   end
-      # 
-      # The above calls to <tt>named_scope</tt> define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red, 
-      # in effect, represents the query <tt>Shirt.find(:all, :conditions => {:color => 'red'})</tt>.
-      #
-      # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by Shirt.red is not an Array; it resembles the association object
-      # constructed by a <tt>has_many</tt> declaration. For instance, you can invoke <tt>Shirt.red.find(:first)</tt>, <tt>Shirt.red.count</tt>,
-      # <tt>Shirt.red.find(:all, :conditions => {:size => 'small'})</tt>. Also, just
-      # as with the association objects, named \scopes act like an Array, implementing Enumerable; <tt>Shirt.red.each(&block)</tt>,
-      # <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if Shirt.red really was an Array.
-      #
-      # These named \scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are both red and dry clean only.
-      # Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt> returns the number of garments
-      # for which these criteria obtain. Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
-      #
-      # All \scopes are available as class methods on the ActiveRecord::Base descendant upon which the \scopes were defined. But they are also available to
-      # <tt>has_many</tt> associations. If,
-      #
-      #   class Person < ActiveRecord::Base
-      #     has_many :shirts
-      #   end
-      #
-      # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
-      # only shirts.
-      #
-      # Named \scopes can also be procedural:
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :colored, lambda { |color|
-      #       { :conditions => { :color => color } }
-      #     }
-      #   end
-      #
-      # In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
-      #
-      # Named \scopes can also have extensions, just as with <tt>has_many</tt> declarations:
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :red, :conditions => {:color => 'red'} do
-      #       def dom_id
-      #         'red_shirts'
-      #       end
-      #     end
-      #   end
-      #
-      #
-      # For testing complex named \scopes, you can examine the scoping options using the
-      # <tt>proxy_options</tt> method on the proxy itself.
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :colored, lambda { |color|
-      #       { :conditions => { :color => color } }
-      #     }
-      #   end
-      #
-      #   expected_options = { :conditions => { :colored => 'red' } }
-      #   assert_equal expected_options, Shirt.colored('red').proxy_options
-      def named_scope(name, options = {}, &block)
-        name = name.to_sym
-        scopes[name] = lambda do |parent_scope, *args|
-          Scope.new(parent_scope, case options
-            when Hash
-              options
-            when Proc
-              options.call(*args)
-          end, &block)
-        end
-        metaclass.instance_eval do
-          define_method name do |*args|
-            scopes[name].call(self, *args)
-          end
-        end
-      end
-    end
-
-    class Scope
-      attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined
-      NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? many? respond_to?).to_set
-      [].methods.each do |m|
-        unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
-          delegate m, :to => :proxy_found
-        end
-      end
-
-      delegate :scopes, :with_scope, :scoped_methods, :to => :proxy_scope
-
-      def initialize(proxy_scope, options, &block)
-        options ||= {}
-        [options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
-        extend Module.new(&block) if block_given?
-        unless Scope === proxy_scope
-          @current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
-        end
-        @proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
-      end
-
-      def reload
-        load_found; self
-      end
-
-      def first(*args)
-        if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
-          proxy_found.first(*args)
-        else
-          find(:first, *args)
-        end
-      end
-
-      def last(*args)
-        if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
-          proxy_found.last(*args)
-        else
-          find(:last, *args)
-        end
-      end
-
-      def size
-        @found ? @found.length : count
-      end
-
-      def empty?
-        @found ? @found.empty? : count.zero?
-      end
-
-      def respond_to?(method, include_private = false)
-        super || @proxy_scope.respond_to?(method, include_private)
-      end
-
-      def any?
-        if block_given?
-          proxy_found.any? { |*block_args| yield(*block_args) }
-        else
-          !empty?
-        end
-      end
-
-      # Returns true if the named scope has more than 1 matching record.
-      def many?
-        if block_given?
-          proxy_found.many? { |*block_args| yield(*block_args) }
-        else
-          size > 1
-        end
-      end
-
-      protected
-      def proxy_found
-        @found || load_found
-      end
-
-      private
-      def method_missing(method, *args, &block)
-        if scopes.include?(method)
-          scopes[method].call(self, *args)
-        else
-          with_scope({:find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ?  proxy_options[:conditions] : {}}, :reverse_merge) do
-            method = :new if method == :build
-            if current_scoped_methods_when_defined && !scoped_methods.include?(current_scoped_methods_when_defined)
-              with_scope current_scoped_methods_when_defined do
-                proxy_scope.send(method, *args, &block)
-              end
-            else
-              proxy_scope.send(method, *args, &block)
-            end
-          end
-        end
-      end
-
-      def load_found
-        @found = find(:all)
-      end
-    end
-  end
-end
-{% endhighlight %}
-</div>
\ No newline at end of file
-- 
cgit v1.2.1