diff --git a/.gitignore b/.gitignore
index b03d344..e91dffb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,7 @@
 *.swp
 profile
 *.moved-aside
+xos/configurations/frontend/Dockerfile
+xos/core/xoslib/karma-*
+xos/core/xoslib/docs
+node_modules
diff --git a/xos/configurations/common/admin-openrc.sh b/xos/configurations/common/admin-openrc.sh
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/xos/configurations/common/admin-openrc.sh
diff --git a/xos/configurations/frontend/Dockerfile.frontend b/xos/configurations/frontend/Dockerfile.frontend
index 3c8d283..4f0acf6 100644
--- a/xos/configurations/frontend/Dockerfile.frontend
+++ b/xos/configurations/frontend/Dockerfile.frontend
@@ -2,4 +2,18 @@
 
 RUN echo "autostart=false" >> /etc/supervisor/conf.d/observer.conf
 
+# Install Node.js
+RUN sudo apt-get install -y \
+      nodejs \
+      npm
+
+# Link nodejs to node
+RUN sudo ln -s "$(which nodejs)" /usr/bin/node
+
+RUN echo "Node Version: "
+RUN node -v
+
+# TODO
+# - Enter /opt/xos/core/xoslib and run npm install
+
 CMD /usr/bin/make -C /opt/xos/configurations/frontend -f Makefile.inside
diff --git a/xos/configurations/frontend/Makefile b/xos/configurations/frontend/Makefile
index d03e1bc..a72eb2b 100644
--- a/xos/configurations/frontend/Makefile
+++ b/xos/configurations/frontend/Makefile
@@ -1,6 +1,7 @@
 MYIP:=$(shell hostname -i)
 RUNNING_CONTAINER=$(shell sudo docker ps|grep "xos"|awk '{print $$NF}')
 LAST_CONTAINER=$(shell sudo docker ps -l -q)
+XOS_FOLDER=$(shell pwd)
 
 all: frontend
 
@@ -8,8 +9,10 @@
 	sudo apt-get -y install httpie
 	cat ../common/Dockerfile.common Dockerfile.frontend > Dockerfile
 	cd ../../..; sudo docker build -t xos -f xos/configurations/frontend/Dockerfile .
-	sudo docker run -d --add-host="0.0.0.0:$(MYIP)" -p 9999:8000 xos
-	bash ../common/wait_for_xos.sh
+	echo $(XOS_FOLDER)
+	sudo docker run -v $(XOS_FOLDER)/../../core/xoslib:/opt/xos/core/xoslib -p 9000:8000 --add-host="0.0.0.0:127.0.0.1" xos
+	#sudo docker run -d --add-host="0.0.0.0:$(MYIP)" -p 9999:8000 xos
+	#bash ../common/wait_for_xos.sh
 
 stop:
 	sudo docker stop $(RUNNING_CONTAINER)
diff --git a/xos/configurations/frontend/README b/xos/configurations/frontend/README
deleted file mode 100644
index ba8875e..0000000
--- a/xos/configurations/frontend/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This configuration launches an XOS container on Cloudlab that runs the XOS develserver. The container is left running
-in the backgorund.
-
-The observer is not started, and there is no openstack backend connected for XOS. 
-
-This configuration is intended for developing the XOS GUI. 
diff --git a/xos/configurations/frontend/README.md b/xos/configurations/frontend/README.md
new file mode 100644
index 0000000..6303bfc
--- /dev/null
+++ b/xos/configurations/frontend/README.md
@@ -0,0 +1,33 @@
+# XOS UI Development
+
+This configuration launches an XOS container on Cloudlab that runs the XOS develserver. The container is left running
+in the backgorund.
+
+The observer is not started, and there is no openstack backend connected for XOS. 
+
+This configuration is intended for developing the XOS GUI. 
+
+## Getting Started
+
+- Navigate to '/xos/configurations/frontend' folder
+- Run `make` command
+
+You'll be able to visit XOS at `0.0.0.0:9000` and the `xos/core/xoslib` folder is shared with the container. This means that any update to that folder is automatically reported in the container.
+
+## Test
+
+To run the FE tests, navigate to: `xos/core/xoslib`, and run 'npm test'.
+
+This will install the required `npm` dependencies and run the test.
+
+Tests are runned in a headless browser (_PhantomJs_) by _Karma_ and the assertions are made with _Jasmine_. This is a pretty common standard for FE testing so you should feel at home.
+
+You can find the tests in the `spec/` folder, each source file has a corresponding `.test` file in it.
+
+## JS Styleguide
+
+This project is following [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml). To contribute please install [Eslint](http://eslint.org/) in your editor and run `npm run eslint` before commit.
+
+> _NOTE_
+> Many of the already present file were not Style compliant. Linting for them has been disabled as it was to time consuming fix all of them. If **you are going to work** on that files, please **start fixing style issues**, and then **remove the `/* eslint-disable */`** comment
+
diff --git a/xos/core/static/xos.css b/xos/core/static/xos.css
index 00e1f2b..96ca8b1 100644
--- a/xos/core/static/xos.css
+++ b/xos/core/static/xos.css
@@ -316,7 +316,7 @@
 text-shadow: rgb(46, 43, 43) 0.1em 0.1em 0.2em;
 letter-spacing: 1px;
 
-left: 10px;
+/*left: 10px;*/
 background-image: url("right_arrow.png");
     background-position: 97% center;
 }
@@ -390,9 +390,9 @@
 /*background-color: #D6E7F8;*/
 font-weight:normal;
 font-size: 1.2em;
-font-weight: bold;
+/*font-weight: bold;*/
 color:#ffffff;
-padding-top:10px;
+/*padding-top:10px;*/
 text-decoration:none;
 }
 
@@ -415,7 +415,7 @@
 /*background-color: #448CCA;*/
 background-color: #515151;
 font-weight:normal;
-font-size: 1.2em;
+/*font-size: 1.2em;*/
 /*color:#ffffff;*/
 padding-top:10px;
 text-decoration:none;
@@ -571,10 +571,14 @@
 border: none;
 }
 
+.nav-tabs-suit li a{
+  font-weight: normal;
+}
+
 .nav-tabs-suit li a:hover{
 border: none;
 color: #ffffff;
-letter-spacing: 1px;
+/*letter-spacing: 1px;*/
 text-shadow: rgb(46, 43, 43) 0.1em 0.1em 0.2em;
 }
 
diff --git a/xos/core/xoslib/.eslintignore b/xos/core/xoslib/.eslintignore
new file mode 100644
index 0000000..be5c014
--- /dev/null
+++ b/xos/core/xoslib/.eslintignore
@@ -0,0 +1,4 @@
+node_modules/**/*.js
+static/js/xsh/**/*.js
+static/js/vendor/**/*.js
+spec/helpers/*.js
\ No newline at end of file
diff --git a/xos/core/xoslib/.eslintrc b/xos/core/xoslib/.eslintrc
new file mode 100644
index 0000000..3615cae
--- /dev/null
+++ b/xos/core/xoslib/.eslintrc
@@ -0,0 +1,27 @@
+{
+  "extends": "defaults/configurations/google",
+  "env" : {
+    "browser": true
+  },
+  "rules" : {
+    "camelcase": [0],
+    "no-underscore-dangle": [0],
+    "eqeqeq": [1],
+    "no-alert": [1],
+    "no-unused-vars": [1],
+    "key-spacing": [2, {
+        "beforeColon": false,
+        "afterColon": true
+    }],
+    "valid-jsdoc": 2,
+    "max-len": [1, 120, 4, {"ignoreComments": true, "ignoreUrls": true}],
+    brace-style: [2, "stroustrup"]
+  },
+  "globals": {
+    "$": false,
+    "_": false,
+    "Backbone": false,
+    "Marionette": false,
+    "xos": false
+  }
+}
diff --git a/xos/core/xoslib/jsdoc.conf.json b/xos/core/xoslib/jsdoc.conf.json
new file mode 100644
index 0000000..3352b79
--- /dev/null
+++ b/xos/core/xoslib/jsdoc.conf.json
@@ -0,0 +1,30 @@
+{
+  "tags": {
+    "allowUnknownTags": true
+  },
+  "plugins": ["plugins/markdown"],
+  "templates": {
+    "cleverLinks": false,
+    "monospaceLinks": false,
+    "dateFormat": "ddd MMM Do YYYY",
+    "outputSourceFiles": true,
+    "outputSourcePath": true,
+    "systemName": "XOS Lib",
+    "footer": "",
+    "copyright": "DocStrap Copyright © 2012-2014 The contributors to the JSDoc3 and DocStrap projects.",
+    "navType": "vertical",
+    "theme": "cosmo",
+    "linenums": true,
+    "collapseSymbols": false,
+    "inverseNav": true,
+    "highlightTutorialCode": true,
+    "protocol": "html://"
+  },
+  "markdown": {
+    "parser": "gfm",
+    "hardwrap": true
+  },
+  "opts": {
+    "template": "./node_modules/ink-docstrap/template/"
+  }
+}
diff --git a/xos/core/xoslib/karma.conf.js b/xos/core/xoslib/karma.conf.js
new file mode 100644
index 0000000..5eba2fe
--- /dev/null
+++ b/xos/core/xoslib/karma.conf.js
@@ -0,0 +1,83 @@
+// Karma configuration
+// Generated on Tue Oct 06 2015 09:27:10 GMT+0000 (UTC)
+
+/* eslint indent: [2,2], quotes: [2, "single"]*/
+
+/*eslint-disable*/
+module.exports = function(config) {
+/*eslint-enable*/
+  config.set({
+
+    // base path that will be used to resolve all patterns (eg. files, exclude)
+    basePath: '',
+
+
+    // frameworks to use
+    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+    frameworks: ['jasmine'],
+
+
+    // list of files / patterns to load in the browser
+    files: [
+      'static/js/vendor/jquery-1.11.3.js',
+      'static/js/vendor/underscore-min.js',
+      'static/js/vendor/backbone.js',
+      'static/js/vendor/backbone.wreqr.js',
+      'static/js/vendor/backbone.babysitter.js',
+      'static/js/vendor/backbone.marionette.js',
+      'static/js/vendor/backbone.syphon.js',
+      'static/js/xoslib/*.js',
+
+      'spec/helpers/jasmine-jquery.js',
+      'spec/**/*.test.js',
+
+      'spec/**/*.html'
+    ],
+
+
+    // list of files to exclude
+    exclude: [
+      //'**/xos-utils.test.js' //skip this test, useful in dev, comment before commit
+    ],
+
+
+    // preprocess matching files before serving them to the browser
+    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+    preprocessors: {
+      'spec/**/*.test.js': ['babel']
+    },
+
+
+    // test results reporter to use
+    // possible values: 'dots', 'progress'
+    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+    reporters: ['mocha'],
+
+
+    // web server port
+    port: 9876,
+
+
+    // enable / disable colors in the output (reporters and logs)
+    colors: true,
+
+
+    // level of logging
+    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+    logLevel: config.LOG_INFO,
+
+
+    // enable / disable watching file and executing tests whenever any file changes
+    autoWatch: true,
+
+
+    // start these browsers
+    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+    browsers: ['PhantomJS'],
+
+
+    // Continuous Integration mode
+    // if true, Karma captures browsers, runs the tests and exits
+    singleRun: false
+  });
+};
diff --git a/xos/core/xoslib/package.json b/xos/core/xoslib/package.json
new file mode 100644
index 0000000..d2ed905
--- /dev/null
+++ b/xos/core/xoslib/package.json
@@ -0,0 +1,27 @@
+{
+  "name": "xoslib",
+  "version": "0.0.0",
+  "description": "Add to the following in settings.py",
+  "main": "index.js",
+  "scripts": {
+    "pretest": "npm install",
+    "test": "karma start",
+    "lint": "eslint .",
+    "docs": "jsdoc static/js -r -c ./jsdoc.conf.json -d docs"
+  },
+  "author": "",
+  "license": "BSD-2-Clause",
+  "devDependencies": {
+    "eslint": "~1.6.0",
+    "eslint-config-defaults": "^7.0.1",
+    "ink-docstrap": "^0.5.2",
+    "jasmine-core": "~2.3.4",
+    "jsdoc": "^3.3.3",
+    "karma": "~0.13.10",
+    "karma-babel-preprocessor": "~5.2.2",
+    "karma-jasmine": "~0.3.6",
+    "karma-mocha-reporter": "~1.1.1",
+    "karma-phantomjs-launcher": "~0.2.1",
+    "phantomjs": "~1.9.18"
+  }
+}
diff --git a/xos/core/xoslib/spec/.eslintrc b/xos/core/xoslib/spec/.eslintrc
new file mode 100644
index 0000000..eb98f18
--- /dev/null
+++ b/xos/core/xoslib/spec/.eslintrc
@@ -0,0 +1,50 @@
+{
+  "ecmaFeatures": {
+    "blockBindings": true,
+    "forOf" : true,
+    "generators": true,
+    "destructuring": true,
+    "forOf": true,
+    "arrowFunctions": true,
+    "templateStrings": true,
+    "destructuring": true,
+    "forOf": true,
+    "arrowFunctions": true,
+    "templateStrings": true,
+    "generators": true
+  },
+  "env" : {
+    "browser": true,
+    "node": true,
+    "es6": true
+  },
+  "rules" : {
+    "quotes": [1, "single"],
+    "camelcase": [0],
+    "no-underscore-dangle": [0],
+    "eqeqeq": [1],
+    "no-alert": [1],
+    "no-unused-vars": [1],
+    "key-spacing": [2, {
+        "beforeColon": false,
+        "afterColon": true
+    }],
+    "indent": [2, 2],
+    "no-undef": [0],
+    "newline-after-var": [0]
+  },
+  "globals": {
+    "console": false,
+    "describe": false,
+    "xdescribe": false,
+    "it": false,
+    "xit": false,
+    "before": false,
+    "beforeEach": false,
+    "after": false,
+    "afterEach": false,
+    "expect": false,
+    "jasmine": false,
+    "spyOn": false
+  }
+}
diff --git a/xos/core/xoslib/spec/helpers/jasmine-jquery.js b/xos/core/xoslib/spec/helpers/jasmine-jquery.js
new file mode 100644
index 0000000..7713331
--- /dev/null
+++ b/xos/core/xoslib/spec/helpers/jasmine-jquery.js
@@ -0,0 +1,840 @@
+/*!
+Jasmine-jQuery: a set of jQuery helpers for Jasmine tests.
+
+Version 2.1.1
+
+https://github.com/velesin/jasmine-jquery
+
+Copyright (c) 2010-2014 Wojciech Zawistowski, Travis Jeffery
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+(function (root, factory) {
+     if (typeof module !== 'undefined' && module.exports) {
+        factory(root, root.jasmine, require('jquery'));
+    } else {
+        factory(root, root.jasmine, root.jQuery);
+    }
+}((function() {return this; })(), function (window, jasmine, $) { "use strict";
+
+  jasmine.spiedEventsKey = function (selector, eventName) {
+    return [$(selector).selector, eventName].toString()
+  }
+
+  jasmine.getFixtures = function () {
+    return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures()
+  }
+
+  jasmine.getStyleFixtures = function () {
+    return jasmine.currentStyleFixtures_ = jasmine.currentStyleFixtures_ || new jasmine.StyleFixtures()
+  }
+
+  jasmine.Fixtures = function () {
+    this.containerId = 'jasmine-fixtures'
+    this.fixturesCache_ = {}
+    this.fixturesPath = 'spec/javascripts/fixtures'
+  }
+
+  jasmine.Fixtures.prototype.set = function (html) {
+    this.cleanUp()
+    return this.createContainer_(html)
+  }
+
+  jasmine.Fixtures.prototype.appendSet= function (html) {
+    this.addToContainer_(html)
+  }
+
+  jasmine.Fixtures.prototype.preload = function () {
+    this.read.apply(this, arguments)
+  }
+
+  jasmine.Fixtures.prototype.load = function () {
+    this.cleanUp()
+    this.createContainer_(this.read.apply(this, arguments))
+  }
+
+  jasmine.Fixtures.prototype.appendLoad = function () {
+    this.addToContainer_(this.read.apply(this, arguments))
+  }
+
+  jasmine.Fixtures.prototype.read = function () {
+    var htmlChunks = []
+      , fixtureUrls = arguments
+
+    for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+      htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]))
+    }
+
+    return htmlChunks.join('')
+  }
+
+  jasmine.Fixtures.prototype.clearCache = function () {
+    this.fixturesCache_ = {}
+  }
+
+  jasmine.Fixtures.prototype.cleanUp = function () {
+    $('#' + this.containerId).remove()
+  }
+
+  jasmine.Fixtures.prototype.sandbox = function (attributes) {
+    var attributesToSet = attributes || {}
+    return $('<div id="sandbox" />').attr(attributesToSet)
+  }
+
+  jasmine.Fixtures.prototype.createContainer_ = function (html) {
+    var container = $('<div>')
+    .attr('id', this.containerId)
+    .html(html)
+
+    $(document.body).append(container)
+    return container
+  }
+
+  jasmine.Fixtures.prototype.addToContainer_ = function (html){
+    var container = $(document.body).find('#'+this.containerId).append(html)
+
+    if (!container.length) {
+      this.createContainer_(html)
+    }
+  }
+
+  jasmine.Fixtures.prototype.getFixtureHtml_ = function (url) {
+    if (typeof this.fixturesCache_[url] === 'undefined') {
+      this.loadFixtureIntoCache_(url)
+    }
+    return this.fixturesCache_[url]
+  }
+
+  jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
+    var self = this
+      , url = this.makeFixtureUrl_(relativeUrl)
+      , htmlText = ''
+      , request = $.ajax({
+        async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+        cache: false,
+        url: url,
+        dataType: 'html',
+        success: function (data, status, $xhr) {
+          htmlText = $xhr.responseText
+        }
+      }).fail(function ($xhr, status, err) {
+          console.log($xhr.responseText);
+          console.log($xhr.getAllResponseHeaders());
+          throw new Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
+      })
+
+      var scripts = $($.parseHTML(htmlText, true)).find('script[src]') || [];
+
+      scripts.each(function(){
+        $.ajax({
+            async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+            cache: false,
+            dataType: 'script',
+            url: $(this).attr('src'),
+            success: function (data, status, $xhr) {
+                htmlText += '<script>' + $xhr.responseText + '</script>'
+            },
+            error: function ($xhr, status, err) {
+                throw new Error('Script could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
+            }
+        });
+      })
+
+      self.fixturesCache_[relativeUrl] = htmlText;
+  }
+
+  jasmine.Fixtures.prototype.makeFixtureUrl_ = function (relativeUrl){
+    return this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
+  }
+
+  jasmine.Fixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) {
+    return this[methodName].apply(this, passedArguments)
+  }
+
+
+  jasmine.StyleFixtures = function () {
+    this.fixturesCache_ = {}
+    this.fixturesNodes_ = []
+    this.fixturesPath = 'spec/javascripts/fixtures'
+  }
+
+  jasmine.StyleFixtures.prototype.set = function (css) {
+    this.cleanUp()
+    this.createStyle_(css)
+  }
+
+  jasmine.StyleFixtures.prototype.appendSet = function (css) {
+    this.createStyle_(css)
+  }
+
+  jasmine.StyleFixtures.prototype.preload = function () {
+    this.read_.apply(this, arguments)
+  }
+
+  jasmine.StyleFixtures.prototype.load = function () {
+    this.cleanUp()
+    this.createStyle_(this.read_.apply(this, arguments))
+  }
+
+  jasmine.StyleFixtures.prototype.appendLoad = function () {
+    this.createStyle_(this.read_.apply(this, arguments))
+  }
+
+  jasmine.StyleFixtures.prototype.cleanUp = function () {
+    while(this.fixturesNodes_.length) {
+      this.fixturesNodes_.pop().remove()
+    }
+  }
+
+  jasmine.StyleFixtures.prototype.createStyle_ = function (html) {
+    var styleText = $('<div></div>').html(html).text()
+      , style = $('<style>' + styleText + '</style>')
+
+    this.fixturesNodes_.push(style)
+    $('head').append(style)
+  }
+
+  jasmine.StyleFixtures.prototype.clearCache = jasmine.Fixtures.prototype.clearCache
+  jasmine.StyleFixtures.prototype.read_ = jasmine.Fixtures.prototype.read
+  jasmine.StyleFixtures.prototype.getFixtureHtml_ = jasmine.Fixtures.prototype.getFixtureHtml_
+  jasmine.StyleFixtures.prototype.loadFixtureIntoCache_ = jasmine.Fixtures.prototype.loadFixtureIntoCache_
+  jasmine.StyleFixtures.prototype.makeFixtureUrl_ = jasmine.Fixtures.prototype.makeFixtureUrl_
+  jasmine.StyleFixtures.prototype.proxyCallTo_ = jasmine.Fixtures.prototype.proxyCallTo_
+
+  jasmine.getJSONFixtures = function () {
+    return jasmine.currentJSONFixtures_ = jasmine.currentJSONFixtures_ || new jasmine.JSONFixtures()
+  }
+
+  jasmine.JSONFixtures = function () {
+    this.fixturesCache_ = {}
+    this.fixturesPath = 'spec/javascripts/fixtures/json'
+  }
+
+  jasmine.JSONFixtures.prototype.load = function () {
+    this.read.apply(this, arguments)
+    return this.fixturesCache_
+  }
+
+  jasmine.JSONFixtures.prototype.read = function () {
+    var fixtureUrls = arguments
+
+    for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+      this.getFixtureData_(fixtureUrls[urlIndex])
+    }
+
+    return this.fixturesCache_
+  }
+
+  jasmine.JSONFixtures.prototype.clearCache = function () {
+    this.fixturesCache_ = {}
+  }
+
+  jasmine.JSONFixtures.prototype.getFixtureData_ = function (url) {
+    if (!this.fixturesCache_[url]) this.loadFixtureIntoCache_(url)
+    return this.fixturesCache_[url]
+  }
+
+  jasmine.JSONFixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
+    var self = this
+      , url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
+
+    $.ajax({
+      async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+      cache: false,
+      dataType: 'json',
+      url: url,
+      success: function (data) {
+        self.fixturesCache_[relativeUrl] = data
+      },
+      error: function ($xhr, status, err) {
+        throw new Error('JSONFixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
+      }
+    })
+  }
+
+  jasmine.JSONFixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) {
+    return this[methodName].apply(this, passedArguments)
+  }
+
+  jasmine.jQuery = function () {}
+
+  jasmine.jQuery.browserTagCaseIndependentHtml = function (html) {
+    return $('<div/>').append(html).html()
+  }
+
+  jasmine.jQuery.elementToString = function (element) {
+    return $(element).map(function () { return this.outerHTML; }).toArray().join(', ')
+  }
+
+  var data = {
+      spiedEvents: {}
+    , handlers:    []
+  }
+
+  jasmine.jQuery.events = {
+    spyOn: function (selector, eventName) {
+      var handler = function (e) {
+        var calls = (typeof data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] !== 'undefined') ? data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0
+        data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = {
+          args: jasmine.util.argsToArray(arguments),
+          calls: ++calls
+        }
+      }
+
+      $(selector).on(eventName, handler)
+      data.handlers.push(handler)
+
+      return {
+        selector: selector,
+        eventName: eventName,
+        handler: handler,
+        reset: function (){
+          delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
+        },
+        calls: {
+          count: function () {
+              return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ?
+                data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0;
+          },
+          any: function () {
+              return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ?
+                !!data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : false;
+          }
+        }
+      }
+    },
+
+    args: function (selector, eventName) {
+      var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].args
+
+      if (!actualArgs) {
+        throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent."
+      }
+
+      return actualArgs
+    },
+
+    wasTriggered: function (selector, eventName) {
+      return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)])
+    },
+
+    wasTriggeredWith: function (selector, eventName, expectedArgs, util, customEqualityTesters) {
+      var actualArgs = jasmine.jQuery.events.args(selector, eventName).slice(1)
+
+      if (Object.prototype.toString.call(expectedArgs) !== '[object Array]')
+        actualArgs = actualArgs[0]
+
+      return util.equals(actualArgs, expectedArgs, customEqualityTesters)
+    },
+
+    wasPrevented: function (selector, eventName) {
+      var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
+        , args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args
+        , e = args ? args[0] : undefined
+
+      return e && e.isDefaultPrevented()
+    },
+
+    wasStopped: function (selector, eventName) {
+      var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
+        , args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args
+        , e = args ? args[0] : undefined
+
+      return e && e.isPropagationStopped()
+    },
+
+    cleanUp: function () {
+      data.spiedEvents = {}
+      data.handlers    = []
+    }
+  }
+
+  var hasProperty = function (actualValue, expectedValue) {
+    if (expectedValue === undefined)
+      return actualValue !== undefined
+
+    return actualValue === expectedValue
+  }
+
+  beforeEach(function () {
+    jasmine.addMatchers({
+      toHaveClass: function () {
+        return {
+          compare: function (actual, className) {
+            return { pass: $(actual).hasClass(className) }
+          }
+        }
+      },
+
+      toHaveCss: function () {
+        return {
+          compare: function (actual, css) {
+            for (var prop in css){
+              var value = css[prop]
+              // see issue #147 on gh
+              ;if (value === 'auto' && $(actual).get(0).style[prop] === 'auto') continue
+              if ($(actual).css(prop) !== value) return { pass: false }
+            }
+            return { pass: true }
+          }
+        }
+      },
+
+      toBeVisible: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $(actual).is(':visible') }
+          }
+        }
+      },
+
+      toBeHidden: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $(actual).is(':hidden') }
+          }
+        }
+      },
+
+      toBeSelected: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $(actual).is(':selected') }
+          }
+        }
+      },
+
+      toBeChecked: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $(actual).is(':checked') }
+          }
+        }
+      },
+
+      toBeEmpty: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $(actual).is(':empty') }
+          }
+        }
+      },
+
+      toBeInDOM: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $.contains(document.documentElement, $(actual)[0]) }
+          }
+        }
+      },
+
+      toExist: function () {
+        return {
+          compare: function (actual) {
+            return { pass: $(actual).length }
+          }
+        }
+      },
+
+      toHaveLength: function () {
+        return {
+          compare: function (actual, length) {
+            return { pass: $(actual).length === length }
+          }
+        }
+      },
+
+      toHaveAttr: function () {
+        return {
+          compare: function (actual, attributeName, expectedAttributeValue) {
+            return { pass: hasProperty($(actual).attr(attributeName), expectedAttributeValue) }
+          }
+        }
+      },
+
+      toHaveProp: function () {
+        return {
+          compare: function (actual, propertyName, expectedPropertyValue) {
+            return { pass: hasProperty($(actual).prop(propertyName), expectedPropertyValue) }
+          }
+        }
+      },
+
+      toHaveId: function () {
+        return {
+          compare: function (actual, id) {
+            return { pass: $(actual).attr('id') == id }
+          }
+        }
+      },
+
+      toHaveHtml: function () {
+        return {
+          compare: function (actual, html) {
+            return { pass: $(actual).html() == jasmine.jQuery.browserTagCaseIndependentHtml(html) }
+          }
+        }
+      },
+
+      toContainHtml: function () {
+        return {
+          compare: function (actual, html) {
+            var actualHtml = $(actual).html()
+              , expectedHtml = jasmine.jQuery.browserTagCaseIndependentHtml(html)
+
+            return { pass: (actualHtml.indexOf(expectedHtml) >= 0) }
+          }
+        }
+      },
+
+      toHaveText: function () {
+        return {
+          compare: function (actual, text) {
+            var actualText = $(actual).text()
+            var trimmedText = $.trim(actualText)
+
+            if (text && $.isFunction(text.test)) {
+              return { pass: text.test(actualText) || text.test(trimmedText) }
+            } else {
+              return { pass: (actualText == text || trimmedText == text) }
+            }
+          }
+        }
+      },
+
+      toContainText: function () {
+        return {
+          compare: function (actual, text) {
+            var trimmedText = $.trim($(actual).text())
+
+            if (text && $.isFunction(text.test)) {
+              return { pass: text.test(trimmedText) }
+            } else {
+              return { pass: trimmedText.indexOf(text) != -1 }
+            }
+          }
+        }
+      },
+
+      toHaveValue: function () {
+        return {
+          compare: function (actual, value) {
+            return { pass: $(actual).val() === value }
+          }
+        }
+      },
+
+      toHaveData: function () {
+        return {
+          compare: function (actual, key, expectedValue) {
+            return { pass: hasProperty($(actual).data(key), expectedValue) }
+          }
+        }
+      },
+
+      toContainElement: function () {
+        return {
+          compare: function (actual, selector) {
+            return { pass: $(actual).find(selector).length }
+          }
+        }
+      },
+
+      toBeMatchedBy: function () {
+        return {
+          compare: function (actual, selector) {
+            return { pass: $(actual).filter(selector).length }
+          }
+        }
+      },
+
+      toBeDisabled: function () {
+        return {
+          compare: function (actual, selector) {
+            return { pass: $(actual).is(':disabled') }
+          }
+        }
+      },
+
+      toBeFocused: function (selector) {
+        return {
+          compare: function (actual, selector) {
+            return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement }
+          }
+        }
+      },
+
+      toHandle: function () {
+        return {
+          compare: function (actual, event) {
+            if ( !actual || actual.length === 0 ) return { pass: false };
+            var events = $._data($(actual).get(0), "events")
+
+            if (!events || !event || typeof event !== "string") {
+              return { pass: false }
+            }
+
+            var namespaces = event.split(".")
+              , eventType = namespaces.shift()
+              , sortedNamespaces = namespaces.slice(0).sort()
+              , namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)")
+
+            if (events[eventType] && namespaces.length) {
+              for (var i = 0; i < events[eventType].length; i++) {
+                var namespace = events[eventType][i].namespace
+
+                if (namespaceRegExp.test(namespace))
+                  return { pass: true }
+              }
+            } else {
+              return { pass: (events[eventType] && events[eventType].length > 0) }
+            }
+
+            return { pass: false }
+          }
+        }
+      },
+
+      toHandleWith: function () {
+        return {
+          compare: function (actual, eventName, eventHandler) {
+            if ( !actual || actual.length === 0 ) return { pass: false };
+            var normalizedEventName = eventName.split('.')[0]
+              , stack = $._data($(actual).get(0), "events")[normalizedEventName]
+
+            for (var i = 0; i < stack.length; i++) {
+              if (stack[i].handler == eventHandler) return { pass: true }
+            }
+
+            return { pass: false }
+          }
+        }
+      },
+
+      toHaveBeenTriggeredOn: function () {
+        return {
+          compare: function (actual, selector) {
+            var result = { pass: jasmine.jQuery.events.wasTriggered(selector, actual) }
+
+            result.message = result.pass ?
+              "Expected event " + $(actual) + " not to have been triggered on " + selector :
+              "Expected event " + $(actual) + " to have been triggered on " + selector
+
+            return result;
+          }
+        }
+      },
+
+      toHaveBeenTriggered: function (){
+        return {
+          compare: function (actual) {
+            var eventName = actual.eventName
+              , selector = actual.selector
+              , result = { pass: jasmine.jQuery.events.wasTriggered(selector, eventName) }
+
+            result.message = result.pass ?
+            "Expected event " + eventName + " not to have been triggered on " + selector :
+              "Expected event " + eventName + " to have been triggered on " + selector
+
+            return result
+          }
+        }
+      },
+
+      toHaveBeenTriggeredOnAndWith: function (j$, customEqualityTesters) {
+        return {
+          compare: function (actual, selector, expectedArgs) {
+            var wasTriggered = jasmine.jQuery.events.wasTriggered(selector, actual)
+              , result = { pass: wasTriggered && jasmine.jQuery.events.wasTriggeredWith(selector, actual, expectedArgs, j$, customEqualityTesters) }
+
+              if (wasTriggered) {
+                var actualArgs = jasmine.jQuery.events.args(selector, actual, expectedArgs)[1]
+                result.message = result.pass ?
+                  "Expected event " + actual + " not to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) :
+                  "Expected event " + actual + " to have been triggered with " + jasmine.pp(expectedArgs) + "  but it was triggered with " + jasmine.pp(actualArgs)
+
+              } else {
+                // todo check on this
+                result.message = result.pass ?
+                  "Expected event " + actual + " not to have been triggered on " + selector :
+                  "Expected event " + actual + " to have been triggered on " + selector
+              }
+
+              return result
+          }
+        }
+      },
+
+      toHaveBeenPreventedOn: function () {
+        return {
+          compare: function (actual, selector) {
+            var result = { pass: jasmine.jQuery.events.wasPrevented(selector, actual) }
+
+            result.message = result.pass ?
+              "Expected event " + actual + " not to have been prevented on " + selector :
+              "Expected event " + actual + " to have been prevented on " + selector
+
+            return result
+          }
+        }
+      },
+
+      toHaveBeenPrevented: function () {
+        return {
+          compare: function (actual) {
+            var eventName = actual.eventName
+              , selector = actual.selector
+              , result = { pass: jasmine.jQuery.events.wasPrevented(selector, eventName) }
+
+            result.message = result.pass ?
+              "Expected event " + eventName + " not to have been prevented on " + selector :
+              "Expected event " + eventName + " to have been prevented on " + selector
+
+            return result
+          }
+        }
+      },
+
+      toHaveBeenStoppedOn: function () {
+        return {
+          compare: function (actual, selector) {
+            var result = { pass: jasmine.jQuery.events.wasStopped(selector, actual) }
+
+            result.message = result.pass ?
+              "Expected event " + actual + " not to have been stopped on " + selector :
+              "Expected event " + actual + " to have been stopped on " + selector
+
+            return result;
+          }
+        }
+      },
+
+      toHaveBeenStopped: function () {
+        return {
+          compare: function (actual) {
+            var eventName = actual.eventName
+              , selector = actual.selector
+              , result = { pass: jasmine.jQuery.events.wasStopped(selector, eventName) }
+
+            result.message = result.pass ?
+              "Expected event " + eventName + " not to have been stopped on " + selector :
+              "Expected event " + eventName + " to have been stopped on " + selector
+
+            return result
+          }
+        }
+      }
+    })
+
+    jasmine.getEnv().addCustomEqualityTester(function(a, b) {
+     if (a && b) {
+       if (a instanceof $ || jasmine.isDomNode(a)) {
+         var $a = $(a)
+
+         if (b instanceof $)
+           return $a.length == b.length && a.is(b)
+
+         return $a.is(b);
+       }
+
+       if (b instanceof $ || jasmine.isDomNode(b)) {
+         var $b = $(b)
+
+         if (a instanceof $)
+           return a.length == $b.length && $b.is(a)
+
+         return $(b).is(a);
+       }
+     }
+    })
+
+    jasmine.getEnv().addCustomEqualityTester(function (a, b) {
+     if (a instanceof $ && b instanceof $ && a.size() == b.size())
+        return a.is(b)
+    })
+  })
+
+  afterEach(function () {
+    jasmine.getFixtures().cleanUp()
+    jasmine.getStyleFixtures().cleanUp()
+    jasmine.jQuery.events.cleanUp()
+  })
+
+  window.readFixtures = function () {
+    return jasmine.getFixtures().proxyCallTo_('read', arguments)
+  }
+
+  window.preloadFixtures = function () {
+    jasmine.getFixtures().proxyCallTo_('preload', arguments)
+  }
+
+  window.loadFixtures = function () {
+    jasmine.getFixtures().proxyCallTo_('load', arguments)
+  }
+
+  window.appendLoadFixtures = function () {
+    jasmine.getFixtures().proxyCallTo_('appendLoad', arguments)
+  }
+
+  window.setFixtures = function (html) {
+    return jasmine.getFixtures().proxyCallTo_('set', arguments)
+  }
+
+  window.appendSetFixtures = function () {
+    jasmine.getFixtures().proxyCallTo_('appendSet', arguments)
+  }
+
+  window.sandbox = function (attributes) {
+    return jasmine.getFixtures().sandbox(attributes)
+  }
+
+  window.spyOnEvent = function (selector, eventName) {
+    return jasmine.jQuery.events.spyOn(selector, eventName)
+  }
+
+  window.preloadStyleFixtures = function () {
+    jasmine.getStyleFixtures().proxyCallTo_('preload', arguments)
+  }
+
+  window.loadStyleFixtures = function () {
+    jasmine.getStyleFixtures().proxyCallTo_('load', arguments)
+  }
+
+  window.appendLoadStyleFixtures = function () {
+    jasmine.getStyleFixtures().proxyCallTo_('appendLoad', arguments)
+  }
+
+  window.setStyleFixtures = function (html) {
+    jasmine.getStyleFixtures().proxyCallTo_('set', arguments)
+  }
+
+  window.appendSetStyleFixtures = function (html) {
+    jasmine.getStyleFixtures().proxyCallTo_('appendSet', arguments)
+  }
+
+  window.loadJSONFixtures = function () {
+    return jasmine.getJSONFixtures().proxyCallTo_('load', arguments)
+  }
+
+  window.getJSONFixture = function (url) {
+    return jasmine.getJSONFixtures().proxyCallTo_('read', arguments)[url]
+  }
+}));
diff --git a/xos/core/xoslib/spec/smoke.test.js b/xos/core/xoslib/spec/smoke.test.js
new file mode 100644
index 0000000..2c27544
--- /dev/null
+++ b/xos/core/xoslib/spec/smoke.test.js
@@ -0,0 +1,7 @@
+'use strict';
+
+describe('The test environment', () => {
+  it('should correctly work', () => {
+    expect(true).toBe(true);
+  });
+});
diff --git a/xos/core/xoslib/spec/views/helloworld.test.js b/xos/core/xoslib/spec/views/helloworld.test.js
new file mode 100644
index 0000000..1d8ea86
--- /dev/null
+++ b/xos/core/xoslib/spec/views/helloworld.test.js
@@ -0,0 +1,12 @@
+'use strict';
+
+describe('The HelloWorld template', () => {
+
+  beforeEach(() => {
+    spyOn(xos.slices, 'startPolling');
+  });
+
+  xit('should call startPolling method', () => {
+    expect(xos.slices.startPolling).toHaveBeenCalled();
+  });
+});
diff --git a/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/make_same_width.html b/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/make_same_width.html
new file mode 100644
index 0000000..8227c99
--- /dev/null
+++ b/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/make_same_width.html
@@ -0,0 +1,5 @@
+<div class="container">
+  <div style="width: 200px"></div>
+  <div style="width: 300px"></div>
+  <div style="width: 400px"></div>
+</div>
\ No newline at end of file
diff --git a/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/table_rows.html b/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/table_rows.html
new file mode 100644
index 0000000..417108d
--- /dev/null
+++ b/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/table_rows.html
@@ -0,0 +1,19 @@
+<div class="container">
+  <table class="test-table" border="2">
+    <tr>
+      <td height="150">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi eaque voluptatum, itaque dolor ut animi ea, laboriosam nobis perspiciatis ducimus asperiores excepturi. Architecto earum, harum nesciunt libero maxime repellat dicta.</td>
+    </tr>
+    <tr>
+      <td height="150">Autem esse, accusantium adipisci, aliquid debitis inventore alias error dolores veniam nesciunt possimus animi dolorum magnam nostrum et asperiores id natus, deleniti ullam illum magni cupiditate suscipit hic. Temporibus, non?</td>
+    </tr>
+    <tr>
+      <td height="150">Tempore sapiente sed laborum commodi explicabo praesentium, molestiae repellendus sit minima magni natus doloremque eius vel voluptatem officiis, blanditiis incidunt nobis! Aut, dolorum, impedit assumenda inventore blanditiis voluptas mollitia nihil.</td>
+    </tr>
+    <tr>
+      <td height="150">Quae esse, earum tenetur, quam at iure cumque unde suscipit corporis, nemo voluptatibus. Ducimus, ratione quidem ut earum? Error, esse quae. Quis ea vero, tempore minus voluptates possimus iure deleniti.</td>
+    </tr>
+    <tr>
+      <td height="150">Asperiores sequi dignissimos doloribus commodi tenetur blanditiis eaque accusantium, hic molestias quas modi minima ratione reiciendis ut id voluptatem eveniet, culpa placeat? Dolor soluta, non cumque adipisci architecto sapiente ullam!</td>
+    </tr>
+  </table>
+</div>
\ No newline at end of file
diff --git a/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/template_from_id.html b/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/template_from_id.html
new file mode 100644
index 0000000..02dcb96
--- /dev/null
+++ b/xos/core/xoslib/spec/xoslib/fixtures/xos-utils/template_from_id.html
@@ -0,0 +1,7 @@
+<script type="text/template" id="static-test">
+  <p>Test Template</p>
+</script>
+
+<script type="text/template" id="dynamic-test">
+  <p>Test <%= stuff %></p>
+</script>
\ No newline at end of file
diff --git a/xos/core/xoslib/spec/xoslib/xos-backbone.test.js b/xos/core/xoslib/spec/xoslib/xos-backbone.test.js
new file mode 100644
index 0000000..f97cc07
--- /dev/null
+++ b/xos/core/xoslib/spec/xoslib/xos-backbone.test.js
@@ -0,0 +1,345 @@
+'use strict';
+
+describe('The Xos Backbone', () => {
+
+  beforeEach(() => {
+    $.extend(xosdefaults,{
+      test: {config: true}
+    });
+  });
+
+  describe('get_defaults mehod', () => {
+
+    it('should return default config', () => {
+      let res = get_defaults('test');
+      expect(res).toEqual({config: true});
+    });
+
+    it('should return undefined', () => {
+      let res = get_defaults('notset');
+      expect(res).toBeUndefined();
+    });
+
+  });
+
+  describe('The extend_defaults method', () => {
+
+    it('should return an extended config', () => {
+      let extended = extend_defaults('test', {extended: true});
+      expect(extended).toEqual({config: true, extended: true});
+    });
+
+    it('should return an new config', () => {
+      let extended = extend_defaults('notset', {extended: true});
+      expect(extended).toEqual({extended: true});
+    });
+
+  });
+
+  describe('The define_model method', () => {
+
+    var testLib;
+
+    beforeEach(() => {
+      var TestLibDefinition = function() {
+        /* eslint-disable no-invalid-this*/
+        this.allCollectionNames = [];
+        this.allCollections = [];
+        /* eslint-enable no-invalid-this*/
+      };
+
+      testLib = new TestLibDefinition();
+    });
+
+    it('should create a model and attach it to xos lib', () => {
+      define_model(testLib, {
+        urlRoot: 'testUrl',
+        modelName: 'testModel'
+      });
+
+      expect(testLib.allCollectionNames[0]).toEqual('testModels');
+      expect(typeof testLib['testModel']).toBe('function');
+
+    });
+
+    describe('when a model is created', () => {
+      var model;
+      beforeEach(() => {
+        define_model(testLib, {
+          urlRoot: 'testUrl',
+          modelName: 'testModel',
+          // collectionName: 'testCollection',
+          relatedCollections: {instances: 'slices'},
+          foreignCollections: ['sites'],
+          foreignFields: {slice: 'slices'},
+          m2mFields: {sites: 'sites'},
+          listFields: ['name'],
+          detailFields: ['name', 'age'],
+          addFields: ['add'],
+          inputType: {add: 'checkbox'}
+        });
+        /*eslint-disable new-cap*/
+        model = new testLib.testModel();
+        /*eslint-enable new-cap*/
+
+        // add defaults and validator for `testModel`
+        xosdefaults['testModel'] = {name: 'Scott'};
+        xosvalidators['testModel'] = {network_ports: ['portspec']};
+      });
+
+      it('should have a name', () => {
+        expect(model.modelName).toEqual('testModel');
+      });
+
+      it('should have a default collectionName', () => {
+        expect(model.collectionName).toEqual('testModels');
+      });
+
+      describe('whith a custom collectionName', () => {
+        var customCollectionName;
+        beforeEach(() => {
+          define_model(testLib, {
+            urlRoot: 'collUrl',
+            modelName: 'customCollectionName',
+            collectionName: 'myCollection'
+          });
+
+          /*eslint-disable new-cap*/
+          customCollectionName = new testLib.customCollectionName();
+          /*eslint-enable new-cap*/
+        });
+
+        it('should have the custom collectionName', () => {
+          expect(customCollectionName.collectionName).toBe('myCollection');
+        });
+
+        afterEach(() => {
+          customCollectionName = null;
+        });
+      });
+
+      it('should have a valid url', () => {
+        expect(model.url()).toEqual('testUrl/?no_hyperlinks=1');
+      });
+
+      it('should have related collections', () => {
+        expect(model.relatedCollections).toEqual({instances: 'slices'});
+      });
+
+      it('should have foreign collections', () => {
+        expect(model.foreignCollections).toEqual(['sites']);
+      });
+
+      it('should have foreign fields', () => {
+        expect(model.foreignFields).toEqual({slice: 'slices'});
+      });
+
+      it('should have m2m fields', () => {
+        expect(model.m2mFields).toEqual({sites: 'sites'});
+      });
+
+      it('should have list field', () => {
+        expect(model.listFields).toEqual(['name']);
+      });
+
+      it('should have deatil field', () => {
+        expect(model.detailFields).toEqual(['name', 'age']);
+      });
+
+      it('should have add field', () => {
+        expect(model.addFields).toEqual(['add']);
+      });
+
+      it('should have input types defined', () => {
+        expect(model.inputType).toEqual({add: 'checkbox'});
+      });
+
+      it('should have standard defaults', () => {
+        expect(model.defaults).toEqual({name: 'Scott'});
+      });
+
+      describe('when default are defined', () => {
+
+        var extendDefault;
+        beforeEach(() => {
+          define_model(testLib, {
+            urlRoot: 'collUrl',
+            modelName: 'extendDefault',
+            defaults: extend_defaults('testModel', {surname: 'Baker'})
+          });
+
+          /*eslint-disable new-cap*/
+          extendDefault = new testLib.extendDefault();
+          /*eslint-enable new-cap*/
+        });
+
+        it('should return new defaults', () => {
+          expect(extendDefault.defaults).toEqual({name: 'Scott', surname: 'Baker'});
+        });
+
+        afterEach(() => {
+          extendDefault = null;
+        });
+      });
+
+      it('should add default validators', () => {
+        expect(model.validators).toEqual({network_ports: ['portspec']});
+      });
+
+      describe('when validators are defined', () => {
+
+        var extendValidators;
+        beforeEach(() => {
+          define_model(testLib, {
+            urlRoot: 'collUrl',
+            modelName: 'testModel',
+            validators: {site: ['notBlank']}
+          });
+
+          /*eslint-disable new-cap*/
+          extendValidators = new testLib.testModel();
+          /*eslint-enable new-cap*/
+        });
+
+        it('should return extended validators', () => {
+          expect(extendValidators.validators).toEqual({network_ports: ['portspec'], site: ['notBlank']});
+        });
+
+        afterEach(() => {
+          extendValidators = null;
+        });
+      });
+
+      it('should have a xosValidate method', () => {
+        console.log(model.xosValidate);
+        expect(typeof model.xosValidate).toEqual('function');
+      });
+
+      // TBT
+      // - xosValidate
+      // - Test the default
+      // - Test override
+
+    });
+  });
+
+  describe('getCookie method with no cookie', () => {
+
+    beforeEach(() => {
+      document.cookie = 'fakeCookie=true=;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
+    });
+
+    it('should return null', () => {
+      let res = getCookie('fakeCookie');
+      expect(res).toBeNull();
+    });
+  });
+
+  describe('getCookie method with a fake cookie', () => {
+
+    beforeEach(() => {
+      document.cookie = 'fakeCookie=true';
+    });
+
+    it('should return a cookie value', () => {
+      let res = getCookie('fakeCookie');
+      expect(res).toEqual('true');
+    });
+  });
+});
+
+describe('The XOSModel', () => {
+
+  var model;
+
+  beforeEach(() => {
+    model = new XOSModel();
+  });
+
+  describe('url method', () => {
+    it('should set the correct url', () => {
+      const ctx = {attributes: {resource_uri: 'onlab.us'}};
+      let res = model.url.apply(ctx);
+      expect(res).toEqual('onlab.us/?no_hyperlinks=1');
+    });
+
+    it('should remove query params', () => {
+      const ctx = {attributes: {resource_uri: 'onlab.us?query=params'}};
+      let res = model.url.apply(ctx);
+      expect(res).toEqual('onlab.us/?no_hyperlinks=1');
+    });
+  });
+
+  describe('listMethods method', () => {
+
+    const instance = {
+      m1: () => {},
+      m2: () => {}
+    };
+
+    it('should list all methods in instance', () => {
+      let res = model.listMethods.apply(instance);
+      expect(res.length).toBe(2);
+      expect(res[0]).toEqual('m1');
+    });
+  });
+
+  describe('the Save method', () => {
+    const ctxPS = {
+      preSave: () => {}
+    };
+
+    const args = ['attr', 'opts'];
+
+    beforeEach(() => {
+      spyOn(ctxPS, 'preSave');
+      spyOn(Backbone.Model.prototype, 'save');
+    });
+
+    it('should call the preSave method', () => {
+      model.save.apply(ctxPS, args);
+      expect(ctxPS.preSave).toHaveBeenCalled();
+      expect(Backbone.Model.prototype.save).toHaveBeenCalledWith(args[0], args[1]);
+    });
+
+    it('should not call the preSave method', () => {
+      model.save.apply({}, args);
+      expect(ctxPS.preSave).not.toHaveBeenCalled();
+      expect(Backbone.Model.prototype.save).toHaveBeenCalledWith(args[0], args[1]);
+    });
+  });
+
+  describe('the getChoices method', () => {
+
+    const instance = {
+      m2mFields: {'flavors': 'flavors', 'sites': 'sites', 'images': 'images'}
+    };
+
+    xit('should be tested, what is this doing?', () => {
+      model.getChoices.apply(instance);
+    });
+  });
+
+  describe('the xosValidate method', () => {
+
+    const instance = {
+      validators: {'network_ports': ['portspec']}
+    };
+
+    const validAttrs = {network_ports: 'tcp 123'};
+
+    it('should call specified validator on a field and pass', () => {
+      let err = model.xosValidate.apply(instance, [validAttrs]);
+      expect(err).toBeUndefined();
+    });
+
+    // set wrong value and recall xosValidate
+    const invalidAttrs = {network_ports: 'abd 456'};
+
+    it('should call specified validator on a field and not pass', () => {
+      let err = model.xosValidate.apply(instance, [invalidAttrs]);
+      expect(err).not.toBeUndefined();
+      expect(err).toEqual({network_ports: 'must be a valid portspec (example: \'tcp 123, udp 456-789\')'});
+    });
+  });
+});
\ No newline at end of file
diff --git a/xos/core/xoslib/spec/xoslib/xos-utils.test.js b/xos/core/xoslib/spec/xoslib/xos-utils.test.js
new file mode 100644
index 0000000..fd0193e
--- /dev/null
+++ b/xos/core/xoslib/spec/xoslib/xos-utils.test.js
@@ -0,0 +1,253 @@
+'use strict';
+
+describe('The XOS Lib Utilities', function() {
+
+  var f;
+
+  beforeEach(() => {
+    f = jasmine.getFixtures();
+    f.fixturesPath = 'base/spec/xoslib/fixtures/xos-utils';
+  });
+
+  describe('The idInArray method', function() {
+    it('should match a string ID', () => {
+      let res = idInArray('1', [1, 2, 3]);
+      expect(res).toBeTruthy();
+    });
+
+    it('should march a number ID', () => {
+      let res = idInArray(1, [1, 2, 3]);
+      expect(res).toBeTruthy();
+    });
+
+    it('should not match this ID', () => {
+      let res = idInArray(4, [1, 2, 3]);
+      expect(res).toBeFalsy();
+    });
+  });
+
+  describe('The templateFromId method', () => {
+
+    beforeEach(() => {
+      f.load('template_from_id.html');
+    });
+
+    it('should load a static template', () => {
+      let st = templateFromId('#static-test');
+      expect($(st()).text()).toEqual('Test Template');
+    });
+
+    it('should load a dynamic template', () => {
+      let dn = templateFromId('#dynamic-test');
+      expect($(dn({stuff: 'Template'})).text()).toEqual('Test Template');
+    });
+  });
+
+  describe('The firstCharUpper', () => {
+    it('should return the first char UPPERCASE', () => {
+      let res = firstCharUpper('test');
+      expect(res).toEqual('Test');
+    });
+  });
+
+  describe('The toTitleCase', () => {
+    it('should convert all word\'s first letter to uppercase and the other to lowercase', () => {
+      let res = toTitleCase('tesT tEst');
+      expect(res).toEqual('Test Test');
+    });
+  });
+
+  describe('The fieldNameToHumanReadable method', () => {
+    it('should convert lodash to spaces and apply toTitleCase', () => {
+      let res = fieldNameToHumanReadable('tEst_fIelD');
+      expect(res).toEqual('Test Field');
+    });
+  });
+
+  describe('The limitTableRows', () => {
+
+    beforeEach(() => {
+      f.load('table_rows.html');
+    });
+
+    it('should limit the table container height', () => {
+
+      // table border = 2, td height = 150, see fixture html
+      // resulting table height: 308
+      // .conatiner height: 308 + 2 (table border top)
+
+      limitTableRows('table.test-table', 2);
+      expect($('.container')[0]).toHaveCss({height: '310px'});
+    });
+  });
+
+  describe('The validateField', () => {
+    it('should should validate notBlank', () => {
+      let res = validateField('notBlank', null);
+      expect(res).toEqual('can not be blank');
+    });
+
+    it('should validate a url', () => {
+      let res = validateField('url', 'test a fake url');
+      expect(res).toEqual('must be a valid url');
+    });
+
+    it('should validate a port', () => {
+      let res = validateField('portspec', 'i a not a port');
+      expect(res).toEqual('must be a valid portspec (example: \'tcp 123, udp 456-789\')');
+    });
+
+    it('should return true for a valid url', () => {
+      let res = validateField('url', 'www.onlab.us');
+      expect(res).toBeTruthy();
+    });
+  });
+
+  describe('The array_diff method', () => {
+    it('should return the difference between two array', () => {
+      let res = array_diff([1,2,3], [1,2,5]);
+      expect(res).toEqual(['3', '5']); //is this right?
+      console.log('convert the array to a string, can\'t we use lodash?');
+    });
+  });
+
+  describe('The array_subtract method', () => {
+    it('should substract two arrays', () => {
+      let res = array_subtract([1,2],[1,2,3]);
+      expect(res).toEqual([1,2]);
+      console.log('[1,2] - [1,2,3] = [1,2]?');
+    });
+  });
+
+  describe('The array_same_elements method', () => {
+    it('should return true if array have same elements', () => {
+      let res = array_same_elements([1,2],[2,1]);
+      expect(res).toBeTruthy();
+    });
+
+    it('should return false if array have different elements', () => {
+      let res = array_same_elements([1,2],[2,2]);
+      expect(res).toBeFalsy();
+    });
+  });
+
+  describe('The array_pair_lookup method', () => {
+    it('should return corresponding values in other array', () => {
+      let res = array_pair_lookup('Baker', ['Scott', 'Jhon'], ['Baker', 'Snow']);
+      expect(res).toEqual('Scott');
+    });
+
+    it('should return missing value', () => {
+      let res = array_pair_lookup('Larry', ['Scott', 'Jhon'], ['Baker', 'Snow']);
+      expect(res).toEqual('object #Larry');
+    });
+  });
+
+  describe('The all_options method', () => {
+
+    beforeEach(() => {
+      f.set(`
+        <select id="test-select">
+          <option value="1">1</option>
+          <option value="2">2</option>
+          <option value="3">3/option>
+        </select>
+      `);
+    });
+
+    it('should return all options from a select', () => {
+      let res = all_options('#test-select');
+      expect(res).toEqual(['1','2','3']);
+    });
+  });
+
+  describe('The make_same_width method', () => {
+
+    beforeEach(() => {
+      f.load('make_same_width.html');
+    });
+
+    it('should set elements to same width', () => {
+      make_same_width('.container', 'div');
+      $('.container div').each(function(index, item) {
+        expect($(item)).toHaveCss({width: '400px'});
+      });
+    });
+  });
+
+  describe('The strip_scripts method', () => {
+    it('should strip scripts tag', () => {
+      const mockHtml = `
+        <!DOCTYPE html>
+        <html lang="en">
+          <head>
+            <meta charset="UTF-8" />
+            <title>Test</title>
+            <script src="myScript.js"></script>
+          </head>
+          <body></body>
+        </html>
+      `;
+
+      let res = strip_scripts(mockHtml);
+      expect(res.indexOf('script')).toBe(-1);
+    });
+  });
+
+  describe('The parse_portlist method', () => {
+    it('should parse space separated ports', () => {
+      let res = parse_portlist('tcp 123, tcp 124');
+      expect(res).toEqual([{l4_protocol: 'tcp', l4_port: '123'},{l4_protocol: 'tcp', l4_port: '124'}]);
+    });
+
+    it('should parse / separated ports', () => {
+      let res = parse_portlist('tcp/123, tcp/124');
+      expect(res).toEqual([{l4_protocol: 'tcp', l4_port: '123'},{l4_protocol: 'tcp', l4_port: '124'}]);
+    });
+
+    it('should parse : joined ports', () => {
+      let res = parse_portlist('tcp 123:124');
+      expect(res).toEqual([{l4_protocol: 'tcp', l4_port: '123:124'}]);
+    });
+
+    it('should parse - joined ports', () => {
+      let res = parse_portlist('tcp 123-124');
+      expect(res).toEqual([{l4_protocol: 'tcp', l4_port: '123:124'}]);
+    });
+
+    it('should throw an error for malformed separator', () => {
+      let res = () => {
+        return parse_portlist('tcp+123, tcp+124');
+      };
+      expect(res).toThrow('malformed port specifier tcp+123, format example: "tcp 123, tcp 201:206, udp 333"');
+    });
+
+    it('should should throw if unknown protocol', () => {
+      let res = () => {
+        parse_portlist('abc 123');
+      };
+      expect(res).toThrow('unknown protocol abc');
+    });
+  });
+
+  describe('The portlist_regexp', () => {
+
+    const r = portlist_regexp();
+
+    it('should not match tcp', () => {
+      expect('tcp'.match(r)).toBeNull();
+    });
+
+    it('should match tcp 123', () => {
+      expect('tcp 123'.match(r)[0]).toEqual('tcp 123');
+    });
+
+    it('should match udp 123', () => {
+      expect('udp 123'.match(r)[0]).toEqual('udp 123');
+    });
+
+    it('should match tcp 123, upd 456', () => {
+      expect('tcp 123, udp 456'.match(r)[0]).toEqual('tcp 123, udp 456');
+    });
+  });
+});
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/gentle.js b/xos/core/xoslib/static/js/gentle.js
index f79bde2..008886a 100644
--- a/xos/core/xoslib/static/js/gentle.js
+++ b/xos/core/xoslib/static/js/gentle.js
@@ -1,49 +1,50 @@
+
 var ContactManager = new Marionette.Application();
 
 ContactManager.addRegions({
-    mainRegion: "#main-region"
+  mainRegion: '#main-region'
 });
 
 ContactManager.Contact = Backbone.Model.extend({});
 
 ContactManager.ContactCollection = Backbone.Collection.extend({
-    model: ContactManager.Contact
+  model: ContactManager.Contact
 });
 
 ContactManager.ContactItemView = Marionette.ItemView.extend({
-    tagName: "li",
-    template: "#contact-list-item"
+  tagName: 'li',
+  template: '#contact-list-item'
 });
 
 ContactManager.ContactsView = Marionette.CollectionView.extend({
-    tagName: "ul",
-    childView: ContactManager.ContactItemView
+  tagName: 'ul',
+  childView: ContactManager.ContactItemView
 });
 
-ContactManager.on("start", function(){
-    var contacts = new ContactManager.ContactCollection([
-        {
-            firstName: "Bob",
-            lastName: "Brigham",
-            phoneNumber: "555-0163"
-        },
-        {
-            firstName: "Alice",
-            lastName: "Arten",
-            phoneNumber: "555-0184"
-        },
-        {
-            firstName: "Charlie",
-            lastName: "Campbell",
-            phoneNumber: "555-0129"
-        }
-    ]);
+ContactManager.on('start', function() {
+  var contacts = new ContactManager.ContactCollection([
+    {
+      firstName: 'Bob',
+      lastName: 'Brigham',
+      phoneNumber: '555-0163'
+    },
+    {
+      firstName: 'Alice',
+      lastName: 'Arten',
+      phoneNumber: '555-0184'
+    },
+    {
+      firstName: 'Charlie',
+      lastName: 'Campbell',
+      phoneNumber: '555-0129'
+    }
+  ]);
 
-    var contactsView = new ContactManager.ContactsView({
-        collection: contacts
-    });
+  var contactsView = new ContactManager.ContactsView({
+    collection: contacts
+  });
 
-    ContactManager.mainRegion.show(contactsView);
+  ContactManager.mainRegion.show(contactsView);
 });
 
 ContactManager.start();
diff --git a/xos/core/xoslib/static/js/helloworld.js b/xos/core/xoslib/static/js/helloworld.js
index 1563094..d34a968 100644
--- a/xos/core/xoslib/static/js/helloworld.js
+++ b/xos/core/xoslib/static/js/helloworld.js
@@ -1,27 +1,38 @@
+/* eslint-disable guard-for-in */
+
 // helloworld.js
 function updateHelloWorldData() {
-    var html = "<table class='table table-bordered table-striped'>";
-    for (var slicekey in xos.slices.models) {
-        slice = xos.slices.models[slicekey]
-        html = html + "<tr><td>" + slice.get("name") + "</td><td>" + slice.get("description") + "</td></tr>";
-    }
-    html = html + "</table>";
-    $('#dynamicTableOfInterestingThings').html(html);
+  var html = '<table class="table table-bordered table-striped">';
+
+  for (var slicekey in xos.slices.models) {
+    var slice = xos.slices.models[slicekey];
+
+    html = html + '<tr><td>' + slice.get('name') + '</td><td>' + slice.get('description') + '</td></tr>';
+  }
+  html = html + '</table>';
+  $('#dynamicTableOfInterestingThings').html(html);
 }
 
-$(document).ready(function(){
-    xos.slices.on("change", function() { updateHelloWorldData(); });
-    xos.slices.on("remove", function() { updateHelloWorldData(); });
-    xos.slices.on("sort", function() { updateHelloWorldData();  });
+$(document).ready(function() {
+  xos.slices.on('change', function() {
+    updateHelloWorldData();
+  });
+  xos.slices.on('remove', function() {
+    updateHelloWorldData();
+  });
+  xos.slices.on('sort', function() {
+    updateHelloWorldData();
+  });
 
-    xos.slices.startPolling();
+  xos.slices.startPolling();
 });
 
 // helloworld.js
 $(document).ready(function() {
-    $('#submitNewDescription').bind('click', function() {
-        newDescription = $("#newDescription").val();
-        xos.slices.models[0].set("description", newDescription);
-        xos.slices.models[0].save();
-    });
+  $('#submitNewDescription').bind('click', function() {
+    var newDescription = $('#newDescription').val();
+
+    xos.slices.models[0].set('description', newDescription);
+    xos.slices.models[0].save();
+  });
 });
diff --git a/xos/core/xoslib/static/js/picker.js b/xos/core/xoslib/static/js/picker.js
index 075bdc5..35b6cd1 100644
--- a/xos/core/xoslib/static/js/picker.js
+++ b/xos/core/xoslib/static/js/picker.js
@@ -1,54 +1,55 @@
-function init_picker(selector, ordered) {
-    //console.log("init_picker");
-    //console.log($(selector));
-
-    var addBtn = $(selector).find(".btn-picker-add");
-    var removeBtn = $(selector).find(".btn-picker-remove");
-    var upBtn = $(selector).find(".btn-picker-up");
-    var downBtn = $(selector).find(".btn-picker-down");
-    var from = $(selector).find(".select-picker-from");
-    var to = $(selector).find(".select-picker-to");
-
-    if (!ordered) {
-        upBtn.hide();
-        downBtn.hide();
-    }
-
-    addBtn.click(function(){
-        console.log("add");
-        from.find(":selected").each( function() {
-            to.append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
-            $(this).remove();
-        });
+function init_picker(selector, ordered) {
+  //console.log("init_picker");
+  //console.log($(selector));
+
+  var addBtn = $(selector).find('.btn-picker-add');
+  var removeBtn = $(selector).find('.btn-picker-remove');
+  var upBtn = $(selector).find('.btn-picker-up');
+  var downBtn = $(selector).find('.btn-picker-down');
+  var from = $(selector).find('.select-picker-from');
+  var to = $(selector).find('.select-picker-to');
+
+  if (!ordered) {
+    upBtn.hide();
+    downBtn.hide();
+  }
+
+  addBtn.click(function() {
+    from.find(':selected').each(function() {
+      to.append('<option value="' + $(this).val() + '"">' + $(this).text() + '</option>');
+      $(this).remove();
     });
-    removeBtn.click(function(){
-        console.log("remove");
-        to.find(":selected").each( function() {
-            from.append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
-            $(this).remove();
-        });
+  });
+  removeBtn.click(function() {
+    to.find(':selected').each(function() {
+      from.append('<option value="' + $(this).val() + '">' + $(this).text() + '</option>');
+      $(this).remove();
     });
-    upBtn.bind('click', function() {
-        to.find(":selected").each( function() {
-            var newPos = to.find('option').index(this) - 1;
-            if (newPos > -1) {
-                to.find("option").eq(newPos).before("<option value='"+$(this).val()+"' selected='selected'>"+$(this).text()+"</option>");
-                $(this).remove();
-            }
-        });
+  });
+  upBtn.bind('click', function() {
+    to.find(':selected').each(function() {
+      var newPos = to.find('option').index(this) - 1;
+
+      if (newPos > -1) {
+        to.find('option').eq(newPos).before('<option value="' + $(this).val() + '" selected="selected">' + $(this).text() + '</option>');
+        $(this).remove();
+      }
     });
-    downBtn.bind('click', function() {
-        var countOptions = to.find("option").size();
-        to.find(":selected").each( function() {
-            var newPos = to.find("option").index(this) + 1;
-            if (newPos < countOptions) {
-                to.find("option").eq(newPos).after("<option value='"+$(this).val()+"' selected='selected'>"+$(this).text()+"</option>");
-                $(this).remove();
-            }
-        });
+  });
+  downBtn.bind('click', function() {
+    var countOptions = to.find('option').size();
+
+    to.find(':selected').each(function() {
+      var newPos = to.find('option').index(this) + 1;
+
+      if (newPos < countOptions) {
+        to.find('option').eq(newPos).after('<option value="' + $(this).val() + '" selected="selected">' + $(this).text() + '</option>');
+        $(this).remove();
+      }
     });
+  });
 };
 
 function init_spinner(selector, value) {
-     var spinner = $(selector).spinner( "value", value);
+  $(selector).spinner('value', value);
 };
diff --git a/xos/core/xoslib/static/js/sliceEditor.js b/xos/core/xoslib/static/js/sliceEditor.js
index c629944..12ed86f 100644
--- a/xos/core/xoslib/static/js/sliceEditor.js
+++ b/xos/core/xoslib/static/js/sliceEditor.js
@@ -1,23 +1,24 @@
-/* This is a demo of using xoslib with Marionette
-
-   The main window is split into two halves. The left half has a CollectionView
-   (SliceListView) that lists all slices the user has access to. The right half
-   has an ItemView (SliceDetailView) that allows the user to edit the
-   name and description of a slice, as well as a <Save> button to save it.
-*/
-
-SliceEditorApp = new Marionette.Application();
-
-SliceEditorApp.addRegions({
-  sliceList: "#sliceEditorList",
-  sliceDetail: "#sliceEditorDetail",
-});
-
-/* SliceListItemView: This is the item view that is used by SliceListView to
-   display slice names.
-*/
-
-SliceEditorApp.SliceListItemView = Marionette.ItemView.extend({
+/* eslint-disable */
+/* This is a demo of using xoslib with Marionette
+
+   The main window is split into two halves. The left half has a CollectionView
+   (SliceListView) that lists all slices the user has access to. The right half
+   has an ItemView (SliceDetailView) that allows the user to edit the
+   name and description of a slice, as well as a <Save> button to save it.
+*/
+
+SliceEditorApp = new Marionette.Application();
+
+SliceEditorApp.addRegions({
+  sliceList: "#sliceEditorList",
+  sliceDetail: "#sliceEditorDetail",
+});
+
+/* SliceListItemView: This is the item view that is used by SliceListView to
+   display slice names.
+*/
+
+SliceEditorApp.SliceListItemView = Marionette.ItemView.extend({
   template: "#sliceeditor-listitem-template",
   tagName: 'li',
   className: 'sliceeditor-listitem',
@@ -47,8 +48,8 @@
 
 /* SliceListView: This displays a list of slice names.
 */
-
-SliceEditorApp.SliceListView = Marionette.CollectionView.extend({
+
+SliceEditorApp.SliceListView = Marionette.CollectionView.extend({
   tagName: "ul",
   childView: SliceEditorApp.SliceListItemView,
 
@@ -95,16 +96,16 @@
         this.dirty = false;
     },
 });
-
-SliceEditorApp.on("start", function() {
-  var sliceListView = new SliceEditorApp.SliceListView({
+
+SliceEditorApp.on("start", function() {
+  var sliceListView = new SliceEditorApp.SliceListView({
     collection: xos.slicesPlus
   });
   SliceEditorApp.sliceList.show(sliceListView);
   xos.slicesPlus.startPolling();
-});
-
-$(document).ready(function(){
-  SliceEditorApp.start();
-});
-
+});
+
+$(document).ready(function(){
+  SliceEditorApp.start();
+});
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/sliverListTest.js b/xos/core/xoslib/static/js/sliverListTest.js
index 3a0c1fb..4b60697 100644
--- a/xos/core/xoslib/static/js/sliverListTest.js
+++ b/xos/core/xoslib/static/js/sliverListTest.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 (function(){
 
 window.InstanceView = Backbone.View.extend({
@@ -144,3 +145,4 @@
     });
 });
 })();
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/test.js b/xos/core/xoslib/static/js/test.js
index bb32760..9135134 100644
--- a/xos/core/xoslib/static/js/test.js
+++ b/xos/core/xoslib/static/js/test.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 TestApp = new XOSApplication();
 
 TestApp.addRegions({
@@ -19,22 +20,22 @@
 });
 
 //TestApp.navigateToDetail = function(detailView) {
-//     $(TestApp.detailBoxId).show();
-//     TestApp.detail.show(detailView);
-//};
-
-TestApp.navigateToModel = function(app, detailClass, detailNavLink, model) {
-
-    var detailView = new detailClass({
-        model: model,
-    });
-
-    $(app.detailBoxId).show();
-    app.detail.show(detailView);
-    detailView.showLinkedItems();
-};
-
-TestApp.on("start", function() {
+//     $(TestApp.detailBoxId).show();
+//     TestApp.detail.show(detailView);
+//};
+
+TestApp.navigateToModel = function(app, detailClass, detailNavLink, model) {
+
+    var detailView = new detailClass({
+        model: model,
+    });
+
+    $(app.detailBoxId).show();
+    app.detail.show(detailView);
+    detailView.showLinkedItems();
+};
+
+TestApp.on("start", function() {
      var objs = ['deployment', 'image', 'networkTemplate', 'network', 'port', 'networkDeployment', 'node', 'service', 'site', 'slice', 'sliceDeployment', 'slicePrivilege', 'instance', 'user', 'sliceRole', 'userDeployment'];
 
      for (var index in objs) {
@@ -46,9 +47,9 @@
          region_name = name + "List";
 
          detailClass = XOSDetailView.extend({
-            template: detail_template,
-            app: TestApp,
-         });
+            template: detail_template,
+            app: TestApp,
+         });
 
          itemViewClass = XOSItemView.extend({
              detailClass: detailClass,
@@ -81,4 +82,4 @@
 $(document).ready(function(){
     TestApp.start();
 });
-
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/vendor/jquery-1.11.3.js b/xos/core/xoslib/static/js/vendor/jquery-1.11.3.js
new file mode 100644
index 0000000..6feb110
--- /dev/null
+++ b/xos/core/xoslib/static/js/vendor/jquery-1.11.3.js
@@ -0,0 +1,10351 @@
+/*!
+ * jQuery JavaScript Library v1.11.3
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-04-28T16:19Z
+ */
+
+(function( global, factory ) {
+
+	if ( typeof module === "object" && typeof module.exports === "object" ) {
+		// For CommonJS and CommonJS-like environments where a proper window is present,
+		// execute the factory and get jQuery
+		// For environments that do not inherently posses a window with a document
+		// (such as Node.js), expose a jQuery-making factory as module.exports
+		// This accentuates the need for the creation of a real window
+		// e.g. var jQuery = require("jquery")(window);
+		// See ticket #14549 for more info
+		module.exports = global.document ?
+			factory( global, true ) :
+			function( w ) {
+				if ( !w.document ) {
+					throw new Error( "jQuery requires a window with a document" );
+				}
+				return factory( w );
+			};
+	} else {
+		factory( global );
+	}
+
+// Pass this if window is not defined yet
+}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//
+
+var deletedIds = [];
+
+var slice = deletedIds.slice;
+
+var concat = deletedIds.concat;
+
+var push = deletedIds.push;
+
+var indexOf = deletedIds.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var support = {};
+
+
+
+var
+	version = "1.11.3",
+
+	// Define a local copy of jQuery
+	jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		// Need init if jQuery is called (just allow error to be thrown if not included)
+		return new jQuery.fn.init( selector, context );
+	},
+
+	// Support: Android<4.1, IE<9
+	// Make sure we trim BOM and NBSP
+	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+	// Matches dashed string for camelizing
+	rmsPrefix = /^-ms-/,
+	rdashAlpha = /-([\da-z])/gi,
+
+	// Used by jQuery.camelCase as callback to replace()
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
+	};
+
+jQuery.fn = jQuery.prototype = {
+	// The current version of jQuery being used
+	jquery: version,
+
+	constructor: jQuery,
+
+	// Start with an empty selector
+	selector: "",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	toArray: function() {
+		return slice.call( this );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num != null ?
+
+			// Return just the one element from the set
+			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+
+			// Return all the elements in a clean array
+			slice.call( this );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems ) {
+
+		// Build a new jQuery matched element set
+		var ret = jQuery.merge( this.constructor(), elems );
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+		ret.context = this.context;
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ) );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	eq: function( i ) {
+		var len = this.length,
+			j = +i + ( i < 0 ? len : 0 );
+		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: deletedIds.sort,
+	splice: deletedIds.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var src, copyIsArray, copy, name, options, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+
+		// skip the boolean and the target
+		target = arguments[ i ] || {};
+		i++;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( i === length ) {
+		target = this;
+		i--;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	// Unique for each copy of jQuery on the page
+	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+	// Assume jQuery is ready without the ready module
+	isReady: true,
+
+	error: function( msg ) {
+		throw new Error( msg );
+	},
+
+	noop: function() {},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	isWindow: function( obj ) {
+		/* jshint eqeqeq: false */
+		return obj != null && obj == obj.window;
+	},
+
+	isNumeric: function( obj ) {
+		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
+		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+		// subtraction forces infinities to NaN
+		// adding 1 corrects loss of precision from parseFloat (#15100)
+		return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
+	},
+
+	isEmptyObject: function( obj ) {
+		var name;
+		for ( name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	isPlainObject: function( obj ) {
+		var key;
+
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+
+		try {
+			// Not own constructor property must be Object
+			if ( obj.constructor &&
+				!hasOwn.call(obj, "constructor") &&
+				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+				return false;
+			}
+		} catch ( e ) {
+			// IE8,9 Will throw exceptions on certain host objects #9897
+			return false;
+		}
+
+		// Support: IE<9
+		// Handle iteration over inherited properties before own properties.
+		if ( support.ownLast ) {
+			for ( key in obj ) {
+				return hasOwn.call( obj, key );
+			}
+		}
+
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+		for ( key in obj ) {}
+
+		return key === undefined || hasOwn.call( obj, key );
+	},
+
+	type: function( obj ) {
+		if ( obj == null ) {
+			return obj + "";
+		}
+		return typeof obj === "object" || typeof obj === "function" ?
+			class2type[ toString.call(obj) ] || "object" :
+			typeof obj;
+	},
+
+	// Evaluates a script in a global context
+	// Workarounds based on findings by Jim Driscoll
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+	globalEval: function( data ) {
+		if ( data && jQuery.trim( data ) ) {
+			// We use execScript on Internet Explorer
+			// We use an anonymous function so that context is window
+			// rather than jQuery in Firefox
+			( window.execScript || function( data ) {
+				window[ "eval" ].call( window, data );
+			} )( data );
+		}
+	},
+
+	// Convert dashed to camelCase; used by the css and data modules
+	// Microsoft forgot to hump their vendor prefix (#9572)
+	camelCase: function( string ) {
+		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+	},
+
+	// args is for internal usage only
+	each: function( obj, callback, args ) {
+		var value,
+			i = 0,
+			length = obj.length,
+			isArray = isArraylike( obj );
+
+		if ( args ) {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return obj;
+	},
+
+	// Support: Android<4.1, IE<9
+	trim: function( text ) {
+		return text == null ?
+			"" :
+			( text + "" ).replace( rtrim, "" );
+	},
+
+	// results is for internal usage only
+	makeArray: function( arr, results ) {
+		var ret = results || [];
+
+		if ( arr != null ) {
+			if ( isArraylike( Object(arr) ) ) {
+				jQuery.merge( ret,
+					typeof arr === "string" ?
+					[ arr ] : arr
+				);
+			} else {
+				push.call( ret, arr );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, arr, i ) {
+		var len;
+
+		if ( arr ) {
+			if ( indexOf ) {
+				return indexOf.call( arr, elem, i );
+			}
+
+			len = arr.length;
+			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+			for ( ; i < len; i++ ) {
+				// Skip accessing in sparse arrays
+				if ( i in arr && arr[ i ] === elem ) {
+					return i;
+				}
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var len = +second.length,
+			j = 0,
+			i = first.length;
+
+		while ( j < len ) {
+			first[ i++ ] = second[ j++ ];
+		}
+
+		// Support: IE<9
+		// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
+		if ( len !== len ) {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, invert ) {
+		var callbackInverse,
+			matches = [],
+			i = 0,
+			length = elems.length,
+			callbackExpect = !invert;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( ; i < length; i++ ) {
+			callbackInverse = !callback( elems[ i ], i );
+			if ( callbackInverse !== callbackExpect ) {
+				matches.push( elems[ i ] );
+			}
+		}
+
+		return matches;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var value,
+			i = 0,
+			length = elems.length,
+			isArray = isArraylike( elems ),
+			ret = [];
+
+		// Go through the array, translating each of the items to their new values
+		if ( isArray ) {
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret.push( value );
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( i in elems ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret.push( value );
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// Bind a function to a context, optionally partially applying any
+	// arguments.
+	proxy: function( fn, context ) {
+		var args, proxy, tmp;
+
+		if ( typeof context === "string" ) {
+			tmp = fn[ context ];
+			context = fn;
+			fn = tmp;
+		}
+
+		// Quick check to determine if target is callable, in the spec
+		// this throws a TypeError, but we will just return undefined.
+		if ( !jQuery.isFunction( fn ) ) {
+			return undefined;
+		}
+
+		// Simulated bind
+		args = slice.call( arguments, 2 );
+		proxy = function() {
+			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+		};
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+		return proxy;
+	},
+
+	now: function() {
+		return +( new Date() );
+	},
+
+	// jQuery.support is not used in Core but other projects attach their
+	// properties to it so it needs to exist.
+	support: support
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+
+	// Support: iOS 8.2 (not reproducible in simulator)
+	// `in` check used to prevent JIT error (gh-2145)
+	// hasOwn isn't used here due to false negatives
+	// regarding Nodelist length in IE
+	var length = "length" in obj && obj.length,
+		type = jQuery.type( obj );
+
+	if ( type === "function" || jQuery.isWindow( obj ) ) {
+		return false;
+	}
+
+	if ( obj.nodeType === 1 && length ) {
+		return true;
+	}
+
+	return type === "array" || length === 0 ||
+		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.2.0-pre
+ * http://sizzlejs.com/
+ *
+ * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-12-16
+ */
+(function( window ) {
+
+var i,
+	support,
+	Expr,
+	getText,
+	isXML,
+	tokenize,
+	compile,
+	select,
+	outermostContext,
+	sortInput,
+	hasDuplicate,
+
+	// Local document vars
+	setDocument,
+	document,
+	docElem,
+	documentIsHTML,
+	rbuggyQSA,
+	rbuggyMatches,
+	matches,
+	contains,
+
+	// Instance-specific data
+	expando = "sizzle" + 1 * new Date(),
+	preferredDoc = window.document,
+	dirruns = 0,
+	done = 0,
+	classCache = createCache(),
+	tokenCache = createCache(),
+	compilerCache = createCache(),
+	sortOrder = function( a, b ) {
+		if ( a === b ) {
+			hasDuplicate = true;
+		}
+		return 0;
+	},
+
+	// General-purpose constants
+	MAX_NEGATIVE = 1 << 31,
+
+	// Instance methods
+	hasOwn = ({}).hasOwnProperty,
+	arr = [],
+	pop = arr.pop,
+	push_native = arr.push,
+	push = arr.push,
+	slice = arr.slice,
+	// Use a stripped-down indexOf as it's faster than native
+	// http://jsperf.com/thor-indexof-vs-for/5
+	indexOf = function( list, elem ) {
+		var i = 0,
+			len = list.length;
+		for ( ; i < len; i++ ) {
+			if ( list[i] === elem ) {
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+	// Regular expressions
+
+	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+	whitespace = "[\\x20\\t\\r\\n\\f]",
+	// http://www.w3.org/TR/css3-syntax/#characters
+	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+	// Loosely modeled on CSS identifier characters
+	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+	identifier = characterEncoding.replace( "w", "w#" ),
+
+	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
+		// Operator (capture 2)
+		"*([*^$|!~]?=)" + whitespace +
+		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+		"*\\]",
+
+	pseudos = ":(" + characterEncoding + ")(?:\\((" +
+		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+		// 1. quoted (capture 3; capture 4 or capture 5)
+		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+		// 2. simple (capture 6)
+		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+		// 3. anything else (capture 2)
+		".*" +
+		")\\)|)",
+
+	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+	rwhitespace = new RegExp( whitespace + "+", "g" ),
+	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+	rpseudo = new RegExp( pseudos ),
+	ridentifier = new RegExp( "^" + identifier + "$" ),
+
+	matchExpr = {
+		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
+		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+		"ATTR": new RegExp( "^" + attributes ),
+		"PSEUDO": new RegExp( "^" + pseudos ),
+		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+		// For use in libraries implementing .is()
+		// We use this for POS matching in `select`
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+	},
+
+	rinputs = /^(?:input|select|textarea|button)$/i,
+	rheader = /^h\d$/i,
+
+	rnative = /^[^{]+\{\s*\[native \w/,
+
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
+	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+	rsibling = /[+~]/,
+	rescape = /'|\\/g,
+
+	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+	funescape = function( _, escaped, escapedWhitespace ) {
+		var high = "0x" + escaped - 0x10000;
+		// NaN means non-codepoint
+		// Support: Firefox<24
+		// Workaround erroneous numeric interpretation of +"0x"
+		return high !== high || escapedWhitespace ?
+			escaped :
+			high < 0 ?
+				// BMP codepoint
+				String.fromCharCode( high + 0x10000 ) :
+				// Supplemental Plane codepoint (surrogate pair)
+				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+	},
+
+	// Used for iframes
+	// See setDocument()
+	// Removing the function wrapper causes a "Permission Denied"
+	// error in IE
+	unloadHandler = function() {
+		setDocument();
+	};
+
+// Optimize for push.apply( _, NodeList )
+try {
+	push.apply(
+		(arr = slice.call( preferredDoc.childNodes )),
+		preferredDoc.childNodes
+	);
+	// Support: Android<4.0
+	// Detect silently failing push.apply
+	arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+	push = { apply: arr.length ?
+
+		// Leverage slice if possible
+		function( target, els ) {
+			push_native.apply( target, slice.call(els) );
+		} :
+
+		// Support: IE<9
+		// Otherwise append directly
+		function( target, els ) {
+			var j = target.length,
+				i = 0;
+			// Can't trust NodeList.length
+			while ( (target[j++] = els[i++]) ) {}
+			target.length = j - 1;
+		}
+	};
+}
+
+function Sizzle( selector, context, results, seed ) {
+	var match, elem, m, nodeType,
+		// QSA vars
+		i, groups, old, nid, newContext, newSelector;
+
+	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+		setDocument( context );
+	}
+
+	context = context || document;
+	results = results || [];
+	nodeType = context.nodeType;
+
+	if ( typeof selector !== "string" || !selector ||
+		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+		return results;
+	}
+
+	if ( !seed && documentIsHTML ) {
+
+		// Try to shortcut find operations when possible (e.g., not under DocumentFragment)
+		if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+			// Speed-up: Sizzle("#ID")
+			if ( (m = match[1]) ) {
+				if ( nodeType === 9 ) {
+					elem = context.getElementById( m );
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document (jQuery #6963)
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE, Opera, and Webkit return items
+						// by name instead of ID
+						if ( elem.id === m ) {
+							results.push( elem );
+							return results;
+						}
+					} else {
+						return results;
+					}
+				} else {
+					// Context is not a document
+					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+						contains( context, elem ) && elem.id === m ) {
+						results.push( elem );
+						return results;
+					}
+				}
+
+			// Speed-up: Sizzle("TAG")
+			} else if ( match[2] ) {
+				push.apply( results, context.getElementsByTagName( selector ) );
+				return results;
+
+			// Speed-up: Sizzle(".CLASS")
+			} else if ( (m = match[3]) && support.getElementsByClassName ) {
+				push.apply( results, context.getElementsByClassName( m ) );
+				return results;
+			}
+		}
+
+		// QSA path
+		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+			nid = old = expando;
+			newContext = context;
+			newSelector = nodeType !== 1 && selector;
+
+			// qSA works strangely on Element-rooted queries
+			// We can work around this by specifying an extra ID on the root
+			// and working up from there (Thanks to Andrew Dupont for the technique)
+			// IE 8 doesn't work on object elements
+			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+				groups = tokenize( selector );
+
+				if ( (old = context.getAttribute("id")) ) {
+					nid = old.replace( rescape, "\\$&" );
+				} else {
+					context.setAttribute( "id", nid );
+				}
+				nid = "[id='" + nid + "'] ";
+
+				i = groups.length;
+				while ( i-- ) {
+					groups[i] = nid + toSelector( groups[i] );
+				}
+				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
+				newSelector = groups.join(",");
+			}
+
+			if ( newSelector ) {
+				try {
+					push.apply( results,
+						newContext.querySelectorAll( newSelector )
+					);
+					return results;
+				} catch(qsaError) {
+				} finally {
+					if ( !old ) {
+						context.removeAttribute("id");
+					}
+				}
+			}
+		}
+	}
+
+	// All others
+	return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *	deleting the oldest entry
+ */
+function createCache() {
+	var keys = [];
+
+	function cache( key, value ) {
+		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+		if ( keys.push( key + " " ) > Expr.cacheLength ) {
+			// Only keep the most recent entries
+			delete cache[ keys.shift() ];
+		}
+		return (cache[ key + " " ] = value);
+	}
+	return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+	fn[ expando ] = true;
+	return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+	var div = document.createElement("div");
+
+	try {
+		return !!fn( div );
+	} catch (e) {
+		return false;
+	} finally {
+		// Remove from its parent by default
+		if ( div.parentNode ) {
+			div.parentNode.removeChild( div );
+		}
+		// release memory in IE
+		div = null;
+	}
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+	var arr = attrs.split("|"),
+		i = attrs.length;
+
+	while ( i-- ) {
+		Expr.attrHandle[ arr[i] ] = handler;
+	}
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+	var cur = b && a,
+		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+			( ~b.sourceIndex || MAX_NEGATIVE ) -
+			( ~a.sourceIndex || MAX_NEGATIVE );
+
+	// Use IE sourceIndex if available on both nodes
+	if ( diff ) {
+		return diff;
+	}
+
+	// Check if b follows a
+	if ( cur ) {
+		while ( (cur = cur.nextSibling) ) {
+			if ( cur === b ) {
+				return -1;
+			}
+		}
+	}
+
+	return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return name === "input" && elem.type === type;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return (name === "input" || name === "button") && elem.type === type;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+	return markFunction(function( argument ) {
+		argument = +argument;
+		return markFunction(function( seed, matches ) {
+			var j,
+				matchIndexes = fn( [], seed.length, argument ),
+				i = matchIndexes.length;
+
+			// Match elements found at the specified indexes
+			while ( i-- ) {
+				if ( seed[ (j = matchIndexes[i]) ] ) {
+					seed[j] = !(matches[j] = seed[j]);
+				}
+			}
+		});
+	});
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+	return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833)
+	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+	var hasCompare, parent,
+		doc = node ? node.ownerDocument || node : preferredDoc;
+
+	// If no document and documentElement is available, return
+	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+		return document;
+	}
+
+	// Set our document
+	document = doc;
+	docElem = doc.documentElement;
+	parent = doc.defaultView;
+
+	// Support: IE>8
+	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
+	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
+	// IE6-8 do not support the defaultView property so parent will be undefined
+	if ( parent && parent !== parent.top ) {
+		// IE11 does not have attachEvent, so all must suffer
+		if ( parent.addEventListener ) {
+			parent.addEventListener( "unload", unloadHandler, false );
+		} else if ( parent.attachEvent ) {
+			parent.attachEvent( "onunload", unloadHandler );
+		}
+	}
+
+	/* Support tests
+	---------------------------------------------------------------------- */
+	documentIsHTML = !isXML( doc );
+
+	/* Attributes
+	---------------------------------------------------------------------- */
+
+	// Support: IE<8
+	// Verify that getAttribute really returns attributes and not properties
+	// (excepting IE8 booleans)
+	support.attributes = assert(function( div ) {
+		div.className = "i";
+		return !div.getAttribute("className");
+	});
+
+	/* getElement(s)By*
+	---------------------------------------------------------------------- */
+
+	// Check if getElementsByTagName("*") returns only elements
+	support.getElementsByTagName = assert(function( div ) {
+		div.appendChild( doc.createComment("") );
+		return !div.getElementsByTagName("*").length;
+	});
+
+	// Support: IE<9
+	support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
+
+	// Support: IE<10
+	// Check if getElementById returns elements by name
+	// The broken getElementById methods don't pick up programatically-set names,
+	// so use a roundabout getElementsByName test
+	support.getById = assert(function( div ) {
+		docElem.appendChild( div ).id = expando;
+		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+	});
+
+	// ID find and filter
+	if ( support.getById ) {
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+				var m = context.getElementById( id );
+				// Check parentNode to catch when Blackberry 4.6 returns
+				// nodes that are no longer in the document #6963
+				return m && m.parentNode ? [ m ] : [];
+			}
+		};
+		Expr.filter["ID"] = function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				return elem.getAttribute("id") === attrId;
+			};
+		};
+	} else {
+		// Support: IE6/7
+		// getElementById is not reliable as a find shortcut
+		delete Expr.find["ID"];
+
+		Expr.filter["ID"] =  function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+				return node && node.value === attrId;
+			};
+		};
+	}
+
+	// Tag
+	Expr.find["TAG"] = support.getElementsByTagName ?
+		function( tag, context ) {
+			if ( typeof context.getElementsByTagName !== "undefined" ) {
+				return context.getElementsByTagName( tag );
+
+			// DocumentFragment nodes don't have gEBTN
+			} else if ( support.qsa ) {
+				return context.querySelectorAll( tag );
+			}
+		} :
+
+		function( tag, context ) {
+			var elem,
+				tmp = [],
+				i = 0,
+				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+				results = context.getElementsByTagName( tag );
+
+			// Filter out possible comments
+			if ( tag === "*" ) {
+				while ( (elem = results[i++]) ) {
+					if ( elem.nodeType === 1 ) {
+						tmp.push( elem );
+					}
+				}
+
+				return tmp;
+			}
+			return results;
+		};
+
+	// Class
+	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+		if ( documentIsHTML ) {
+			return context.getElementsByClassName( className );
+		}
+	};
+
+	/* QSA/matchesSelector
+	---------------------------------------------------------------------- */
+
+	// QSA and matchesSelector support
+
+	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+	rbuggyMatches = [];
+
+	// qSa(:focus) reports false when true (Chrome 21)
+	// We allow this because of a bug in IE8/9 that throws an error
+	// whenever `document.activeElement` is accessed on an iframe
+	// So, we allow :focus to pass through QSA all the time to avoid the IE error
+	// See http://bugs.jquery.com/ticket/13378
+	rbuggyQSA = [];
+
+	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+		// Build QSA regex
+		// Regex strategy adopted from Diego Perini
+		assert(function( div ) {
+			// Select is set to empty string on purpose
+			// This is to test IE's treatment of not explicitly
+			// setting a boolean content attribute,
+			// since its presence should be enough
+			// http://bugs.jquery.com/ticket/12359
+			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
+				"<select id='" + expando + "-\f]' msallowcapture=''>" +
+				"<option selected=''></option></select>";
+
+			// Support: IE8, Opera 11-12.16
+			// Nothing should be selected when empty strings follow ^= or $= or *=
+			// The test attribute must be unknown in Opera but "safe" for WinRT
+			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+			}
+
+			// Support: IE8
+			// Boolean attributes and "value" are not treated correctly
+			if ( !div.querySelectorAll("[selected]").length ) {
+				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+			}
+
+			// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
+			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+				rbuggyQSA.push("~=");
+			}
+
+			// Webkit/Opera - :checked should return selected option elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":checked").length ) {
+				rbuggyQSA.push(":checked");
+			}
+
+			// Support: Safari 8+, iOS 8+
+			// https://bugs.webkit.org/show_bug.cgi?id=136851
+			// In-page `selector#id sibing-combinator selector` fails
+			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
+				rbuggyQSA.push(".#.+[+~]");
+			}
+		});
+
+		assert(function( div ) {
+			// Support: Windows 8 Native Apps
+			// The type and name attributes are restricted during .innerHTML assignment
+			var input = doc.createElement("input");
+			input.setAttribute( "type", "hidden" );
+			div.appendChild( input ).setAttribute( "name", "D" );
+
+			// Support: IE8
+			// Enforce case-sensitivity of name attribute
+			if ( div.querySelectorAll("[name=d]").length ) {
+				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+			}
+
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":enabled").length ) {
+				rbuggyQSA.push( ":enabled", ":disabled" );
+			}
+
+			// Opera 10-11 does not throw on post-comma invalid pseudos
+			div.querySelectorAll("*,:x");
+			rbuggyQSA.push(",.*:");
+		});
+	}
+
+	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+		docElem.webkitMatchesSelector ||
+		docElem.mozMatchesSelector ||
+		docElem.oMatchesSelector ||
+		docElem.msMatchesSelector) )) ) {
+
+		assert(function( div ) {
+			// Check to see if it's possible to do matchesSelector
+			// on a disconnected node (IE 9)
+			support.disconnectedMatch = matches.call( div, "div" );
+
+			// This should fail with an exception
+			// Gecko does not error, returns false instead
+			matches.call( div, "[s!='']:x" );
+			rbuggyMatches.push( "!=", pseudos );
+		});
+	}
+
+	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+	/* Contains
+	---------------------------------------------------------------------- */
+	hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+	// Element contains another
+	// Purposefully does not implement inclusive descendent
+	// As in, an element does not contain itself
+	contains = hasCompare || rnative.test( docElem.contains ) ?
+		function( a, b ) {
+			var adown = a.nodeType === 9 ? a.documentElement : a,
+				bup = b && b.parentNode;
+			return a === bup || !!( bup && bup.nodeType === 1 && (
+				adown.contains ?
+					adown.contains( bup ) :
+					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+			));
+		} :
+		function( a, b ) {
+			if ( b ) {
+				while ( (b = b.parentNode) ) {
+					if ( b === a ) {
+						return true;
+					}
+				}
+			}
+			return false;
+		};
+
+	/* Sorting
+	---------------------------------------------------------------------- */
+
+	// Document order sorting
+	sortOrder = hasCompare ?
+	function( a, b ) {
+
+		// Flag for duplicate removal
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		// Sort on method existence if only one input has compareDocumentPosition
+		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+		if ( compare ) {
+			return compare;
+		}
+
+		// Calculate position if both inputs belong to the same document
+		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+			a.compareDocumentPosition( b ) :
+
+			// Otherwise we know they are disconnected
+			1;
+
+		// Disconnected nodes
+		if ( compare & 1 ||
+			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+			// Choose the first element that is related to our preferred document
+			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+				return -1;
+			}
+			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+				return 1;
+			}
+
+			// Maintain original order
+			return sortInput ?
+				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+				0;
+		}
+
+		return compare & 4 ? -1 : 1;
+	} :
+	function( a, b ) {
+		// Exit early if the nodes are identical
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		var cur,
+			i = 0,
+			aup = a.parentNode,
+			bup = b.parentNode,
+			ap = [ a ],
+			bp = [ b ];
+
+		// Parentless nodes are either documents or disconnected
+		if ( !aup || !bup ) {
+			return a === doc ? -1 :
+				b === doc ? 1 :
+				aup ? -1 :
+				bup ? 1 :
+				sortInput ?
+				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+				0;
+
+		// If the nodes are siblings, we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+		}
+
+		// Otherwise we need full lists of their ancestors for comparison
+		cur = a;
+		while ( (cur = cur.parentNode) ) {
+			ap.unshift( cur );
+		}
+		cur = b;
+		while ( (cur = cur.parentNode) ) {
+			bp.unshift( cur );
+		}
+
+		// Walk down the tree looking for a discrepancy
+		while ( ap[i] === bp[i] ) {
+			i++;
+		}
+
+		return i ?
+			// Do a sibling check if the nodes have a common ancestor
+			siblingCheck( ap[i], bp[i] ) :
+
+			// Otherwise nodes in our document sort first
+			ap[i] === preferredDoc ? -1 :
+			bp[i] === preferredDoc ? 1 :
+			0;
+	};
+
+	return doc;
+};
+
+Sizzle.matches = function( expr, elements ) {
+	return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	// Make sure that attribute selectors are quoted
+	expr = expr.replace( rattributeQuotes, "='$1']" );
+
+	if ( support.matchesSelector && documentIsHTML &&
+		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+		try {
+			var ret = matches.call( elem, expr );
+
+			// IE 9's matchesSelector returns false on disconnected nodes
+			if ( ret || support.disconnectedMatch ||
+					// As well, disconnected nodes are said to be in a document
+					// fragment in IE 9
+					elem.document && elem.document.nodeType !== 11 ) {
+				return ret;
+			}
+		} catch (e) {}
+	}
+
+	return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+	// Set document vars if needed
+	if ( ( context.ownerDocument || context ) !== document ) {
+		setDocument( context );
+	}
+	return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	var fn = Expr.attrHandle[ name.toLowerCase() ],
+		// Don't get fooled by Object.prototype properties (jQuery #13807)
+		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+			fn( elem, name, !documentIsHTML ) :
+			undefined;
+
+	return val !== undefined ?
+		val :
+		support.attributes || !documentIsHTML ?
+			elem.getAttribute( name ) :
+			(val = elem.getAttributeNode(name)) && val.specified ?
+				val.value :
+				null;
+};
+
+Sizzle.error = function( msg ) {
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+	var elem,
+		duplicates = [],
+		j = 0,
+		i = 0;
+
+	// Unless we *know* we can detect duplicates, assume their presence
+	hasDuplicate = !support.detectDuplicates;
+	sortInput = !support.sortStable && results.slice( 0 );
+	results.sort( sortOrder );
+
+	if ( hasDuplicate ) {
+		while ( (elem = results[i++]) ) {
+			if ( elem === results[ i ] ) {
+				j = duplicates.push( i );
+			}
+		}
+		while ( j-- ) {
+			results.splice( duplicates[ j ], 1 );
+		}
+	}
+
+	// Clear input after sorting to release objects
+	// See https://github.com/jquery/sizzle/pull/225
+	sortInput = null;
+
+	return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+	var node,
+		ret = "",
+		i = 0,
+		nodeType = elem.nodeType;
+
+	if ( !nodeType ) {
+		// If no nodeType, this is expected to be an array
+		while ( (node = elem[i++]) ) {
+			// Do not traverse comment nodes
+			ret += getText( node );
+		}
+	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+		// Use textContent for elements
+		// innerText usage removed for consistency of new lines (jQuery #11153)
+		if ( typeof elem.textContent === "string" ) {
+			return elem.textContent;
+		} else {
+			// Traverse its children
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				ret += getText( elem );
+			}
+		}
+	} else if ( nodeType === 3 || nodeType === 4 ) {
+		return elem.nodeValue;
+	}
+	// Do not include comment or processing instruction nodes
+
+	return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+	// Can be adjusted by the user
+	cacheLength: 50,
+
+	createPseudo: markFunction,
+
+	match: matchExpr,
+
+	attrHandle: {},
+
+	find: {},
+
+	relative: {
+		">": { dir: "parentNode", first: true },
+		" ": { dir: "parentNode" },
+		"+": { dir: "previousSibling", first: true },
+		"~": { dir: "previousSibling" }
+	},
+
+	preFilter: {
+		"ATTR": function( match ) {
+			match[1] = match[1].replace( runescape, funescape );
+
+			// Move the given value to match[3] whether quoted or unquoted
+			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+			if ( match[2] === "~=" ) {
+				match[3] = " " + match[3] + " ";
+			}
+
+			return match.slice( 0, 4 );
+		},
+
+		"CHILD": function( match ) {
+			/* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 what (child|of-type)
+				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				4 xn-component of xn+y argument ([+-]?\d*n|)
+				5 sign of xn-component
+				6 x of xn-component
+				7 sign of y-component
+				8 y of y-component
+			*/
+			match[1] = match[1].toLowerCase();
+
+			if ( match[1].slice( 0, 3 ) === "nth" ) {
+				// nth-* requires argument
+				if ( !match[3] ) {
+					Sizzle.error( match[0] );
+				}
+
+				// numeric x and y parameters for Expr.filter.CHILD
+				// remember that false/true cast respectively to 0/1
+				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+			// other types prohibit arguments
+			} else if ( match[3] ) {
+				Sizzle.error( match[0] );
+			}
+
+			return match;
+		},
+
+		"PSEUDO": function( match ) {
+			var excess,
+				unquoted = !match[6] && match[2];
+
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
+				return null;
+			}
+
+			// Accept quoted arguments as-is
+			if ( match[3] ) {
+				match[2] = match[4] || match[5] || "";
+
+			// Strip excess characters from unquoted arguments
+			} else if ( unquoted && rpseudo.test( unquoted ) &&
+				// Get excess from tokenize (recursively)
+				(excess = tokenize( unquoted, true )) &&
+				// advance to the next closing parenthesis
+				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+				// excess is a negative index
+				match[0] = match[0].slice( 0, excess );
+				match[2] = unquoted.slice( 0, excess );
+			}
+
+			// Return only captures needed by the pseudo filter method (type and argument)
+			return match.slice( 0, 3 );
+		}
+	},
+
+	filter: {
+
+		"TAG": function( nodeNameSelector ) {
+			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+			return nodeNameSelector === "*" ?
+				function() { return true; } :
+				function( elem ) {
+					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+				};
+		},
+
+		"CLASS": function( className ) {
+			var pattern = classCache[ className + " " ];
+
+			return pattern ||
+				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+				classCache( className, function( elem ) {
+					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+				});
+		},
+
+		"ATTR": function( name, operator, check ) {
+			return function( elem ) {
+				var result = Sizzle.attr( elem, name );
+
+				if ( result == null ) {
+					return operator === "!=";
+				}
+				if ( !operator ) {
+					return true;
+				}
+
+				result += "";
+
+				return operator === "=" ? result === check :
+					operator === "!=" ? result !== check :
+					operator === "^=" ? check && result.indexOf( check ) === 0 :
+					operator === "*=" ? check && result.indexOf( check ) > -1 :
+					operator === "$=" ? check && result.slice( -check.length ) === check :
+					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+					false;
+			};
+		},
+
+		"CHILD": function( type, what, argument, first, last ) {
+			var simple = type.slice( 0, 3 ) !== "nth",
+				forward = type.slice( -4 ) !== "last",
+				ofType = what === "of-type";
+
+			return first === 1 && last === 0 ?
+
+				// Shortcut for :nth-*(n)
+				function( elem ) {
+					return !!elem.parentNode;
+				} :
+
+				function( elem, context, xml ) {
+					var cache, outerCache, node, diff, nodeIndex, start,
+						dir = simple !== forward ? "nextSibling" : "previousSibling",
+						parent = elem.parentNode,
+						name = ofType && elem.nodeName.toLowerCase(),
+						useCache = !xml && !ofType;
+
+					if ( parent ) {
+
+						// :(first|last|only)-(child|of-type)
+						if ( simple ) {
+							while ( dir ) {
+								node = elem;
+								while ( (node = node[ dir ]) ) {
+									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+										return false;
+									}
+								}
+								// Reverse direction for :only-* (if we haven't yet done so)
+								start = dir = type === "only" && !start && "nextSibling";
+							}
+							return true;
+						}
+
+						start = [ forward ? parent.firstChild : parent.lastChild ];
+
+						// non-xml :nth-child(...) stores cache data on `parent`
+						if ( forward && useCache ) {
+							// Seek `elem` from a previously-cached index
+							outerCache = parent[ expando ] || (parent[ expando ] = {});
+							cache = outerCache[ type ] || [];
+							nodeIndex = cache[0] === dirruns && cache[1];
+							diff = cache[0] === dirruns && cache[2];
+							node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+								// Fallback to seeking `elem` from the start
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								// When found, cache indexes on `parent` and break
+								if ( node.nodeType === 1 && ++diff && node === elem ) {
+									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+									break;
+								}
+							}
+
+						// Use previously-cached element index if available
+						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+							diff = cache[1];
+
+						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+						} else {
+							// Use the same loop as above to seek `elem` from the start
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+									// Cache the index of each encountered element
+									if ( useCache ) {
+										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+									}
+
+									if ( node === elem ) {
+										break;
+									}
+								}
+							}
+						}
+
+						// Incorporate the offset, then check against cycle size
+						diff -= last;
+						return diff === first || ( diff % first === 0 && diff / first >= 0 );
+					}
+				};
+		},
+
+		"PSEUDO": function( pseudo, argument ) {
+			// pseudo-class names are case-insensitive
+			// http://www.w3.org/TR/selectors/#pseudo-classes
+			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+			// Remember that setFilters inherits from pseudos
+			var args,
+				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+					Sizzle.error( "unsupported pseudo: " + pseudo );
+
+			// The user may use createPseudo to indicate that
+			// arguments are needed to create the filter function
+			// just as Sizzle does
+			if ( fn[ expando ] ) {
+				return fn( argument );
+			}
+
+			// But maintain support for old signatures
+			if ( fn.length > 1 ) {
+				args = [ pseudo, pseudo, "", argument ];
+				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+					markFunction(function( seed, matches ) {
+						var idx,
+							matched = fn( seed, argument ),
+							i = matched.length;
+						while ( i-- ) {
+							idx = indexOf( seed, matched[i] );
+							seed[ idx ] = !( matches[ idx ] = matched[i] );
+						}
+					}) :
+					function( elem ) {
+						return fn( elem, 0, args );
+					};
+			}
+
+			return fn;
+		}
+	},
+
+	pseudos: {
+		// Potentially complex pseudos
+		"not": markFunction(function( selector ) {
+			// Trim the selector passed to compile
+			// to avoid treating leading and trailing
+			// spaces as combinators
+			var input = [],
+				results = [],
+				matcher = compile( selector.replace( rtrim, "$1" ) );
+
+			return matcher[ expando ] ?
+				markFunction(function( seed, matches, context, xml ) {
+					var elem,
+						unmatched = matcher( seed, null, xml, [] ),
+						i = seed.length;
+
+					// Match elements unmatched by `matcher`
+					while ( i-- ) {
+						if ( (elem = unmatched[i]) ) {
+							seed[i] = !(matches[i] = elem);
+						}
+					}
+				}) :
+				function( elem, context, xml ) {
+					input[0] = elem;
+					matcher( input, null, xml, results );
+					// Don't keep the element (issue #299)
+					input[0] = null;
+					return !results.pop();
+				};
+		}),
+
+		"has": markFunction(function( selector ) {
+			return function( elem ) {
+				return Sizzle( selector, elem ).length > 0;
+			};
+		}),
+
+		"contains": markFunction(function( text ) {
+			text = text.replace( runescape, funescape );
+			return function( elem ) {
+				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+			};
+		}),
+
+		// "Whether an element is represented by a :lang() selector
+		// is based solely on the element's language value
+		// being equal to the identifier C,
+		// or beginning with the identifier C immediately followed by "-".
+		// The matching of C against the element's language value is performed case-insensitively.
+		// The identifier C does not have to be a valid language name."
+		// http://www.w3.org/TR/selectors/#lang-pseudo
+		"lang": markFunction( function( lang ) {
+			// lang value must be a valid identifier
+			if ( !ridentifier.test(lang || "") ) {
+				Sizzle.error( "unsupported lang: " + lang );
+			}
+			lang = lang.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				var elemLang;
+				do {
+					if ( (elemLang = documentIsHTML ?
+						elem.lang :
+						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+						elemLang = elemLang.toLowerCase();
+						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+					}
+				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+				return false;
+			};
+		}),
+
+		// Miscellaneous
+		"target": function( elem ) {
+			var hash = window.location && window.location.hash;
+			return hash && hash.slice( 1 ) === elem.id;
+		},
+
+		"root": function( elem ) {
+			return elem === docElem;
+		},
+
+		"focus": function( elem ) {
+			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+		},
+
+		// Boolean properties
+		"enabled": function( elem ) {
+			return elem.disabled === false;
+		},
+
+		"disabled": function( elem ) {
+			return elem.disabled === true;
+		},
+
+		"checked": function( elem ) {
+			// In CSS3, :checked should return both checked and selected elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			var nodeName = elem.nodeName.toLowerCase();
+			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+		},
+
+		"selected": function( elem ) {
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			if ( elem.parentNode ) {
+				elem.parentNode.selectedIndex;
+			}
+
+			return elem.selected === true;
+		},
+
+		// Contents
+		"empty": function( elem ) {
+			// http://www.w3.org/TR/selectors/#empty-pseudo
+			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+			//   but not by others (comment: 8; processing instruction: 7; etc.)
+			// nodeType < 6 works because attributes (2) do not appear as children
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				if ( elem.nodeType < 6 ) {
+					return false;
+				}
+			}
+			return true;
+		},
+
+		"parent": function( elem ) {
+			return !Expr.pseudos["empty"]( elem );
+		},
+
+		// Element/input types
+		"header": function( elem ) {
+			return rheader.test( elem.nodeName );
+		},
+
+		"input": function( elem ) {
+			return rinputs.test( elem.nodeName );
+		},
+
+		"button": function( elem ) {
+			var name = elem.nodeName.toLowerCase();
+			return name === "input" && elem.type === "button" || name === "button";
+		},
+
+		"text": function( elem ) {
+			var attr;
+			return elem.nodeName.toLowerCase() === "input" &&
+				elem.type === "text" &&
+
+				// Support: IE<8
+				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+		},
+
+		// Position-in-collection
+		"first": createPositionalPseudo(function() {
+			return [ 0 ];
+		}),
+
+		"last": createPositionalPseudo(function( matchIndexes, length ) {
+			return [ length - 1 ];
+		}),
+
+		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			return [ argument < 0 ? argument + length : argument ];
+		}),
+
+		"even": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 0;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 1;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; --i >= 0; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; ++i < length; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		})
+	}
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+	Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+	Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+	var matched, match, tokens, type,
+		soFar, groups, preFilters,
+		cached = tokenCache[ selector + " " ];
+
+	if ( cached ) {
+		return parseOnly ? 0 : cached.slice( 0 );
+	}
+
+	soFar = selector;
+	groups = [];
+	preFilters = Expr.preFilter;
+
+	while ( soFar ) {
+
+		// Comma and first run
+		if ( !matched || (match = rcomma.exec( soFar )) ) {
+			if ( match ) {
+				// Don't consume trailing commas as valid
+				soFar = soFar.slice( match[0].length ) || soFar;
+			}
+			groups.push( (tokens = []) );
+		}
+
+		matched = false;
+
+		// Combinators
+		if ( (match = rcombinators.exec( soFar )) ) {
+			matched = match.shift();
+			tokens.push({
+				value: matched,
+				// Cast descendant combinators to space
+				type: match[0].replace( rtrim, " " )
+			});
+			soFar = soFar.slice( matched.length );
+		}
+
+		// Filters
+		for ( type in Expr.filter ) {
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+				(match = preFilters[ type ]( match ))) ) {
+				matched = match.shift();
+				tokens.push({
+					value: matched,
+					type: type,
+					matches: match
+				});
+				soFar = soFar.slice( matched.length );
+			}
+		}
+
+		if ( !matched ) {
+			break;
+		}
+	}
+
+	// Return the length of the invalid excess
+	// if we're just parsing
+	// Otherwise, throw an error or return tokens
+	return parseOnly ?
+		soFar.length :
+		soFar ?
+			Sizzle.error( selector ) :
+			// Cache the tokens
+			tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+	var i = 0,
+		len = tokens.length,
+		selector = "";
+	for ( ; i < len; i++ ) {
+		selector += tokens[i].value;
+	}
+	return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+	var dir = combinator.dir,
+		checkNonElements = base && dir === "parentNode",
+		doneName = done++;
+
+	return combinator.first ?
+		// Check against closest ancestor/preceding element
+		function( elem, context, xml ) {
+			while ( (elem = elem[ dir ]) ) {
+				if ( elem.nodeType === 1 || checkNonElements ) {
+					return matcher( elem, context, xml );
+				}
+			}
+		} :
+
+		// Check against all ancestor/preceding elements
+		function( elem, context, xml ) {
+			var oldCache, outerCache,
+				newCache = [ dirruns, doneName ];
+
+			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+			if ( xml ) {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						if ( matcher( elem, context, xml ) ) {
+							return true;
+						}
+					}
+				}
+			} else {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						outerCache = elem[ expando ] || (elem[ expando ] = {});
+						if ( (oldCache = outerCache[ dir ]) &&
+							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+							// Assign to newCache so results back-propagate to previous elements
+							return (newCache[ 2 ] = oldCache[ 2 ]);
+						} else {
+							// Reuse newcache so results back-propagate to previous elements
+							outerCache[ dir ] = newCache;
+
+							// A match means we're done; a fail means we have to keep checking
+							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+								return true;
+							}
+						}
+					}
+				}
+			}
+		};
+}
+
+function elementMatcher( matchers ) {
+	return matchers.length > 1 ?
+		function( elem, context, xml ) {
+			var i = matchers.length;
+			while ( i-- ) {
+				if ( !matchers[i]( elem, context, xml ) ) {
+					return false;
+				}
+			}
+			return true;
+		} :
+		matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+	var i = 0,
+		len = contexts.length;
+	for ( ; i < len; i++ ) {
+		Sizzle( selector, contexts[i], results );
+	}
+	return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+	var elem,
+		newUnmatched = [],
+		i = 0,
+		len = unmatched.length,
+		mapped = map != null;
+
+	for ( ; i < len; i++ ) {
+		if ( (elem = unmatched[i]) ) {
+			if ( !filter || filter( elem, context, xml ) ) {
+				newUnmatched.push( elem );
+				if ( mapped ) {
+					map.push( i );
+				}
+			}
+		}
+	}
+
+	return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+	if ( postFilter && !postFilter[ expando ] ) {
+		postFilter = setMatcher( postFilter );
+	}
+	if ( postFinder && !postFinder[ expando ] ) {
+		postFinder = setMatcher( postFinder, postSelector );
+	}
+	return markFunction(function( seed, results, context, xml ) {
+		var temp, i, elem,
+			preMap = [],
+			postMap = [],
+			preexisting = results.length,
+
+			// Get initial elements from seed or context
+			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+			// Prefilter to get matcher input, preserving a map for seed-results synchronization
+			matcherIn = preFilter && ( seed || !selector ) ?
+				condense( elems, preMap, preFilter, context, xml ) :
+				elems,
+
+			matcherOut = matcher ?
+				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+					// ...intermediate processing is necessary
+					[] :
+
+					// ...otherwise use results directly
+					results :
+				matcherIn;
+
+		// Find primary matches
+		if ( matcher ) {
+			matcher( matcherIn, matcherOut, context, xml );
+		}
+
+		// Apply postFilter
+		if ( postFilter ) {
+			temp = condense( matcherOut, postMap );
+			postFilter( temp, [], context, xml );
+
+			// Un-match failing elements by moving them back to matcherIn
+			i = temp.length;
+			while ( i-- ) {
+				if ( (elem = temp[i]) ) {
+					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+				}
+			}
+		}
+
+		if ( seed ) {
+			if ( postFinder || preFilter ) {
+				if ( postFinder ) {
+					// Get the final matcherOut by condensing this intermediate into postFinder contexts
+					temp = [];
+					i = matcherOut.length;
+					while ( i-- ) {
+						if ( (elem = matcherOut[i]) ) {
+							// Restore matcherIn since elem is not yet a final match
+							temp.push( (matcherIn[i] = elem) );
+						}
+					}
+					postFinder( null, (matcherOut = []), temp, xml );
+				}
+
+				// Move matched elements from seed to results to keep them synchronized
+				i = matcherOut.length;
+				while ( i-- ) {
+					if ( (elem = matcherOut[i]) &&
+						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+						seed[temp] = !(results[temp] = elem);
+					}
+				}
+			}
+
+		// Add elements to results, through postFinder if defined
+		} else {
+			matcherOut = condense(
+				matcherOut === results ?
+					matcherOut.splice( preexisting, matcherOut.length ) :
+					matcherOut
+			);
+			if ( postFinder ) {
+				postFinder( null, results, matcherOut, xml );
+			} else {
+				push.apply( results, matcherOut );
+			}
+		}
+	});
+}
+
+function matcherFromTokens( tokens ) {
+	var checkContext, matcher, j,
+		len = tokens.length,
+		leadingRelative = Expr.relative[ tokens[0].type ],
+		implicitRelative = leadingRelative || Expr.relative[" "],
+		i = leadingRelative ? 1 : 0,
+
+		// The foundational matcher ensures that elements are reachable from top-level context(s)
+		matchContext = addCombinator( function( elem ) {
+			return elem === checkContext;
+		}, implicitRelative, true ),
+		matchAnyContext = addCombinator( function( elem ) {
+			return indexOf( checkContext, elem ) > -1;
+		}, implicitRelative, true ),
+		matchers = [ function( elem, context, xml ) {
+			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+				(checkContext = context).nodeType ?
+					matchContext( elem, context, xml ) :
+					matchAnyContext( elem, context, xml ) );
+			// Avoid hanging onto element (issue #299)
+			checkContext = null;
+			return ret;
+		} ];
+
+	for ( ; i < len; i++ ) {
+		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+		} else {
+			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+			// Return special upon seeing a positional matcher
+			if ( matcher[ expando ] ) {
+				// Find the next relative operator (if any) for proper handling
+				j = ++i;
+				for ( ; j < len; j++ ) {
+					if ( Expr.relative[ tokens[j].type ] ) {
+						break;
+					}
+				}
+				return setMatcher(
+					i > 1 && elementMatcher( matchers ),
+					i > 1 && toSelector(
+						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
+						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+					).replace( rtrim, "$1" ),
+					matcher,
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+					j < len && toSelector( tokens )
+				);
+			}
+			matchers.push( matcher );
+		}
+	}
+
+	return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+	var bySet = setMatchers.length > 0,
+		byElement = elementMatchers.length > 0,
+		superMatcher = function( seed, context, xml, results, outermost ) {
+			var elem, j, matcher,
+				matchedCount = 0,
+				i = "0",
+				unmatched = seed && [],
+				setMatched = [],
+				contextBackup = outermostContext,
+				// We must always have either seed elements or outermost context
+				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+				// Use integer dirruns iff this is the outermost matcher
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+				len = elems.length;
+
+			if ( outermost ) {
+				outermostContext = context !== document && context;
+			}
+
+			// Add elements passing elementMatchers directly to results
+			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+			// Support: IE<9, Safari
+			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
+			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+				if ( byElement && elem ) {
+					j = 0;
+					while ( (matcher = elementMatchers[j++]) ) {
+						if ( matcher( elem, context, xml ) ) {
+							results.push( elem );
+							break;
+						}
+					}
+					if ( outermost ) {
+						dirruns = dirrunsUnique;
+					}
+				}
+
+				// Track unmatched elements for set filters
+				if ( bySet ) {
+					// They will have gone through all possible matchers
+					if ( (elem = !matcher && elem) ) {
+						matchedCount--;
+					}
+
+					// Lengthen the array for every element, matched or not
+					if ( seed ) {
+						unmatched.push( elem );
+					}
+				}
+			}
+
+			// Apply set filters to unmatched elements
+			matchedCount += i;
+			if ( bySet && i !== matchedCount ) {
+				j = 0;
+				while ( (matcher = setMatchers[j++]) ) {
+					matcher( unmatched, setMatched, context, xml );
+				}
+
+				if ( seed ) {
+					// Reintegrate element matches to eliminate the need for sorting
+					if ( matchedCount > 0 ) {
+						while ( i-- ) {
+							if ( !(unmatched[i] || setMatched[i]) ) {
+								setMatched[i] = pop.call( results );
+							}
+						}
+					}
+
+					// Discard index placeholder values to get only actual matches
+					setMatched = condense( setMatched );
+				}
+
+				// Add matches to results
+				push.apply( results, setMatched );
+
+				// Seedless set matches succeeding multiple successful matchers stipulate sorting
+				if ( outermost && !seed && setMatched.length > 0 &&
+					( matchedCount + setMatchers.length ) > 1 ) {
+
+					Sizzle.uniqueSort( results );
+				}
+			}
+
+			// Override manipulation of globals by nested matchers
+			if ( outermost ) {
+				dirruns = dirrunsUnique;
+				outermostContext = contextBackup;
+			}
+
+			return unmatched;
+		};
+
+	return bySet ?
+		markFunction( superMatcher ) :
+		superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+	var i,
+		setMatchers = [],
+		elementMatchers = [],
+		cached = compilerCache[ selector + " " ];
+
+	if ( !cached ) {
+		// Generate a function of recursive functions that can be used to check each element
+		if ( !match ) {
+			match = tokenize( selector );
+		}
+		i = match.length;
+		while ( i-- ) {
+			cached = matcherFromTokens( match[i] );
+			if ( cached[ expando ] ) {
+				setMatchers.push( cached );
+			} else {
+				elementMatchers.push( cached );
+			}
+		}
+
+		// Cache the compiled function
+		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+		// Save selector and tokenization
+		cached.selector = selector;
+	}
+	return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ *  selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ *  selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+	var i, tokens, token, type, find,
+		compiled = typeof selector === "function" && selector,
+		match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+	results = results || [];
+
+	// Try to minimize operations if there is no seed and only one group
+	if ( match.length === 1 ) {
+
+		// Take a shortcut and set the context if the root selector is an ID
+		tokens = match[0] = match[0].slice( 0 );
+		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+				support.getById && context.nodeType === 9 && documentIsHTML &&
+				Expr.relative[ tokens[1].type ] ) {
+
+			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+			if ( !context ) {
+				return results;
+
+			// Precompiled matchers will still verify ancestry, so step up a level
+			} else if ( compiled ) {
+				context = context.parentNode;
+			}
+
+			selector = selector.slice( tokens.shift().value.length );
+		}
+
+		// Fetch a seed set for right-to-left matching
+		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+		while ( i-- ) {
+			token = tokens[i];
+
+			// Abort if we hit a combinator
+			if ( Expr.relative[ (type = token.type) ] ) {
+				break;
+			}
+			if ( (find = Expr.find[ type ]) ) {
+				// Search, expanding context for leading sibling combinators
+				if ( (seed = find(
+					token.matches[0].replace( runescape, funescape ),
+					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+				)) ) {
+
+					// If seed is empty or no tokens remain, we can return early
+					tokens.splice( i, 1 );
+					selector = seed.length && toSelector( tokens );
+					if ( !selector ) {
+						push.apply( results, seed );
+						return results;
+					}
+
+					break;
+				}
+			}
+		}
+	}
+
+	// Compile and execute a filtering function if one is not provided
+	// Provide `match` to avoid retokenization if we modified the selector above
+	( compiled || compile( selector, match ) )(
+		seed,
+		context,
+		!documentIsHTML,
+		results,
+		rsibling.test( selector ) && testContext( context.parentNode ) || context
+	);
+	return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+	// Should return 1, but returns 4 (following)
+	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+	div.innerHTML = "<a href='#'></a>";
+	return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+	addHandle( "type|href|height|width", function( elem, name, isXML ) {
+		if ( !isXML ) {
+			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+		}
+	});
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+	div.innerHTML = "<input/>";
+	div.firstChild.setAttribute( "value", "" );
+	return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+	addHandle( "value", function( elem, name, isXML ) {
+		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+			return elem.defaultValue;
+		}
+	});
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+	return div.getAttribute("disabled") == null;
+}) ) {
+	addHandle( booleans, function( elem, name, isXML ) {
+		var val;
+		if ( !isXML ) {
+			return elem[ name ] === true ? name.toLowerCase() :
+					(val = elem.getAttributeNode( name )) && val.specified ?
+					val.value :
+				null;
+		}
+	});
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep( elements, function( elem, i ) {
+			/* jshint -W018 */
+			return !!qualifier.call( elem, i, elem ) !== not;
+		});
+
+	}
+
+	if ( qualifier.nodeType ) {
+		return jQuery.grep( elements, function( elem ) {
+			return ( elem === qualifier ) !== not;
+		});
+
+	}
+
+	if ( typeof qualifier === "string" ) {
+		if ( risSimple.test( qualifier ) ) {
+			return jQuery.filter( qualifier, elements, not );
+		}
+
+		qualifier = jQuery.filter( qualifier, elements );
+	}
+
+	return jQuery.grep( elements, function( elem ) {
+		return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
+	});
+}
+
+jQuery.filter = function( expr, elems, not ) {
+	var elem = elems[ 0 ];
+
+	if ( not ) {
+		expr = ":not(" + expr + ")";
+	}
+
+	return elems.length === 1 && elem.nodeType === 1 ?
+		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+			return elem.nodeType === 1;
+		}));
+};
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var i,
+			ret = [],
+			self = this,
+			len = self.length;
+
+		if ( typeof selector !== "string" ) {
+			return this.pushStack( jQuery( selector ).filter(function() {
+				for ( i = 0; i < len; i++ ) {
+					if ( jQuery.contains( self[ i ], this ) ) {
+						return true;
+					}
+				}
+			}) );
+		}
+
+		for ( i = 0; i < len; i++ ) {
+			jQuery.find( selector, self[ i ], ret );
+		}
+
+		// Needed because $( selector, context ) becomes $( context ).find( selector )
+		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+		ret.selector = this.selector ? this.selector + " " + selector : selector;
+		return ret;
+	},
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector || [], false) );
+	},
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector || [], true) );
+	},
+	is: function( selector ) {
+		return !!winnow(
+			this,
+
+			// If this is a positional/relative selector, check membership in the returned set
+			// so $("p:first").is("p:last") won't return true for a doc with two "p".
+			typeof selector === "string" && rneedsContext.test( selector ) ?
+				jQuery( selector ) :
+				selector || [],
+			false
+		).length;
+	}
+});
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	document = window.document,
+
+	// A simple way to check for HTML strings
+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+	// Strict HTML recognition (#11290: must start with <)
+	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+	init = jQuery.fn.init = function( selector, context ) {
+		var match, elem;
+
+		// HANDLE: $(""), $(null), $(undefined), $(false)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = rquickExpr.exec( selector );
+			}
+
+			// Match html or make sure no context is specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					context = context instanceof jQuery ? context[0] : context;
+
+					// scripts is true for back-compat
+					// Intentionally let the error be thrown if parseHTML is not present
+					jQuery.merge( this, jQuery.parseHTML(
+						match[1],
+						context && context.nodeType ? context.ownerDocument || context : document,
+						true
+					) );
+
+					// HANDLE: $(html, props)
+					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+						for ( match in context ) {
+							// Properties of context are called as methods if possible
+							if ( jQuery.isFunction( this[ match ] ) ) {
+								this[ match ]( context[ match ] );
+
+							// ...and otherwise set as attributes
+							} else {
+								this.attr( match, context[ match ] );
+							}
+						}
+					}
+
+					return this;
+
+				// HANDLE: $(#id)
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return ( context || rootjQuery ).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(DOMElement)
+		} else if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return typeof rootjQuery.ready !== "undefined" ?
+				rootjQuery.ready( selector ) :
+				// Execute immediately if ready is not present
+				selector( jQuery );
+		}
+
+		if ( selector.selector !== undefined ) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	};
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+	// methods guaranteed to produce a unique set when starting from a unique set
+	guaranteedUnique = {
+		children: true,
+		contents: true,
+		next: true,
+		prev: true
+	};
+
+jQuery.extend({
+	dir: function( elem, dir, until ) {
+		var matched = [],
+			cur = elem[ dir ];
+
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+
+jQuery.fn.extend({
+	has: function( target ) {
+		var i,
+			targets = jQuery( target, this ),
+			len = targets.length;
+
+		return this.filter(function() {
+			for ( i = 0; i < len; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	closest: function( selectors, context ) {
+		var cur,
+			i = 0,
+			l = this.length,
+			matched = [],
+			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+				jQuery( selectors, context || this.context ) :
+				0;
+
+		for ( ; i < l; i++ ) {
+			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+				// Always skip document fragments
+				if ( cur.nodeType < 11 && (pos ?
+					pos.index(cur) > -1 :
+
+					// Don't pass non-elements to Sizzle
+					cur.nodeType === 1 &&
+						jQuery.find.matchesSelector(cur, selectors)) ) {
+
+					matched.push( cur );
+					break;
+				}
+			}
+		}
+
+		return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
+	},
+
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+
+		// No argument, return index in parent
+		if ( !elem ) {
+			return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
+		}
+
+		// index in selector
+		if ( typeof elem === "string" ) {
+			return jQuery.inArray( this[0], jQuery( elem ) );
+		}
+
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		return this.pushStack(
+			jQuery.unique(
+				jQuery.merge( this.get(), jQuery( selector, context ) )
+			)
+		);
+	},
+
+	addBack: function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter(selector)
+		);
+	}
+});
+
+function sibling( cur, dir ) {
+	do {
+		cur = cur[ dir ];
+	} while ( cur && cur.nodeType !== 1 );
+
+	return cur;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return sibling( elem, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return sibling( elem, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.merge( [], elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+
+		if ( name.slice( -5 ) !== "Until" ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		if ( this.length > 1 ) {
+			// Remove duplicates
+			if ( !guaranteedUnique[ name ] ) {
+				ret = jQuery.unique( ret );
+			}
+
+			// Reverse order for parents* and prev-derivatives
+			if ( rparentsprev.test( name ) ) {
+				ret = ret.reverse();
+			}
+		}
+
+		return this.pushStack( ret );
+	};
+});
+var rnotwhite = (/\S+/g);
+
+
+
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+	var object = optionsCache[ options ] = {};
+	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+		object[ flag ] = true;
+	});
+	return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *	options: an optional list of space-separated options that will change how
+ *			the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *	memory:			will keep track of previous values and will call any callback added
+ *					after the list has been fired right away with the latest "memorized"
+ *					values (like a Deferred)
+ *
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *	stopOnFalse:	interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+	// Convert options from String-formatted to Object-formatted if needed
+	// (we check in cache first)
+	options = typeof options === "string" ?
+		( optionsCache[ options ] || createOptions( options ) ) :
+		jQuery.extend( {}, options );
+
+	var // Flag to know if list is currently firing
+		firing,
+		// Last fire value (for non-forgettable lists)
+		memory,
+		// Flag to know if list was already fired
+		fired,
+		// End of the loop when firing
+		firingLength,
+		// Index of currently firing callback (modified by remove if needed)
+		firingIndex,
+		// First callback to fire (used internally by add and fireWith)
+		firingStart,
+		// Actual callback list
+		list = [],
+		// Stack of fire calls for repeatable lists
+		stack = !options.once && [],
+		// Fire callbacks
+		fire = function( data ) {
+			memory = options.memory && data;
+			fired = true;
+			firingIndex = firingStart || 0;
+			firingStart = 0;
+			firingLength = list.length;
+			firing = true;
+			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+					memory = false; // To prevent further calls using add
+					break;
+				}
+			}
+			firing = false;
+			if ( list ) {
+				if ( stack ) {
+					if ( stack.length ) {
+						fire( stack.shift() );
+					}
+				} else if ( memory ) {
+					list = [];
+				} else {
+					self.disable();
+				}
+			}
+		},
+		// Actual Callbacks object
+		self = {
+			// Add a callback or a collection of callbacks to the list
+			add: function() {
+				if ( list ) {
+					// First, we save the current length
+					var start = list.length;
+					(function add( args ) {
+						jQuery.each( args, function( _, arg ) {
+							var type = jQuery.type( arg );
+							if ( type === "function" ) {
+								if ( !options.unique || !self.has( arg ) ) {
+									list.push( arg );
+								}
+							} else if ( arg && arg.length && type !== "string" ) {
+								// Inspect recursively
+								add( arg );
+							}
+						});
+					})( arguments );
+					// Do we need to add the callbacks to the
+					// current firing batch?
+					if ( firing ) {
+						firingLength = list.length;
+					// With memory, if we're not firing then
+					// we should call right away
+					} else if ( memory ) {
+						firingStart = start;
+						fire( memory );
+					}
+				}
+				return this;
+			},
+			// Remove a callback from the list
+			remove: function() {
+				if ( list ) {
+					jQuery.each( arguments, function( _, arg ) {
+						var index;
+						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+							list.splice( index, 1 );
+							// Handle firing indexes
+							if ( firing ) {
+								if ( index <= firingLength ) {
+									firingLength--;
+								}
+								if ( index <= firingIndex ) {
+									firingIndex--;
+								}
+							}
+						}
+					});
+				}
+				return this;
+			},
+			// Check if a given callback is in the list.
+			// If no argument is given, return whether or not list has callbacks attached.
+			has: function( fn ) {
+				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+			},
+			// Remove all callbacks from the list
+			empty: function() {
+				list = [];
+				firingLength = 0;
+				return this;
+			},
+			// Have the list do nothing anymore
+			disable: function() {
+				list = stack = memory = undefined;
+				return this;
+			},
+			// Is it disabled?
+			disabled: function() {
+				return !list;
+			},
+			// Lock the list in its current state
+			lock: function() {
+				stack = undefined;
+				if ( !memory ) {
+					self.disable();
+				}
+				return this;
+			},
+			// Is it locked?
+			locked: function() {
+				return !stack;
+			},
+			// Call all callbacks with the given context and arguments
+			fireWith: function( context, args ) {
+				if ( list && ( !fired || stack ) ) {
+					args = args || [];
+					args = [ context, args.slice ? args.slice() : args ];
+					if ( firing ) {
+						stack.push( args );
+					} else {
+						fire( args );
+					}
+				}
+				return this;
+			},
+			// Call all the callbacks with the given arguments
+			fire: function() {
+				self.fireWith( this, arguments );
+				return this;
+			},
+			// To know if the callbacks have already been called at least once
+			fired: function() {
+				return !!fired;
+			}
+		};
+
+	return self;
+};
+
+
+jQuery.extend({
+
+	Deferred: function( func ) {
+		var tuples = [
+				// action, add listener, listener list, final state
+				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+				[ "notify", "progress", jQuery.Callbacks("memory") ]
+			],
+			state = "pending",
+			promise = {
+				state: function() {
+					return state;
+				},
+				always: function() {
+					deferred.done( arguments ).fail( arguments );
+					return this;
+				},
+				then: function( /* fnDone, fnFail, fnProgress */ ) {
+					var fns = arguments;
+					return jQuery.Deferred(function( newDefer ) {
+						jQuery.each( tuples, function( i, tuple ) {
+							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+							// deferred[ done | fail | progress ] for forwarding actions to newDefer
+							deferred[ tuple[1] ](function() {
+								var returned = fn && fn.apply( this, arguments );
+								if ( returned && jQuery.isFunction( returned.promise ) ) {
+									returned.promise()
+										.done( newDefer.resolve )
+										.fail( newDefer.reject )
+										.progress( newDefer.notify );
+								} else {
+									newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+								}
+							});
+						});
+						fns = null;
+					}).promise();
+				},
+				// Get a promise for this deferred
+				// If obj is provided, the promise aspect is added to the object
+				promise: function( obj ) {
+					return obj != null ? jQuery.extend( obj, promise ) : promise;
+				}
+			},
+			deferred = {};
+
+		// Keep pipe for back-compat
+		promise.pipe = promise.then;
+
+		// Add list-specific methods
+		jQuery.each( tuples, function( i, tuple ) {
+			var list = tuple[ 2 ],
+				stateString = tuple[ 3 ];
+
+			// promise[ done | fail | progress ] = list.add
+			promise[ tuple[1] ] = list.add;
+
+			// Handle state
+			if ( stateString ) {
+				list.add(function() {
+					// state = [ resolved | rejected ]
+					state = stateString;
+
+				// [ reject_list | resolve_list ].disable; progress_list.lock
+				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+			}
+
+			// deferred[ resolve | reject | notify ]
+			deferred[ tuple[0] ] = function() {
+				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+				return this;
+			};
+			deferred[ tuple[0] + "With" ] = list.fireWith;
+		});
+
+		// Make the deferred a promise
+		promise.promise( deferred );
+
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+
+		// All done!
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( subordinate /* , ..., subordinateN */ ) {
+		var i = 0,
+			resolveValues = slice.call( arguments ),
+			length = resolveValues.length,
+
+			// the count of uncompleted subordinates
+			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+			// Update function for both resolve and progress values
+			updateFunc = function( i, contexts, values ) {
+				return function( value ) {
+					contexts[ i ] = this;
+					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+					if ( values === progressValues ) {
+						deferred.notifyWith( contexts, values );
+
+					} else if ( !(--remaining) ) {
+						deferred.resolveWith( contexts, values );
+					}
+				};
+			},
+
+			progressValues, progressContexts, resolveContexts;
+
+		// add listeners to Deferred subordinates; treat others as resolved
+		if ( length > 1 ) {
+			progressValues = new Array( length );
+			progressContexts = new Array( length );
+			resolveContexts = new Array( length );
+			for ( ; i < length; i++ ) {
+				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+					resolveValues[ i ].promise()
+						.done( updateFunc( i, resolveContexts, resolveValues ) )
+						.fail( deferred.reject )
+						.progress( updateFunc( i, progressContexts, progressValues ) );
+				} else {
+					--remaining;
+				}
+			}
+		}
+
+		// if we're not waiting on anything, resolve the master
+		if ( !remaining ) {
+			deferred.resolveWith( resolveContexts, resolveValues );
+		}
+
+		return deferred.promise();
+	}
+});
+
+
+// The deferred used on DOM ready
+var readyList;
+
+jQuery.fn.ready = function( fn ) {
+	// Add the callback
+	jQuery.ready.promise().done( fn );
+
+	return this;
+};
+
+jQuery.extend({
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Hold (or release) the ready event
+	holdReady: function( hold ) {
+		if ( hold ) {
+			jQuery.readyWait++;
+		} else {
+			jQuery.ready( true );
+		}
+	},
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+
+		// Abort if there are pending holds or we're already ready
+		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+			return;
+		}
+
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( !document.body ) {
+			return setTimeout( jQuery.ready );
+		}
+
+		// Remember that the DOM is ready
+		jQuery.isReady = true;
+
+		// If a normal DOM Ready event fired, decrement, and wait if need be
+		if ( wait !== true && --jQuery.readyWait > 0 ) {
+			return;
+		}
+
+		// If there are functions bound, to execute
+		readyList.resolveWith( document, [ jQuery ] );
+
+		// Trigger any bound ready events
+		if ( jQuery.fn.triggerHandler ) {
+			jQuery( document ).triggerHandler( "ready" );
+			jQuery( document ).off( "ready" );
+		}
+	}
+});
+
+/**
+ * Clean-up method for dom ready events
+ */
+function detach() {
+	if ( document.addEventListener ) {
+		document.removeEventListener( "DOMContentLoaded", completed, false );
+		window.removeEventListener( "load", completed, false );
+
+	} else {
+		document.detachEvent( "onreadystatechange", completed );
+		window.detachEvent( "onload", completed );
+	}
+}
+
+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+	// readyState === "complete" is good enough for us to call the dom ready in oldIE
+	if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+		detach();
+		jQuery.ready();
+	}
+}
+
+jQuery.ready.promise = function( obj ) {
+	if ( !readyList ) {
+
+		readyList = jQuery.Deferred();
+
+		// Catch cases where $(document).ready() is called after the browser event has already occurred.
+		// we once tried to use readyState "interactive" here, but it caused issues like the one
+		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			setTimeout( jQuery.ready );
+
+		// Standards-based browsers support DOMContentLoaded
+		} else if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", completed, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", completed, false );
+
+		// If IE event model is used
+		} else {
+			// Ensure firing before onload, maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", completed );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", completed );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var top = false;
+
+			try {
+				top = window.frameElement == null && document.documentElement;
+			} catch(e) {}
+
+			if ( top && top.doScroll ) {
+				(function doScrollCheck() {
+					if ( !jQuery.isReady ) {
+
+						try {
+							// Use the trick by Diego Perini
+							// http://javascript.nwbox.com/IEContentLoaded/
+							top.doScroll("left");
+						} catch(e) {
+							return setTimeout( doScrollCheck, 50 );
+						}
+
+						// detach all dom ready events
+						detach();
+
+						// and execute any waiting functions
+						jQuery.ready();
+					}
+				})();
+			}
+		}
+	}
+	return readyList.promise( obj );
+};
+
+
+var strundefined = typeof undefined;
+
+
+
+// Support: IE<9
+// Iteration over object's inherited properties before its own
+var i;
+for ( i in jQuery( support ) ) {
+	break;
+}
+support.ownLast = i !== "0";
+
+// Note: most support tests are defined in their respective modules.
+// false until the test is run
+support.inlineBlockNeedsLayout = false;
+
+// Execute ASAP in case we need to set body.style.zoom
+jQuery(function() {
+	// Minified: var a,b,c,d
+	var val, div, body, container;
+
+	body = document.getElementsByTagName( "body" )[ 0 ];
+	if ( !body || !body.style ) {
+		// Return for frameset docs that don't have a body
+		return;
+	}
+
+	// Setup
+	div = document.createElement( "div" );
+	container = document.createElement( "div" );
+	container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+	body.appendChild( container ).appendChild( div );
+
+	if ( typeof div.style.zoom !== strundefined ) {
+		// Support: IE<8
+		// Check if natively block-level elements act like inline-block
+		// elements when setting their display to 'inline' and giving
+		// them layout
+		div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
+
+		support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
+		if ( val ) {
+			// Prevent IE 6 from affecting layout for positioned elements #11048
+			// Prevent IE from shrinking the body in IE 7 mode #12869
+			// Support: IE<8
+			body.style.zoom = 1;
+		}
+	}
+
+	body.removeChild( container );
+});
+
+
+
+
+(function() {
+	var div = document.createElement( "div" );
+
+	// Execute the test only if not already executed in another module.
+	if (support.deleteExpando == null) {
+		// Support: IE<9
+		support.deleteExpando = true;
+		try {
+			delete div.test;
+		} catch( e ) {
+			support.deleteExpando = false;
+		}
+	}
+
+	// Null elements to avoid leaks in IE.
+	div = null;
+})();
+
+
+/**
+ * Determines whether an object can have data
+ */
+jQuery.acceptData = function( elem ) {
+	var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
+		nodeType = +elem.nodeType || 1;
+
+	// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
+	return nodeType !== 1 && nodeType !== 9 ?
+		false :
+
+		// Nodes accept data unless otherwise specified; rejection can be conditional
+		!noData || noData !== true && elem.getAttribute("classid") === noData;
+};
+
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+	rmultiDash = /([A-Z])/g;
+
+function dataAttr( elem, key, data ) {
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+
+		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+		data = elem.getAttribute( name );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = data === "true" ? true :
+					data === "false" ? false :
+					data === "null" ? null :
+					// Only convert to a number if it doesn't change the string
+					+data + "" === data ? +data :
+					rbrace.test( data ) ? jQuery.parseJSON( data ) :
+					data;
+			} catch( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			jQuery.data( elem, key, data );
+
+		} else {
+			data = undefined;
+		}
+	}
+
+	return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+	var name;
+	for ( name in obj ) {
+
+		// if the public data object is empty, the private is still empty
+		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+			continue;
+		}
+		if ( name !== "toJSON" ) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var ret, thisCache,
+		internalKey = jQuery.expando,
+
+		// We have to handle DOM nodes and JS objects differently because IE6-7
+		// can't GC object references properly across the DOM-JS boundary
+		isNode = elem.nodeType,
+
+		// Only DOM nodes need the global jQuery cache; JS object data is
+		// attached directly to the object so GC can occur automatically
+		cache = isNode ? jQuery.cache : elem,
+
+		// Only defining an ID for JS objects if its cache already exists allows
+		// the code to shortcut on the same path as a DOM node with no cache
+		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+	// Avoid doing any more work than we need to when trying to get data on an
+	// object that has no data at all
+	if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
+		return;
+	}
+
+	if ( !id ) {
+		// Only DOM nodes need a new unique ID for each element since their data
+		// ends up in the global cache
+		if ( isNode ) {
+			id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
+		} else {
+			id = internalKey;
+		}
+	}
+
+	if ( !cache[ id ] ) {
+		// Avoid exposing jQuery metadata on plain JS objects when the object
+		// is serialized using JSON.stringify
+		cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
+	}
+
+	// An object can be passed to jQuery.data instead of a key/value pair; this gets
+	// shallow copied over onto the existing cache
+	if ( typeof name === "object" || typeof name === "function" ) {
+		if ( pvt ) {
+			cache[ id ] = jQuery.extend( cache[ id ], name );
+		} else {
+			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+		}
+	}
+
+	thisCache = cache[ id ];
+
+	// jQuery data() is stored in a separate object inside the object's internal data
+	// cache in order to avoid key collisions between internal data and user-defined
+	// data.
+	if ( !pvt ) {
+		if ( !thisCache.data ) {
+			thisCache.data = {};
+		}
+
+		thisCache = thisCache.data;
+	}
+
+	if ( data !== undefined ) {
+		thisCache[ jQuery.camelCase( name ) ] = data;
+	}
+
+	// Check for both converted-to-camel and non-converted data property names
+	// If a data property was specified
+	if ( typeof name === "string" ) {
+
+		// First Try to find as-is property data
+		ret = thisCache[ name ];
+
+		// Test for null|undefined property data
+		if ( ret == null ) {
+
+			// Try to find the camelCased property
+			ret = thisCache[ jQuery.camelCase( name ) ];
+		}
+	} else {
+		ret = thisCache;
+	}
+
+	return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var thisCache, i,
+		isNode = elem.nodeType,
+
+		// See jQuery.data for more information
+		cache = isNode ? jQuery.cache : elem,
+		id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+	// If there is already no cache entry for this object, there is no
+	// purpose in continuing
+	if ( !cache[ id ] ) {
+		return;
+	}
+
+	if ( name ) {
+
+		thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+		if ( thisCache ) {
+
+			// Support array or space separated string names for data keys
+			if ( !jQuery.isArray( name ) ) {
+
+				// try the string as a key before any manipulation
+				if ( name in thisCache ) {
+					name = [ name ];
+				} else {
+
+					// split the camel cased version by spaces unless a key with the spaces exists
+					name = jQuery.camelCase( name );
+					if ( name in thisCache ) {
+						name = [ name ];
+					} else {
+						name = name.split(" ");
+					}
+				}
+			} else {
+				// If "name" is an array of keys...
+				// When data is initially created, via ("key", "val") signature,
+				// keys will be converted to camelCase.
+				// Since there is no way to tell _how_ a key was added, remove
+				// both plain key and camelCase key. #12786
+				// This will only penalize the array argument path.
+				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+			}
+
+			i = name.length;
+			while ( i-- ) {
+				delete thisCache[ name[i] ];
+			}
+
+			// If there is no data left in the cache, we want to continue
+			// and let the cache object itself get destroyed
+			if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
+				return;
+			}
+		}
+	}
+
+	// See jQuery.data for more information
+	if ( !pvt ) {
+		delete cache[ id ].data;
+
+		// Don't destroy the parent cache unless the internal data object
+		// had been the only thing left in it
+		if ( !isEmptyDataObject( cache[ id ] ) ) {
+			return;
+		}
+	}
+
+	// Destroy the cache
+	if ( isNode ) {
+		jQuery.cleanData( [ elem ], true );
+
+	// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+	/* jshint eqeqeq: false */
+	} else if ( support.deleteExpando || cache != cache.window ) {
+		/* jshint eqeqeq: true */
+		delete cache[ id ];
+
+	// When all else fails, null
+	} else {
+		cache[ id ] = null;
+	}
+}
+
+jQuery.extend({
+	cache: {},
+
+	// The following elements (space-suffixed to avoid Object.prototype collisions)
+	// throw uncatchable exceptions if you attempt to set expando properties
+	noData: {
+		"applet ": true,
+		"embed ": true,
+		// ...but Flash objects (which have this classid) *can* handle expandos
+		"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+	},
+
+	hasData: function( elem ) {
+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+		return !!elem && !isEmptyDataObject( elem );
+	},
+
+	data: function( elem, name, data ) {
+		return internalData( elem, name, data );
+	},
+
+	removeData: function( elem, name ) {
+		return internalRemoveData( elem, name );
+	},
+
+	// For internal use only.
+	_data: function( elem, name, data ) {
+		return internalData( elem, name, data, true );
+	},
+
+	_removeData: function( elem, name ) {
+		return internalRemoveData( elem, name, true );
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		var i, name, data,
+			elem = this[0],
+			attrs = elem && elem.attributes;
+
+		// Special expections of .data basically thwart jQuery.access,
+		// so implement the relevant behavior ourselves
+
+		// Gets all values
+		if ( key === undefined ) {
+			if ( this.length ) {
+				data = jQuery.data( elem );
+
+				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+					i = attrs.length;
+					while ( i-- ) {
+
+						// Support: IE11+
+						// The attrs elements can be null (#14894)
+						if ( attrs[ i ] ) {
+							name = attrs[ i ].name;
+							if ( name.indexOf( "data-" ) === 0 ) {
+								name = jQuery.camelCase( name.slice(5) );
+								dataAttr( elem, name, data[ name ] );
+							}
+						}
+					}
+					jQuery._data( elem, "parsedAttrs", true );
+				}
+			}
+
+			return data;
+		}
+
+		// Sets multiple values
+		if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		return arguments.length > 1 ?
+
+			// Sets one value
+			this.each(function() {
+				jQuery.data( this, key, value );
+			}) :
+
+			// Gets one value
+			// Try to fetch any internally stored data first
+			elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		var queue;
+
+		if ( elem ) {
+			type = ( type || "fx" ) + "queue";
+			queue = jQuery._data( elem, type );
+
+			// Speed up dequeue by getting out quickly if this is just a lookup
+			if ( data ) {
+				if ( !queue || jQuery.isArray(data) ) {
+					queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+				} else {
+					queue.push( data );
+				}
+			}
+			return queue || [];
+		}
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			startLength = queue.length,
+			fn = queue.shift(),
+			hooks = jQuery._queueHooks( elem, type ),
+			next = function() {
+				jQuery.dequeue( elem, type );
+			};
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+			startLength--;
+		}
+
+		if ( fn ) {
+
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift( "inprogress" );
+			}
+
+			// clear up the last queue stop function
+			delete hooks.stop;
+			fn.call( elem, next, hooks );
+		}
+
+		if ( !startLength && hooks ) {
+			hooks.empty.fire();
+		}
+	},
+
+	// not intended for public consumption - generates a queueHooks object, or returns the current one
+	_queueHooks: function( elem, type ) {
+		var key = type + "queueHooks";
+		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+			empty: jQuery.Callbacks("once memory").add(function() {
+				jQuery._removeData( elem, type + "queue" );
+				jQuery._removeData( elem, key );
+			})
+		});
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		var setter = 2;
+
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+			setter--;
+		}
+
+		if ( arguments.length < setter ) {
+			return jQuery.queue( this[0], type );
+		}
+
+		return data === undefined ?
+			this :
+			this.each(function() {
+				var queue = jQuery.queue( this, type, data );
+
+				// ensure a hooks for this queue
+				jQuery._queueHooks( this, type );
+
+				if ( type === "fx" && queue[0] !== "inprogress" ) {
+					jQuery.dequeue( this, type );
+				}
+			});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	},
+	// Get a promise resolved when queues of a certain type
+	// are emptied (fx is the type by default)
+	promise: function( type, obj ) {
+		var tmp,
+			count = 1,
+			defer = jQuery.Deferred(),
+			elements = this,
+			i = this.length,
+			resolve = function() {
+				if ( !( --count ) ) {
+					defer.resolveWith( elements, [ elements ] );
+				}
+			};
+
+		if ( typeof type !== "string" ) {
+			obj = type;
+			type = undefined;
+		}
+		type = type || "fx";
+
+		while ( i-- ) {
+			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+			if ( tmp && tmp.empty ) {
+				count++;
+				tmp.empty.add( resolve );
+			}
+		}
+		resolve();
+		return defer.promise( obj );
+	}
+});
+var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHidden = function( elem, el ) {
+		// isHidden might be called from jQuery#filter function;
+		// in that case, element will be second argument
+		elem = el || elem;
+		return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+	};
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+	var i = 0,
+		length = elems.length,
+		bulk = key == null;
+
+	// Sets many values
+	if ( jQuery.type( key ) === "object" ) {
+		chainable = true;
+		for ( i in key ) {
+			jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+		}
+
+	// Sets one value
+	} else if ( value !== undefined ) {
+		chainable = true;
+
+		if ( !jQuery.isFunction( value ) ) {
+			raw = true;
+		}
+
+		if ( bulk ) {
+			// Bulk operations run against the entire set
+			if ( raw ) {
+				fn.call( elems, value );
+				fn = null;
+
+			// ...except when executing function values
+			} else {
+				bulk = fn;
+				fn = function( elem, key, value ) {
+					return bulk.call( jQuery( elem ), value );
+				};
+			}
+		}
+
+		if ( fn ) {
+			for ( ; i < length; i++ ) {
+				fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+			}
+		}
+	}
+
+	return chainable ?
+		elems :
+
+		// Gets
+		bulk ?
+			fn.call( elems ) :
+			length ? fn( elems[0], key ) : emptyGet;
+};
+var rcheckableType = (/^(?:checkbox|radio)$/i);
+
+
+
+(function() {
+	// Minified: var a,b,c
+	var input = document.createElement( "input" ),
+		div = document.createElement( "div" ),
+		fragment = document.createDocumentFragment();
+
+	// Setup
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+	// IE strips leading whitespace when .innerHTML is used
+	support.leadingWhitespace = div.firstChild.nodeType === 3;
+
+	// Make sure that tbody elements aren't automatically inserted
+	// IE will insert them into empty tables
+	support.tbody = !div.getElementsByTagName( "tbody" ).length;
+
+	// Make sure that link elements get serialized correctly by innerHTML
+	// This requires a wrapper element in IE
+	support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
+
+	// Makes sure cloning an html5 element does not cause problems
+	// Where outerHTML is undefined, this still works
+	support.html5Clone =
+		document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
+
+	// Check if a disconnected checkbox will retain its checked
+	// value of true after appended to the DOM (IE6/7)
+	input.type = "checkbox";
+	input.checked = true;
+	fragment.appendChild( input );
+	support.appendChecked = input.checked;
+
+	// Make sure textarea (and checkbox) defaultValue is properly cloned
+	// Support: IE6-IE11+
+	div.innerHTML = "<textarea>x</textarea>";
+	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+
+	// #11217 - WebKit loses check when the name is after the checked attribute
+	fragment.appendChild( div );
+	div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
+
+	// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
+	// old WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	// Support: IE<9
+	// Opera does not clone events (and typeof div.attachEvent === undefined).
+	// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+	support.noCloneEvent = true;
+	if ( div.attachEvent ) {
+		div.attachEvent( "onclick", function() {
+			support.noCloneEvent = false;
+		});
+
+		div.cloneNode( true ).click();
+	}
+
+	// Execute the test only if not already executed in another module.
+	if (support.deleteExpando == null) {
+		// Support: IE<9
+		support.deleteExpando = true;
+		try {
+			delete div.test;
+		} catch( e ) {
+			support.deleteExpando = false;
+		}
+	}
+})();
+
+
+(function() {
+	var i, eventName,
+		div = document.createElement( "div" );
+
+	// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
+	for ( i in { submit: true, change: true, focusin: true }) {
+		eventName = "on" + i;
+
+		if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
+			// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
+			div.setAttribute( eventName, "t" );
+			support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
+		}
+	}
+
+	// Null elements to avoid leaks in IE.
+	div = null;
+})();
+
+
+var rformElems = /^(?:input|select|textarea)$/i,
+	rkeyEvent = /^key/,
+	rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+	return true;
+}
+
+function returnFalse() {
+	return false;
+}
+
+function safeActiveElement() {
+	try {
+		return document.activeElement;
+	} catch ( err ) { }
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+	global: {},
+
+	add: function( elem, types, handler, data, selector ) {
+		var tmp, events, t, handleObjIn,
+			special, eventHandle, handleObj,
+			handlers, type, namespaces, origType,
+			elemData = jQuery._data( elem );
+
+		// Don't attach events to noData or text/comment nodes (but allow plain objects)
+		if ( !elemData ) {
+			return;
+		}
+
+		// Caller can pass in an object of custom data in lieu of the handler
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+			selector = handleObjIn.selector;
+		}
+
+		// Make sure that the handler has a unique ID, used to find/remove it later
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure and main handler, if this is the first
+		if ( !(events = elemData.events) ) {
+			events = elemData.events = {};
+		}
+		if ( !(eventHandle = elemData.handle) ) {
+			eventHandle = elemData.handle = function( e ) {
+				// Discard the second event of a jQuery.event.trigger() and
+				// when an event is called after a page has unloaded
+				return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
+					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+			eventHandle.elem = elem;
+		}
+
+		// Handle multiple events separated by a space
+		types = ( types || "" ).match( rnotwhite ) || [ "" ];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// There *must* be a type, no attaching namespace-only handlers
+			if ( !type ) {
+				continue;
+			}
+
+			// If event changes its type, use the special event handlers for the changed type
+			special = jQuery.event.special[ type ] || {};
+
+			// If selector defined, determine special event api type, otherwise given type
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+
+			// Update special based on newly reset type
+			special = jQuery.event.special[ type ] || {};
+
+			// handleObj is passed to all event handlers
+			handleObj = jQuery.extend({
+				type: type,
+				origType: origType,
+				data: data,
+				handler: handler,
+				guid: handler.guid,
+				selector: selector,
+				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+				namespace: namespaces.join(".")
+			}, handleObjIn );
+
+			// Init the event handler queue if we're the first
+			if ( !(handlers = events[ type ]) ) {
+				handlers = events[ type ] = [];
+				handlers.delegateCount = 0;
+
+				// Only use addEventListener/attachEvent if the special events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+
+			if ( special.add ) {
+				special.add.call( elem, handleObj );
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add to the element's handler list, delegates in front
+			if ( selector ) {
+				handlers.splice( handlers.delegateCount++, 0, handleObj );
+			} else {
+				handlers.push( handleObj );
+			}
+
+			// Keep track of which events have ever been used, for event optimization
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, selector, mappedTypes ) {
+		var j, handleObj, tmp,
+			origCount, t, events,
+			special, handlers, type,
+			namespaces, origType,
+			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+		if ( !elemData || !(events = elemData.events) ) {
+			return;
+		}
+
+		// Once for each type.namespace in types; type may be omitted
+		types = ( types || "" ).match( rnotwhite ) || [ "" ];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// Unbind all events (on this namespace, if provided) for the element
+			if ( !type ) {
+				for ( type in events ) {
+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+				}
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+			handlers = events[ type ] || [];
+			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+			// Remove matching events
+			origCount = j = handlers.length;
+			while ( j-- ) {
+				handleObj = handlers[ j ];
+
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
+					( !handler || handler.guid === handleObj.guid ) &&
+					( !tmp || tmp.test( handleObj.namespace ) ) &&
+					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+					handlers.splice( j, 1 );
+
+					if ( handleObj.selector ) {
+						handlers.delegateCount--;
+					}
+					if ( special.remove ) {
+						special.remove.call( elem, handleObj );
+					}
+				}
+			}
+
+			// Remove generic event handler if we removed something and no more handlers exist
+			// (avoids potential for endless recursion during removal of special event handlers)
+			if ( origCount && !handlers.length ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			delete elemData.handle;
+
+			// removeData also checks for emptiness and clears the expando if empty
+			// so use it instead of delete
+			jQuery._removeData( elem, "events" );
+		}
+	},
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+		var handle, ontype, cur,
+			bubbleType, special, tmp, i,
+			eventPath = [ elem || document ],
+			type = hasOwn.call( event, "type" ) ? event.type : event,
+			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+		cur = tmp = elem = elem || document;
+
+		// Don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// focus/blur morphs to focusin/out; ensure we're not firing them right now
+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+			return;
+		}
+
+		if ( type.indexOf(".") >= 0 ) {
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split(".");
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+		ontype = type.indexOf(":") < 0 && "on" + type;
+
+		// Caller can pass in a jQuery.Event object, Object, or just an event type string
+		event = event[ jQuery.expando ] ?
+			event :
+			new jQuery.Event( type, typeof event === "object" && event );
+
+		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+		event.isTrigger = onlyHandlers ? 2 : 3;
+		event.namespace = namespaces.join(".");
+		event.namespace_re = event.namespace ?
+			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+			null;
+
+		// Clean up the event in case it is being reused
+		event.result = undefined;
+		if ( !event.target ) {
+			event.target = elem;
+		}
+
+		// Clone any incoming data and prepend the event, creating the handler arg list
+		data = data == null ?
+			[ event ] :
+			jQuery.makeArray( data, [ event ] );
+
+		// Allow special events to draw outside the lines
+		special = jQuery.event.special[ type ] || {};
+		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+			return;
+		}
+
+		// Determine event propagation path in advance, per W3C events spec (#9951)
+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+			bubbleType = special.delegateType || type;
+			if ( !rfocusMorph.test( bubbleType + type ) ) {
+				cur = cur.parentNode;
+			}
+			for ( ; cur; cur = cur.parentNode ) {
+				eventPath.push( cur );
+				tmp = cur;
+			}
+
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
+			if ( tmp === (elem.ownerDocument || document) ) {
+				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+			}
+		}
+
+		// Fire handlers on the event path
+		i = 0;
+		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+			event.type = i > 1 ?
+				bubbleType :
+				special.bindType || type;
+
+			// jQuery handler
+			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+
+			// Native handler
+			handle = ontype && cur[ ontype ];
+			if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
+				event.result = handle.apply( cur, data );
+				if ( event.result === false ) {
+					event.preventDefault();
+				}
+			}
+		}
+		event.type = type;
+
+		// If nobody prevented the default action, do it now
+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+			if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
+				jQuery.acceptData( elem ) ) {
+
+				// Call a native DOM method on the target with the same name name as the event.
+				// Can't use an .isFunction() check here because IE6/7 fails that test.
+				// Don't do default actions on window, that's where global variables be (#6170)
+				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+					// Don't re-trigger an onFOO event when we call its FOO() method
+					tmp = elem[ ontype ];
+
+					if ( tmp ) {
+						elem[ ontype ] = null;
+					}
+
+					// Prevent re-triggering of the same event, since we already bubbled it above
+					jQuery.event.triggered = type;
+					try {
+						elem[ type ]();
+					} catch ( e ) {
+						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
+						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
+					}
+					jQuery.event.triggered = undefined;
+
+					if ( tmp ) {
+						elem[ ontype ] = tmp;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	dispatch: function( event ) {
+
+		// Make a writable jQuery.Event from the native event object
+		event = jQuery.event.fix( event );
+
+		var i, ret, handleObj, matched, j,
+			handlerQueue = [],
+			args = slice.call( arguments ),
+			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+			special = jQuery.event.special[ event.type ] || {};
+
+		// Use the fix-ed jQuery.Event rather than the (read-only) native event
+		args[0] = event;
+		event.delegateTarget = this;
+
+		// Call the preDispatch hook for the mapped type, and let it bail if desired
+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+			return;
+		}
+
+		// Determine handlers
+		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+		// Run delegates first; they may want to stop propagation beneath us
+		i = 0;
+		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+			event.currentTarget = matched.elem;
+
+			j = 0;
+			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+				// Triggered event must either 1) have no namespace, or
+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+					event.handleObj = handleObj;
+					event.data = handleObj.data;
+
+					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+							.apply( matched.elem, args );
+
+					if ( ret !== undefined ) {
+						if ( (event.result = ret) === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+				}
+			}
+		}
+
+		// Call the postDispatch hook for the mapped type
+		if ( special.postDispatch ) {
+			special.postDispatch.call( this, event );
+		}
+
+		return event.result;
+	},
+
+	handlers: function( event, handlers ) {
+		var sel, handleObj, matches, i,
+			handlerQueue = [],
+			delegateCount = handlers.delegateCount,
+			cur = event.target;
+
+		// Find delegate handlers
+		// Black-hole SVG <use> instance trees (#13180)
+		// Avoid non-left-click bubbling in Firefox (#3861)
+		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+			/* jshint eqeqeq: false */
+			for ( ; cur != this; cur = cur.parentNode || this ) {
+				/* jshint eqeqeq: true */
+
+				// Don't check non-elements (#13208)
+				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+				if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+					matches = [];
+					for ( i = 0; i < delegateCount; i++ ) {
+						handleObj = handlers[ i ];
+
+						// Don't conflict with Object.prototype properties (#13203)
+						sel = handleObj.selector + " ";
+
+						if ( matches[ sel ] === undefined ) {
+							matches[ sel ] = handleObj.needsContext ?
+								jQuery( sel, this ).index( cur ) >= 0 :
+								jQuery.find( sel, this, null, [ cur ] ).length;
+						}
+						if ( matches[ sel ] ) {
+							matches.push( handleObj );
+						}
+					}
+					if ( matches.length ) {
+						handlerQueue.push({ elem: cur, handlers: matches });
+					}
+				}
+			}
+		}
+
+		// Add the remaining (directly-bound) handlers
+		if ( delegateCount < handlers.length ) {
+			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+		}
+
+		return handlerQueue;
+	},
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// Create a writable copy of the event object and normalize some properties
+		var i, prop, copy,
+			type = event.type,
+			originalEvent = event,
+			fixHook = this.fixHooks[ type ];
+
+		if ( !fixHook ) {
+			this.fixHooks[ type ] = fixHook =
+				rmouseEvent.test( type ) ? this.mouseHooks :
+				rkeyEvent.test( type ) ? this.keyHooks :
+				{};
+		}
+		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+		event = new jQuery.Event( originalEvent );
+
+		i = copy.length;
+		while ( i-- ) {
+			prop = copy[ i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Support: IE<9
+		// Fix target property (#1925)
+		if ( !event.target ) {
+			event.target = originalEvent.srcElement || document;
+		}
+
+		// Support: Chrome 23+, Safari?
+		// Target should not be a text node (#504, #13143)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Support: IE<9
+		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+		event.metaKey = !!event.metaKey;
+
+		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+	},
+
+	// Includes some event props shared by KeyEvent and MouseEvent
+	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+	fixHooks: {},
+
+	keyHooks: {
+		props: "char charCode key keyCode".split(" "),
+		filter: function( event, original ) {
+
+			// Add which for key events
+			if ( event.which == null ) {
+				event.which = original.charCode != null ? original.charCode : original.keyCode;
+			}
+
+			return event;
+		}
+	},
+
+	mouseHooks: {
+		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+		filter: function( event, original ) {
+			var body, eventDoc, doc,
+				button = original.button,
+				fromElement = original.fromElement;
+
+			// Calculate pageX/Y if missing and clientX/Y available
+			if ( event.pageX == null && original.clientX != null ) {
+				eventDoc = event.target.ownerDocument || document;
+				doc = eventDoc.documentElement;
+				body = eventDoc.body;
+
+				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+			}
+
+			// Add relatedTarget, if necessary
+			if ( !event.relatedTarget && fromElement ) {
+				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+			}
+
+			// Add which for click: 1 === left; 2 === middle; 3 === right
+			// Note: button is not normalized, so don't use it
+			if ( !event.which && button !== undefined ) {
+				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+			}
+
+			return event;
+		}
+	},
+
+	special: {
+		load: {
+			// Prevent triggered image.load events from bubbling to window.load
+			noBubble: true
+		},
+		focus: {
+			// Fire native event if possible so blur/focus sequence is correct
+			trigger: function() {
+				if ( this !== safeActiveElement() && this.focus ) {
+					try {
+						this.focus();
+						return false;
+					} catch ( e ) {
+						// Support: IE<9
+						// If we error on focus to hidden element (#1486, #12518),
+						// let .trigger() run the handlers
+					}
+				}
+			},
+			delegateType: "focusin"
+		},
+		blur: {
+			trigger: function() {
+				if ( this === safeActiveElement() && this.blur ) {
+					this.blur();
+					return false;
+				}
+			},
+			delegateType: "focusout"
+		},
+		click: {
+			// For checkbox, fire native event so checked state will be right
+			trigger: function() {
+				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+					this.click();
+					return false;
+				}
+			},
+
+			// For cross-browser consistency, don't fire native .click() on links
+			_default: function( event ) {
+				return jQuery.nodeName( event.target, "a" );
+			}
+		},
+
+		beforeunload: {
+			postDispatch: function( event ) {
+
+				// Support: Firefox 20+
+				// Firefox doesn't alert if the returnValue field is not set.
+				if ( event.result !== undefined && event.originalEvent ) {
+					event.originalEvent.returnValue = event.result;
+				}
+			}
+		}
+	},
+
+	simulate: function( type, elem, event, bubble ) {
+		// Piggyback on a donor event to simulate a different one.
+		// Fake originalEvent to avoid donor's stopPropagation, but if the
+		// simulated event prevents default then we do the same on the donor.
+		var e = jQuery.extend(
+			new jQuery.Event(),
+			event,
+			{
+				type: type,
+				isSimulated: true,
+				originalEvent: {}
+			}
+		);
+		if ( bubble ) {
+			jQuery.event.trigger( e, null, elem );
+		} else {
+			jQuery.event.dispatch.call( elem, e );
+		}
+		if ( e.isDefaultPrevented() ) {
+			event.preventDefault();
+		}
+	}
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} :
+	function( elem, type, handle ) {
+		var name = "on" + type;
+
+		if ( elem.detachEvent ) {
+
+			// #8545, #7054, preventing memory leaks for custom events in IE6-8
+			// detachEvent needed property on element, by name of that event, to properly expose it to GC
+			if ( typeof elem[ name ] === strundefined ) {
+				elem[ name ] = null;
+			}
+
+			elem.detachEvent( name, handle );
+		}
+	};
+
+jQuery.Event = function( src, props ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !(this instanceof jQuery.Event) ) {
+		return new jQuery.Event( src, props );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+
+		// Events bubbling up the document may have been marked as prevented
+		// by a handler lower down the tree; reflect the correct value.
+		this.isDefaultPrevented = src.defaultPrevented ||
+				src.defaultPrevented === undefined &&
+				// Support: IE < 9, Android < 4.0
+				src.returnValue === false ?
+			returnTrue :
+			returnFalse;
+
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// Put explicitly provided properties onto the event object
+	if ( props ) {
+		jQuery.extend( this, props );
+	}
+
+	// Create a timestamp if incoming event doesn't have one
+	this.timeStamp = src && src.timeStamp || jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse,
+
+	preventDefault: function() {
+		var e = this.originalEvent;
+
+		this.isDefaultPrevented = returnTrue;
+		if ( !e ) {
+			return;
+		}
+
+		// If preventDefault exists, run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// Support: IE
+		// Otherwise set the returnValue property of the original event to false
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		var e = this.originalEvent;
+
+		this.isPropagationStopped = returnTrue;
+		if ( !e ) {
+			return;
+		}
+		// If stopPropagation exists, run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+
+		// Support: IE
+		// Set the cancelBubble property of the original event to true
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		var e = this.originalEvent;
+
+		this.isImmediatePropagationStopped = returnTrue;
+
+		if ( e && e.stopImmediatePropagation ) {
+			e.stopImmediatePropagation();
+		}
+
+		this.stopPropagation();
+	}
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout",
+	pointerenter: "pointerover",
+	pointerleave: "pointerout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		delegateType: fix,
+		bindType: fix,
+
+		handle: function( event ) {
+			var ret,
+				target = this,
+				related = event.relatedTarget,
+				handleObj = event.handleObj;
+
+			// For mousenter/leave call the handler if related is outside the target.
+			// NB: No relatedTarget if the mouse left/entered the browser window
+			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+				event.type = handleObj.origType;
+				ret = handleObj.handler.apply( this, arguments );
+				event.type = fix;
+			}
+			return ret;
+		}
+	};
+});
+
+// IE submit delegation
+if ( !support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Lazy-add a submit handler when a descendant form may potentially be submitted
+			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+				// Node name check avoids a VML-related crash in IE (#9807)
+				var elem = e.target,
+					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+				if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+					jQuery.event.add( form, "submit._submit", function( event ) {
+						event._submit_bubble = true;
+					});
+					jQuery._data( form, "submitBubbles", true );
+				}
+			});
+			// return undefined since we don't need an event listener
+		},
+
+		postDispatch: function( event ) {
+			// If form was submitted by the user, bubble the event up the tree
+			if ( event._submit_bubble ) {
+				delete event._submit_bubble;
+				if ( this.parentNode && !event.isTrigger ) {
+					jQuery.event.simulate( "submit", this.parentNode, event, true );
+				}
+			}
+		},
+
+		teardown: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+			jQuery.event.remove( this, "._submit" );
+		}
+	};
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !support.changeBubbles ) {
+
+	jQuery.event.special.change = {
+
+		setup: function() {
+
+			if ( rformElems.test( this.nodeName ) ) {
+				// IE doesn't fire change on a check/radio until blur; trigger it on click
+				// after a propertychange. Eat the blur-change in special.change.handle.
+				// This still fires onchange a second time for check/radio after blur.
+				if ( this.type === "checkbox" || this.type === "radio" ) {
+					jQuery.event.add( this, "propertychange._change", function( event ) {
+						if ( event.originalEvent.propertyName === "checked" ) {
+							this._just_changed = true;
+						}
+					});
+					jQuery.event.add( this, "click._change", function( event ) {
+						if ( this._just_changed && !event.isTrigger ) {
+							this._just_changed = false;
+						}
+						// Allow triggered, simulated change events (#11500)
+						jQuery.event.simulate( "change", this, event, true );
+					});
+				}
+				return false;
+			}
+			// Delegated event; lazy-add a change handler on descendant inputs
+			jQuery.event.add( this, "beforeactivate._change", function( e ) {
+				var elem = e.target;
+
+				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+					jQuery.event.add( elem, "change._change", function( event ) {
+						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+							jQuery.event.simulate( "change", this.parentNode, event, true );
+						}
+					});
+					jQuery._data( elem, "changeBubbles", true );
+				}
+			});
+		},
+
+		handle: function( event ) {
+			var elem = event.target;
+
+			// Swallow native change events from checkbox/radio, we already triggered them above
+			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+				return event.handleObj.handler.apply( this, arguments );
+			}
+		},
+
+		teardown: function() {
+			jQuery.event.remove( this, "._change" );
+
+			return !rformElems.test( this.nodeName );
+		}
+	};
+}
+
+// Create "bubbling" focus and blur events
+if ( !support.focusinBubbles ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+		// Attach a single capturing handler on the document while someone wants focusin/focusout
+		var handler = function( event ) {
+				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+			};
+
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				var doc = this.ownerDocument || this,
+					attaches = jQuery._data( doc, fix );
+
+				if ( !attaches ) {
+					doc.addEventListener( orig, handler, true );
+				}
+				jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
+			},
+			teardown: function() {
+				var doc = this.ownerDocument || this,
+					attaches = jQuery._data( doc, fix ) - 1;
+
+				if ( !attaches ) {
+					doc.removeEventListener( orig, handler, true );
+					jQuery._removeData( doc, fix );
+				} else {
+					jQuery._data( doc, fix, attaches );
+				}
+			}
+		};
+	});
+}
+
+jQuery.fn.extend({
+
+	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+		var type, origFn;
+
+		// Types can be a map of types/handlers
+		if ( typeof types === "object" ) {
+			// ( types-Object, selector, data )
+			if ( typeof selector !== "string" ) {
+				// ( types-Object, data )
+				data = data || selector;
+				selector = undefined;
+			}
+			for ( type in types ) {
+				this.on( type, selector, data, types[ type ], one );
+			}
+			return this;
+		}
+
+		if ( data == null && fn == null ) {
+			// ( types, fn )
+			fn = selector;
+			data = selector = undefined;
+		} else if ( fn == null ) {
+			if ( typeof selector === "string" ) {
+				// ( types, selector, fn )
+				fn = data;
+				data = undefined;
+			} else {
+				// ( types, data, fn )
+				fn = data;
+				data = selector;
+				selector = undefined;
+			}
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		} else if ( !fn ) {
+			return this;
+		}
+
+		if ( one === 1 ) {
+			origFn = fn;
+			fn = function( event ) {
+				// Can use an empty set, since event contains the info
+				jQuery().off( event );
+				return origFn.apply( this, arguments );
+			};
+			// Use same guid so caller can remove using origFn
+			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+		}
+		return this.each( function() {
+			jQuery.event.add( this, types, fn, data, selector );
+		});
+	},
+	one: function( types, selector, data, fn ) {
+		return this.on( types, selector, data, fn, 1 );
+	},
+	off: function( types, selector, fn ) {
+		var handleObj, type;
+		if ( types && types.preventDefault && types.handleObj ) {
+			// ( event )  dispatched jQuery.Event
+			handleObj = types.handleObj;
+			jQuery( types.delegateTarget ).off(
+				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+				handleObj.selector,
+				handleObj.handler
+			);
+			return this;
+		}
+		if ( typeof types === "object" ) {
+			// ( types-object [, selector] )
+			for ( type in types ) {
+				this.off( type, selector, types[ type ] );
+			}
+			return this;
+		}
+		if ( selector === false || typeof selector === "function" ) {
+			// ( types [, fn] )
+			fn = selector;
+			selector = undefined;
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		}
+		return this.each(function() {
+			jQuery.event.remove( this, types, fn, selector );
+		});
+	},
+
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+	triggerHandler: function( type, data ) {
+		var elem = this[0];
+		if ( elem ) {
+			return jQuery.event.trigger( type, data, elem, true );
+		}
+	}
+});
+
+
+function createSafeFragment( document ) {
+	var list = nodeNames.split( "|" ),
+		safeFrag = document.createDocumentFragment();
+
+	if ( safeFrag.createElement ) {
+		while ( list.length ) {
+			safeFrag.createElement(
+				list.pop()
+			);
+		}
+	}
+	return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+	rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnoInnerhtml = /<(?:script|style|link)/i,
+	// checked="checked" or checked
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	rscriptType = /^$|\/(?:java|ecma)script/i,
+	rscriptTypeMasked = /^true\/(.*)/,
+	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+	// We have to close these tags to support XHTML (#13200)
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		area: [ 1, "<map>", "</map>" ],
+		param: [ 1, "<object>", "</object>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+		// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+		// unless wrapped in a div with non-breaking characters in front of it.
+		_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
+	},
+	safeFragment = createSafeFragment( document ),
+	fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+function getAll( context, tag ) {
+	var elems, elem,
+		i = 0,
+		found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
+			typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
+			undefined;
+
+	if ( !found ) {
+		for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+			if ( !tag || jQuery.nodeName( elem, tag ) ) {
+				found.push( elem );
+			} else {
+				jQuery.merge( found, getAll( elem, tag ) );
+			}
+		}
+	}
+
+	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+		jQuery.merge( [ context ], found ) :
+		found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+	if ( rcheckableType.test( elem.type ) ) {
+		elem.defaultChecked = elem.checked;
+	}
+}
+
+// Support: IE<8
+// Manipulating tables requires a tbody
+function manipulationTarget( elem, content ) {
+	return jQuery.nodeName( elem, "table" ) &&
+		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
+
+		elem.getElementsByTagName("tbody")[0] ||
+			elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
+		elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+	elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
+	return elem;
+}
+function restoreScript( elem ) {
+	var match = rscriptTypeMasked.exec( elem.type );
+	if ( match ) {
+		elem.type = match[1];
+	} else {
+		elem.removeAttribute("type");
+	}
+	return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+	var elem,
+		i = 0;
+	for ( ; (elem = elems[i]) != null; i++ ) {
+		jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+	}
+}
+
+function cloneCopyEvent( src, dest ) {
+
+	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+		return;
+	}
+
+	var type, i, l,
+		oldData = jQuery._data( src ),
+		curData = jQuery._data( dest, oldData ),
+		events = oldData.events;
+
+	if ( events ) {
+		delete curData.handle;
+		curData.events = {};
+
+		for ( type in events ) {
+			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+				jQuery.event.add( dest, type, events[ type ][ i ] );
+			}
+		}
+	}
+
+	// make the cloned public data object a copy from the original
+	if ( curData.data ) {
+		curData.data = jQuery.extend( {}, curData.data );
+	}
+}
+
+function fixCloneNodeIssues( src, dest ) {
+	var nodeName, e, data;
+
+	// We do not need to do anything for non-Elements
+	if ( dest.nodeType !== 1 ) {
+		return;
+	}
+
+	nodeName = dest.nodeName.toLowerCase();
+
+	// IE6-8 copies events bound via attachEvent when using cloneNode.
+	if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
+		data = jQuery._data( dest );
+
+		for ( e in data.events ) {
+			jQuery.removeEvent( dest, e, data.handle );
+		}
+
+		// Event data gets referenced instead of copied if the expando gets copied too
+		dest.removeAttribute( jQuery.expando );
+	}
+
+	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+	if ( nodeName === "script" && dest.text !== src.text ) {
+		disableScript( dest ).text = src.text;
+		restoreScript( dest );
+
+	// IE6-10 improperly clones children of object elements using classid.
+	// IE10 throws NoModificationAllowedError if parent is null, #12132.
+	} else if ( nodeName === "object" ) {
+		if ( dest.parentNode ) {
+			dest.outerHTML = src.outerHTML;
+		}
+
+		// This path appears unavoidable for IE9. When cloning an object
+		// element in IE9, the outerHTML strategy above is not sufficient.
+		// If the src has innerHTML and the destination does not,
+		// copy the src.innerHTML into the dest.innerHTML. #10324
+		if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+			dest.innerHTML = src.innerHTML;
+		}
+
+	} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+		// IE6-8 fails to persist the checked state of a cloned checkbox
+		// or radio button. Worse, IE6-7 fail to give the cloned element
+		// a checked appearance if the defaultChecked value isn't also set
+
+		dest.defaultChecked = dest.checked = src.checked;
+
+		// IE6-7 get confused and end up setting the value of a cloned
+		// checkbox/radio button to an empty string instead of "on"
+		if ( dest.value !== src.value ) {
+			dest.value = src.value;
+		}
+
+	// IE6-8 fails to return the selected option to the default selected
+	// state when cloning options
+	} else if ( nodeName === "option" ) {
+		dest.defaultSelected = dest.selected = src.defaultSelected;
+
+	// IE6-8 fails to set the defaultValue to the correct value when
+	// cloning other types of input fields
+	} else if ( nodeName === "input" || nodeName === "textarea" ) {
+		dest.defaultValue = src.defaultValue;
+	}
+}
+
+jQuery.extend({
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+		var destElements, node, clone, i, srcElements,
+			inPage = jQuery.contains( elem.ownerDocument, elem );
+
+		if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+			clone = elem.cloneNode( true );
+
+		// IE<=8 does not properly clone detached, unknown element nodes
+		} else {
+			fragmentDiv.innerHTML = elem.outerHTML;
+			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+		}
+
+		if ( (!support.noCloneEvent || !support.noCloneChecked) &&
+				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+
+			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+			destElements = getAll( clone );
+			srcElements = getAll( elem );
+
+			// Fix all IE cloning issues
+			for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+				// Ensure that the destination node is not null; Fixes #9587
+				if ( destElements[i] ) {
+					fixCloneNodeIssues( node, destElements[i] );
+				}
+			}
+		}
+
+		// Copy the events from the original to the clone
+		if ( dataAndEvents ) {
+			if ( deepDataAndEvents ) {
+				srcElements = srcElements || getAll( elem );
+				destElements = destElements || getAll( clone );
+
+				for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+					cloneCopyEvent( node, destElements[i] );
+				}
+			} else {
+				cloneCopyEvent( elem, clone );
+			}
+		}
+
+		// Preserve script evaluation history
+		destElements = getAll( clone, "script" );
+		if ( destElements.length > 0 ) {
+			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+		}
+
+		destElements = srcElements = node = null;
+
+		// Return the cloned set
+		return clone;
+	},
+
+	buildFragment: function( elems, context, scripts, selection ) {
+		var j, elem, contains,
+			tmp, tag, tbody, wrap,
+			l = elems.length,
+
+			// Ensure a safe fragment
+			safe = createSafeFragment( context ),
+
+			nodes = [],
+			i = 0;
+
+		for ( ; i < l; i++ ) {
+			elem = elems[ i ];
+
+			if ( elem || elem === 0 ) {
+
+				// Add nodes directly
+				if ( jQuery.type( elem ) === "object" ) {
+					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+				// Convert non-html into a text node
+				} else if ( !rhtml.test( elem ) ) {
+					nodes.push( context.createTextNode( elem ) );
+
+				// Convert html into DOM nodes
+				} else {
+					tmp = tmp || safe.appendChild( context.createElement("div") );
+
+					// Deserialize a standard representation
+					tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
+					wrap = wrapMap[ tag ] || wrapMap._default;
+
+					tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+					// Descend through wrappers to the right content
+					j = wrap[0];
+					while ( j-- ) {
+						tmp = tmp.lastChild;
+					}
+
+					// Manually add leading whitespace removed by IE
+					if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+						nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+					}
+
+					// Remove IE's autoinserted <tbody> from table fragments
+					if ( !support.tbody ) {
+
+						// String was a <table>, *may* have spurious <tbody>
+						elem = tag === "table" && !rtbody.test( elem ) ?
+							tmp.firstChild :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !rtbody.test( elem ) ?
+								tmp :
+								0;
+
+						j = elem && elem.childNodes.length;
+						while ( j-- ) {
+							if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+								elem.removeChild( tbody );
+							}
+						}
+					}
+
+					jQuery.merge( nodes, tmp.childNodes );
+
+					// Fix #12392 for WebKit and IE > 9
+					tmp.textContent = "";
+
+					// Fix #12392 for oldIE
+					while ( tmp.firstChild ) {
+						tmp.removeChild( tmp.firstChild );
+					}
+
+					// Remember the top-level container for proper cleanup
+					tmp = safe.lastChild;
+				}
+			}
+		}
+
+		// Fix #11356: Clear elements from fragment
+		if ( tmp ) {
+			safe.removeChild( tmp );
+		}
+
+		// Reset defaultChecked for any radios and checkboxes
+		// about to be appended to the DOM in IE 6/7 (#8060)
+		if ( !support.appendChecked ) {
+			jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+		}
+
+		i = 0;
+		while ( (elem = nodes[ i++ ]) ) {
+
+			// #4087 - If origin and destination elements are the same, and this is
+			// that element, do not do anything
+			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+				continue;
+			}
+
+			contains = jQuery.contains( elem.ownerDocument, elem );
+
+			// Append to fragment
+			tmp = getAll( safe.appendChild( elem ), "script" );
+
+			// Preserve script evaluation history
+			if ( contains ) {
+				setGlobalEval( tmp );
+			}
+
+			// Capture executables
+			if ( scripts ) {
+				j = 0;
+				while ( (elem = tmp[ j++ ]) ) {
+					if ( rscriptType.test( elem.type || "" ) ) {
+						scripts.push( elem );
+					}
+				}
+			}
+		}
+
+		tmp = null;
+
+		return safe;
+	},
+
+	cleanData: function( elems, /* internal */ acceptData ) {
+		var elem, type, id, data,
+			i = 0,
+			internalKey = jQuery.expando,
+			cache = jQuery.cache,
+			deleteExpando = support.deleteExpando,
+			special = jQuery.event.special;
+
+		for ( ; (elem = elems[i]) != null; i++ ) {
+			if ( acceptData || jQuery.acceptData( elem ) ) {
+
+				id = elem[ internalKey ];
+				data = id && cache[ id ];
+
+				if ( data ) {
+					if ( data.events ) {
+						for ( type in data.events ) {
+							if ( special[ type ] ) {
+								jQuery.event.remove( elem, type );
+
+							// This is a shortcut to avoid jQuery.event.remove's overhead
+							} else {
+								jQuery.removeEvent( elem, type, data.handle );
+							}
+						}
+					}
+
+					// Remove cache only if it was not already removed by jQuery.event.remove
+					if ( cache[ id ] ) {
+
+						delete cache[ id ];
+
+						// IE does not allow us to delete expando properties from nodes,
+						// nor does it have a removeAttribute function on Document nodes;
+						// we must handle all of these cases
+						if ( deleteExpando ) {
+							delete elem[ internalKey ];
+
+						} else if ( typeof elem.removeAttribute !== strundefined ) {
+							elem.removeAttribute( internalKey );
+
+						} else {
+							elem[ internalKey ] = null;
+						}
+
+						deletedIds.push( id );
+					}
+				}
+			}
+		}
+	}
+});
+
+jQuery.fn.extend({
+	text: function( value ) {
+		return access( this, function( value ) {
+			return value === undefined ?
+				jQuery.text( this ) :
+				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+		}, null, value, arguments.length );
+	},
+
+	append: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				var target = manipulationTarget( this, elem );
+				target.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				var target = manipulationTarget( this, elem );
+				target.insertBefore( elem, target.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this );
+			}
+		});
+	},
+
+	after: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			}
+		});
+	},
+
+	remove: function( selector, keepData /* Internal Use Only */ ) {
+		var elem,
+			elems = selector ? jQuery.filter( selector, this ) : this,
+			i = 0;
+
+		for ( ; (elem = elems[i]) != null; i++ ) {
+
+			if ( !keepData && elem.nodeType === 1 ) {
+				jQuery.cleanData( getAll( elem ) );
+			}
+
+			if ( elem.parentNode ) {
+				if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+					setGlobalEval( getAll( elem, "script" ) );
+				}
+				elem.parentNode.removeChild( elem );
+			}
+		}
+
+		return this;
+	},
+
+	empty: function() {
+		var elem,
+			i = 0;
+
+		for ( ; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( getAll( elem, false ) );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+
+			// If this is a select, ensure that it displays empty (#12336)
+			// Support: IE<9
+			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+				elem.options.length = 0;
+			}
+		}
+
+		return this;
+	},
+
+	clone: function( dataAndEvents, deepDataAndEvents ) {
+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+		return this.map(function() {
+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+		});
+	},
+
+	html: function( value ) {
+		return access( this, function( value ) {
+			var elem = this[ 0 ] || {},
+				i = 0,
+				l = this.length;
+
+			if ( value === undefined ) {
+				return elem.nodeType === 1 ?
+					elem.innerHTML.replace( rinlinejQuery, "" ) :
+					undefined;
+			}
+
+			// See if we can take a shortcut and just use innerHTML
+			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+				( support.htmlSerialize || !rnoshimcache.test( value )  ) &&
+				( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+				!wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
+
+				value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+				try {
+					for (; i < l; i++ ) {
+						// Remove element nodes and prevent memory leaks
+						elem = this[i] || {};
+						if ( elem.nodeType === 1 ) {
+							jQuery.cleanData( getAll( elem, false ) );
+							elem.innerHTML = value;
+						}
+					}
+
+					elem = 0;
+
+				// If using innerHTML throws an exception, use the fallback method
+				} catch(e) {}
+			}
+
+			if ( elem ) {
+				this.empty().append( value );
+			}
+		}, null, value, arguments.length );
+	},
+
+	replaceWith: function() {
+		var arg = arguments[ 0 ];
+
+		// Make the changes, replacing each context element with the new content
+		this.domManip( arguments, function( elem ) {
+			arg = this.parentNode;
+
+			jQuery.cleanData( getAll( this ) );
+
+			if ( arg ) {
+				arg.replaceChild( elem, this );
+			}
+		});
+
+		// Force removal if there was no new content (e.g., from empty arguments)
+		return arg && (arg.length || arg.nodeType) ? this : this.remove();
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, callback ) {
+
+		// Flatten any nested arrays
+		args = concat.apply( [], args );
+
+		var first, node, hasScripts,
+			scripts, doc, fragment,
+			i = 0,
+			l = this.length,
+			set = this,
+			iNoClone = l - 1,
+			value = args[0],
+			isFunction = jQuery.isFunction( value );
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( isFunction ||
+				( l > 1 && typeof value === "string" &&
+					!support.checkClone && rchecked.test( value ) ) ) {
+			return this.each(function( index ) {
+				var self = set.eq( index );
+				if ( isFunction ) {
+					args[0] = value.call( this, index, self.html() );
+				}
+				self.domManip( args, callback );
+			});
+		}
+
+		if ( l ) {
+			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
+			first = fragment.firstChild;
+
+			if ( fragment.childNodes.length === 1 ) {
+				fragment = first;
+			}
+
+			if ( first ) {
+				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+				hasScripts = scripts.length;
+
+				// Use the original fragment for the last item instead of the first because it can end up
+				// being emptied incorrectly in certain situations (#8070).
+				for ( ; i < l; i++ ) {
+					node = fragment;
+
+					if ( i !== iNoClone ) {
+						node = jQuery.clone( node, true, true );
+
+						// Keep references to cloned scripts for later restoration
+						if ( hasScripts ) {
+							jQuery.merge( scripts, getAll( node, "script" ) );
+						}
+					}
+
+					callback.call( this[i], node, i );
+				}
+
+				if ( hasScripts ) {
+					doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+					// Reenable scripts
+					jQuery.map( scripts, restoreScript );
+
+					// Evaluate executable scripts on first document insertion
+					for ( i = 0; i < hasScripts; i++ ) {
+						node = scripts[ i ];
+						if ( rscriptType.test( node.type || "" ) &&
+							!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+							if ( node.src ) {
+								// Optional AJAX dependency, but won't run scripts if not present
+								if ( jQuery._evalUrl ) {
+									jQuery._evalUrl( node.src );
+								}
+							} else {
+								jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+							}
+						}
+					}
+				}
+
+				// Fix #11809: Avoid leaking memory
+				fragment = first = null;
+			}
+		}
+
+		return this;
+	}
+});
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var elems,
+			i = 0,
+			ret = [],
+			insert = jQuery( selector ),
+			last = insert.length - 1;
+
+		for ( ; i <= last; i++ ) {
+			elems = i === last ? this : this.clone(true);
+			jQuery( insert[i] )[ original ]( elems );
+
+			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+			push.apply( ret, elems.get() );
+		}
+
+		return this.pushStack( ret );
+	};
+});
+
+
+var iframe,
+	elemdisplay = {};
+
+/**
+ * Retrieve the actual display of a element
+ * @param {String} name nodeName of the element
+ * @param {Object} doc Document object
+ */
+// Called only from within defaultDisplay
+function actualDisplay( name, doc ) {
+	var style,
+		elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+
+		// getDefaultComputedStyle might be reliably used only on attached element
+		display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
+
+			// Use of this method is a temporary fix (more like optmization) until something better comes along,
+			// since it was removed from specification and supported only in FF
+			style.display : jQuery.css( elem[ 0 ], "display" );
+
+	// We don't have any data stored on the element,
+	// so use "detach" method as fast way to get rid of the element
+	elem.detach();
+
+	return display;
+}
+
+/**
+ * Try to determine the default display value of an element
+ * @param {String} nodeName
+ */
+function defaultDisplay( nodeName ) {
+	var doc = document,
+		display = elemdisplay[ nodeName ];
+
+	if ( !display ) {
+		display = actualDisplay( nodeName, doc );
+
+		// If the simple way fails, read from inside an iframe
+		if ( display === "none" || !display ) {
+
+			// Use the already-created iframe if possible
+			iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
+
+			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+			doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
+
+			// Support: IE
+			doc.write();
+			doc.close();
+
+			display = actualDisplay( nodeName, doc );
+			iframe.detach();
+		}
+
+		// Store the correct default display
+		elemdisplay[ nodeName ] = display;
+	}
+
+	return display;
+}
+
+
+(function() {
+	var shrinkWrapBlocksVal;
+
+	support.shrinkWrapBlocks = function() {
+		if ( shrinkWrapBlocksVal != null ) {
+			return shrinkWrapBlocksVal;
+		}
+
+		// Will be changed later if needed.
+		shrinkWrapBlocksVal = false;
+
+		// Minified: var b,c,d
+		var div, body, container;
+
+		body = document.getElementsByTagName( "body" )[ 0 ];
+		if ( !body || !body.style ) {
+			// Test fired too early or in an unsupported environment, exit.
+			return;
+		}
+
+		// Setup
+		div = document.createElement( "div" );
+		container = document.createElement( "div" );
+		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+		body.appendChild( container ).appendChild( div );
+
+		// Support: IE6
+		// Check if elements with layout shrink-wrap their children
+		if ( typeof div.style.zoom !== strundefined ) {
+			// Reset CSS: box-sizing; display; margin; border
+			div.style.cssText =
+				// Support: Firefox<29, Android 2.3
+				// Vendor-prefix box-sizing
+				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
+				"box-sizing:content-box;display:block;margin:0;border:0;" +
+				"padding:1px;width:1px;zoom:1";
+			div.appendChild( document.createElement( "div" ) ).style.width = "5px";
+			shrinkWrapBlocksVal = div.offsetWidth !== 3;
+		}
+
+		body.removeChild( container );
+
+		return shrinkWrapBlocksVal;
+	};
+
+})();
+var rmargin = (/^margin/);
+
+var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
+
+
+
+var getStyles, curCSS,
+	rposition = /^(top|right|bottom|left)$/;
+
+if ( window.getComputedStyle ) {
+	getStyles = function( elem ) {
+		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
+		// IE throws on elements created in popups
+		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
+		if ( elem.ownerDocument.defaultView.opener ) {
+			return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
+		}
+
+		return window.getComputedStyle( elem, null );
+	};
+
+	curCSS = function( elem, name, computed ) {
+		var width, minWidth, maxWidth, ret,
+			style = elem.style;
+
+		computed = computed || getStyles( elem );
+
+		// getPropertyValue is only needed for .css('filter') in IE9, see #12537
+		ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
+
+		if ( computed ) {
+
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+				ret = jQuery.style( elem, name );
+			}
+
+			// A tribute to the "awesome hack by Dean Edwards"
+			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+				// Remember the original values
+				width = style.width;
+				minWidth = style.minWidth;
+				maxWidth = style.maxWidth;
+
+				// Put in the new values to get a computed value out
+				style.minWidth = style.maxWidth = style.width = ret;
+				ret = computed.width;
+
+				// Revert the changed values
+				style.width = width;
+				style.minWidth = minWidth;
+				style.maxWidth = maxWidth;
+			}
+		}
+
+		// Support: IE
+		// IE returns zIndex value as an integer.
+		return ret === undefined ?
+			ret :
+			ret + "";
+	};
+} else if ( document.documentElement.currentStyle ) {
+	getStyles = function( elem ) {
+		return elem.currentStyle;
+	};
+
+	curCSS = function( elem, name, computed ) {
+		var left, rs, rsLeft, ret,
+			style = elem.style;
+
+		computed = computed || getStyles( elem );
+		ret = computed ? computed[ name ] : undefined;
+
+		// Avoid setting ret to empty string here
+		// so we don't default to auto
+		if ( ret == null && style && style[ name ] ) {
+			ret = style[ name ];
+		}
+
+		// From the awesome hack by Dean Edwards
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+		// If we're not dealing with a regular pixel number
+		// but a number that has a weird ending, we need to convert it to pixels
+		// but not position css attributes, as those are proportional to the parent element instead
+		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+			// Remember the original values
+			left = style.left;
+			rs = elem.runtimeStyle;
+			rsLeft = rs && rs.left;
+
+			// Put in the new values to get a computed value out
+			if ( rsLeft ) {
+				rs.left = elem.currentStyle.left;
+			}
+			style.left = name === "fontSize" ? "1em" : ret;
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			if ( rsLeft ) {
+				rs.left = rsLeft;
+			}
+		}
+
+		// Support: IE
+		// IE returns zIndex value as an integer.
+		return ret === undefined ?
+			ret :
+			ret + "" || "auto";
+	};
+}
+
+
+
+
+function addGetHookIf( conditionFn, hookFn ) {
+	// Define the hook, we'll check on the first run if it's really needed.
+	return {
+		get: function() {
+			var condition = conditionFn();
+
+			if ( condition == null ) {
+				// The test was not ready at this point; screw the hook this time
+				// but check again when needed next time.
+				return;
+			}
+
+			if ( condition ) {
+				// Hook not needed (or it's not possible to use it due to missing dependency),
+				// remove it.
+				// Since there are no other hooks for marginRight, remove the whole object.
+				delete this.get;
+				return;
+			}
+
+			// Hook needed; redefine it so that the support test is not executed again.
+
+			return (this.get = hookFn).apply( this, arguments );
+		}
+	};
+}
+
+
+(function() {
+	// Minified: var b,c,d,e,f,g, h,i
+	var div, style, a, pixelPositionVal, boxSizingReliableVal,
+		reliableHiddenOffsetsVal, reliableMarginRightVal;
+
+	// Setup
+	div = document.createElement( "div" );
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+	a = div.getElementsByTagName( "a" )[ 0 ];
+	style = a && a.style;
+
+	// Finish early in limited (non-browser) environments
+	if ( !style ) {
+		return;
+	}
+
+	style.cssText = "float:left;opacity:.5";
+
+	// Support: IE<9
+	// Make sure that element opacity exists (as opposed to filter)
+	support.opacity = style.opacity === "0.5";
+
+	// Verify style float existence
+	// (IE uses styleFloat instead of cssFloat)
+	support.cssFloat = !!style.cssFloat;
+
+	div.style.backgroundClip = "content-box";
+	div.cloneNode( true ).style.backgroundClip = "";
+	support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+	// Support: Firefox<29, Android 2.3
+	// Vendor-prefix box-sizing
+	support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
+		style.WebkitBoxSizing === "";
+
+	jQuery.extend(support, {
+		reliableHiddenOffsets: function() {
+			if ( reliableHiddenOffsetsVal == null ) {
+				computeStyleTests();
+			}
+			return reliableHiddenOffsetsVal;
+		},
+
+		boxSizingReliable: function() {
+			if ( boxSizingReliableVal == null ) {
+				computeStyleTests();
+			}
+			return boxSizingReliableVal;
+		},
+
+		pixelPosition: function() {
+			if ( pixelPositionVal == null ) {
+				computeStyleTests();
+			}
+			return pixelPositionVal;
+		},
+
+		// Support: Android 2.3
+		reliableMarginRight: function() {
+			if ( reliableMarginRightVal == null ) {
+				computeStyleTests();
+			}
+			return reliableMarginRightVal;
+		}
+	});
+
+	function computeStyleTests() {
+		// Minified: var b,c,d,j
+		var div, body, container, contents;
+
+		body = document.getElementsByTagName( "body" )[ 0 ];
+		if ( !body || !body.style ) {
+			// Test fired too early or in an unsupported environment, exit.
+			return;
+		}
+
+		// Setup
+		div = document.createElement( "div" );
+		container = document.createElement( "div" );
+		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+		body.appendChild( container ).appendChild( div );
+
+		div.style.cssText =
+			// Support: Firefox<29, Android 2.3
+			// Vendor-prefix box-sizing
+			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
+			"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
+			"border:1px;padding:1px;width:4px;position:absolute";
+
+		// Support: IE<9
+		// Assume reasonable values in the absence of getComputedStyle
+		pixelPositionVal = boxSizingReliableVal = false;
+		reliableMarginRightVal = true;
+
+		// Check for getComputedStyle so that this code is not run in IE<9.
+		if ( window.getComputedStyle ) {
+			pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+			boxSizingReliableVal =
+				( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+			// Support: Android 2.3
+			// Div with explicit width and no margin-right incorrectly
+			// gets computed margin-right based on width of container (#3333)
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+			contents = div.appendChild( document.createElement( "div" ) );
+
+			// Reset CSS: box-sizing; display; margin; border; padding
+			contents.style.cssText = div.style.cssText =
+				// Support: Firefox<29, Android 2.3
+				// Vendor-prefix box-sizing
+				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
+				"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
+			contents.style.marginRight = contents.style.width = "0";
+			div.style.width = "1px";
+
+			reliableMarginRightVal =
+				!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
+
+			div.removeChild( contents );
+		}
+
+		// Support: IE8
+		// Check if table cells still have offsetWidth/Height when they are set
+		// to display:none and there are still other visible table cells in a
+		// table row; if so, offsetWidth/Height are not reliable for use when
+		// determining if an element has been hidden directly using
+		// display:none (it is still safe to use offsets if a parent element is
+		// hidden; don safety goggles and see bug #4512 for more information).
+		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+		contents = div.getElementsByTagName( "td" );
+		contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
+		reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
+		if ( reliableHiddenOffsetsVal ) {
+			contents[ 0 ].style.display = "";
+			contents[ 1 ].style.display = "none";
+			reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
+		}
+
+		body.removeChild( container );
+	}
+
+})();
+
+
+// A method for quickly swapping in/out CSS properties to get correct calculations.
+jQuery.swap = function( elem, options, callback, args ) {
+	var ret, name,
+		old = {};
+
+	// Remember the old values, and insert the new ones
+	for ( name in options ) {
+		old[ name ] = elem.style[ name ];
+		elem.style[ name ] = options[ name ];
+	}
+
+	ret = callback.apply( elem, args || [] );
+
+	// Revert the old values
+	for ( name in options ) {
+		elem.style[ name ] = old[ name ];
+	}
+
+	return ret;
+};
+
+
+var
+		ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity\s*=\s*([^)]*)/,
+
+	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
+	rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
+
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssNormalTransform = {
+		letterSpacing: "0",
+		fontWeight: "400"
+	},
+
+	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+	// shortcut for names that are not vendor prefixed
+	if ( name in style ) {
+		return name;
+	}
+
+	// check for vendor prefixed names
+	var capName = name.charAt(0).toUpperCase() + name.slice(1),
+		origName = name,
+		i = cssPrefixes.length;
+
+	while ( i-- ) {
+		name = cssPrefixes[ i ] + capName;
+		if ( name in style ) {
+			return name;
+		}
+	}
+
+	return origName;
+}
+
+function showHide( elements, show ) {
+	var display, elem, hidden,
+		values = [],
+		index = 0,
+		length = elements.length;
+
+	for ( ; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+
+		values[ index ] = jQuery._data( elem, "olddisplay" );
+		display = elem.style.display;
+		if ( show ) {
+			// Reset the inline display of this element to learn if it is
+			// being hidden by cascaded rules or not
+			if ( !values[ index ] && display === "none" ) {
+				elem.style.display = "";
+			}
+
+			// Set elements which have been overridden with display: none
+			// in a stylesheet to whatever the default browser style is
+			// for such an element
+			if ( elem.style.display === "" && isHidden( elem ) ) {
+				values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
+			}
+		} else {
+			hidden = isHidden( elem );
+
+			if ( display && display !== "none" || !hidden ) {
+				jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+			}
+		}
+	}
+
+	// Set the display of most of the elements in a second loop
+	// to avoid the constant reflow
+	for ( index = 0; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+			elem.style.display = show ? values[ index ] || "" : "none";
+		}
+	}
+
+	return elements;
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+	var matches = rnumsplit.exec( value );
+	return matches ?
+		// Guard against undefined "subtract", e.g., when used as in cssHooks
+		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+		value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+	var i = extra === ( isBorderBox ? "border" : "content" ) ?
+		// If we already have the right measurement, avoid augmentation
+		4 :
+		// Otherwise initialize for horizontal or vertical properties
+		name === "width" ? 1 : 0,
+
+		val = 0;
+
+	for ( ; i < 4; i += 2 ) {
+		// both box models exclude margin, so add it if we want it
+		if ( extra === "margin" ) {
+			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+		}
+
+		if ( isBorderBox ) {
+			// border-box includes padding, so remove it if we want content
+			if ( extra === "content" ) {
+				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+			}
+
+			// at this point, extra isn't border nor margin, so remove border
+			if ( extra !== "margin" ) {
+				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		} else {
+			// at this point, extra isn't content, so add padding
+			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+			// at this point, extra isn't content nor padding, so add border
+			if ( extra !== "padding" ) {
+				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		}
+	}
+
+	return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+	// Start with offset property, which is equivalent to the border-box value
+	var valueIsBorderBox = true,
+		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+		styles = getStyles( elem ),
+		isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+	// some non-html elements return undefined for offsetWidth, so check for null/undefined
+	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+	if ( val <= 0 || val == null ) {
+		// Fall back to computed then uncomputed css if necessary
+		val = curCSS( elem, name, styles );
+		if ( val < 0 || val == null ) {
+			val = elem.style[ name ];
+		}
+
+		// Computed unit is not pixels. Stop here and return.
+		if ( rnumnonpx.test(val) ) {
+			return val;
+		}
+
+		// we need the check for style in case a browser which returns unreliable values
+		// for getComputedStyle silently falls back to the reliable elem.style
+		valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
+
+		// Normalize "", auto, and prepare for extra
+		val = parseFloat( val ) || 0;
+	}
+
+	// use the active box-sizing model to add/subtract irrelevant styles
+	return ( val +
+		augmentWidthOrHeight(
+			elem,
+			name,
+			extra || ( isBorderBox ? "border" : "content" ),
+			valueIsBorderBox,
+			styles
+		)
+	) + "px";
+}
+
+jQuery.extend({
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity" );
+					return ret === "" ? "1" : ret;
+				}
+			}
+		}
+	},
+
+	// Don't automatically add "px" to these possibly-unitless properties
+	cssNumber: {
+		"columnCount": true,
+		"fillOpacity": true,
+		"flexGrow": true,
+		"flexShrink": true,
+		"fontWeight": true,
+		"lineHeight": true,
+		"opacity": true,
+		"order": true,
+		"orphans": true,
+		"widows": true,
+		"zIndex": true,
+		"zoom": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {
+		// normalize float css property
+		"float": support.cssFloat ? "cssFloat" : "styleFloat"
+	},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, type, hooks,
+			origName = jQuery.camelCase( name ),
+			style = elem.style;
+
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			type = typeof value;
+
+			// convert relative number strings (+= or -=) to relative numbers. #7345
+			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+				// Fixes bug #9237
+				type = "number";
+			}
+
+			// Make sure that null and NaN values aren't set. See: #7116
+			if ( value == null || value !== value ) {
+				return;
+			}
+
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
+			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+				value += "px";
+			}
+
+			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+			// but it would mean to define eight (for every problematic property) identical functions
+			if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+				style[ name ] = "inherit";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+				// Support: IE
+				// Swallow errors from 'invalid' CSS values (#5509)
+				try {
+					style[ name ] = value;
+				} catch(e) {}
+			}
+
+		} else {
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, extra, styles ) {
+		var num, val, hooks,
+			origName = jQuery.camelCase( name );
+
+		// Make sure that we're working with the right name
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks ) {
+			val = hooks.get( elem, true, extra );
+		}
+
+		// Otherwise, if a way to get the computed value exists, use that
+		if ( val === undefined ) {
+			val = curCSS( elem, name, styles );
+		}
+
+		//convert "normal" to computed value
+		if ( val === "normal" && name in cssNormalTransform ) {
+			val = cssNormalTransform[ name ];
+		}
+
+		// Return, converting to number if forced or a qualifier was provided and val looks numeric
+		if ( extra === "" || extra ) {
+			num = parseFloat( val );
+			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+		}
+		return val;
+	}
+});
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+	jQuery.cssHooks[ name ] = {
+		get: function( elem, computed, extra ) {
+			if ( computed ) {
+				// certain elements can have dimension info if we invisibly show them
+				// however, it must have a current display style that would benefit from this
+				return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
+					jQuery.swap( elem, cssShow, function() {
+						return getWidthOrHeight( elem, name, extra );
+					}) :
+					getWidthOrHeight( elem, name, extra );
+			}
+		},
+
+		set: function( elem, value, extra ) {
+			var styles = extra && getStyles( elem );
+			return setPositiveNumber( elem, value, extra ?
+				augmentWidthOrHeight(
+					elem,
+					name,
+					extra,
+					support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+					styles
+				) : 0
+			);
+		}
+	};
+});
+
+if ( !support.opacity ) {
+	jQuery.cssHooks.opacity = {
+		get: function( elem, computed ) {
+			// IE uses filters for opacity
+			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+				computed ? "1" : "";
+		},
+
+		set: function( elem, value ) {
+			var style = elem.style,
+				currentStyle = elem.currentStyle,
+				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+				filter = currentStyle && currentStyle.filter || style.filter || "";
+
+			// IE has trouble with opacity if it does not have layout
+			// Force it by setting the zoom level
+			style.zoom = 1;
+
+			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+			// if value === "", then remove inline opacity #12685
+			if ( ( value >= 1 || value === "" ) &&
+					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+					style.removeAttribute ) {
+
+				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+				// if "filter:" is present at all, clearType is disabled, we want to avoid this
+				// style.removeAttribute is IE Only, but so apparently is this code path...
+				style.removeAttribute( "filter" );
+
+				// if there is no filter style applied in a css rule or unset inline opacity, we are done
+				if ( value === "" || currentStyle && !currentStyle.filter ) {
+					return;
+				}
+			}
+
+			// otherwise, set new filter values
+			style.filter = ralpha.test( filter ) ?
+				filter.replace( ralpha, opacity ) :
+				filter + " " + opacity;
+		}
+	};
+}
+
+jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
+	function( elem, computed ) {
+		if ( computed ) {
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+			// Work around by temporarily setting element display to inline-block
+			return jQuery.swap( elem, { "display": "inline-block" },
+				curCSS, [ elem, "marginRight" ] );
+		}
+	}
+);
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+	margin: "",
+	padding: "",
+	border: "Width"
+}, function( prefix, suffix ) {
+	jQuery.cssHooks[ prefix + suffix ] = {
+		expand: function( value ) {
+			var i = 0,
+				expanded = {},
+
+				// assumes a single number if not a string
+				parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+			for ( ; i < 4; i++ ) {
+				expanded[ prefix + cssExpand[ i ] + suffix ] =
+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+			}
+
+			return expanded;
+		}
+	};
+
+	if ( !rmargin.test( prefix ) ) {
+		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+	}
+});
+
+jQuery.fn.extend({
+	css: function( name, value ) {
+		return access( this, function( elem, name, value ) {
+			var styles, len,
+				map = {},
+				i = 0;
+
+			if ( jQuery.isArray( name ) ) {
+				styles = getStyles( elem );
+				len = name.length;
+
+				for ( ; i < len; i++ ) {
+					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+				}
+
+				return map;
+			}
+
+			return value !== undefined ?
+				jQuery.style( elem, name, value ) :
+				jQuery.css( elem, name );
+		}, name, value, arguments.length > 1 );
+	},
+	show: function() {
+		return showHide( this, true );
+	},
+	hide: function() {
+		return showHide( this );
+	},
+	toggle: function( state ) {
+		if ( typeof state === "boolean" ) {
+			return state ? this.show() : this.hide();
+		}
+
+		return this.each(function() {
+			if ( isHidden( this ) ) {
+				jQuery( this ).show();
+			} else {
+				jQuery( this ).hide();
+			}
+		});
+	}
+});
+
+
+function Tween( elem, options, prop, end, easing ) {
+	return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+	constructor: Tween,
+	init: function( elem, options, prop, end, easing, unit ) {
+		this.elem = elem;
+		this.prop = prop;
+		this.easing = easing || "swing";
+		this.options = options;
+		this.start = this.now = this.cur();
+		this.end = end;
+		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+	},
+	cur: function() {
+		var hooks = Tween.propHooks[ this.prop ];
+
+		return hooks && hooks.get ?
+			hooks.get( this ) :
+			Tween.propHooks._default.get( this );
+	},
+	run: function( percent ) {
+		var eased,
+			hooks = Tween.propHooks[ this.prop ];
+
+		if ( this.options.duration ) {
+			this.pos = eased = jQuery.easing[ this.easing ](
+				percent, this.options.duration * percent, 0, 1, this.options.duration
+			);
+		} else {
+			this.pos = eased = percent;
+		}
+		this.now = ( this.end - this.start ) * eased + this.start;
+
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		if ( hooks && hooks.set ) {
+			hooks.set( this );
+		} else {
+			Tween.propHooks._default.set( this );
+		}
+		return this;
+	}
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+	_default: {
+		get: function( tween ) {
+			var result;
+
+			if ( tween.elem[ tween.prop ] != null &&
+				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+				return tween.elem[ tween.prop ];
+			}
+
+			// passing an empty string as a 3rd parameter to .css will automatically
+			// attempt a parseFloat and fallback to a string if the parse fails
+			// so, simple values such as "10px" are parsed to Float.
+			// complex values such as "rotate(1rad)" are returned as is.
+			result = jQuery.css( tween.elem, tween.prop, "" );
+			// Empty strings, null, undefined and "auto" are converted to 0.
+			return !result || result === "auto" ? 0 : result;
+		},
+		set: function( tween ) {
+			// use step hook for back compat - use cssHook if its there - use .style if its
+			// available and use plain properties where available
+			if ( jQuery.fx.step[ tween.prop ] ) {
+				jQuery.fx.step[ tween.prop ]( tween );
+			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+			} else {
+				tween.elem[ tween.prop ] = tween.now;
+			}
+		}
+	}
+};
+
+// Support: IE <=9
+// Panic based approach to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+	set: function( tween ) {
+		if ( tween.elem.nodeType && tween.elem.parentNode ) {
+			tween.elem[ tween.prop ] = tween.now;
+		}
+	}
+};
+
+jQuery.easing = {
+	linear: function( p ) {
+		return p;
+	},
+	swing: function( p ) {
+		return 0.5 - Math.cos( p * Math.PI ) / 2;
+	}
+};
+
+jQuery.fx = Tween.prototype.init;
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+
+
+
+var
+	fxNow, timerId,
+	rfxtypes = /^(?:toggle|show|hide)$/,
+	rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
+	rrun = /queueHooks$/,
+	animationPrefilters = [ defaultPrefilter ],
+	tweeners = {
+		"*": [ function( prop, value ) {
+			var tween = this.createTween( prop, value ),
+				target = tween.cur(),
+				parts = rfxnum.exec( value ),
+				unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+				// Starting value computation is required for potential unit mismatches
+				start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
+					rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+				scale = 1,
+				maxIterations = 20;
+
+			if ( start && start[ 3 ] !== unit ) {
+				// Trust units reported by jQuery.css
+				unit = unit || start[ 3 ];
+
+				// Make sure we update the tween properties later on
+				parts = parts || [];
+
+				// Iteratively approximate from a nonzero starting point
+				start = +target || 1;
+
+				do {
+					// If previous iteration zeroed out, double until we get *something*
+					// Use a string for doubling factor so we don't accidentally see scale as unchanged below
+					scale = scale || ".5";
+
+					// Adjust and apply
+					start = start / scale;
+					jQuery.style( tween.elem, prop, start + unit );
+
+				// Update scale, tolerating zero or NaN from tween.cur()
+				// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+				} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+			}
+
+			// Update tween properties
+			if ( parts ) {
+				start = tween.start = +start || +target || 0;
+				tween.unit = unit;
+				// If a +=/-= token was provided, we're doing a relative animation
+				tween.end = parts[ 1 ] ?
+					start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+					+parts[ 2 ];
+			}
+
+			return tween;
+		} ]
+	};
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+	setTimeout(function() {
+		fxNow = undefined;
+	});
+	return ( fxNow = jQuery.now() );
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+	var which,
+		attrs = { height: type },
+		i = 0;
+
+	// if we include width, step value is 1 to do all cssExpand values,
+	// if we don't include width, step value is 2 to skip over Left and Right
+	includeWidth = includeWidth ? 1 : 0;
+	for ( ; i < 4 ; i += 2 - includeWidth ) {
+		which = cssExpand[ i ];
+		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+	}
+
+	if ( includeWidth ) {
+		attrs.opacity = attrs.width = type;
+	}
+
+	return attrs;
+}
+
+function createTween( value, prop, animation ) {
+	var tween,
+		collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+		index = 0,
+		length = collection.length;
+	for ( ; index < length; index++ ) {
+		if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+			// we're done with this property
+			return tween;
+		}
+	}
+}
+
+function defaultPrefilter( elem, props, opts ) {
+	/* jshint validthis: true */
+	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
+		anim = this,
+		orig = {},
+		style = elem.style,
+		hidden = elem.nodeType && isHidden( elem ),
+		dataShow = jQuery._data( elem, "fxshow" );
+
+	// handle queue: false promises
+	if ( !opts.queue ) {
+		hooks = jQuery._queueHooks( elem, "fx" );
+		if ( hooks.unqueued == null ) {
+			hooks.unqueued = 0;
+			oldfire = hooks.empty.fire;
+			hooks.empty.fire = function() {
+				if ( !hooks.unqueued ) {
+					oldfire();
+				}
+			};
+		}
+		hooks.unqueued++;
+
+		anim.always(function() {
+			// doing this makes sure that the complete handler will be called
+			// before this completes
+			anim.always(function() {
+				hooks.unqueued--;
+				if ( !jQuery.queue( elem, "fx" ).length ) {
+					hooks.empty.fire();
+				}
+			});
+		});
+	}
+
+	// height/width overflow pass
+	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+		// Make sure that nothing sneaks out
+		// Record all 3 overflow attributes because IE does not
+		// change the overflow attribute when overflowX and
+		// overflowY are set to the same value
+		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+		// Set display property to inline-block for height/width
+		// animations on inline elements that are having width/height animated
+		display = jQuery.css( elem, "display" );
+
+		// Test default display if display is currently "none"
+		checkDisplay = display === "none" ?
+			jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
+
+		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
+
+			// inline-level elements accept inline-block;
+			// block-level elements need to be inline with layout
+			if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
+				style.display = "inline-block";
+			} else {
+				style.zoom = 1;
+			}
+		}
+	}
+
+	if ( opts.overflow ) {
+		style.overflow = "hidden";
+		if ( !support.shrinkWrapBlocks() ) {
+			anim.always(function() {
+				style.overflow = opts.overflow[ 0 ];
+				style.overflowX = opts.overflow[ 1 ];
+				style.overflowY = opts.overflow[ 2 ];
+			});
+		}
+	}
+
+	// show/hide pass
+	for ( prop in props ) {
+		value = props[ prop ];
+		if ( rfxtypes.exec( value ) ) {
+			delete props[ prop ];
+			toggle = toggle || value === "toggle";
+			if ( value === ( hidden ? "hide" : "show" ) ) {
+
+				// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
+				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+					hidden = true;
+				} else {
+					continue;
+				}
+			}
+			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+
+		// Any non-fx value stops us from restoring the original display value
+		} else {
+			display = undefined;
+		}
+	}
+
+	if ( !jQuery.isEmptyObject( orig ) ) {
+		if ( dataShow ) {
+			if ( "hidden" in dataShow ) {
+				hidden = dataShow.hidden;
+			}
+		} else {
+			dataShow = jQuery._data( elem, "fxshow", {} );
+		}
+
+		// store state if its toggle - enables .stop().toggle() to "reverse"
+		if ( toggle ) {
+			dataShow.hidden = !hidden;
+		}
+		if ( hidden ) {
+			jQuery( elem ).show();
+		} else {
+			anim.done(function() {
+				jQuery( elem ).hide();
+			});
+		}
+		anim.done(function() {
+			var prop;
+			jQuery._removeData( elem, "fxshow" );
+			for ( prop in orig ) {
+				jQuery.style( elem, prop, orig[ prop ] );
+			}
+		});
+		for ( prop in orig ) {
+			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+
+			if ( !( prop in dataShow ) ) {
+				dataShow[ prop ] = tween.start;
+				if ( hidden ) {
+					tween.end = tween.start;
+					tween.start = prop === "width" || prop === "height" ? 1 : 0;
+				}
+			}
+		}
+
+	// If this is a noop like .hide().hide(), restore an overwritten display value
+	} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
+		style.display = display;
+	}
+}
+
+function propFilter( props, specialEasing ) {
+	var index, name, easing, value, hooks;
+
+	// camelCase, specialEasing and expand cssHook pass
+	for ( index in props ) {
+		name = jQuery.camelCase( index );
+		easing = specialEasing[ name ];
+		value = props[ index ];
+		if ( jQuery.isArray( value ) ) {
+			easing = value[ 1 ];
+			value = props[ index ] = value[ 0 ];
+		}
+
+		if ( index !== name ) {
+			props[ name ] = value;
+			delete props[ index ];
+		}
+
+		hooks = jQuery.cssHooks[ name ];
+		if ( hooks && "expand" in hooks ) {
+			value = hooks.expand( value );
+			delete props[ name ];
+
+			// not quite $.extend, this wont overwrite keys already present.
+			// also - reusing 'index' from above because we have the correct "name"
+			for ( index in value ) {
+				if ( !( index in props ) ) {
+					props[ index ] = value[ index ];
+					specialEasing[ index ] = easing;
+				}
+			}
+		} else {
+			specialEasing[ name ] = easing;
+		}
+	}
+}
+
+function Animation( elem, properties, options ) {
+	var result,
+		stopped,
+		index = 0,
+		length = animationPrefilters.length,
+		deferred = jQuery.Deferred().always( function() {
+			// don't match elem in the :animated selector
+			delete tick.elem;
+		}),
+		tick = function() {
+			if ( stopped ) {
+				return false;
+			}
+			var currentTime = fxNow || createFxNow(),
+				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+				// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+				temp = remaining / animation.duration || 0,
+				percent = 1 - temp,
+				index = 0,
+				length = animation.tweens.length;
+
+			for ( ; index < length ; index++ ) {
+				animation.tweens[ index ].run( percent );
+			}
+
+			deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+			if ( percent < 1 && length ) {
+				return remaining;
+			} else {
+				deferred.resolveWith( elem, [ animation ] );
+				return false;
+			}
+		},
+		animation = deferred.promise({
+			elem: elem,
+			props: jQuery.extend( {}, properties ),
+			opts: jQuery.extend( true, { specialEasing: {} }, options ),
+			originalProperties: properties,
+			originalOptions: options,
+			startTime: fxNow || createFxNow(),
+			duration: options.duration,
+			tweens: [],
+			createTween: function( prop, end ) {
+				var tween = jQuery.Tween( elem, animation.opts, prop, end,
+						animation.opts.specialEasing[ prop ] || animation.opts.easing );
+				animation.tweens.push( tween );
+				return tween;
+			},
+			stop: function( gotoEnd ) {
+				var index = 0,
+					// if we are going to the end, we want to run all the tweens
+					// otherwise we skip this part
+					length = gotoEnd ? animation.tweens.length : 0;
+				if ( stopped ) {
+					return this;
+				}
+				stopped = true;
+				for ( ; index < length ; index++ ) {
+					animation.tweens[ index ].run( 1 );
+				}
+
+				// resolve when we played the last frame
+				// otherwise, reject
+				if ( gotoEnd ) {
+					deferred.resolveWith( elem, [ animation, gotoEnd ] );
+				} else {
+					deferred.rejectWith( elem, [ animation, gotoEnd ] );
+				}
+				return this;
+			}
+		}),
+		props = animation.props;
+
+	propFilter( props, animation.opts.specialEasing );
+
+	for ( ; index < length ; index++ ) {
+		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+		if ( result ) {
+			return result;
+		}
+	}
+
+	jQuery.map( props, createTween, animation );
+
+	if ( jQuery.isFunction( animation.opts.start ) ) {
+		animation.opts.start.call( elem, animation );
+	}
+
+	jQuery.fx.timer(
+		jQuery.extend( tick, {
+			elem: elem,
+			anim: animation,
+			queue: animation.opts.queue
+		})
+	);
+
+	// attach callbacks from options
+	return animation.progress( animation.opts.progress )
+		.done( animation.opts.done, animation.opts.complete )
+		.fail( animation.opts.fail )
+		.always( animation.opts.always );
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+	tweener: function( props, callback ) {
+		if ( jQuery.isFunction( props ) ) {
+			callback = props;
+			props = [ "*" ];
+		} else {
+			props = props.split(" ");
+		}
+
+		var prop,
+			index = 0,
+			length = props.length;
+
+		for ( ; index < length ; index++ ) {
+			prop = props[ index ];
+			tweeners[ prop ] = tweeners[ prop ] || [];
+			tweeners[ prop ].unshift( callback );
+		}
+	},
+
+	prefilter: function( callback, prepend ) {
+		if ( prepend ) {
+			animationPrefilters.unshift( callback );
+		} else {
+			animationPrefilters.push( callback );
+		}
+	}
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+		complete: fn || !fn && easing ||
+			jQuery.isFunction( speed ) && speed,
+		duration: speed,
+		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+	};
+
+	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+	// normalize opt.queue - true/undefined/null -> "fx"
+	if ( opt.queue == null || opt.queue === true ) {
+		opt.queue = "fx";
+	}
+
+	// Queueing
+	opt.old = opt.complete;
+
+	opt.complete = function() {
+		if ( jQuery.isFunction( opt.old ) ) {
+			opt.old.call( this );
+		}
+
+		if ( opt.queue ) {
+			jQuery.dequeue( this, opt.queue );
+		}
+	};
+
+	return opt;
+};
+
+jQuery.fn.extend({
+	fadeTo: function( speed, to, easing, callback ) {
+
+		// show any hidden elements after setting opacity to 0
+		return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+			// animate to the value specified
+			.end().animate({ opacity: to }, speed, easing, callback );
+	},
+	animate: function( prop, speed, easing, callback ) {
+		var empty = jQuery.isEmptyObject( prop ),
+			optall = jQuery.speed( speed, easing, callback ),
+			doAnimation = function() {
+				// Operate on a copy of prop so per-property easing won't be lost
+				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+				// Empty animations, or finishing resolves immediately
+				if ( empty || jQuery._data( this, "finish" ) ) {
+					anim.stop( true );
+				}
+			};
+			doAnimation.finish = doAnimation;
+
+		return empty || optall.queue === false ?
+			this.each( doAnimation ) :
+			this.queue( optall.queue, doAnimation );
+	},
+	stop: function( type, clearQueue, gotoEnd ) {
+		var stopQueue = function( hooks ) {
+			var stop = hooks.stop;
+			delete hooks.stop;
+			stop( gotoEnd );
+		};
+
+		if ( typeof type !== "string" ) {
+			gotoEnd = clearQueue;
+			clearQueue = type;
+			type = undefined;
+		}
+		if ( clearQueue && type !== false ) {
+			this.queue( type || "fx", [] );
+		}
+
+		return this.each(function() {
+			var dequeue = true,
+				index = type != null && type + "queueHooks",
+				timers = jQuery.timers,
+				data = jQuery._data( this );
+
+			if ( index ) {
+				if ( data[ index ] && data[ index ].stop ) {
+					stopQueue( data[ index ] );
+				}
+			} else {
+				for ( index in data ) {
+					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+						stopQueue( data[ index ] );
+					}
+				}
+			}
+
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+					timers[ index ].anim.stop( gotoEnd );
+					dequeue = false;
+					timers.splice( index, 1 );
+				}
+			}
+
+			// start the next in the queue if the last step wasn't forced
+			// timers currently will call their complete callbacks, which will dequeue
+			// but only if they were gotoEnd
+			if ( dequeue || !gotoEnd ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	},
+	finish: function( type ) {
+		if ( type !== false ) {
+			type = type || "fx";
+		}
+		return this.each(function() {
+			var index,
+				data = jQuery._data( this ),
+				queue = data[ type + "queue" ],
+				hooks = data[ type + "queueHooks" ],
+				timers = jQuery.timers,
+				length = queue ? queue.length : 0;
+
+			// enable finishing flag on private data
+			data.finish = true;
+
+			// empty the queue first
+			jQuery.queue( this, type, [] );
+
+			if ( hooks && hooks.stop ) {
+				hooks.stop.call( this, true );
+			}
+
+			// look for any active animations, and finish them
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+					timers[ index ].anim.stop( true );
+					timers.splice( index, 1 );
+				}
+			}
+
+			// look for any animations in the old queue and finish them
+			for ( index = 0; index < length; index++ ) {
+				if ( queue[ index ] && queue[ index ].finish ) {
+					queue[ index ].finish.call( this );
+				}
+			}
+
+			// turn off finishing flag
+			delete data.finish;
+		});
+	}
+});
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+	var cssFn = jQuery.fn[ name ];
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return speed == null || typeof speed === "boolean" ?
+			cssFn.apply( this, arguments ) :
+			this.animate( genFx( name, true ), speed, easing, callback );
+	};
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show"),
+	slideUp: genFx("hide"),
+	slideToggle: genFx("toggle"),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" },
+	fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return this.animate( props, speed, easing, callback );
+	};
+});
+
+jQuery.timers = [];
+jQuery.fx.tick = function() {
+	var timer,
+		timers = jQuery.timers,
+		i = 0;
+
+	fxNow = jQuery.now();
+
+	for ( ; i < timers.length; i++ ) {
+		timer = timers[ i ];
+		// Checks the timer has not already been removed
+		if ( !timer() && timers[ i ] === timer ) {
+			timers.splice( i--, 1 );
+		}
+	}
+
+	if ( !timers.length ) {
+		jQuery.fx.stop();
+	}
+	fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+	jQuery.timers.push( timer );
+	if ( timer() ) {
+		jQuery.fx.start();
+	} else {
+		jQuery.timers.pop();
+	}
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+	if ( !timerId ) {
+		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+	}
+};
+
+jQuery.fx.stop = function() {
+	clearInterval( timerId );
+	timerId = null;
+};
+
+jQuery.fx.speeds = {
+	slow: 600,
+	fast: 200,
+	// Default speed
+	_default: 400
+};
+
+
+// Based off of the plugin by Clint Helfers, with permission.
+// http://blindsignals.com/index.php/2009/07/jquery-delay/
+jQuery.fn.delay = function( time, type ) {
+	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+	type = type || "fx";
+
+	return this.queue( type, function( next, hooks ) {
+		var timeout = setTimeout( next, time );
+		hooks.stop = function() {
+			clearTimeout( timeout );
+		};
+	});
+};
+
+
+(function() {
+	// Minified: var a,b,c,d,e
+	var input, div, select, a, opt;
+
+	// Setup
+	div = document.createElement( "div" );
+	div.setAttribute( "className", "t" );
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+	a = div.getElementsByTagName("a")[ 0 ];
+
+	// First batch of tests.
+	select = document.createElement("select");
+	opt = select.appendChild( document.createElement("option") );
+	input = div.getElementsByTagName("input")[ 0 ];
+
+	a.style.cssText = "top:1px";
+
+	// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+	support.getSetAttribute = div.className !== "t";
+
+	// Get the style information from getAttribute
+	// (IE uses .cssText instead)
+	support.style = /top/.test( a.getAttribute("style") );
+
+	// Make sure that URLs aren't manipulated
+	// (IE normalizes it by default)
+	support.hrefNormalized = a.getAttribute("href") === "/a";
+
+	// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+	support.checkOn = !!input.value;
+
+	// Make sure that a selected-by-default option has a working selected property.
+	// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+	support.optSelected = opt.selected;
+
+	// Tests for enctype support on a form (#6743)
+	support.enctype = !!document.createElement("form").enctype;
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as disabled)
+	select.disabled = true;
+	support.optDisabled = !opt.disabled;
+
+	// Support: IE8 only
+	// Check if we can trust getAttribute("value")
+	input = document.createElement( "input" );
+	input.setAttribute( "value", "" );
+	support.input = input.getAttribute( "value" ) === "";
+
+	// Check if an input maintains its value after becoming a radio
+	input.value = "t";
+	input.setAttribute( "type", "radio" );
+	support.radioValue = input.value === "t";
+})();
+
+
+var rreturn = /\r/g;
+
+jQuery.fn.extend({
+	val: function( value ) {
+		var hooks, ret, isFunction,
+			elem = this[0];
+
+		if ( !arguments.length ) {
+			if ( elem ) {
+				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+					return ret;
+				}
+
+				ret = elem.value;
+
+				return typeof ret === "string" ?
+					// handle most common string cases
+					ret.replace(rreturn, "") :
+					// handle cases where value is null/undef or number
+					ret == null ? "" : ret;
+			}
+
+			return;
+		}
+
+		isFunction = jQuery.isFunction( value );
+
+		return this.each(function( i ) {
+			var val;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call( this, i, jQuery( this ).val() );
+			} else {
+				val = value;
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray( val ) ) {
+				val = jQuery.map( val, function( value ) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+			// If set returns undefined, fall back to normal setting
+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	valHooks: {
+		option: {
+			get: function( elem ) {
+				var val = jQuery.find.attr( elem, "value" );
+				return val != null ?
+					val :
+					// Support: IE10-11+
+					// option.text throws exceptions (#14686, #14858)
+					jQuery.trim( jQuery.text( elem ) );
+			}
+		},
+		select: {
+			get: function( elem ) {
+				var value, option,
+					options = elem.options,
+					index = elem.selectedIndex,
+					one = elem.type === "select-one" || index < 0,
+					values = one ? null : [],
+					max = one ? index + 1 : options.length,
+					i = index < 0 ?
+						max :
+						one ? index : 0;
+
+				// Loop through all the selected options
+				for ( ; i < max; i++ ) {
+					option = options[ i ];
+
+					// oldIE doesn't update selected after form reset (#2551)
+					if ( ( option.selected || i === index ) &&
+							// Don't return options that are disabled or in a disabled optgroup
+							( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+						// Get the specific value for the option
+						value = jQuery( option ).val();
+
+						// We don't need an array for one selects
+						if ( one ) {
+							return value;
+						}
+
+						// Multi-Selects return an array
+						values.push( value );
+					}
+				}
+
+				return values;
+			},
+
+			set: function( elem, value ) {
+				var optionSet, option,
+					options = elem.options,
+					values = jQuery.makeArray( value ),
+					i = options.length;
+
+				while ( i-- ) {
+					option = options[ i ];
+
+					if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
+
+						// Support: IE6
+						// When new option element is added to select box we need to
+						// force reflow of newly added node in order to workaround delay
+						// of initialization properties
+						try {
+							option.selected = optionSet = true;
+
+						} catch ( _ ) {
+
+							// Will be executed only in IE6
+							option.scrollHeight;
+						}
+
+					} else {
+						option.selected = false;
+					}
+				}
+
+				// Force browsers to behave consistently when non-matching value is set
+				if ( !optionSet ) {
+					elem.selectedIndex = -1;
+				}
+
+				return options;
+			}
+		}
+	}
+});
+
+// Radios and checkboxes getter/setter
+jQuery.each([ "radio", "checkbox" ], function() {
+	jQuery.valHooks[ this ] = {
+		set: function( elem, value ) {
+			if ( jQuery.isArray( value ) ) {
+				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+			}
+		}
+	};
+	if ( !support.checkOn ) {
+		jQuery.valHooks[ this ].get = function( elem ) {
+			// Support: Webkit
+			// "" is returned instead of "on" if a value isn't specified
+			return elem.getAttribute("value") === null ? "on" : elem.value;
+		};
+	}
+});
+
+
+
+
+var nodeHook, boolHook,
+	attrHandle = jQuery.expr.attrHandle,
+	ruseDefault = /^(?:checked|selected)$/i,
+	getSetAttribute = support.getSetAttribute,
+	getSetInput = support.input;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return access( this, jQuery.attr, name, value, arguments.length > 1 );
+	},
+
+	removeAttr: function( name ) {
+		return this.each(function() {
+			jQuery.removeAttr( this, name );
+		});
+	}
+});
+
+jQuery.extend({
+	attr: function( elem, name, value ) {
+		var hooks, ret,
+			nType = elem.nodeType;
+
+		// don't get/set attributes on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( typeof elem.getAttribute === strundefined ) {
+			return jQuery.prop( elem, name, value );
+		}
+
+		// All attributes are lowercase
+		// Grab necessary hook if one is defined
+		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+			name = name.toLowerCase();
+			hooks = jQuery.attrHooks[ name ] ||
+				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
+		}
+
+		if ( value !== undefined ) {
+
+			if ( value === null ) {
+				jQuery.removeAttr( elem, name );
+
+			} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				elem.setAttribute( name, value + "" );
+				return value;
+			}
+
+		} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+			return ret;
+
+		} else {
+			ret = jQuery.find.attr( elem, name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return ret == null ?
+				undefined :
+				ret;
+		}
+	},
+
+	removeAttr: function( elem, value ) {
+		var name, propName,
+			i = 0,
+			attrNames = value && value.match( rnotwhite );
+
+		if ( attrNames && elem.nodeType === 1 ) {
+			while ( (name = attrNames[i++]) ) {
+				propName = jQuery.propFix[ name ] || name;
+
+				// Boolean attributes get special treatment (#10870)
+				if ( jQuery.expr.match.bool.test( name ) ) {
+					// Set corresponding property to false
+					if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+						elem[ propName ] = false;
+					// Support: IE<9
+					// Also clear defaultChecked/defaultSelected (if appropriate)
+					} else {
+						elem[ jQuery.camelCase( "default-" + name ) ] =
+							elem[ propName ] = false;
+					}
+
+				// See #9699 for explanation of this approach (setting first, then removal)
+				} else {
+					jQuery.attr( elem, name, "" );
+				}
+
+				elem.removeAttribute( getSetAttribute ? name : propName );
+			}
+		}
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+					// Setting the type on a radio button after the value resets the value in IE6-9
+					// Reset value to default in case type is set after value during creation
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return value;
+				}
+			}
+		}
+	}
+});
+
+// Hook for boolean attributes
+boolHook = {
+	set: function( elem, value, name ) {
+		if ( value === false ) {
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+			// IE<8 needs the *property* name
+			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+		// Use defaultChecked and defaultSelected for oldIE
+		} else {
+			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+		}
+
+		return name;
+	}
+};
+
+// Retrieve booleans specially
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+
+	var getter = attrHandle[ name ] || jQuery.find.attr;
+
+	attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
+		function( elem, name, isXML ) {
+			var ret, handle;
+			if ( !isXML ) {
+				// Avoid an infinite loop by temporarily removing this function from the getter
+				handle = attrHandle[ name ];
+				attrHandle[ name ] = ret;
+				ret = getter( elem, name, isXML ) != null ?
+					name.toLowerCase() :
+					null;
+				attrHandle[ name ] = handle;
+			}
+			return ret;
+		} :
+		function( elem, name, isXML ) {
+			if ( !isXML ) {
+				return elem[ jQuery.camelCase( "default-" + name ) ] ?
+					name.toLowerCase() :
+					null;
+			}
+		};
+});
+
+// fix oldIE attroperties
+if ( !getSetInput || !getSetAttribute ) {
+	jQuery.attrHooks.value = {
+		set: function( elem, value, name ) {
+			if ( jQuery.nodeName( elem, "input" ) ) {
+				// Does not return so that setAttribute is also used
+				elem.defaultValue = value;
+			} else {
+				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
+				return nodeHook && nodeHook.set( elem, value, name );
+			}
+		}
+	};
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+	// Use this for any attribute in IE6/7
+	// This fixes almost every IE6/7 issue
+	nodeHook = {
+		set: function( elem, value, name ) {
+			// Set the existing or create a new attribute node
+			var ret = elem.getAttributeNode( name );
+			if ( !ret ) {
+				elem.setAttributeNode(
+					(ret = elem.ownerDocument.createAttribute( name ))
+				);
+			}
+
+			ret.value = value += "";
+
+			// Break association with cloned elements by also using setAttribute (#9646)
+			if ( name === "value" || value === elem.getAttribute( name ) ) {
+				return value;
+			}
+		}
+	};
+
+	// Some attributes are constructed with empty-string values when not defined
+	attrHandle.id = attrHandle.name = attrHandle.coords =
+		function( elem, name, isXML ) {
+			var ret;
+			if ( !isXML ) {
+				return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
+					ret.value :
+					null;
+			}
+		};
+
+	// Fixing value retrieval on a button requires this module
+	jQuery.valHooks.button = {
+		get: function( elem, name ) {
+			var ret = elem.getAttributeNode( name );
+			if ( ret && ret.specified ) {
+				return ret.value;
+			}
+		},
+		set: nodeHook.set
+	};
+
+	// Set contenteditable to false on removals(#10429)
+	// Setting to empty string throws an error as an invalid value
+	jQuery.attrHooks.contenteditable = {
+		set: function( elem, value, name ) {
+			nodeHook.set( elem, value === "" ? false : value, name );
+		}
+	};
+
+	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
+	// This is for removals
+	jQuery.each([ "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = {
+			set: function( elem, value ) {
+				if ( value === "" ) {
+					elem.setAttribute( name, "auto" );
+					return value;
+				}
+			}
+		};
+	});
+}
+
+if ( !support.style ) {
+	jQuery.attrHooks.style = {
+		get: function( elem ) {
+			// Return undefined in the case of empty string
+			// Note: IE uppercases css property names, but if we were to .toLowerCase()
+			// .cssText, that would destroy case senstitivity in URL's, like in "background"
+			return elem.style.cssText || undefined;
+		},
+		set: function( elem, value ) {
+			return ( elem.style.cssText = value + "" );
+		}
+	};
+}
+
+
+
+
+var rfocusable = /^(?:input|select|textarea|button|object)$/i,
+	rclickable = /^(?:a|area)$/i;
+
+jQuery.fn.extend({
+	prop: function( name, value ) {
+		return access( this, jQuery.prop, name, value, arguments.length > 1 );
+	},
+
+	removeProp: function( name ) {
+		name = jQuery.propFix[ name ] || name;
+		return this.each(function() {
+			// try/catch handles cases where IE balks (such as removing a property on window)
+			try {
+				this[ name ] = undefined;
+				delete this[ name ];
+			} catch( e ) {}
+		});
+	}
+});
+
+jQuery.extend({
+	propFix: {
+		"for": "htmlFor",
+		"class": "className"
+	},
+
+	prop: function( elem, name, value ) {
+		var ret, hooks, notxml,
+			nType = elem.nodeType;
+
+		// don't get/set properties on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		if ( notxml ) {
+			// Fix name and attach hooks
+			name = jQuery.propFix[ name ] || name;
+			hooks = jQuery.propHooks[ name ];
+		}
+
+		if ( value !== undefined ) {
+			return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
+				ret :
+				( elem[ name ] = value );
+
+		} else {
+			return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
+				ret :
+				elem[ name ];
+		}
+	},
+
+	propHooks: {
+		tabIndex: {
+			get: function( elem ) {
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				// Use proper attribute retrieval(#12072)
+				var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+				return tabindex ?
+					parseInt( tabindex, 10 ) :
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+						0 :
+						-1;
+			}
+		}
+	}
+});
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !support.hrefNormalized ) {
+	// href/src property should get the full normalized URL (#10299/#12915)
+	jQuery.each([ "href", "src" ], function( i, name ) {
+		jQuery.propHooks[ name ] = {
+			get: function( elem ) {
+				return elem.getAttribute( name, 4 );
+			}
+		};
+	});
+}
+
+// Support: Safari, IE9+
+// mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !support.optSelected ) {
+	jQuery.propHooks.selected = {
+		get: function( elem ) {
+			var parent = elem.parentNode;
+
+			if ( parent ) {
+				parent.selectedIndex;
+
+				// Make sure that it also works with optgroups, see #5701
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+			return null;
+		}
+	};
+}
+
+jQuery.each([
+	"tabIndex",
+	"readOnly",
+	"maxLength",
+	"cellSpacing",
+	"cellPadding",
+	"rowSpan",
+	"colSpan",
+	"useMap",
+	"frameBorder",
+	"contentEditable"
+], function() {
+	jQuery.propFix[ this.toLowerCase() ] = this;
+});
+
+// IE6/7 call enctype encoding
+if ( !support.enctype ) {
+	jQuery.propFix.enctype = "encoding";
+}
+
+
+
+
+var rclass = /[\t\r\n\f]/g;
+
+jQuery.fn.extend({
+	addClass: function( value ) {
+		var classes, elem, cur, clazz, j, finalValue,
+			i = 0,
+			len = this.length,
+			proceed = typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).addClass( value.call( this, j, this.className ) );
+			});
+		}
+
+		if ( proceed ) {
+			// The disjunction here is for better compressibility (see removeClass)
+			classes = ( value || "" ).match( rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					" "
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+							cur += clazz + " ";
+						}
+					}
+
+					// only assign if different to avoid unneeded rendering.
+					finalValue = jQuery.trim( cur );
+					if ( elem.className !== finalValue ) {
+						elem.className = finalValue;
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		var classes, elem, cur, clazz, j, finalValue,
+			i = 0,
+			len = this.length,
+			proceed = arguments.length === 0 || typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).removeClass( value.call( this, j, this.className ) );
+			});
+		}
+		if ( proceed ) {
+			classes = ( value || "" ).match( rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				// This expression is here for better compressibility (see addClass)
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					""
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						// Remove *all* instances
+						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+							cur = cur.replace( " " + clazz + " ", " " );
+						}
+					}
+
+					// only assign if different to avoid unneeded rendering.
+					finalValue = value ? jQuery.trim( cur ) : "";
+					if ( elem.className !== finalValue ) {
+						elem.className = finalValue;
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value;
+
+		if ( typeof stateVal === "boolean" && type === "string" ) {
+			return stateVal ? this.addClass( value ) : this.removeClass( value );
+		}
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( i ) {
+				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className,
+					i = 0,
+					self = jQuery( this ),
+					classNames = value.match( rnotwhite ) || [];
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space separated list
+					if ( self.hasClass( className ) ) {
+						self.removeClass( className );
+					} else {
+						self.addClass( className );
+					}
+				}
+
+			// Toggle whole class name
+			} else if ( type === strundefined || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery._data( this, "__className__", this.className );
+				}
+
+				// If the element has a class name or if we're passed "false",
+				// then remove the whole classname (if there was one, the above saved it).
+				// Otherwise bring back whatever was previously saved (if anything),
+				// falling back to the empty string if nothing was stored.
+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ",
+			i = 0,
+			l = this.length;
+		for ( ; i < l; i++ ) {
+			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+});
+
+
+
+
+// Return jQuery for attributes-only inclusion
+
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( data, fn ) {
+		return arguments.length > 0 ?
+			this.on( name, null, data, fn ) :
+			this.trigger( name );
+	};
+});
+
+jQuery.fn.extend({
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	},
+
+	bind: function( types, data, fn ) {
+		return this.on( types, null, data, fn );
+	},
+	unbind: function( types, fn ) {
+		return this.off( types, null, fn );
+	},
+
+	delegate: function( selector, types, data, fn ) {
+		return this.on( types, selector, data, fn );
+	},
+	undelegate: function( selector, types, fn ) {
+		// ( namespace ) or ( selector, types [, fn] )
+		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+	}
+});
+
+
+var nonce = jQuery.now();
+
+var rquery = (/\?/);
+
+
+
+var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
+
+jQuery.parseJSON = function( data ) {
+	// Attempt to parse using the native JSON parser first
+	if ( window.JSON && window.JSON.parse ) {
+		// Support: Android 2.3
+		// Workaround failure to string-cast null input
+		return window.JSON.parse( data + "" );
+	}
+
+	var requireNonComma,
+		depth = null,
+		str = jQuery.trim( data + "" );
+
+	// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
+	// after removing valid tokens
+	return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
+
+		// Force termination if we see a misplaced comma
+		if ( requireNonComma && comma ) {
+			depth = 0;
+		}
+
+		// Perform no more replacements after returning to outermost depth
+		if ( depth === 0 ) {
+			return token;
+		}
+
+		// Commas must not follow "[", "{", or ","
+		requireNonComma = open || comma;
+
+		// Determine new depth
+		// array/object open ("[" or "{"): depth += true - false (increment)
+		// array/object close ("]" or "}"): depth += false - true (decrement)
+		// other cases ("," or primitive): depth += true - true (numeric cast)
+		depth += !close - !open;
+
+		// Remove this token
+		return "";
+	}) ) ?
+		( Function( "return " + str ) )() :
+		jQuery.error( "Invalid JSON: " + data );
+};
+
+
+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+	var xml, tmp;
+	if ( !data || typeof data !== "string" ) {
+		return null;
+	}
+	try {
+		if ( window.DOMParser ) { // Standard
+			tmp = new DOMParser();
+			xml = tmp.parseFromString( data, "text/xml" );
+		} else { // IE
+			xml = new ActiveXObject( "Microsoft.XMLDOM" );
+			xml.async = "false";
+			xml.loadXML( data );
+		}
+	} catch( e ) {
+		xml = undefined;
+	}
+	if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+		jQuery.error( "Invalid XML: " + data );
+	}
+	return xml;
+};
+
+
+var
+	// Document location
+	ajaxLocParts,
+	ajaxLocation,
+
+	rhash = /#.*$/,
+	rts = /([?&])_=[^&]*/,
+	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+	// #7653, #8125, #8152: local protocol detection
+	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+	rnoContent = /^(?:GET|HEAD)$/,
+	rprotocol = /^\/\//,
+	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
+
+	/* Prefilters
+	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+	 * 2) These are called:
+	 *    - BEFORE asking for a transport
+	 *    - AFTER param serialization (s.data is a string if s.processData is true)
+	 * 3) key is the dataType
+	 * 4) the catchall symbol "*" can be used
+	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+	 */
+	prefilters = {},
+
+	/* Transports bindings
+	 * 1) key is the dataType
+	 * 2) the catchall symbol "*" can be used
+	 * 3) selection will start with transport dataType and THEN go to "*" if needed
+	 */
+	transports = {},
+
+	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+	allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+	ajaxLocation = location.href;
+} catch( e ) {
+	// Use the href attribute of an A element
+	// since IE will modify it given document.location
+	ajaxLocation = document.createElement( "a" );
+	ajaxLocation.href = "";
+	ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+	// dataTypeExpression is optional and defaults to "*"
+	return function( dataTypeExpression, func ) {
+
+		if ( typeof dataTypeExpression !== "string" ) {
+			func = dataTypeExpression;
+			dataTypeExpression = "*";
+		}
+
+		var dataType,
+			i = 0,
+			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
+
+		if ( jQuery.isFunction( func ) ) {
+			// For each dataType in the dataTypeExpression
+			while ( (dataType = dataTypes[i++]) ) {
+				// Prepend if requested
+				if ( dataType.charAt( 0 ) === "+" ) {
+					dataType = dataType.slice( 1 ) || "*";
+					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+				// Otherwise append
+				} else {
+					(structure[ dataType ] = structure[ dataType ] || []).push( func );
+				}
+			}
+		}
+	};
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+	var inspected = {},
+		seekingTransport = ( structure === transports );
+
+	function inspect( dataType ) {
+		var selected;
+		inspected[ dataType ] = true;
+		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+			if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+				options.dataTypes.unshift( dataTypeOrTransport );
+				inspect( dataTypeOrTransport );
+				return false;
+			} else if ( seekingTransport ) {
+				return !( selected = dataTypeOrTransport );
+			}
+		});
+		return selected;
+	}
+
+	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+	var deep, key,
+		flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+	for ( key in src ) {
+		if ( src[ key ] !== undefined ) {
+			( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+		}
+	}
+	if ( deep ) {
+		jQuery.extend( true, target, deep );
+	}
+
+	return target;
+}
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+	var firstDataType, ct, finalDataType, type,
+		contents = s.contents,
+		dataTypes = s.dataTypes;
+
+	// Remove auto dataType and get content-type in the process
+	while ( dataTypes[ 0 ] === "*" ) {
+		dataTypes.shift();
+		if ( ct === undefined ) {
+			ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+		}
+	}
+
+	// Check if we're dealing with a known content-type
+	if ( ct ) {
+		for ( type in contents ) {
+			if ( contents[ type ] && contents[ type ].test( ct ) ) {
+				dataTypes.unshift( type );
+				break;
+			}
+		}
+	}
+
+	// Check to see if we have a response for the expected dataType
+	if ( dataTypes[ 0 ] in responses ) {
+		finalDataType = dataTypes[ 0 ];
+	} else {
+		// Try convertible dataTypes
+		for ( type in responses ) {
+			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+				finalDataType = type;
+				break;
+			}
+			if ( !firstDataType ) {
+				firstDataType = type;
+			}
+		}
+		// Or just use first one
+		finalDataType = finalDataType || firstDataType;
+	}
+
+	// If we found a dataType
+	// We add the dataType to the list if needed
+	// and return the corresponding response
+	if ( finalDataType ) {
+		if ( finalDataType !== dataTypes[ 0 ] ) {
+			dataTypes.unshift( finalDataType );
+		}
+		return responses[ finalDataType ];
+	}
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+	var conv2, current, conv, tmp, prev,
+		converters = {},
+		// Work with a copy of dataTypes in case we need to modify it for conversion
+		dataTypes = s.dataTypes.slice();
+
+	// Create converters map with lowercased keys
+	if ( dataTypes[ 1 ] ) {
+		for ( conv in s.converters ) {
+			converters[ conv.toLowerCase() ] = s.converters[ conv ];
+		}
+	}
+
+	current = dataTypes.shift();
+
+	// Convert to each sequential dataType
+	while ( current ) {
+
+		if ( s.responseFields[ current ] ) {
+			jqXHR[ s.responseFields[ current ] ] = response;
+		}
+
+		// Apply the dataFilter if provided
+		if ( !prev && isSuccess && s.dataFilter ) {
+			response = s.dataFilter( response, s.dataType );
+		}
+
+		prev = current;
+		current = dataTypes.shift();
+
+		if ( current ) {
+
+			// There's only work to do if current dataType is non-auto
+			if ( current === "*" ) {
+
+				current = prev;
+
+			// Convert response if prev dataType is non-auto and differs from current
+			} else if ( prev !== "*" && prev !== current ) {
+
+				// Seek a direct converter
+				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+				// If none found, seek a pair
+				if ( !conv ) {
+					for ( conv2 in converters ) {
+
+						// If conv2 outputs current
+						tmp = conv2.split( " " );
+						if ( tmp[ 1 ] === current ) {
+
+							// If prev can be converted to accepted input
+							conv = converters[ prev + " " + tmp[ 0 ] ] ||
+								converters[ "* " + tmp[ 0 ] ];
+							if ( conv ) {
+								// Condense equivalence converters
+								if ( conv === true ) {
+									conv = converters[ conv2 ];
+
+								// Otherwise, insert the intermediate dataType
+								} else if ( converters[ conv2 ] !== true ) {
+									current = tmp[ 0 ];
+									dataTypes.unshift( tmp[ 1 ] );
+								}
+								break;
+							}
+						}
+					}
+				}
+
+				// Apply converter (if not an equivalence)
+				if ( conv !== true ) {
+
+					// Unless errors are allowed to bubble, catch and return them
+					if ( conv && s[ "throws" ] ) {
+						response = conv( response );
+					} else {
+						try {
+							response = conv( response );
+						} catch ( e ) {
+							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return { state: "success", data: response };
+}
+
+jQuery.extend({
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	ajaxSettings: {
+		url: ajaxLocation,
+		type: "GET",
+		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+		global: true,
+		processData: true,
+		async: true,
+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+		/*
+		timeout: 0,
+		data: null,
+		dataType: null,
+		username: null,
+		password: null,
+		cache: null,
+		throws: false,
+		traditional: false,
+		headers: {},
+		*/
+
+		accepts: {
+			"*": allTypes,
+			text: "text/plain",
+			html: "text/html",
+			xml: "application/xml, text/xml",
+			json: "application/json, text/javascript"
+		},
+
+		contents: {
+			xml: /xml/,
+			html: /html/,
+			json: /json/
+		},
+
+		responseFields: {
+			xml: "responseXML",
+			text: "responseText",
+			json: "responseJSON"
+		},
+
+		// Data converters
+		// Keys separate source (or catchall "*") and destination types with a single space
+		converters: {
+
+			// Convert anything to text
+			"* text": String,
+
+			// Text to html (true = no transformation)
+			"text html": true,
+
+			// Evaluate text as a json expression
+			"text json": jQuery.parseJSON,
+
+			// Parse text as xml
+			"text xml": jQuery.parseXML
+		},
+
+		// For options that shouldn't be deep extended:
+		// you can add your own custom options here if
+		// and when you create one that shouldn't be
+		// deep extended (see ajaxExtend)
+		flatOptions: {
+			url: true,
+			context: true
+		}
+	},
+
+	// Creates a full fledged settings object into target
+	// with both ajaxSettings and settings fields.
+	// If target is omitted, writes into ajaxSettings.
+	ajaxSetup: function( target, settings ) {
+		return settings ?
+
+			// Building a settings object
+			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+			// Extending ajaxSettings
+			ajaxExtend( jQuery.ajaxSettings, target );
+	},
+
+	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+	ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+	// Main method
+	ajax: function( url, options ) {
+
+		// If url is an object, simulate pre-1.5 signature
+		if ( typeof url === "object" ) {
+			options = url;
+			url = undefined;
+		}
+
+		// Force options to be an object
+		options = options || {};
+
+		var // Cross-domain detection vars
+			parts,
+			// Loop variable
+			i,
+			// URL without anti-cache param
+			cacheURL,
+			// Response headers as string
+			responseHeadersString,
+			// timeout handle
+			timeoutTimer,
+
+			// To know if global events are to be dispatched
+			fireGlobals,
+
+			transport,
+			// Response headers
+			responseHeaders,
+			// Create the final options object
+			s = jQuery.ajaxSetup( {}, options ),
+			// Callbacks context
+			callbackContext = s.context || s,
+			// Context for global events is callbackContext if it is a DOM node or jQuery collection
+			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+				jQuery( callbackContext ) :
+				jQuery.event,
+			// Deferreds
+			deferred = jQuery.Deferred(),
+			completeDeferred = jQuery.Callbacks("once memory"),
+			// Status-dependent callbacks
+			statusCode = s.statusCode || {},
+			// Headers (they are sent all at once)
+			requestHeaders = {},
+			requestHeadersNames = {},
+			// The jqXHR state
+			state = 0,
+			// Default abort message
+			strAbort = "canceled",
+			// Fake xhr
+			jqXHR = {
+				readyState: 0,
+
+				// Builds headers hashtable if needed
+				getResponseHeader: function( key ) {
+					var match;
+					if ( state === 2 ) {
+						if ( !responseHeaders ) {
+							responseHeaders = {};
+							while ( (match = rheaders.exec( responseHeadersString )) ) {
+								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+							}
+						}
+						match = responseHeaders[ key.toLowerCase() ];
+					}
+					return match == null ? null : match;
+				},
+
+				// Raw string
+				getAllResponseHeaders: function() {
+					return state === 2 ? responseHeadersString : null;
+				},
+
+				// Caches the header
+				setRequestHeader: function( name, value ) {
+					var lname = name.toLowerCase();
+					if ( !state ) {
+						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+						requestHeaders[ name ] = value;
+					}
+					return this;
+				},
+
+				// Overrides response content-type header
+				overrideMimeType: function( type ) {
+					if ( !state ) {
+						s.mimeType = type;
+					}
+					return this;
+				},
+
+				// Status-dependent callbacks
+				statusCode: function( map ) {
+					var code;
+					if ( map ) {
+						if ( state < 2 ) {
+							for ( code in map ) {
+								// Lazy-add the new callback in a way that preserves old ones
+								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+							}
+						} else {
+							// Execute the appropriate callbacks
+							jqXHR.always( map[ jqXHR.status ] );
+						}
+					}
+					return this;
+				},
+
+				// Cancel the request
+				abort: function( statusText ) {
+					var finalText = statusText || strAbort;
+					if ( transport ) {
+						transport.abort( finalText );
+					}
+					done( 0, finalText );
+					return this;
+				}
+			};
+
+		// Attach deferreds
+		deferred.promise( jqXHR ).complete = completeDeferred.add;
+		jqXHR.success = jqXHR.done;
+		jqXHR.error = jqXHR.fail;
+
+		// Remove hash character (#7531: and string promotion)
+		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+		// Handle falsy url in the settings object (#10093: consistency with old signature)
+		// We also use the url parameter if available
+		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+		// Alias method option to type as per ticket #12004
+		s.type = options.method || options.type || s.method || s.type;
+
+		// Extract dataTypes list
+		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
+
+		// A cross-domain request is in order when we have a protocol:host:port mismatch
+		if ( s.crossDomain == null ) {
+			parts = rurl.exec( s.url.toLowerCase() );
+			s.crossDomain = !!( parts &&
+				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
+						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
+			);
+		}
+
+		// Convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Apply prefilters
+		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+		// If request was aborted inside a prefilter, stop there
+		if ( state === 2 ) {
+			return jqXHR;
+		}
+
+		// We can fire global events as of now if asked to
+		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
+		fireGlobals = jQuery.event && s.global;
+
+		// Watch for a new set of requests
+		if ( fireGlobals && jQuery.active++ === 0 ) {
+			jQuery.event.trigger("ajaxStart");
+		}
+
+		// Uppercase the type
+		s.type = s.type.toUpperCase();
+
+		// Determine if request has content
+		s.hasContent = !rnoContent.test( s.type );
+
+		// Save the URL in case we're toying with the If-Modified-Since
+		// and/or If-None-Match header later on
+		cacheURL = s.url;
+
+		// More options handling for requests with no content
+		if ( !s.hasContent ) {
+
+			// If data is available, append data to url
+			if ( s.data ) {
+				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+				// #9682: remove data so that it's not used in an eventual retry
+				delete s.data;
+			}
+
+			// Add anti-cache in url if needed
+			if ( s.cache === false ) {
+				s.url = rts.test( cacheURL ) ?
+
+					// If there is already a '_' parameter, set its value
+					cacheURL.replace( rts, "$1_=" + nonce++ ) :
+
+					// Otherwise add one to the end
+					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
+			}
+		}
+
+		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+		if ( s.ifModified ) {
+			if ( jQuery.lastModified[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+			}
+			if ( jQuery.etag[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+			}
+		}
+
+		// Set the correct header, if data is being sent
+		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+			jqXHR.setRequestHeader( "Content-Type", s.contentType );
+		}
+
+		// Set the Accepts header for the server, depending on the dataType
+		jqXHR.setRequestHeader(
+			"Accept",
+			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+				s.accepts[ "*" ]
+		);
+
+		// Check for headers option
+		for ( i in s.headers ) {
+			jqXHR.setRequestHeader( i, s.headers[ i ] );
+		}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+			// Abort if not done already and return
+			return jqXHR.abort();
+		}
+
+		// aborting is no longer a cancellation
+		strAbort = "abort";
+
+		// Install callbacks on deferreds
+		for ( i in { success: 1, error: 1, complete: 1 } ) {
+			jqXHR[ i ]( s[ i ] );
+		}
+
+		// Get transport
+		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+		// If no transport, we auto-abort
+		if ( !transport ) {
+			done( -1, "No Transport" );
+		} else {
+			jqXHR.readyState = 1;
+
+			// Send global event
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+			}
+			// Timeout
+			if ( s.async && s.timeout > 0 ) {
+				timeoutTimer = setTimeout(function() {
+					jqXHR.abort("timeout");
+				}, s.timeout );
+			}
+
+			try {
+				state = 1;
+				transport.send( requestHeaders, done );
+			} catch ( e ) {
+				// Propagate exception as error if not done
+				if ( state < 2 ) {
+					done( -1, e );
+				// Simply rethrow otherwise
+				} else {
+					throw e;
+				}
+			}
+		}
+
+		// Callback for when everything is done
+		function done( status, nativeStatusText, responses, headers ) {
+			var isSuccess, success, error, response, modified,
+				statusText = nativeStatusText;
+
+			// Called once
+			if ( state === 2 ) {
+				return;
+			}
+
+			// State is "done" now
+			state = 2;
+
+			// Clear timeout if it exists
+			if ( timeoutTimer ) {
+				clearTimeout( timeoutTimer );
+			}
+
+			// Dereference transport for early garbage collection
+			// (no matter how long the jqXHR object will be used)
+			transport = undefined;
+
+			// Cache response headers
+			responseHeadersString = headers || "";
+
+			// Set readyState
+			jqXHR.readyState = status > 0 ? 4 : 0;
+
+			// Determine if successful
+			isSuccess = status >= 200 && status < 300 || status === 304;
+
+			// Get response data
+			if ( responses ) {
+				response = ajaxHandleResponses( s, jqXHR, responses );
+			}
+
+			// Convert no matter what (that way responseXXX fields are always set)
+			response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+			// If successful, handle type chaining
+			if ( isSuccess ) {
+
+				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+				if ( s.ifModified ) {
+					modified = jqXHR.getResponseHeader("Last-Modified");
+					if ( modified ) {
+						jQuery.lastModified[ cacheURL ] = modified;
+					}
+					modified = jqXHR.getResponseHeader("etag");
+					if ( modified ) {
+						jQuery.etag[ cacheURL ] = modified;
+					}
+				}
+
+				// if no content
+				if ( status === 204 || s.type === "HEAD" ) {
+					statusText = "nocontent";
+
+				// if not modified
+				} else if ( status === 304 ) {
+					statusText = "notmodified";
+
+				// If we have data, let's convert it
+				} else {
+					statusText = response.state;
+					success = response.data;
+					error = response.error;
+					isSuccess = !error;
+				}
+			} else {
+				// We extract error from statusText
+				// then normalize statusText and status for non-aborts
+				error = statusText;
+				if ( status || !statusText ) {
+					statusText = "error";
+					if ( status < 0 ) {
+						status = 0;
+					}
+				}
+			}
+
+			// Set data for the fake xhr object
+			jqXHR.status = status;
+			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+			// Success/Error
+			if ( isSuccess ) {
+				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+			} else {
+				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+			}
+
+			// Status-dependent callbacks
+			jqXHR.statusCode( statusCode );
+			statusCode = undefined;
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+					[ jqXHR, s, isSuccess ? success : error ] );
+			}
+
+			// Complete
+			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+				// Handle the global AJAX counter
+				if ( !( --jQuery.active ) ) {
+					jQuery.event.trigger("ajaxStop");
+				}
+			}
+		}
+
+		return jqXHR;
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get( url, data, callback, "json" );
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get( url, undefined, callback, "script" );
+	}
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+	jQuery[ method ] = function( url, data, callback, type ) {
+		// shift arguments if data argument was omitted
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = undefined;
+		}
+
+		return jQuery.ajax({
+			url: url,
+			type: method,
+			dataType: type,
+			data: data,
+			success: callback
+		});
+	};
+});
+
+
+jQuery._evalUrl = function( url ) {
+	return jQuery.ajax({
+		url: url,
+		type: "GET",
+		dataType: "script",
+		async: false,
+		global: false,
+		"throws": true
+	});
+};
+
+
+jQuery.fn.extend({
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append( this );
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ),
+				contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		var isFunction = jQuery.isFunction( html );
+
+		return this.each(function(i) {
+			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	}
+});
+
+
+jQuery.expr.filters.hidden = function( elem ) {
+	// Support: Opera <= 12.12
+	// Opera reports offsetWidths and offsetHeights less than zero on some elements
+	return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+		(!support.reliableHiddenOffsets() &&
+			((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+};
+
+jQuery.expr.filters.visible = function( elem ) {
+	return !jQuery.expr.filters.hidden( elem );
+};
+
+
+
+
+var r20 = /%20/g,
+	rbracket = /\[\]$/,
+	rCRLF = /\r?\n/g,
+	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+	rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+	var name;
+
+	if ( jQuery.isArray( obj ) ) {
+		// Serialize array item.
+		jQuery.each( obj, function( i, v ) {
+			if ( traditional || rbracket.test( prefix ) ) {
+				// Treat each array item as a scalar.
+				add( prefix, v );
+
+			} else {
+				// Item is non-scalar (array or object), encode its numeric index.
+				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+			}
+		});
+
+	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
+		// Serialize object item.
+		for ( name in obj ) {
+			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+		}
+
+	} else {
+		// Serialize scalar item.
+		add( prefix, obj );
+	}
+}
+
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+	var prefix,
+		s = [],
+		add = function( key, value ) {
+			// If value is a function, invoke it and return its value
+			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+		};
+
+	// Set traditional to true for jQuery <= 1.3.2 behavior.
+	if ( traditional === undefined ) {
+		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+	}
+
+	// If an array was passed in, assume that it is an array of form elements.
+	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+		// Serialize the form elements
+		jQuery.each( a, function() {
+			add( this.name, this.value );
+		});
+
+	} else {
+		// If traditional, encode the "old" way (the way 1.3.2 or older
+		// did it), otherwise encode params recursively.
+		for ( prefix in a ) {
+			buildParams( prefix, a[ prefix ], traditional, add );
+		}
+	}
+
+	// Return the resulting serialization
+	return s.join( "&" ).replace( r20, "+" );
+};
+
+jQuery.fn.extend({
+	serialize: function() {
+		return jQuery.param( this.serializeArray() );
+	},
+	serializeArray: function() {
+		return this.map(function() {
+			// Can add propHook for "elements" to filter or add form elements
+			var elements = jQuery.prop( this, "elements" );
+			return elements ? jQuery.makeArray( elements ) : this;
+		})
+		.filter(function() {
+			var type = this.type;
+			// Use .is(":disabled") so that fieldset[disabled] works
+			return this.name && !jQuery( this ).is( ":disabled" ) &&
+				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+				( this.checked || !rcheckableType.test( type ) );
+		})
+		.map(function( i, elem ) {
+			var val = jQuery( this ).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray( val ) ?
+					jQuery.map( val, function( val ) {
+						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+					}) :
+					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+		}).get();
+	}
+});
+
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
+	// Support: IE6+
+	function() {
+
+		// XHR cannot access local files, always use ActiveX for that case
+		return !this.isLocal &&
+
+			// Support: IE7-8
+			// oldIE XHR does not support non-RFC2616 methods (#13240)
+			// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
+			// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
+			// Although this check for six methods instead of eight
+			// since IE also does not support "trace" and "connect"
+			/^(get|post|head|put|delete|options)$/i.test( this.type ) &&
+
+			createStandardXHR() || createActiveXHR();
+	} :
+	// For all other browsers, use the standard XMLHttpRequest object
+	createStandardXHR;
+
+var xhrId = 0,
+	xhrCallbacks = {},
+	xhrSupported = jQuery.ajaxSettings.xhr();
+
+// Support: IE<10
+// Open requests must be manually aborted on unload (#5280)
+// See https://support.microsoft.com/kb/2856746 for more info
+if ( window.attachEvent ) {
+	window.attachEvent( "onunload", function() {
+		for ( var key in xhrCallbacks ) {
+			xhrCallbacks[ key ]( undefined, true );
+		}
+	});
+}
+
+// Determine support properties
+support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+	jQuery.ajaxTransport(function( options ) {
+		// Cross domain only allowed if supported through XMLHttpRequest
+		if ( !options.crossDomain || support.cors ) {
+
+			var callback;
+
+			return {
+				send: function( headers, complete ) {
+					var i,
+						xhr = options.xhr(),
+						id = ++xhrId;
+
+					// Open the socket
+					xhr.open( options.type, options.url, options.async, options.username, options.password );
+
+					// Apply custom fields if provided
+					if ( options.xhrFields ) {
+						for ( i in options.xhrFields ) {
+							xhr[ i ] = options.xhrFields[ i ];
+						}
+					}
+
+					// Override mime type if needed
+					if ( options.mimeType && xhr.overrideMimeType ) {
+						xhr.overrideMimeType( options.mimeType );
+					}
+
+					// X-Requested-With header
+					// For cross-domain requests, seeing as conditions for a preflight are
+					// akin to a jigsaw puzzle, we simply never set it to be sure.
+					// (it can always be set on a per-request basis or even using ajaxSetup)
+					// For same-domain requests, won't change header if already provided.
+					if ( !options.crossDomain && !headers["X-Requested-With"] ) {
+						headers["X-Requested-With"] = "XMLHttpRequest";
+					}
+
+					// Set headers
+					for ( i in headers ) {
+						// Support: IE<9
+						// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
+						// request header to a null-value.
+						//
+						// To keep consistent with other XHR implementations, cast the value
+						// to string and ignore `undefined`.
+						if ( headers[ i ] !== undefined ) {
+							xhr.setRequestHeader( i, headers[ i ] + "" );
+						}
+					}
+
+					// Do send the request
+					// This may raise an exception which is actually
+					// handled in jQuery.ajax (so no try/catch here)
+					xhr.send( ( options.hasContent && options.data ) || null );
+
+					// Listener
+					callback = function( _, isAbort ) {
+						var status, statusText, responses;
+
+						// Was never called and is aborted or complete
+						if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+							// Clean up
+							delete xhrCallbacks[ id ];
+							callback = undefined;
+							xhr.onreadystatechange = jQuery.noop;
+
+							// Abort manually if needed
+							if ( isAbort ) {
+								if ( xhr.readyState !== 4 ) {
+									xhr.abort();
+								}
+							} else {
+								responses = {};
+								status = xhr.status;
+
+								// Support: IE<10
+								// Accessing binary-data responseText throws an exception
+								// (#11426)
+								if ( typeof xhr.responseText === "string" ) {
+									responses.text = xhr.responseText;
+								}
+
+								// Firefox throws an exception when accessing
+								// statusText for faulty cross-domain requests
+								try {
+									statusText = xhr.statusText;
+								} catch( e ) {
+									// We normalize with Webkit giving an empty statusText
+									statusText = "";
+								}
+
+								// Filter status for non standard behaviors
+
+								// If the request is local and we have data: assume a success
+								// (success with no data won't get notified, that's the best we
+								// can do given current implementations)
+								if ( !status && options.isLocal && !options.crossDomain ) {
+									status = responses.text ? 200 : 404;
+								// IE - #1450: sometimes returns 1223 when it should be 204
+								} else if ( status === 1223 ) {
+									status = 204;
+								}
+							}
+						}
+
+						// Call complete if needed
+						if ( responses ) {
+							complete( status, statusText, responses, xhr.getAllResponseHeaders() );
+						}
+					};
+
+					if ( !options.async ) {
+						// if we're in sync mode we fire the callback
+						callback();
+					} else if ( xhr.readyState === 4 ) {
+						// (IE6 & IE7) if it's in cache and has been
+						// retrieved directly we need to fire the callback
+						setTimeout( callback );
+					} else {
+						// Add to the list of active xhr callbacks
+						xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
+					}
+				},
+
+				abort: function() {
+					if ( callback ) {
+						callback( undefined, true );
+					}
+				}
+			};
+		}
+	});
+}
+
+// Functions to create xhrs
+function createStandardXHR() {
+	try {
+		return new window.XMLHttpRequest();
+	} catch( e ) {}
+}
+
+function createActiveXHR() {
+	try {
+		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+	} catch( e ) {}
+}
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+	accepts: {
+		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+	},
+	contents: {
+		script: /(?:java|ecma)script/
+	},
+	converters: {
+		"text script": function( text ) {
+			jQuery.globalEval( text );
+			return text;
+		}
+	}
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+	if ( s.cache === undefined ) {
+		s.cache = false;
+	}
+	if ( s.crossDomain ) {
+		s.type = "GET";
+		s.global = false;
+	}
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+	// This transport only deals with cross domain requests
+	if ( s.crossDomain ) {
+
+		var script,
+			head = document.head || jQuery("head")[0] || document.documentElement;
+
+		return {
+
+			send: function( _, callback ) {
+
+				script = document.createElement("script");
+
+				script.async = true;
+
+				if ( s.scriptCharset ) {
+					script.charset = s.scriptCharset;
+				}
+
+				script.src = s.url;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+
+						// Remove the script
+						if ( script.parentNode ) {
+							script.parentNode.removeChild( script );
+						}
+
+						// Dereference the script
+						script = null;
+
+						// Callback if not abort
+						if ( !isAbort ) {
+							callback( 200, "success" );
+						}
+					}
+				};
+
+				// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+				// Use native DOM manipulation to avoid our domManip AJAX trickery
+				head.insertBefore( script, head.firstChild );
+			},
+
+			abort: function() {
+				if ( script ) {
+					script.onload( undefined, true );
+				}
+			}
+		};
+	}
+});
+
+
+
+
+var oldCallbacks = [],
+	rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+	jsonp: "callback",
+	jsonpCallback: function() {
+		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+		this[ callback ] = true;
+		return callback;
+	}
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+	var callbackName, overwritten, responseContainer,
+		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+			"url" :
+			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+		);
+
+	// Handle iff the expected data type is "jsonp" or we have a parameter to set
+	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+		// Get callback name, remembering preexisting value associated with it
+		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+			s.jsonpCallback() :
+			s.jsonpCallback;
+
+		// Insert callback into url or form data
+		if ( jsonProp ) {
+			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+		} else if ( s.jsonp !== false ) {
+			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+		}
+
+		// Use data converter to retrieve json after script execution
+		s.converters["script json"] = function() {
+			if ( !responseContainer ) {
+				jQuery.error( callbackName + " was not called" );
+			}
+			return responseContainer[ 0 ];
+		};
+
+		// force json dataType
+		s.dataTypes[ 0 ] = "json";
+
+		// Install callback
+		overwritten = window[ callbackName ];
+		window[ callbackName ] = function() {
+			responseContainer = arguments;
+		};
+
+		// Clean-up function (fires after converters)
+		jqXHR.always(function() {
+			// Restore preexisting value
+			window[ callbackName ] = overwritten;
+
+			// Save back as free
+			if ( s[ callbackName ] ) {
+				// make sure that re-using the options doesn't screw things around
+				s.jsonpCallback = originalSettings.jsonpCallback;
+
+				// save the callback name for future use
+				oldCallbacks.push( callbackName );
+			}
+
+			// Call if it was a function and we have a response
+			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+				overwritten( responseContainer[ 0 ] );
+			}
+
+			responseContainer = overwritten = undefined;
+		});
+
+		// Delegate to script
+		return "script";
+	}
+});
+
+
+
+
+// data: string of html
+// context (optional): If specified, the fragment will be created in this context, defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+	if ( !data || typeof data !== "string" ) {
+		return null;
+	}
+	if ( typeof context === "boolean" ) {
+		keepScripts = context;
+		context = false;
+	}
+	context = context || document;
+
+	var parsed = rsingleTag.exec( data ),
+		scripts = !keepScripts && [];
+
+	// Single tag
+	if ( parsed ) {
+		return [ context.createElement( parsed[1] ) ];
+	}
+
+	parsed = jQuery.buildFragment( [ data ], context, scripts );
+
+	if ( scripts && scripts.length ) {
+		jQuery( scripts ).remove();
+	}
+
+	return jQuery.merge( [], parsed.childNodes );
+};
+
+
+// Keep a copy of the old load method
+var _load = jQuery.fn.load;
+
+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+	if ( typeof url !== "string" && _load ) {
+		return _load.apply( this, arguments );
+	}
+
+	var selector, response, type,
+		self = this,
+		off = url.indexOf(" ");
+
+	if ( off >= 0 ) {
+		selector = jQuery.trim( url.slice( off, url.length ) );
+		url = url.slice( 0, off );
+	}
+
+	// If it's a function
+	if ( jQuery.isFunction( params ) ) {
+
+		// We assume that it's the callback
+		callback = params;
+		params = undefined;
+
+	// Otherwise, build a param string
+	} else if ( params && typeof params === "object" ) {
+		type = "POST";
+	}
+
+	// If we have elements to modify, make the request
+	if ( self.length > 0 ) {
+		jQuery.ajax({
+			url: url,
+
+			// if "type" variable is undefined, then "GET" method will be used
+			type: type,
+			dataType: "html",
+			data: params
+		}).done(function( responseText ) {
+
+			// Save response for use in complete callback
+			response = arguments;
+
+			self.html( selector ?
+
+				// If a selector was specified, locate the right elements in a dummy div
+				// Exclude scripts to avoid IE 'Permission Denied' errors
+				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+				// Otherwise use the full result
+				responseText );
+
+		}).complete( callback && function( jqXHR, status ) {
+			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+		});
+	}
+
+	return this;
+};
+
+
+
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
+	jQuery.fn[ type ] = function( fn ) {
+		return this.on( type, fn );
+	};
+});
+
+
+
+
+jQuery.expr.filters.animated = function( elem ) {
+	return jQuery.grep(jQuery.timers, function( fn ) {
+		return elem === fn.elem;
+	}).length;
+};
+
+
+
+
+
+var docElem = window.document.documentElement;
+
+/**
+ * Gets a window from an element
+ */
+function getWindow( elem ) {
+	return jQuery.isWindow( elem ) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
+}
+
+jQuery.offset = {
+	setOffset: function( elem, options, i ) {
+		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+			position = jQuery.css( elem, "position" ),
+			curElem = jQuery( elem ),
+			props = {};
+
+		// set position first, in-case top/left are set even on static elem
+		if ( position === "static" ) {
+			elem.style.position = "relative";
+		}
+
+		curOffset = curElem.offset();
+		curCSSTop = jQuery.css( elem, "top" );
+		curCSSLeft = jQuery.css( elem, "left" );
+		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+			jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
+
+		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+		if ( calculatePosition ) {
+			curPosition = curElem.position();
+			curTop = curPosition.top;
+			curLeft = curPosition.left;
+		} else {
+			curTop = parseFloat( curCSSTop ) || 0;
+			curLeft = parseFloat( curCSSLeft ) || 0;
+		}
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		if ( options.top != null ) {
+			props.top = ( options.top - curOffset.top ) + curTop;
+		}
+		if ( options.left != null ) {
+			props.left = ( options.left - curOffset.left ) + curLeft;
+		}
+
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+jQuery.fn.extend({
+	offset: function( options ) {
+		if ( arguments.length ) {
+			return options === undefined ?
+				this :
+				this.each(function( i ) {
+					jQuery.offset.setOffset( this, options, i );
+				});
+		}
+
+		var docElem, win,
+			box = { top: 0, left: 0 },
+			elem = this[ 0 ],
+			doc = elem && elem.ownerDocument;
+
+		if ( !doc ) {
+			return;
+		}
+
+		docElem = doc.documentElement;
+
+		// Make sure it's not a disconnected DOM node
+		if ( !jQuery.contains( docElem, elem ) ) {
+			return box;
+		}
+
+		// If we don't have gBCR, just use 0,0 rather than error
+		// BlackBerry 5, iOS 3 (original iPhone)
+		if ( typeof elem.getBoundingClientRect !== strundefined ) {
+			box = elem.getBoundingClientRect();
+		}
+		win = getWindow( doc );
+		return {
+			top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
+			left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+		};
+	},
+
+	position: function() {
+		if ( !this[ 0 ] ) {
+			return;
+		}
+
+		var offsetParent, offset,
+			parentOffset = { top: 0, left: 0 },
+			elem = this[ 0 ];
+
+		// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
+		if ( jQuery.css( elem, "position" ) === "fixed" ) {
+			// we assume that getBoundingClientRect is available when computed position is fixed
+			offset = elem.getBoundingClientRect();
+		} else {
+			// Get *real* offsetParent
+			offsetParent = this.offsetParent();
+
+			// Get correct offsets
+			offset = this.offset();
+			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+				parentOffset = offsetParent.offset();
+			}
+
+			// Add offsetParent borders
+			parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+		}
+
+		// Subtract parent offsets and element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		return {
+			top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || docElem;
+
+			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent || docElem;
+		});
+	}
+});
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+	var top = /Y/.test( prop );
+
+	jQuery.fn[ method ] = function( val ) {
+		return access( this, function( elem, method, val ) {
+			var win = getWindow( elem );
+
+			if ( val === undefined ) {
+				return win ? (prop in win) ? win[ prop ] :
+					win.document.documentElement[ method ] :
+					elem[ method ];
+			}
+
+			if ( win ) {
+				win.scrollTo(
+					!top ? val : jQuery( win ).scrollLeft(),
+					top ? val : jQuery( win ).scrollTop()
+				);
+
+			} else {
+				elem[ method ] = val;
+			}
+		}, method, val, arguments.length, null );
+	};
+});
+
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// getComputedStyle returns percent when specified for top/left/bottom/right
+// rather than make the css module depend on the offset module, we just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+		function( elem, computed ) {
+			if ( computed ) {
+				computed = curCSS( elem, prop );
+				// if curCSS returns percentage, fallback to offset
+				return rnumnonpx.test( computed ) ?
+					jQuery( elem ).position()[ prop ] + "px" :
+					computed;
+			}
+		}
+	);
+});
+
+
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+		// margin is only for outerHeight, outerWidth
+		jQuery.fn[ funcName ] = function( margin, value ) {
+			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+			return access( this, function( elem, type, value ) {
+				var doc;
+
+				if ( jQuery.isWindow( elem ) ) {
+					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+					// isn't a whole lot we can do. See pull request at this URL for discussion:
+					// https://github.com/jquery/jquery/pull/764
+					return elem.document.documentElement[ "client" + name ];
+				}
+
+				// Get document width or height
+				if ( elem.nodeType === 9 ) {
+					doc = elem.documentElement;
+
+					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+					// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+					return Math.max(
+						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+						elem.body[ "offset" + name ], doc[ "offset" + name ],
+						doc[ "client" + name ]
+					);
+				}
+
+				return value === undefined ?
+					// Get width or height on the element, requesting but not forcing parseFloat
+					jQuery.css( elem, type, extra ) :
+
+					// Set width or height on the element
+					jQuery.style( elem, type, value, extra );
+			}, type, chainable ? margin : undefined, chainable, null );
+		};
+	});
+});
+
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+	return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+	define( "jquery", [], function() {
+		return jQuery;
+	});
+}
+
+
+
+
+var
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+	if ( window.$ === jQuery ) {
+		window.$ = _$;
+	}
+
+	if ( deep && window.jQuery === jQuery ) {
+		window.jQuery = _jQuery;
+	}
+
+	return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in
+// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( typeof noGlobal === strundefined ) {
+	window.jQuery = window.$ = jQuery;
+}
+
+
+
+
+return jQuery;
+
+}));
diff --git a/xos/core/xoslib/static/js/xosAdminSite.js b/xos/core/xoslib/static/js/xosAdminSite.js
index 13f1d67..78e6f8d 100644
--- a/xos/core/xoslib/static/js/xosAdminSite.js
+++ b/xos/core/xoslib/static/js/xosAdminSite.js
@@ -1,34 +1,35 @@
-OBJS = ['deployment', 'image', 'networkTemplate', 'network', 'port',
-        'node', 'service', 'site', 'slice',  'slicePrivilege', 'instance',
-        'user', 'sliceRole',  'flavor', 'controller', 'siteDeployment',
-        'controller_image', 'controller_network', 'controller_slice', 'controller_user'];
-NAV_OBJS = ['deployment', 'site', 'slice', 'user'];
-
-REWRITES = {"/admin/core/deployment/": "#deployments",
-            "/admin/core/site/" : "#sites",
-            "/admin/core/slice/" : "#slices",
-            "/admin/core/user/" : "#users"};
-
-XOSAdminApp = new XOSApplication({
-    logTableId: "#logTable",
-    statusMsgId: "#statusMsg",
-    hideTabsByDefault: true
-});
-
-XOSAdminApp.addRegions({
-    navigation: "#navigationPanel",
-
-    detail: "#detail",
-    linkedObjs1: "#linkedObjs1",
-    linkedObjs2: "#linkedObjs2",
-    linkedObjs3: "#linkedObjs3",
-    linkedObjs4: "#linkedObjs4",
-
-    addChildDetail: "#xos-addchild-detail",
-
-    rightButtonPanel: "#rightButtonPanel"
-});
-
+/* eslint-disable */
+OBJS = ['deployment', 'image', 'networkTemplate', 'network', 'port',
+        'node', 'service', 'site', 'slice',  'slicePrivilege', 'instance',
+        'user', 'sliceRole',  'flavor', 'controller', 'siteDeployment',
+        'controller_image', 'controller_network', 'controller_slice', 'controller_user'];
+NAV_OBJS = ['deployment', 'site', 'slice', 'user'];
+
+REWRITES = {"/admin/core/deployment/": "#deployments",
+            "/admin/core/site/" : "#sites",
+            "/admin/core/slice/" : "#slices",
+            "/admin/core/user/" : "#users"};
+
+XOSAdminApp = new XOSApplication({
+    logTableId: "#logTable",
+    statusMsgId: "#statusMsg",
+    hideTabsByDefault: true
+});
+
+XOSAdminApp.addRegions({
+    navigation: "#navigationPanel",
+
+    detail: "#detail",
+    linkedObjs1: "#linkedObjs1",
+    linkedObjs2: "#linkedObjs2",
+    linkedObjs3: "#linkedObjs3",
+    linkedObjs4: "#linkedObjs4",
+
+    addChildDetail: "#xos-addchild-detail",
+
+    rightButtonPanel: "#rightButtonPanel"
+});
+
 XOSAdminApp.navigate = function(what, modelName, modelId) {
     console.log("XOSAsminApp.navigate");
     collection_name = modelName + "s";
@@ -82,35 +83,35 @@
      XOSAdminApp["genericListView"] = genericListViewClass;
 
      for (var index in OBJS) {
-         name = OBJS[index];
-         tr_template = '#xosAdmin-' + name + '-listitem-template';
-         table_template = '#xosAdmin-' + name + '-list-template';
-         detail_template = '#xosAdmin-' + name + '-detail-template';
-         add_child_template = '#xosAdmin-' + name + '-add-child-template';
-         collection_name = name + "s";
-         region_name = name + "List";
-
-         if (window["XOSDetailView_" + name]) {
-             detailClass = window["XOSDetailView_" + name].extend({template: "#xos-detail-template",
-                                                                    app: XOSAdminApp});
-         } else {
-             detailClass = genericDetailClass;
-         }
-         if ($(detail_template).length) {
-             detailClass = detailClass.extend({
+         name = OBJS[index];
+         tr_template = '#xosAdmin-' + name + '-listitem-template';
+         table_template = '#xosAdmin-' + name + '-list-template';
+         detail_template = '#xosAdmin-' + name + '-detail-template';
+         add_child_template = '#xosAdmin-' + name + '-add-child-template';
+         collection_name = name + "s";
+         region_name = name + "List";
+
+         if (window["XOSDetailView_" + name]) {
+             detailClass = window["XOSDetailView_" + name].extend({template: "#xos-detail-template",
+                                                                    app: XOSAdminApp});
+         } else {
+             detailClass = genericDetailClass;
+         }
+         if ($(detail_template).length) {
+             detailClass = detailClass.extend({
                 template: detail_template,
              });
          }
          XOSAdminApp[collection_name + "DetailView"] = detailClass;
 
          if (window["XOSDetailView_" + name]) {
-             addClass = window["XOSDetailView_" + name].extend({template: "#xos-add-template",
-                                                                    app: XOSAdminApp});
-         } else {
-             addClass = genericAddChildClass;
-         }
-         if ($(add_child_template).length) {
-             addClass = detailClass.extend({
+             addClass = window["XOSDetailView_" + name].extend({template: "#xos-add-template",
+                                                                    app: XOSAdminApp});
+         } else {
+             addClass = genericAddChildClass;
+         }
+         if ($(add_child_template).length) {
+             addClass = detailClass.extend({
                 template: add_child_template,
              });
          }
@@ -119,30 +120,30 @@
          if ($(tr_template).length) {
              itemViewClass = XOSItemView.extend({
                  template: tr_template,
-                 app: XOSAdminApp,
-             });
-         } else {
-             itemViewClass = genericItemViewClass;
-         }
-
-         if ($(table_template).length) {
-             listViewClass = XOSListView.extend({
-                 childView: itemViewClass,
-                 template: table_template,
-                 collection: xos[collection_name],
-                 title: name + "s",
-                 app: XOSAdminApp,
-             });
-         } else {
-             listViewClass = genericListViewClass.extend( { childView: itemViewClass,
-                                                            collection: xos[collection_name],
-                                                            title: name + "s",
-                                                           } );
-         }
-
-         XOSAdminApp[collection_name + "ListView"] = listViewClass;
-
-         xos[collection_name].fetch(); //startPolling();
+                 app: XOSAdminApp,
+             });
+         } else {
+             itemViewClass = genericItemViewClass;
+         }
+
+         if ($(table_template).length) {
+             listViewClass = XOSListView.extend({
+                 childView: itemViewClass,
+                 template: table_template,
+                 collection: xos[collection_name],
+                 title: name + "s",
+                 app: XOSAdminApp,
+             });
+         } else {
+             listViewClass = genericListViewClass.extend( { childView: itemViewClass,
+                                                            collection: xos[collection_name],
+                                                            title: name + "s",
+                                                           } );
+         }
+
+         XOSAdminApp[collection_name + "ListView"] = listViewClass;
+
+         xos[collection_name].fetch(); //startPolling();
      }
 };
 
@@ -226,22 +227,22 @@
 };
 
 XOSAdminApp.on("start", function() {
-     XOSAdminApp.buildViews();
-
-     XOSAdminApp.initRouter();
-
-     XOSAdminApp.updateNavigationPanel();
-
-     XOSAdminApp.rewriteLinks();
-
-     // fire it once to initially show the progress bar
-     XOSAdminApp.collectionLoadChange();
-
-     // fire it each time the collection load status is updated
-     Backbone.on("xoslib:collectionLoadChange", XOSAdminApp.collectionLoadChange);
-});
-
-$(document).ready(function(){
-    XOSAdminApp.start();
-});
-
+     XOSAdminApp.buildViews();
+
+     XOSAdminApp.initRouter();
+
+     XOSAdminApp.updateNavigationPanel();
+
+     XOSAdminApp.rewriteLinks();
+
+     // fire it once to initially show the progress bar
+     XOSAdminApp.collectionLoadChange();
+
+     // fire it each time the collection load status is updated
+     Backbone.on("xoslib:collectionLoadChange", XOSAdminApp.collectionLoadChange);
+});
+
+$(document).ready(function(){
+    XOSAdminApp.start();
+});
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/xosCord.js b/xos/core/xoslib/static/js/xosCord.js
index f666b77..c9be375 100644
--- a/xos/core/xoslib/static/js/xosCord.js
+++ b/xos/core/xoslib/static/js/xosCord.js
@@ -1,25 +1,26 @@
-OBJS = ['cordSubscriber', 'cordUser']
-
-CordAdminApp = new XOSApplication({
-    logTableId: "#logTable",
-    statusMsgId: "#statusMsg",
-    hideTabsByDefault: true
-});
-
-CordAdminApp.addRegions({
-    navigation: "#navigationPanel",
-
-    detail: "#detail",
-    linkedObjs1: "#linkedObjs1",
-    linkedObjs2: "#linkedObjs2",
-    linkedObjs3: "#linkedObjs3",
-    linkedObjs4: "#linkedObjs4",
-
-    addChildDetail: "#xos-addchild-detail",
-
-    rightButtonPanel: "#rightButtonPanel"
-});
-
+/* eslint-disable */
+OBJS = ['cordSubscriber', 'cordUser'];
+
+CordAdminApp = new XOSApplication({
+    logTableId: "#logTable",
+    statusMsgId: "#statusMsg",
+    hideTabsByDefault: true
+});
+
+CordAdminApp.addRegions({
+    navigation: "#navigationPanel",
+
+    detail: "#detail",
+    linkedObjs1: "#linkedObjs1",
+    linkedObjs2: "#linkedObjs2",
+    linkedObjs3: "#linkedObjs3",
+    linkedObjs4: "#linkedObjs4",
+
+    addChildDetail: "#xos-addchild-detail",
+
+    rightButtonPanel: "#rightButtonPanel"
+});
+
 CordAdminApp.navigate = function(what, modelName, modelId) {
     collection_name = modelName + "s";
     if (what=="list") {
@@ -51,36 +52,36 @@
      CordAdminApp["genericListView"] = genericListViewClass;
 
      for (var index in OBJS) {
-         name = OBJS[index];
-         tr_template = '#xosAdmin-' + name + '-listitem-template';
-         table_template = '#xosAdmin-' + name + '-list-template';
-         detail_template = '#xosAdmin-' + name + '-detail-template';
-         add_child_template = '#xosAdmin-' + name + '-add-child-template';
-         collection_name = name + "s";
-         region_name = name + "List";
-         templates = {cordSubscriber: "#xos-cord-subscriber-template"};
-
-         if (window["XOSDetailView_" + name]) {
-             detailClass = window["XOSDetailView_" + name].extend( {template: templates[name] || "#xos-detail-template",
-                                                                    app: CordAdminApp});
-         } else {
-             detailClass = genericDetailClass.extend( {template: templates[name] || "#xos-detail-template", });
-         }
-         if ($(detail_template).length) {
-             detailClass = detailClass.extend({
+         name = OBJS[index];
+         tr_template = '#xosAdmin-' + name + '-listitem-template';
+         table_template = '#xosAdmin-' + name + '-list-template';
+         detail_template = '#xosAdmin-' + name + '-detail-template';
+         add_child_template = '#xosAdmin-' + name + '-add-child-template';
+         collection_name = name + "s";
+         region_name = name + "List";
+         templates = {cordSubscriber: "#xos-cord-subscriber-template"};
+
+         if (window["XOSDetailView_" + name]) {
+             detailClass = window["XOSDetailView_" + name].extend( {template: templates[name] || "#xos-detail-template",
+                                                                    app: CordAdminApp});
+         } else {
+             detailClass = genericDetailClass.extend( {template: templates[name] || "#xos-detail-template", });
+         }
+         if ($(detail_template).length) {
+             detailClass = detailClass.extend({
                 template: detail_template,
              });
          }
          CordAdminApp[collection_name + "DetailView"] = detailClass;
 
          if (window["XOSDetailView_" + name]) {
-             addClass = window["XOSDetailView_" + name].extend({template: "#xos-add-template",
-                                                                    app: CordAdminApp});
-         } else {
-             addClass = genericAddChildClass;
-         }
-         if ($(add_child_template).length) {
-             addClass = detailClass.extend({
+             addClass = window["XOSDetailView_" + name].extend({template: "#xos-add-template",
+                                                                    app: CordAdminApp});
+         } else {
+             addClass = genericAddChildClass;
+         }
+         if ($(add_child_template).length) {
+             addClass = detailClass.extend({
                 template: add_child_template,
              });
          }
@@ -89,30 +90,30 @@
          if ($(tr_template).length) {
              itemViewClass = XOSItemView.extend({
                  template: tr_template,
-                 app: CordAdminApp,
-             });
-         } else {
-             itemViewClass = genericItemViewClass;
-         }
-
-         if ($(table_template).length) {
-             listViewClass = XOSListView.extend({
-                 childView: itemViewClass,
-                 template: table_template,
-                 collection: xos[collection_name],
-                 title: name + "s",
-                 app: CordAdminApp,
-             });
-         } else {
-             listViewClass = genericListViewClass.extend( { childView: itemViewClass,
-                                                            collection: xos[collection_name],
-                                                            title: name + "s",
-                                                           } );
-         }
-
-         CordAdminApp[collection_name + "ListView"] = listViewClass;
-
-         xos[collection_name].fetch(); //startPolling();
+                 app: CordAdminApp,
+             });
+         } else {
+             itemViewClass = genericItemViewClass;
+         }
+
+         if ($(table_template).length) {
+             listViewClass = XOSListView.extend({
+                 childView: itemViewClass,
+                 template: table_template,
+                 collection: xos[collection_name],
+                 title: name + "s",
+                 app: CordAdminApp,
+             });
+         } else {
+             listViewClass = genericListViewClass.extend( { childView: itemViewClass,
+                                                            collection: xos[collection_name],
+                                                            title: name + "s",
+                                                           } );
+         }
+
+         CordAdminApp[collection_name + "ListView"] = listViewClass;
+
+         xos[collection_name].fetch(); //startPolling();
      }
 };
 
@@ -179,18 +180,18 @@
 };
 
 CordAdminApp.on("start", function() {
-     CordAdminApp.buildViews();
-
-     CordAdminApp.initRouter();
-
-     // fire it once to initially show the progress bar
-     CordAdminApp.collectionLoadChange();
-
-     // fire it each time the collection load status is updated
-     Backbone.on("xoslib:collectionLoadChange", CordAdminApp.collectionLoadChange);
-});
-
-$(document).ready(function(){
-    CordAdminApp.start();
-});
-
+     CordAdminApp.buildViews();
+
+     CordAdminApp.initRouter();
+
+     // fire it once to initially show the progress bar
+     CordAdminApp.collectionLoadChange();
+
+     // fire it each time the collection load status is updated
+     Backbone.on("xoslib:collectionLoadChange", CordAdminApp.collectionLoadChange);
+});
+
+$(document).ready(function(){
+    CordAdminApp.start();
+});
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/xosDeveloper.js b/xos/core/xoslib/static/js/xosDeveloper.js
index aef640e..e4e5afb 100644
--- a/xos/core/xoslib/static/js/xosDeveloper.js
+++ b/xos/core/xoslib/static/js/xosDeveloper.js
@@ -1,62 +1,64 @@
-/* This is an example that uses xoslib + marionette to display the developer
-   view.
+/* eslint-disable guard-for-in, no-undef*/
+/* This is an example that uses xoslib + marionette to display the developer
+   view.
 
-   For an example that uses xoslib + datatables, see xosDeveloper_datatables.js
-*/
+   For an example that uses xoslib + datatables, see xosDeveloper_datatables.js
+*/
 
-DeveloperApp = new Marionette.Application();
+DeveloperApp = new Marionette.Application();
 
 DeveloperApp.addRegions({
-  mainRegion: "#developerView"
-});
-
-DeveloperApp.SliceDetailView = Marionette.ItemView.extend({
-  template: "#developer-slicedetail-template",
+  mainRegion: '#developerView'
+});
+
+DeveloperApp.SliceDetailView = Marionette.ItemView.extend({
+  template: '#developer-slicedetail-template',
   tagName: 'tr',
   className: 'developer_slicedetail'
-});
-
-DeveloperApp.SliceListView = Marionette.CompositeView.extend({
-  tagName: "table",
-  className: "table table-bordered table-striped",
-  template: "#developer-slicetable-template",
-  childView: DeveloperApp.SliceDetailView,
-  childViewContainer: "tbody",
+});
 
-  events: {"click .sort": "changeSort"},
+DeveloperApp.SliceListView = Marionette.CompositeView.extend({
+  tagName: 'table',
+  className: 'table table-bordered table-striped',
+  template: '#developer-slicetable-template',
+  childView: DeveloperApp.SliceDetailView,
+  childViewContainer: 'tbody',
+
+  events: {'click .sort': 'changeSort'},
 
   initialize: function() {
-      this.listenTo(this.collection, 'change', this._renderChildren);
+    this.listenTo(this.collection, 'change', this._renderChildren);
   },
 
   changeSort: function(e) {
-      parts=$(e.currentTarget).attr("id").split('-');
-      order=parts[1];
-      fieldName=parts[2];
-      this.collection.sortVar = fieldName;
-      this.collection.sortOrder = order;
-      this.collection.sort();
+    parts = $(e.currentTarget).attr('id').split('-');
+    order = parts[1];
+    fieldName = parts[2];
+    this.collection.sortVar = fieldName;
+    this.collection.sortOrder = order;
+    this.collection.sort();
   },
 
   attachHtml: function(compositeView, childView, index) {
-      // The REST API will let admin users see everything. For the developer
-      // view we still want to hide slices we are not members of.
-      if (childView.model.get("sliceInfo").roles.length == 0) {
-          return;
-      }
-      DeveloperApp.SliceListView.__super__.attachHtml(compositeView, childView, index);
+    // The REST API will let admin users see everything. For the developer
+    // view we still want to hide slices we are not members of.
+    if(childView.model.get('sliceInfo').roles.length == 0) {
+      return;
+    }
+    DeveloperApp.SliceListView.__super__.attachHtml(compositeView, childView, index);
   },
 });
-
-DeveloperApp.on("start", function() {
-  var developerSliceListView = new DeveloperApp.SliceListView({
+
+DeveloperApp.on('start', function() {
+  var developerSliceListView = new DeveloperApp.SliceListView({
     collection: xos.slicesPlus
   });
+
   DeveloperApp.mainRegion.show(developerSliceListView);
   xos.slicesPlus.startPolling();
-});
-
-$(document).ready(function(){
-  DeveloperApp.start();
-});
-
+});
+
+$(document).ready(function() {
+  DeveloperApp.start();
+});
+
diff --git a/xos/core/xoslib/static/js/xosDeveloper_datatables.js b/xos/core/xoslib/static/js/xosDeveloper_datatables.js
index ed88a9f..fc0153b 100644
--- a/xos/core/xoslib/static/js/xosDeveloper_datatables.js
+++ b/xos/core/xoslib/static/js/xosDeveloper_datatables.js
@@ -1,50 +1,62 @@
+/* eslint-disable guard-for-in, no-undef, indent*/
+
+// TODO write test and then fix lint errors
+
 /* This is an example that uses xoslib + datatables to display the developer
-   view.
-
-   For an example that uses xoslib + marionette, see xosDeveloper.js
-*/
-
-function updateSliceTable(data) {
-    $('#developerView').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="dynamicusersliceinfo"></table>' );
+   view.
+
+   For an example that uses xoslib + marionette, see xosDeveloper.js
+*/
+
+function updateSliceTable(data) {
+    $('#developerView').html('<table cellpadding="0" cellspacing="0" border="0" class="display" id="dynamicusersliceinfo"></table>');
     var actualEntries = [];
 
     for (rowkey in data.models) {
         row = data.models[rowkey];
-        slicename = row.get("name");
-        sliceid = row.get("id");
-        role = row.get("sliceInfo").roles[0] || "";
-        instancecount = row.get("sliceInfo").instanceCount;
-        sitecount = row.get("sliceInfo").siteCount;
-        backendHtml = row.get("backendHtml")
+        slicename = row.get('name');
+        sliceid = row.get('id');
+        role = row.get('sliceInfo').roles[0] || '';
+        instancecount = row.get('sliceInfo').instanceCount;
+        sitecount = row.get('sliceInfo').siteCount;
+        backendHtml = row.get('backendHtml');
 
         //if (! role) {
         //    continue;
         //}
 
-        if (! row.get("current_user_can_see") ) {
+        if (! row.get('current_user_can_see')) {
             continue;
         }
 
-        actualEntries.push([backendHtml + ' <a href="/admin/core/slice/' + sliceid + '">' + slicename + '</a>',
-                            role, instancecount, sitecount]);
+        actualEntries.push([backendHtml +
+            ' <a href="/admin/core/slice/' + sliceid + '">' +
+            slicename + '</a>',
+            role, instancecount, sitecount]);
     }
-    oTable = $('#dynamicusersliceinfo').dataTable( {
-        "bJQueryUI": true,
-        "aaData":  actualEntries ,
-        "bStateSave": true,
-        "aoColumns": [
-            { "sTitle": "Slice" },
-            { "sTitle": "Privilege" , sClass: "alignCenter"},
-            { "sTitle": "Number of Instances" , sClass: "alignCenter"},
-            { "sTitle": "Number of Sites" , sClass: "alignCenter"},
+    oTable = $('#dynamicusersliceinfo').dataTable({
+        'bJQueryUI': true,
+        'aaData': actualEntries,
+        'bStateSave': true,
+        'aoColumns': [
+            {'sTitle': 'Slice'},
+            {'sTitle': 'Privilege' , sClass: 'alignCenter'},
+            {'sTitle': 'Number of Instances' , sClass: 'alignCenter'},
+            {'sTitle': 'Number of Sites' , sClass: 'alignCenter'},
         ]
-    } );
+    });
 }
 
-$(document).ready(function(){
-    xos.slicesPlus.on("change", function() { /*console.log("change");*/ updateSliceTable(xos.slicesPlus); });
-    xos.slicesPlus.on("remove", function() { /*console.log("sort");*/ updateSliceTable(xos.slicesPlus); });
-    xos.slicesPlus.on("sort", function() { /*console.log("sort");*/ updateSliceTable(xos.slicesPlus); });
+$(document).ready(function() {
+    xos.slicesPlus.on('change', function() {
+        updateSliceTable(xos.slicesPlus);
+    });
+    xos.slicesPlus.on('remove', function() {
+        updateSliceTable(xos.slicesPlus);
+    });
+    xos.slicesPlus.on('sort', function() {
+        updateSliceTable(xos.slicesPlus);
+    });
 
     xos.slicesPlus.startPolling();
 });
diff --git a/xos/core/xoslib/static/js/xosHpc.js b/xos/core/xoslib/static/js/xosHpc.js
index a87fdd1..e0b0437 100644
--- a/xos/core/xoslib/static/js/xosHpc.js
+++ b/xos/core/xoslib/static/js/xosHpc.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 SC_RR = 60;
 SC_HPC_PROBE = 600;
 SC_HPC_FETCH = 3600;
@@ -101,5 +102,4 @@
 
     xos.hpcview.startPolling();
 });
-
-
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/xosHpcNodes.js b/xos/core/xoslib/static/js/xosHpcNodes.js
index 729e167..850aeca 100644
--- a/xos/core/xoslib/static/js/xosHpcNodes.js
+++ b/xos/core/xoslib/static/js/xosHpcNodes.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 SC_HPC_FETCH = 3600;
 
 var hpc_data = null;
@@ -104,5 +105,5 @@
 
     xos.hpcview.startPolling();
 });
-
+/* eslint-enable */
 
diff --git a/xos/core/xoslib/static/js/xosHpcUrls.js b/xos/core/xoslib/static/js/xosHpcUrls.js
index 3a8cfe0..cda7b2d 100644
--- a/xos/core/xoslib/static/js/xosHpcUrls.js
+++ b/xos/core/xoslib/static/js/xosHpcUrls.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 SC_HPC_FETCH = 3600;
 
 var hpc_data = null;
@@ -88,4 +89,4 @@
     xos.hpcview.startPolling();
 });
 
-
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/xosTenant.js b/xos/core/xoslib/static/js/xosTenant.js
index 414cb48..f933c89 100644
--- a/xos/core/xoslib/static/js/xosTenant.js
+++ b/xos/core/xoslib/static/js/xosTenant.js
@@ -1,454 +1,524 @@
-XOSTenantSite = XOSModel.extend( {
-    listFields: ["name", "allocated"],
-    modelName: "tenantSite",
-    collectionName: "tenantSites"
-});
-
-XOSTenantSiteCollection = XOSCollection.extend( {
-    listFields: ["name", "allocated", "ready"],
-    modelName: "tenantSite",
-    collectionName: "tenantSites",
-
-    getFromSlice: function(slice) {
-        var tenantSites = [];
-        var id = 0;
-        for (siteName in slice.attributes.site_allocation) {
-            allocated = slice.attributes.site_allocation[siteName];
-            ready = slice.attributes.site_ready[siteName] || 0;
-            tenantSites.push(new XOSTenantSite( { name: siteName, allocated: allocated, ready: ready, id: id} ));
-            id = id + 1;
-        }
-        for (index in xos.tenantview.models[0].attributes.blessed_site_names) {
-            siteName = xos.tenantview.models[0].attributes.blessed_site_names[index];
-            if (! (siteName in slice.attributes.site_allocation)) {
-                tenantSites.push(new XOSTenantSite( { name: siteName, allocated: 0, ready: 0, id: id} ));
-                id = id + 1;
-            }
-        }
-        this.set(tenantSites);
-
-        var that=this;
-        this.listenTo(slice, 'change', function() { that.getReadyFromSlice(slice); })
-    },
-
-    getReadyFromSlice: function(slice) {
-        for (siteName in slice.attributes.site_ready) {
-            ready = slice.attributes.site_ready[siteName];
-            for (index in this.models) {
-                tenantSite = this.models[index];
-                if (tenantSite.attributes.name == siteName) {
-                    tenantSite.set("ready", ready);
-                }
-            }
-        }
-    },
-
-    putToSlice: function(slice) {
-        slice.attributes.site_allocation = {};
-        for (index in this.models) {
-            var model = this.models[index];
-            slice.attributes.site_allocation[ model.attributes.name ] = model.attributes.allocated;
-        }
-    },
-});
-
-XOSEditUsersView = Marionette.ItemView.extend({
-            template: "#tenant-edit-users",
-            viewInitializers: [],
-
-            onShow: function() {
-                _.each(this.viewInitializers, function(initializer) {
-                    initializer();
-                });
-            },
-
-            templateHelpers: function() { return { detailView: this, model: this.model }; },
-
-            });
-
-XOSTenantSummaryView = XOSDetailView.extend({
-            events: {"change": "onChange"},
-
-            onChange: function(e) {
-                XOSTenantApp.setDirty(true);
-            },
-
-            saveSuccess: function() {
-                console.log("saveSuccess!");
-                XOSTenantApp.setDirty(false);
-            },
-
-            });
-
-
-XOSTenantButtonView = Marionette.ItemView.extend({
-            template: "#xos-tenant-buttons-template",
-
-            events: {"click button.btn-tenant-create": "createClicked",
-                     "click button.btn-tenant-delete": "deleteClicked",
-                     "click button.btn-tenant-add-user": "addUserClicked",
-                     "click button.btn-tenant-save": "saveClicked",
-                     "click button.btn-tenant-download-ssh": "downloadClicked",
-                     },
-
-            createClicked: function(e) {
-                     XOSTenantApp.addSlice();
-                     },
-
-            deleteClicked: function(e) {
-                     XOSTenantApp.deleteSlice(this.options.linkedView.model);
-                     },
-
-            addUserClicked: function(e) {
-                     XOSTenantApp.editUsers(this.options.linkedView.model);
-                     },
-
-            downloadClicked: function(e) {
-                     XOSTenantApp.downloadSSH(this.options.linkedView.model);
-                     },
-
-            saveClicked: function(e) {
-                     model = this.options.linkedView.model;
-                     model.tenantSiteCollection.putToSlice(model);
-                     model.attributes.users = model.usersBuffer;
-
-                     e.preventDefault();
-                     this.options.linkedView.save();
-                     //this.options.linkedView.submitContinueClicked.call(this.options.linkedView, e);
-                     //XOSTenantApp.setDirty(false);
-                     },
-            });
-
-XOSTenantApp = new XOSApplication({
-    logTableId: "#logTable",
-    statusMsgId: "#statusMsg",
-    hideTabsByDefault: true,
-    dirty: false,
-    varName: "XOSTenantApp",
-});
-
-XOSTenantApp.addRegions({
-    tenantSliceSelector: "#tenantSliceSelector",
-    tenantSummary: "#tenantSummary",
-    tenantSiteList: "#tenantSiteList",
-    tenantButtons: "#tenantButtons",
-    tenantAddSliceInterior: "#tenant-addslice-interior",
-    tenantEditUsersInterior: "#tenant-edit-users-interior",
-    tenantSSHCommandsInterior: "#tenant-ssh-commands-interior",
-});
-
-XOSTenantApp.setDirty = function(dirty) {
-    XOSTenantApp.dirty = dirty;
-    if (dirty) {
-        $("button.btn-tenant-save").addClass("btn-success");
-    } else {
-        $("button.btn-tenant-save").removeClass("btn-success");
-    }
-};
-
-XOSTenantApp.buildViews = function() {
-     XOSTenantApp.tenantSites = new XOSTenantSiteCollection();
 
-     tenantSummaryClass = XOSTenantSummaryView.extend({template: "#xos-detail-template",
-                                                app: XOSTenantApp,
-                                                detailFields: ["serviceClass", "default_image", "default_flavor", "network_ports"],
-                                                fieldDisplayNames: {serviceClass: "Service Level", "default_flavor": "Flavor", "default_image": "Image", "mount_data_sets": "Data Sets"},
-                                                helpText: {"serviceClass": "Existing instances will be re-instantiated if changed",
-                                                           "default_image": "Existing instances will be re-instantiated if changed",
-                                                           "default_flavor": "Existing instances will be re-instantiated if changed"},
+/* globals XOSModel, XOSCollection */
+/* eslint-disable no-undef, guard-for-in, new-cap */
 
-                                                onShow: function() {
-                                                    // the slice selector is in a different table, so make every label cell the maximal width
-                                                    make_same_width("#xos-tenant-view-panel", ".xos-label-cell");
-                                                },
-                                                });
+XOSTenantSite = XOSModel.extend({
+  listFields: ['name', 'allocated'],
+  modelName: 'tenantSite',
+  collectionName: 'tenantSites'
+});
 
-     XOSTenantApp.tenantSummaryView = tenantSummaryClass;
+XOSTenantSiteCollection = XOSCollection.extend({
+  listFields: ['name', 'allocated', 'ready'],
+  modelName: 'tenantSite',
+  collectionName: 'tenantSites',
 
-     tenantAddClass = XOSDetailView.extend({template: "#xos-detail-template",
-                                                app: XOSTenantApp,
-                                                detailFields: ["name", "description"]});
+  getFromSlice: function(slice) {
+    var tenantSites = [];
+    var id = 0;
+    var that = this;
 
-     XOSTenantApp.tenantAddView = tenantAddClass;
+    for (siteName in slice.attributes.site_allocation) {
+      allocated = slice.attributes.site_allocation[siteName];
+      ready = slice.attributes.site_ready[siteName] || 0;
+      tenantSites.push(new XOSTenantSite({name: siteName, allocated: allocated, ready: ready, id: id}));
+      id = id + 1;
+    }
 
-     tenantSiteItemClass = XOSItemView.extend({template: "#xos-listitem-template",
-                                               app: XOSTenantApp});
+    for (index in xos.tenantview.models[0].attributes.blessed_site_names) {
+      siteName = xos.tenantview.models[0].attributes.blessed_site_names[index];
+      if (! (siteName in slice.attributes.site_allocation)) {
+        tenantSites.push(new XOSTenantSite({name: siteName, allocated: 0, ready: 0, id: id}));
+        id = id + 1;
+      }
+    }
+    this.set(tenantSites);
 
-     XOSTenantApp.tenantSiteItemView = tenantSiteItemClass;
+    this.listenTo(slice, 'change', function() {
+      that.getReadyFromSlice(slice);
+    });
+  },
 
-     tenantSiteListClass = XOSDataTableView.extend({template: "#xos-list-template",
-                                               app: XOSTenantApp,
-                                               childView: tenantSiteItemClass,
-                                               collection: XOSTenantApp.tenantSites,
-                                               title: "sites",
-                                               inputType: {allocated: "spinner"},
-                                               noDeleteColumn: true,
-                                               disablePaginate: true,
-                                               disableFilter: true,
-                                               fieldDisplayNames: {"name": "Site"},
-                                               });
+  getReadyFromSlice: function(slice) {
+    for (siteName in slice.attributes.site_ready) {
+      ready = slice.attributes.site_ready[siteName];
+      for (index in this.models) {
+        tenantSite = this.models[index];
+        if (tenantSite.attributes.name == siteName) {
+          tenantSite.set('ready', ready);
+        }
+      }
+    }
+  },
 
-     XOSTenantApp.tenantSiteListView = tenantSiteListClass;
+  putToSlice: function(slice) {
+    slice.attributes.site_allocation = {};
+    for (index in this.models) {
+      var model = this.models[index];
 
-     XOSTenantApp.tenantSliceSelectorView = SliceSelectorView.extend( {
-         sliceChanged: function(id) {
-             XOSTenantApp.navToSlice(id);
-         },
-         filter: function(slice) {
-             return slice.attributes.current_user_can_see;
-         },
-     });
+      slice.attributes.site_allocation[ model.attributes.name ] = model.attributes.allocated;
+    }
+  },
+});
 
-     xos.sites.fetch();
-     xos.slicesPlus.fetch();
-     xos.tenantview.fetch();
+XOSEditUsersView = Marionette.ItemView.extend({
+  template: '#tenant-edit-users',
+  viewInitializers: [],
+
+  onShow: function() {
+    _.each(this.viewInitializers, function(initializer) {
+      initializer();
+    });
+  },
+
+  templateHelpers: function() {
+    return {detailView: this, model: this.model};
+  }
+
+});
+
+XOSTenantSummaryView = XOSDetailView.extend({
+  events: {'change': 'onChange'},
+
+  onChange: function(e) {
+    XOSTenantApp.setDirty(true);
+  },
+
+  saveSuccess: function() {
+    XOSTenantApp.setDirty(false);
+  },
+
+});
+
+
+XOSTenantButtonView = Marionette.ItemView.extend({
+  template: '#xos-tenant-buttons-template',
+
+  events: {'click button.btn-tenant-create': 'createClicked',
+           'click button.btn-tenant-delete': 'deleteClicked',
+           'click button.btn-tenant-add-user': 'addUserClicked',
+           'click button.btn-tenant-save': 'saveClicked',
+           'click button.btn-tenant-download-ssh': 'downloadClicked',
+           },
+
+  createClicked: function() {
+    XOSTenantApp.addSlice();
+  },
+
+  deleteClicked: function() {
+    XOSTenantApp.deleteSlice(this.options.linkedView.model);
+  },
+
+  addUserClicked: function() {
+    XOSTenantApp.editUsers(this.options.linkedView.model);
+  },
+
+  downloadClicked: function() {
+    XOSTenantApp.downloadSSH(this.options.linkedView.model);
+  },
+
+  saveClicked: function(e) {
+    var model = this.options.linkedView.model;
+
+    model.tenantSiteCollection.putToSlice(model);
+    model.attributes.users = model.usersBuffer;
+
+    e.preventDefault();
+    this.options.linkedView.save();
+    //this.options.linkedView.submitContinueClicked.call(this.options.linkedView, e);
+    //XOSTenantApp.setDirty(false);
+  }
+});
+
+XOSTenantApp = new XOSApplication({
+  logTableId: '#logTable',
+  statusMsgId: '#statusMsg',
+  hideTabsByDefault: true,
+  dirty: false,
+  varName: 'XOSTenantApp',
+});
+
+XOSTenantApp.addRegions({
+  tenantSliceSelector: '#tenantSliceSelector',
+  tenantSummary: '#tenantSummary',
+  tenantSiteList: '#tenantSiteList',
+  tenantButtons: '#tenantButtons',
+  tenantAddSliceInterior: '#tenant-addslice-interior',
+  tenantEditUsersInterior: '#tenant-edit-users-interior',
+  tenantSSHCommandsInterior: '#tenant-ssh-commands-interior',
+});
+
+XOSTenantApp.setDirty = function(dirty) {
+  XOSTenantApp.dirty = dirty;
+  if (dirty) {
+    $('button.btn-tenant-save').addClass('btn-success');
+  }
+  else {
+    $('button.btn-tenant-save').removeClass('btn-success');
+  }
+};
+
+XOSTenantApp.buildViews = function() {
+  XOSTenantApp.tenantSites = new XOSTenantSiteCollection();
+
+  tenantSummaryClass = XOSTenantSummaryView.extend({
+    template: '#xos-detail-template',
+    app: XOSTenantApp,
+    detailFields: ['serviceClass', 'default_image', 'default_flavor', 'network_ports'],
+    fieldDisplayNames: {
+      serviceClass: 'Service Level',
+      default_flavor: 'Flavor',
+      default_image: 'Image',
+      mount_data_sets: 'Data Sets'
+    },
+    helpText: {
+      'serviceClass': 'Existing instances will be re-instantiated if changed',
+      'default_image': 'Existing instances will be re-instantiated if changed',
+      'default_flavor': 'Existing instances will be re-instantiated if changed'
+    },
+    onShow: function() {
+      // the slice selector is in a different table, so make every label cell the maximal width
+      make_same_width('#xos-tenant-view-panel', '.xos-label-cell');
+    },
+  });
+
+  XOSTenantApp.tenantSummaryView = tenantSummaryClass;
+
+  tenantAddClass = XOSDetailView.extend({
+    template: '#xos-detail-template',
+    app: XOSTenantApp,
+    detailFields: ['name', 'description']
+  });
+
+  XOSTenantApp.tenantAddView = tenantAddClass;
+
+  tenantSiteItemClass = XOSItemView.extend({
+    template: '#xos-listitem-template',
+    app: XOSTenantApp
+  });
+
+  XOSTenantApp.tenantSiteItemView = tenantSiteItemClass;
+
+  tenantSiteListClass = XOSDataTableView.extend({
+    template: '#xos-list-template',
+    app: XOSTenantApp,
+    childView: tenantSiteItemClass,
+    collection: XOSTenantApp.tenantSites,
+    title: 'sites',
+    inputType: {allocated: 'spinner'},
+    noDeleteColumn: true,
+    disablePaginate: true,
+    disableFilter: true,
+    fieldDisplayNames: {name: 'Site'},
+  });
+
+  XOSTenantApp.tenantSiteListView = tenantSiteListClass;
+
+  XOSTenantApp.tenantSliceSelectorView = SliceSelectorView.extend({
+    sliceChanged: function(id) {
+      XOSTenantApp.navToSlice(id);
+    },
+    filter: function(slice) {
+      return slice.attributes.current_user_can_see;
+    },
+  });
+
+  xos.sites.fetch();
+  xos.slicesPlus.fetch();
+  xos.tenantview.fetch();
 };
 
 make_choices = function(list_of_names, list_of_values) {
-    result = [];
-    if (!list_of_values) {
-        for (index in list_of_names) {
-            displayName = list_of_names[index];
-            result.push( [displayName, displayName] );
-        }
-    } else {
-        for (index in list_of_names) {
-            displayName = list_of_names[index];
-            id = list_of_values[index];
-            result.push( [displayName, id] );
-        }
+  var result = [];
+  var displayName;
+
+  if (!list_of_values) {
+    for (var index in list_of_names) {
+      displayName = list_of_names[index];
+      result.push([displayName, displayName]);
     }
-    return result;
+  }
+  else {
+    for (var index in list_of_names) {
+      displayName = list_of_names[index];
+      id = list_of_values[index];
+      result.push([displayName, id]);
+    }
+  }
+  return result;
 };
 
 XOSTenantApp.navToSlice = function(id) {
-    XOSTenantApp.viewSlice(xos.slicesPlus.get(id));
+  XOSTenantApp.viewSlice(xos.slicesPlus.get(id));
 };
 
 XOSTenantApp.adjustCollectionField = function(collectionName, id, fieldName, amount) {
-    model = XOSTenantApp[collectionName].get(id);
-    model.set(fieldName, Math.max(model.get(fieldName) + amount, 0));
-    XOSTenantApp.setDirty(true);
+  model = XOSTenantApp[collectionName].get(id);
+  model.set(fieldName, Math.max(model.get(fieldName) + amount, 0));
+  XOSTenantApp.setDirty(true);
 };
 
 XOSTenantApp.addSlice = function() {
-    var app=this;
+  var app = this;
 
-    if (!xos.tenant().current_user_can_create_slice) {
-        window.alert("You do not have sufficient rights to create a slice on your site");
-        return;
+  if (!xos.tenant().current_user_can_create_slice) {
+    window.alert('You do not have sufficient rights to create a slice on your site');
+    return;
+  }
+
+  model = new xos.slicesPlus.model({
+    site: xos.tenant().current_user_site_id,
+    name: xos.tenant().current_user_login_base + '_',
+    creator: xos.tenant().current_user_id
+  });
+
+  var detailView = new XOSTenantApp.tenantAddView({
+    model: model,
+    collection: xos.slicesPlus,
+    noSubmitButton: true,
+  });
+
+  detailView.dialog = $('#tenant-addslice-dialog');
+  app.tenantAddSliceInterior.show(detailView);
+
+  $('#tenant-addslice-dialog').dialog({
+    autoOpen: false,
+    modal: true,
+    width: 640,
+    buttons: {
+      'Create Slice': function() {
+        var addDialog = this;
+
+        detailView.synchronous = true;
+        detailView.afterSave = function() {
+          $(addDialog).dialog('close');
+          XOSTenantApp.navToSlice(detailView.model.id);
+        };
+        detailView.save();
+      },
+      'Cancel': function() {
+        $(this).dialog('close');
+      }
     }
-
-    model = new xos.slicesPlus.model({site: xos.tenant().current_user_site_id,
-                                      name: xos.tenant().current_user_login_base + "_",
-                                      creator: xos.tenant().current_user_id});
-    console.log(model);
-    var detailView = new XOSTenantApp.tenantAddView({model: model,
-                                                     collection: xos.slicesPlus,
-                                                     noSubmitButton: true,
-                                                    });
-    detailView.dialog = $("#tenant-addslice-dialog");
-    app.tenantAddSliceInterior.show(detailView);
-    $("#tenant-addslice-dialog").dialog({
-       autoOpen: false,
-       modal: true,
-       width: 640,
-       buttons : {
-            "Create Slice" : function() {
-              var addDialog = this;
-              console.log("SAVE!!!");
-              detailView.synchronous = true;
-              detailView.afterSave = function() { $(addDialog).dialog("close"); XOSTenantApp.navToSlice(detailView.model.id); }
-              detailView.save();
-            },
-            "Cancel" : function() {
-              $(this).dialog("close");
-            }
-          }
-        });
-    $("#tenant-addslice-dialog").dialog("open");
+  });
+  $('#tenant-addslice-dialog').dialog('open');
 };
 
 XOSTenantApp.editUsers = function(model) {
-    var app=this;
-    var detailView = new XOSEditUsersView({model: model, collection: xos.slicesPlus});
-    detailView.dialog = $("#tenant-edit-users-dialog");
-    app.tenantEditUsersInterior.show(detailView);
-    $("#tenant-edit-users-dialog").dialog({
-       autoOpen: false,
-       modal: true,
-       width: 640,
-       buttons : {
-            "Ok" : function() {
-              var editDialog = this;
-              user_ids = all_options($("#tenant-edit-users-dialog").find(".select-picker-to"));
-              user_ids = user_ids.map( function(x) { return parseInt(x,10); } );
-              if (!array_same_elements(user_ids, model.usersBuffer)) {
-                  XOSTenantApp.setDirty(true);
-              }
-              model.usersBuffer = user_ids;
-              $(editDialog).dialog("close");
-            },
-            "Cancel" : function() {
-              $(this).dialog("close");
-            }
-          }
-        });
-    $("#tenant-edit-users-dialog").dialog("open");
+  var app = this;
+  var detailView = new XOSEditUsersView({model: model, collection: xos.slicesPlus});
+
+  detailView.dialog = $('#tenant-edit-users-dialog');
+  app.tenantEditUsersInterior.show(detailView);
+
+  $('#tenant-edit-users-dialog').dialog({
+    autoOpen: false,
+    modal: true,
+    width: 640,
+    buttons: {
+      'Ok': function() {
+        var editDialog = this;
+        var user_ids = all_options($('#tenant-edit-users-dialog').find('.select-picker-to'));
+
+        user_ids = user_ids.map(function(x) {
+          return parseInt(x,10);
+        });
+
+        if (!array_same_elements(user_ids, model.usersBuffer)) {
+          XOSTenantApp.setDirty(true);
+        }
+        model.usersBuffer = user_ids;
+        $(editDialog).dialog('close');
+      },
+      'Cancel': function() {
+        $(this).dialog('close');
+      }
+    }
+  });
+  $('#tenant-edit-users-dialog').dialog('open');
 };
 
 XOSTenantApp.downloadSSH = function(model) {
-    var sshCommands = "";
-    for (index in model.attributes.sliceInfo.sshCommands) {
-         sshCommand = model.attributes.sliceInfo.sshCommands[index];
-         sshCommands = sshCommands + sshCommand + "\n";
+  var sshCommands = '';
+
+  for (index in model.attributes.sliceInfo.sshCommands) {
+    sshCommand = model.attributes.sliceInfo.sshCommands[index];
+    sshCommands = sshCommands + sshCommand + '\n';
+  }
+
+  if (sshCommands.length == 0) {
+    alert('this slice has no instantiated instances yet');
+    return;
+  }
+
+  var htmlView = new HTMLView({
+    html: '<pre style="overflow: auto; word-wrap: normal; white-space: pre; word-wrap: normal;">' +
+      sshCommands + '</pre>'
+  });
+
+  XOSTenantApp.tenantSSHCommandsInterior.show(htmlView);
+
+  $('#tenant-ssh-commands-dialog').dialog({
+    autoOpen: false,
+    modal: true,
+    width: 640,
+    buttons: {
+      'Download': function() {
+        var dlLink = document.createElement('a');
+
+        dlLink.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(sshCommands));
+        dlLink.setAttribute('download', 'sshcommands.txt');
+        dlLink.click();
+
+        //window.open('data:text/text,' + encodeURIComponent(sshCommands));
+      },
+      'Close': function() {
+        $(this).dialog('close');
+      },
     }
-
-    if (sshCommands.length == 0) {
-         alert("this slice has no instantiated instances yet");
-         return;
-    }
-
-    var htmlView = new HTMLView({html: '<pre style="overflow: auto; word-wrap: normal; white-space: pre; word-wrap: normal;">' + sshCommands + '</pre>'});
-    XOSTenantApp.tenantSSHCommandsInterior.show(htmlView);
-
-    $("#tenant-ssh-commands-dialog").dialog({
-       autoOpen: false,
-       modal: true,
-       width: 640,
-       buttons : {
-            "Download": function() {
-                var dlLink = document.createElement('a');
-                dlLink.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(sshCommands));
-                dlLink.setAttribute('download', 'sshcommands.txt');
-                dlLink.click();
-
-                //window.open('data:text/text,' + encodeURIComponent(sshCommands));
-            },
-            "Close" : function() {
-              $(this).dialog("close");
-            },
-          }
-        });
-    $("#tenant-ssh-commands-dialog").dialog("open");
+  });
+  $('#tenant-ssh-commands-dialog').dialog('open');
 };
 
 XOSTenantApp.deleteSlice = function(model) {
-    var app=this;
-    app.deleteDialog(model, function() { console.log("afterDelete"); app.viewSlice(undefined); });
+  var app = this;
+
+  app.deleteDialog(model, function() {
+    app.viewSlice(undefined);
+  });
 };
 
 XOSTenantApp.viewSlice = function(model) {
-    if (XOSTenantApp.dirty) {
-        if (!confirm("The current instance has unsaved data -- view new instance anyway ?")) {
-            $("#tenantSliceSelector select").val(XOSTenantApp.currentSlice.id);
-            return;
-        }
+  if (XOSTenantApp.dirty) {
+    if (!confirm('The current instance has unsaved data -- view new instance anyway ?')) {
+      $('#tenantSliceSelector select').val(XOSTenantApp.currentSlice.id);
+      return;
     }
+  }
 
-    XOSTenantApp.setDirty(false);
+  XOSTenantApp.setDirty(false);
 
-    if (!model && xos.slicesPlus.models.length > 0) {
-        model = xos.slicesPlus.models[0];
-    }
+  if (!model && xos.slicesPlus.models.length > 0) {
+    model = xos.slicesPlus.models[0];
+  }
 
-    if (model) {
-        sliceSelector = new XOSTenantApp.tenantSliceSelectorView({collection: xos.slicesPlus,
-                                                                  selectedID: model ? model.id : null,
-                                                                 } );
-        XOSTenantApp.sliceSelector = sliceSelector;
-        XOSTenantApp.tenantSliceSelector.show(sliceSelector);
+  if (model) {
+    sliceSelector = new XOSTenantApp.tenantSliceSelectorView({
+      collection: xos.slicesPlus,
+      selectedID: model ? model.id : null,
+    });
 
-        tenantSummary = new XOSTenantApp.tenantSummaryView({model: model,
-                                                            choices: {mount_data_sets: make_choices(xos.tenant().public_volume_names, null),
-                                                                      serviceClass: make_choices(xos.tenant().blessed_service_class_names, xos.tenant().blessed_service_classes),
-                                                                      default_image: make_choices(xos.tenant().blessed_image_names, xos.tenant().blessed_images),
-                                                                      default_flavor: make_choices(xos.tenant().blessed_flavor_names, xos.tenant().blessed_flavors),},
-                                                           });
-        XOSTenantApp.tenantSummary.show(tenantSummary);
+    XOSTenantApp.sliceSelector = sliceSelector;
+    XOSTenantApp.tenantSliceSelector.show(sliceSelector);
 
-        tenantSites = new XOSTenantSiteCollection();
-        tenantSites.getFromSlice(model);
-        model.usersBuffer = model.attributes.users; /* save a copy of 'users' that we can edit. This prevents another view (developer) from overwriting our copy with a fetch from the server */
-        model.usersOrig = model.attributes.users;   /* save an immutable copy that we'll use for username lookups */
-        model.user_namesOrig = model.attributes.user_names;
-        model.tenantSiteCollection = tenantSites;
-        XOSTenantApp.tenantSites = tenantSites;
+    tenantSummary = new XOSTenantApp.tenantSummaryView({
+      model: model,
+      choices: {
+        mount_data_sets: make_choices(xos.tenant().public_volume_names, null),
+        serviceClass: make_choices(xos.tenant().blessed_service_class_names, xos.tenant().blessed_service_classes),
+        default_image: make_choices(xos.tenant().blessed_image_names, xos.tenant().blessed_images),
+        default_flavor: make_choices(xos.tenant().blessed_flavor_names, xos.tenant().blessed_flavors)
+      },
+    });
 
-        tenantSiteList = new XOSTenantApp.tenantSiteListView({collection: tenantSites });
-        XOSTenantApp.tenantSiteList.show(tenantSiteList);
-        // on xos.slicePlus.sort, need to update xostenantapp.tenantSites
+    XOSTenantApp.tenantSummary.show(tenantSummary);
 
-        XOSTenantApp.tenantButtons.show( new XOSTenantButtonView( { app: XOSTenantApp,
-                                                                    linkedView: tenantSummary } ) );
+    tenantSites = new XOSTenantSiteCollection();
+    tenantSites.getFromSlice(model);
+    model.usersBuffer = model.attributes.users; /* save a copy of 'users' that we can edit. This prevents another view (developer) from overwriting our copy with a fetch from the server */
+    model.usersOrig = model.attributes.users;   /* save an immutable copy that we'll use for username lookups */
+    model.user_namesOrig = model.attributes.user_names;
+    model.tenantSiteCollection = tenantSites;
+    XOSTenantApp.tenantSites = tenantSites;
 
-        XOSTenantApp.currentSlice = model;
-    } else {
-        XOSTenantApp.tenantSliceSelector.show(new HTMLView({html: ""}));
-        XOSTenantApp.tenantSummary.show(new HTMLView({html: "You have no slices"}));
-        XOSTenantApp.tenantSiteList.show(new HTMLView({html: ""}));
-        XOSTenantApp.tenantButtons.show( new XOSTenantButtonView( { template: "#xos-tenant-buttons-noslice-template",
-                                                                    app: XOSTenantApp,
-                                                                    linkedView: tenantSummary } ) );
-    }
+    tenantSiteList = new XOSTenantApp.tenantSiteListView({collection: tenantSites});
+    XOSTenantApp.tenantSiteList.show(tenantSiteList);
+    // on xos.slicePlus.sort, need to update xostenantapp.tenantSites
+
+    XOSTenantApp.tenantButtons.show(
+      new XOSTenantButtonView({
+        app: XOSTenantApp,
+        linkedView: tenantSummary
+      })
+    );
+
+    XOSTenantApp.currentSlice = model;
+  }
+  else {
+    XOSTenantApp.tenantSliceSelector.show(new HTMLView({html: ''}));
+    XOSTenantApp.tenantSummary.show(new HTMLView({html: 'You have no slices'}));
+    XOSTenantApp.tenantSiteList.show(new HTMLView({html: ''}));
+    XOSTenantApp.tenantButtons.show(
+      new XOSTenantButtonView({
+        template: '#xos-tenant-buttons-noslice-template',
+        app: XOSTenantApp,
+        linkedView: tenantSummary
+      })
+    );
+  }
 };
 
 XOSTenantApp.sanityCheck = function() {
-    errors = [];
-    if (xos.tenant().blessed_deployments && xos.tenant().blessed_deployments.length == 0) {
-        errors.push("no blessed deployments");
-    }
-    if (xos.tenant().blessed_service_classes.length == 0) {
-        errors.push("no blessed service classes");
-    }
-    if (xos.tenant().blessed_flavors.length == 0) {
-        errors.push("no blessed flavors");
-    }
-    if (xos.tenant().blessed_images.length == 0) {
-        errors.push("no blessed images");
-    }
-    if (xos.tenant().blessed_sites.length == 0) {
-        errors.push("no blessed sites");
-    }
-    if (xos.tenant().current_user_site_id == null) {
-        errors.push("current user does not have a site");
-    }
+  errors = [];
+  if (xos.tenant().blessed_deployments && xos.tenant().blessed_deployments.length == 0) {
+    errors.push('no blessed deployments');
+  }
+  if (xos.tenant().blessed_service_classes.length == 0) {
+    errors.push('no blessed service classes');
+  }
+  if (xos.tenant().blessed_flavors.length == 0) {
+    errors.push('no blessed flavors');
+  }
+  if (xos.tenant().blessed_images.length == 0) {
+    errors.push('no blessed images');
+  }
+  if (xos.tenant().blessed_sites.length == 0) {
+    errors.push('no blessed sites');
+  }
+  if (xos.tenant().current_user_site_id == null) {
+    errors.push('current user does not have a site');
+  }
 
-    if (errors.length > 0) {
-         t = templateFromId("#tenant-sanity-check")
-         $("#tenantSummary").html( t({errors: errors, blessed_deployment_names: xos.tenant().blessed_deployment_names}) );
-         return false;
-    }
+  if (errors.length > 0) {
+    t = templateFromId('#tenant-sanity-check');
+    $('#tenantSummary').html(t({
+      errors: errors,
+      blessed_deployment_names:
+      xos.tenant().blessed_deployment_names
+    }));
+    return false;
+  }
 
-    return true;
-}
-
-XOSTenantApp.collectionLoadChange = function() {
-    stats = xos.getCollectionStatus();
-
-    if (!XOSTenantApp.navigationStarted) {
-        if (stats["isLoaded"] + stats["failedLoad"] >= stats["startedLoad"]) {
-            if (XOSTenantApp.sanityCheck()) {
-                XOSTenantApp.viewSlice(undefined);
-            }
-        } else {
-            $("#tenantSummary").html("<h3>Loading...</h3><div id='xos-startup-progress'></div>");
-            $("#xos-startup-progress").progressbar({value: stats["completedLoad"], max: stats["startedLoad"]});
-        }
-    }
+  return true;
 };
 
-XOSTenantApp.on("start", function() {
-     XOSTenantApp.buildViews();
-
-     // fire it once to initially show the progress bar
-     XOSTenantApp.collectionLoadChange();
-
-     // fire it each time the collection load status is updated
-     Backbone.on("xoslib:collectionLoadChange", XOSTenantApp.collectionLoadChange);
-});
-
-$(document).ready(function(){
-    XOSTenantApp.start();
-});
-
+XOSTenantApp.collectionLoadChange = function() {
+  stats = xos.getCollectionStatus();
+
+  if (!XOSTenantApp.navigationStarted) {
+    if (stats['isLoaded'] + stats['failedLoad'] >= stats['startedLoad']) {
+      if (XOSTenantApp.sanityCheck()) {
+        XOSTenantApp.viewSlice(undefined);
+      }
+    }
+    else {
+      $('#tenantSummary').html('<h3>Loading...</h3><div id="xos-startup-progress"></div>');
+      $('#xos-startup-progress').progressbar({value: stats['completedLoad'], max: stats['startedLoad']});
+    }
+  }
+};
+
+XOSTenantApp.on('start', function() {
+  XOSTenantApp.buildViews();
+
+  // fire it once to initially show the progress bar
+  XOSTenantApp.collectionLoadChange();
+
+  // fire it each time the collection load status is updated
+  Backbone.on('xoslib:collectionLoadChange', XOSTenantApp.collectionLoadChange);
+});
+
+$(document).ready(function() {
+  XOSTenantApp.start();
+});
+/* eslint-enable */
diff --git a/xos/core/xoslib/static/js/xoslib/xos-backbone.js b/xos/core/xoslib/static/js/xoslib/xos-backbone.js
index dfc6c38..a677d88 100644
--- a/xos/core/xoslib/static/js/xoslib/xos-backbone.js
+++ b/xos/core/xoslib/static/js/xoslib/xos-backbone.js
@@ -1,4 +1,6 @@
-if (! window.XOSLIB_LOADED ) {
+
+/* eslint-disable*/
+if (! window.XOSLIB_LOADED) {
     window.XOSLIB_LOADED=true;
 
     XOS_BASE = "/xos";
@@ -53,199 +55,224 @@
 
         /* from backbone-tastypie.js */
         url: function() {
-                    var url = this.attributes.resource_uri;
+            // TODO handle error if no property
+            var url = this.attributes.resource_uri;
 
-                    if (!url) {
-                        if (this.id) {
-                            url = this.urlRoot + this.id;
-                        } else {
-                            // this happens when creating a new model.
-                            url = this.urlRoot;
-                        }
-                    }
-
-                    if (!url) {
-                        // XXX I'm not sure this does anything useful
-                        url = ( _.isFunction( this.collection.url ) ? this.collection.url() : this.collection.url );
-                        url = url || this.urlRoot;
-                    }
-
-                    // remove any existing query parameters
-                    url && ( url.indexOf("?") > -1 ) && ( url = url.split("?")[0] );
-
-                    url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
-
-                    url && ( url += "?no_hyperlinks=1" );
-
-                    return url;
-            },
-
-            listMethods: function() {
-                var res = [];
-                for(var m in this) {
-                    if(typeof this[m] == "function") {
-                        res.push(m)
-                    }
-                }
-                return res;
-            },
-
-            save: function(attributes, options) {
-                if (this.preSave) {
-                    this.preSave();
+            if (!url) {
+                if (this.id) {
+                    url = this.urlRoot + this.id;
                 }
-                return Backbone.Model.prototype.save.call(this, attributes, options);
-            },
-
-            getChoices: function(fieldName, excludeChosen) {
-                choices=[];
-                if (fieldName in this.m2mFields) {
-                    for (index in xos[this.m2mFields[fieldName]].models) {
-                        candidate = xos[this.m2mFields[fieldName]].models[index];
-                        if (excludeChosen && idInArray(candidate.id, this.attributes[fieldName])) {
-                            continue;
-                        }
-                        choices.push(candidate.id);
-                    }
+                else {
+                    // this happens when creating a new model.
+                    url = this.urlRoot;
                 }
-                return choices;
-            },
+            }
 
-            /* If a 'validate' method is supplied, then it will be called
-               automatically on save. Unfortunately, save calls neither the
-               'error' nor the 'success' callback if the validator fails.
+            if (!url) {
+                // XXX I'm not sure this does anything useful
+                url = _.isFunction(this.collection.url) ? this.collection.url() : this.collection.url;
+                url = url || this.urlRoot;
+            }
 
-               For now, we're calling our validator 'xosValidate' so this
-               autoamtic validation doesn't occur.
-            */
+            // remove any existing query parameters
+            url && url.indexOf("?") > -1  && (url = url.split("?")[0]);
 
-            xosValidate: function(attrs, options) {
-                errors = {};
-                foundErrors = false;
-                _.each(this.validators, function(validatorList, fieldName) {
-                    _.each(validatorList, function(validator) {
-                        if (fieldName in attrs) {
-                            validatorResult = validateField(validator, attrs[fieldName], this)
-                            if (validatorResult != true) {
-                                errors[fieldName] = validatorResult;
-                                foundErrors = true;
-                            }
+            url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
+
+            url && ( url += "?no_hyperlinks=1" );
+
+            return url;
+        },
+
+        listMethods: function() {
+            var res = [];
+            for(var m in this) {
+                if(typeof this[m] == "function") {
+                    res.push(m)
+                }
+            }
+            return res;
+        },
+
+        save: function(attributes, options) {
+            if (this.preSave) {
+                this.preSave();
+            }
+            return Backbone.Model.prototype.save.call(this, attributes, options);
+        },
+
+        getChoices: function(fieldName, excludeChosen) {
+            choices=[];
+            console.log(xos);
+            if (fieldName in this.m2mFields) {
+                for (index in xos[this.m2mFields[fieldName]].models) {
+                    candidate = xos[this.m2mFields[fieldName]].models[index];
+                    if (excludeChosen && idInArray(candidate.id, this.attributes[fieldName])) {
+                        continue;
+                    }
+                    choices.push(candidate.id);
+                }
+            }
+            return choices;
+        },
+
+        /* If a 'validate' method is supplied, then it will be called
+           automatically on save. Unfortunately, save calls neither the
+           'error' nor the 'success' callback if the validator fails.
+
+           For now, we're calling our validator 'xosValidate' so this
+           autoamtic validation doesn't occur.
+        */
+
+        /**
+        * This should call custom validators defined in the model
+        *
+        * @param {object} attrs an object containin the model attributes
+        * @param {object} options (unused)
+        * @returns {Array} Errors list
+        */
+        xosValidate: function(attrs, options) {
+            errors = {};
+            foundErrors = false;
+
+            _.each(this.validators, function(validatorList, fieldName) {
+                _.each(validatorList, function(validator) {
+                    if (fieldName in attrs) {
+                        // call validateField method in xos-utils.js
+                        validatorResult = validateField(validator, attrs[fieldName], this);
+                        if (validatorResult != true) {
+                            errors[fieldName] = validatorResult;
+                            foundErrors = true;
                         }
-                    });
+                    }
                 });
-                if (foundErrors) {
-                    return errors;
-                }
-                // backbone.js semantics -- on successful validate, return nothing
-            },
+            });
+            if (foundErrors) {
+                return errors;
+            }
+            // backbone.js semantics -- on successful validate, return nothing
+        },
 
-            /* uncommenting this would make validate() call xosValidate()
-            validate: function(attrs, options) {
-                r = this.xosValidate(attrs, options);
-                console.log("validate");
-                console.log(r);
-                return r;
-            }, */
+        /* uncommenting this would make validate() call xosValidate()
+        validate: function(attrs, options) {
+            r = this.xosValidate(attrs, options);
+            console.log("validate");
+            console.log(r);
+            return r;
+        }, */
     });
 
     XOSCollection = Backbone.Collection.extend({
         objects: function() {
-                    return this.models.map(function(element) { return element.attributes; });
-                 },
+            return this.models.map(function(element) {
+                return element.attributes;
+            });
+        },
 
-        initialize: function(){
-          this.isLoaded = false;
-          this.failedLoad = false;
-          this.startedLoad = false;
-          this.sortVar = 'name';
-          this.sortOrder = 'asc';
-          this.on( "sort", this.sorted );
-        },
-
-        relatedCollections: [],
-        foreignCollections: [],
-        foreignFields: {},
+        initialize: function() {
+            this.isLoaded = false;
+            this.failedLoad = false;
+            this.startedLoad = false;
+            this.sortVar = 'name';
+            this.sortOrder = 'asc';
+            this.on('sort', this.sorted);
+        },
+
+        relatedCollections: [],
+        foreignCollections: [],
+        foreignFields: {},
         m2mFields: {},
         readonlyFields: [],
-        detailLinkFields: [],
-
-        sorted: function() {
-            //console.log("sorted " + this.modelName);
-        },
-
-        simpleComparator: function( model ){
-          parts=this.sortVar.split(".");
-          result = model.get(parts[0]);
-          for (index=1; index<parts.length; ++index) {
-              result=result[parts[index]];
-          }
-          return result;
-        },
-
-        comparator: function (left, right) {
-            var l = this.simpleComparator(left);
-            var r = this.simpleComparator(right);
-
-            if (l === void 0) return -1;
-            if (r === void 0) return 1;
-
-            if (this.sortOrder=="desc") {
-                return l < r ? 1 : l > r ? -1 : 0;
-            } else {
-                return l < r ? -1 : l > r ? 1 : 0;
-            }
-        },
-
-        fetchSuccess: function(collection, response, options) {
-            //console.log("fetch succeeded " + collection.modelName);
-            this.failedLoad = false;
-            this.fetching = false;
-            if (!this.isLoaded) {
-                this.isLoaded = true;
-                Backbone.trigger("xoslib:collectionLoadChange", this);
-            }
-            this.trigger("fetchStateChange");
-            if (options["orig_success"]) {
-                options["orig_success"](collection, response, options);
-            }
-        },
-
-        fetchFailure: function(collection, response, options) {
-            //console.log("fetch failed " + collection.modelName);
-            this.fetching = false;
-            if ((!this.isLoaded) && (!this.failedLoad)) {
-                this.failedLoad=true;
-                Backbone.trigger("xoslib:collectionLoadChange", this);
-            }
-            this.trigger("fetchStateChange");
-            if (options["orig_failure"]) {
-                options["orig_failure"](collection, response, options);
-            }
-        },
-
-        fetch: function(options) {
-            var self=this;
-            this.fetching=true;
-            //console.log("fetch " + this.modelName);
-            if (!this.startedLoad) {
-                this.startedLoad=true;
-                Backbone.trigger("xoslib:collectionLoadChange", this);
-            }
-            this.trigger("fetchStateChange");
-            if (options == undefined) {
-                options = {};
-            }
-            options["orig_success"] = options["success"];
-            options["orig_failure"] = options["failure"];
-            options["success"] = function(collection, response, options) { self.fetchSuccess.call(self, collection, response, options); };
-            options["failure"] = this.fetchFailure;
-            Backbone.Collection.prototype.fetch.call(this, options);
-        },
-
-        startPolling: function() {
-            if (!this._polling) {
+        detailLinkFields: [],
+
+        sorted: function() {
+            //console.log("sorted " + this.modelName);
+        },
+
+        simpleComparator: function(model) {
+            parts=this.sortVar.split(".");
+            result = model.get(parts[0]);
+            for (index=1; index<parts.length; ++index) {
+                result=result[parts[index]];
+            }
+            return result;
+        },
+
+        comparator: function(left, right) {
+            var l = this.simpleComparator(left);
+            var r = this.simpleComparator(right);
+
+            if (l === void 0) {
+                return -1;
+            }
+            if (r === void 0) {
+                return 1;
+            }
+
+            if (this.sortOrder == "desc") {
+                return l < r ? 1 : l > r ? -1 : 0;
+            }
+            else {
+                return l < r ? -1 : l > r ? 1 : 0;
+            }
+        },
+
+        fetchSuccess: function(collection, response, options) {
+            //console.log("fetch succeeded " + collection.modelName);
+            this.failedLoad = false;
+            this.fetching = false;
+            if (!this.isLoaded) {
+                this.isLoaded = true;
+                Backbone.trigger("xoslib:collectionLoadChange", this);
+            }
+            this.trigger("fetchStateChange");
+            if (options["orig_success"]) {
+                options["orig_success"](collection, response, options);
+            }
+        },
+
+        fetchFailure: function(collection, response, options) {
+            //console.log("fetch failed " + collection.modelName);
+            this.fetching = false;
+            if (!this.isLoaded && !this.failedLoad) {
+                this.failedLoad=true;
+                Backbone.trigger("xoslib:collectionLoadChange", this);
+            }
+            this.trigger("fetchStateChange");
+            if (options["orig_failure"]) {
+                options["orig_failure"](collection, response, options);
+            }
+        },
+
+        fetch: function(options) {
+            var self=this;
+
+            this.fetching=true;
+            //console.log("fetch " + this.modelName);
+            if (!this.startedLoad) {
+                this.startedLoad=true;
+                Backbone.trigger("xoslib:collectionLoadChange", this);
+            }
+            this.trigger("fetchStateChange");
+            if (options == undefined) {
+                options = {};
+            }
+            options["orig_success"] = options["success"];
+            options["orig_failure"] = options["failure"];
+            options["success"] = function(collection, response, options) {
+                self.fetchSuccess.call(self, collection, response, options);
+            };
+            options["failure"] = this.fetchFailure;
+            Backbone.Collection.prototype.fetch.call(this, options);
+        },
+
+        startPolling: function() {
+            if (!this._polling) {
                 var collection=this;
-                setInterval(function() { collection.fetch(); }, 10000);
+
+                setInterval(function() {
+                    collection.fetch();
+                }, 10000);
                 this._polling=true;
                 this.fetch();
             }
@@ -275,8 +302,8 @@
             }
 
                 // when the original success function completes mark this collection as fetched
-            var self = this,
-            successWrapper = function(success){
+            var self = this;
+            var successWrapper = function(success){
                 return function(){
                     self._fetched = true;
                     success && success.apply(this, arguments);
@@ -312,35 +339,35 @@
         */
 
         filterBy: function(fieldName, value) {
-             filtered = this.filter(function(obj) {
-                 return obj.get(fieldName) == value;
-                 });
-             return new this.constructor(filtered);
+            filtered = this.filter(function(obj) {
+                return obj.get(fieldName) == value;
+                });
+            return new this.constructor(filtered);
         },
 
         /* from backbone-tastypie.js */
         url: function( models ) {
-                    var url = this.urlRoot || ( models && models.length && models[0].urlRoot );
-                    url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
+            var url = this.urlRoot || ( models && models.length && models[0].urlRoot );
+            url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
 
-                    url && ( url += "?no_hyperlinks=1" );
+            url && ( url += "?no_hyperlinks=1" );
 
-                    if (this.currentUserCanSee) {
-                        url && ( url += "&current_user_can_see=1" );
-                    }
+            if (this.currentUserCanSee) {
+                url && ( url += "&current_user_can_see=1" );
+            }
 
-                    return url;
-            },
+            return url;
+        },
 
         listMethods: function() {
-                var res = [];
-                for(var m in this) {
-                    if(typeof this[m] == "function") {
-                        res.push(m)
-                    }
-                }
-                return res;
-            },
+            var res = [];
+            for(var m in this) {
+                if(typeof this[m] == "function") {
+                    res.push(m)
+                }
+            }
+            return res;
+        },
     });
 
     function get_defaults(modelName) {
@@ -359,7 +386,50 @@
         }
     }
 
+    /**
+    * This is an helper function to define XOS model.
+    *
+    * @param {object} lib A backbone collection library (eg: xos)
+    * @param {object} attrs The model attributes
+    * @param {string} attrs.modelName The name of the model
+    * @param {string} attrs.urlRoot The base url for the collection
+    * @param {object} [attrs.relatedCollections] collections which should be drawn as an inline 
+                                                 list when the detail view is displayed. 
+                                                 Format: **collection:collectionFieldName** 
+                                                 where **collectionFieldName** is the name of the field 
+                                                 in the collection that points back to the collection 
+                                                 in the detail view.
+    * @param {array} [attrs.foreignCollections] collections which are used in idToName() calls
+                                when presenting the data to the user. Used to
+                                create a listento event. Somewhat
+                                redundant with foreignFields.
+    * @param {object} [attrs.foreignFields] **localFieldName:collection**. Used to
+                                automatically map ids into humanReadableNames
+                                when presenting data to the user.
+    * @param {object} [attrs.m2mFields] **localFieldName:collection**. Used to
+                                populate choices in picker lists. Similar to
+                                foreignFields.
+    * @param {Array} [attrs.listFields] Fields to display in lists
+    * @param {Array} {attrs.detailFields} Fields to display in detail views
+    * @param {Array} [attrs.addFields] Fields to display in popup add windows
+    * @param {Object} [attrs.inputType] by default, "detailFields" will be displayed
+                                as text input controls. This will let you display
+                                a checkbox or a picker instead.
+    * @param {Object} [attrs.defaults] Override the model defaults, `extend_defaults` can be used.
+    * @param {Object} [attrs.validators] Add validators to this model. Use `validateField` method in xos-util.js
+    * @param {function} [attrs.preSave] A pre-save method
+    * @param {function} [attrs.xosValidate] Override the default xosValidate.
+    *                                       If you want to call it either start the function with
+    *                                       `errors = XOSModel.prototype.xosValidate.call(this, attrs, options);`
+    * @returns void
+    */
+
     function define_model(lib, attrs) {
+
+        // NOTE shouldn't we trhow an error if no:
+        // - attrs.urlRoot
+        // - attrs.modelName
+
         modelName = attrs.modelName;
         modelClassName = modelName;
         collectionClass = attrs.collectionClass || XOSCollection;
@@ -371,6 +441,8 @@
 
         attrs.inputType = attrs.inputType || {};
         attrs.foreignFields = attrs.foreignFields || {};
+        // NOTE m2mFields are not set in modelAttr,
+        // see list in for loop
         attrs.m2mFields = attrs.m2mFields || {};
         attrs.readOnlyFields = attrs.readOnlyFields || [];
         attrs.detailLinkFields = attrs.detailLinkFields || ["id","name"];
@@ -389,7 +461,9 @@
                 modelAttrs[key] = value;
                 collectionAttrs[key] = value;
             }
-            if ($.inArray(key, ["validate", "preSave", "readOnlyFields"]) >= 0) {
+            // NOTE xosValidate added by Matteo Scandolo
+            // check with Scott
+            if ($.inArray(key, ["validate", "preSave", "readOnlyFields", "xosValidate"]) >= 0) {
                 modelAttrs[key] = value;
             }
         }
@@ -398,17 +472,18 @@
             modelAttrs.defaults = get_defaults(modelName);
         }
 
-//        if ((typeof xosdefaults !== "undefined") && xosdefaults[modelName]) {
-//            modelAttrs["defaults"] = xosdefaults[modelName];
-//        }
-
+        // if there are default validators for this model
+        // extend with customs
         if ((typeof xosvalidators !== "undefined") && xosvalidators[modelName]) {
             modelAttrs["validators"] = $.extend({}, xosvalidators[modelName], attrs["validators"] || {});
-        } else if (attrs["validators"]) {
-            modelAttrs["validators"] = attrs["validators"];
-            console.log(attrs);
-            console.log(modelAttrs);
         }
+        // else use custom
+        else if (attrs["validators"]) {
+            modelAttrs["validators"] = attrs["validators"];
+            // console.log(attrs);
+            // console.log(modelAttrs);
+        }
+        // NOTE Why define validators in multiple places?
 
         lib[modelName] = XOSModel.extend(modelAttrs);
 
@@ -485,27 +560,27 @@
                             });
 
         define_model(this, {urlRoot: SLICE_API,
-                           relatedCollections: {"instances": "slice", "slicePrivileges": "slice", "networks": "owner", "controller_slices": "slice"},
-                           foreignCollections: ["services", "sites"],
-                           foreignFields: {"service": "services", "site": "sites"},
-                           listFields: ["backend_status", "id", "name", "enabled", "description", "slice_url", "site", "max_instances", "service"],
-                           detailFields: ["backend_status", "backend_register", "name", "site", "enabled", "description", "slice_url", "max_instances"],
-                           inputType: {"enabled": "checkbox"},
-                           modelName: "slice",
-                           xosValidate: function(attrs, options) {
-                               errors = XOSModel.prototype.xosValidate.call(this, attrs, options);
-                               // validate that slice.name starts with site.login_base
-                               site = attrs.site || this.site;
-                               if ((site!=undefined) && (attrs.name!=undefined)) {
-                                   site = xos.sites.get(site);
-                                   if (attrs.name.indexOf(site.attributes.login_base+"_") != 0) {
+                            relatedCollections: {"instances": "slice", "slicePrivileges": "slice", "networks": "owner", "controller_slices": "slice"},
+                            foreignCollections: ["services", "sites"],
+                            foreignFields: {"service": "services", "site": "sites"},
+                            listFields: ["backend_status", "id", "name", "enabled", "description", "slice_url", "site", "max_instances", "service"],
+                            detailFields: ["backend_status", "backend_register", "name", "site", "enabled", "description", "slice_url", "max_instances"],
+                            inputType: {"enabled": "checkbox"},
+                            modelName: "slice",
+                            xosValidate: function(attrs, options) {
+                                errors = XOSModel.prototype.xosValidate.call(this, attrs, options);
+                                // validate that slice.name starts with site.login_base
+                                site = attrs.site || this.site;
+                                if ((site!=undefined) && (attrs.name!=undefined)) {
+                                    site = xos.sites.get(site);
+                                    if (attrs.name.indexOf(site.attributes.login_base+"_") != 0) {
                                         errors = errors || {};
                                         errors["name"] = "must start with " + site.attributes.login_base + "_";
-                                   }
-                               }
-                               return errors;
-                             },
-                           });
+                                    }
+                                }
+                                return errors;
+                            },
+                        });
 
         define_model(this, {urlRoot: SLICEPRIVILEGE_API,
                             foreignCollections: ["slices", "users", "sliceRoles"],
@@ -698,30 +773,31 @@
         // enhanced REST
         // XXX this really needs to somehow be combined with Slice, to avoid duplication
         define_model(this, {urlRoot: SLICEPLUS_API,
-                           relatedCollections: {"instances": "slice", "slicePrivileges": "slice", "networks": "owner"},
-                           foreignCollections: ["services", "sites"],
-                           foreignFields: {"service": "services", "site": "sites"},
-                           listFields: ["backend_status", "id", "name", "enabled", "description", "slice_url", "site", "max_instances", "service"],
-                           detailFields: ["backend_status", "backend_register", "name", "site", "enabled", "description", "slice_url", "max_instances"],
-                           inputType: {"enabled": "checkbox"},
-                           modelName: "slicePlus",
-                           collectionName: "slicesPlus",
-                           defaults: extend_defaults("slice", {"network_ports": "", "site_allocation": []}),
-                           validators: {"network_ports": ["portspec"]},
-                           xosValidate: function(attrs, options) {
-                               errors = XOSModel.prototype.xosValidate.call(this, attrs, options);
-                               // validate that slice.name starts with site.login_base
-                               site = attrs.site || this.site;
-                               if ((site!=undefined) && (attrs.name!=undefined)) {
-                                   site = xos.sites.get(site);
-                                   if (attrs.name.indexOf(site.attributes.login_base+"_") != 0) {
+                            relatedCollections: {"instances": "slice", "slicePrivileges": "slice", "networks": "owner"},
+                            foreignCollections: ["services", "sites"],
+                            foreignFields: {"service": "services", "site": "sites"},
+                            listFields: ["backend_status", "id", "name", "enabled", "description", "slice_url", "site", "max_instances", "service"],
+                            detailFields: ["backend_status", "backend_register", "name", "site", "enabled", "description", "slice_url", "max_instances"],
+                            inputType: {"enabled": "checkbox"},
+                            modelName: "slicePlus",
+                            collectionName: "slicesPlus",
+                            defaults: extend_defaults("slice", {"network_ports": "", "site_allocation": []}),
+                            validators: {"network_ports": ["portspec"]},
+                            xosValidate: function(attrs, options) {
+                                errors = XOSModel.prototype.xosValidate.call(this, attrs, options);
+                                // validate that slice.name starts with site.login_base
+
+                                var site = xos.tenant().current_user_login_base;
+                                if ((site!=undefined) && (attrs.name!=undefined)) {
+                                    if (attrs.name.indexOf(site + "_") < 0) {
                                         errors = errors || {};
-                                        errors["name"] = "must start with " + site.attributes.login_base + "_";
-                                   }
-                               }
-                               return errors;
-                             },
-                           });
+                                        errors["name"] = "must start with " + site + "_";
+                                    }
+                                }
+
+                                return errors;
+                            },
+                        });
 
         define_model(this, {urlRoot: TENANTVIEW_API,
                             modelName: "tenantview",
@@ -787,29 +863,30 @@
     xos = new xoslib();
 
     function getCookie(name) {
-        var cookieValue = null;
-        if (document.cookie && document.cookie != '') {
-            var cookies = document.cookie.split(';');
-            for (var i = 0; i < cookies.length; i++) {
-                var cookie = jQuery.trim(cookies[i]);
-                // Does this cookie string begin with the name we want?
-                if (cookie.substring(0, name.length + 1) == (name + '=')) {
-                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
-                    break;
-                }
-            }
-        }
-        return cookieValue;
+        var cookieValue = null;
+        if (document.cookie && document.cookie != '') {
+            var cookies = document.cookie.split(';');
+            for (var i = 0; i < cookies.length; i++) {
+                var cookie = jQuery.trim(cookies[i]);
+                // Does this cookie string begin with the name we want?
+                if (cookie.substring(0, name.length + 1) == (name + '=')) {
+                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                    break;
+                }
+            }
+        }
+        return cookieValue;
     }
 
     (function() {
-      var _sync = Backbone.sync;
-      Backbone.sync = function(method, model, options){
-        options.beforeSend = function(xhr){
-          var token = getCookie("csrftoken");
-          xhr.setRequestHeader('X-CSRFToken', token);
-        };
-        return _sync(method, model, options);
-      };
+        var _sync = Backbone.sync;
+        Backbone.sync = function(method, model, options){
+            options.beforeSend = function(xhr){
+                var token = getCookie("csrftoken");
+                xhr.setRequestHeader('X-CSRFToken', token);
+            };
+            return _sync(method, model, options);
+        };
     })();
 }
+/* eslint-enable */
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/xoslib/xos-defaults.js b/xos/core/xoslib/static/js/xoslib/xos-defaults.js
index 4c38f3a..06ee0d9 100644
--- a/xos/core/xoslib/static/js/xoslib/xos-defaults.js
+++ b/xos/core/xoslib/static/js/xoslib/xos-defaults.js
@@ -1,3 +1,6 @@
+/* eslint-disable quotes, no-undef, max-len, new-cap*/
+/* eslint indent: [2, 2]*/
+console.warn('**** XOS DEFAULT ****');
 function xos_get_defaults() {
   this.account = {"updated": null, "policed": null, "created": null, "deleted": false, "site": null, "lazy_blocked": false, "backend_register": "{}", "write_protect": false, "backend_status": "0 - Provisioning in progress", "no_sync": false, "enacted": null};
   this.charge = {"updated": null, "slice": null, "date": null, "policed": null, "created": null, "deleted": false, "object": null, "account": null, "lazy_blocked": false, "backend_register": "{}", "write_protect": false, "amount": 0.0, "state": "pending", "invoice": null, "coreHours": 0.0, "backend_status": "0 - Provisioning in progress", "kind": "besteffort", "no_sync": false, "enacted": null};
@@ -64,3 +67,4 @@
   this.userDashboardView = {"updated": null, "policed": null, "created": null, "deleted": false, "dashboardView": null, "lazy_blocked": false, "backend_register": "{}", "write_protect": false, "user": null, "backend_status": "0 - Provisioning in progress", "order": 0, "no_sync": false, "enacted": null};
 };
 xosdefaults = new xos_get_defaults();
+/* eslint-enable quotes, no-undef, max-len, new-cap*/
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/xoslib/xos-util.js b/xos/core/xoslib/static/js/xoslib/xos-util.js
index 6f4db85..66c01ce 100644
--- a/xos/core/xoslib/static/js/xoslib/xos-util.js
+++ b/xos/core/xoslib/static/js/xoslib/xos-util.js
@@ -1,9 +1,12 @@
-// misc utility functions
+/* eslint-disable indent*/
+////////////////////////////
+// misc utility functions //
+////////////////////////////
 
 function idInArray(id, arr) {
     // because sometimes ids are strings and sometimes they're integers
-    for (index in arr) {
-        if (id.toString() == arr[index].toString()) {
+    for (var index in arr) {
+        if (id.toString() === arr[index].toString()) {
             return true;
         }
     }
@@ -24,113 +27,140 @@
     return s.charAt(0).toUpperCase() + s.slice(1);
 }
 
-function toTitleCase(str)
-{
-    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
+function toTitleCase(str) {
+    return str.replace(/\w\S*/g, function(txt) {
+        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
+    });
 }
 
-function fieldNameToHumanReadable(str)
-{
-    str = str.replace("_", " ");
+function fieldNameToHumanReadable(str) {
+    str = str.replace('_', ' ');
     return toTitleCase(str);
 }
 
 // http://stackoverflow.com/questions/2117320/set-maximum-displayed-rows-count-for-html-table
 function limitTableRows(tableSelector, maxRows) {
-    var table = $(tableSelector)[0] //document.getElementById(tableId);
+    var table = $(tableSelector)[0]; //document.getElementById(tableId);
     var wrapper = table.parentNode;
     var rowsInTable = table.rows.length;
+
     try {
         var border = getComputedStyle(table.rows[0].cells[0], '').getPropertyValue('border-top-width');
+
         border = border.replace('px', '') * 1;
-    } catch (e) {
+    }
+    catch (e) {
         var border = table.rows[0].cells[0].currentStyle.borderWidth;
-        border = (border.replace('px', '') * 1) / 2;
+
+        border = border.replace('px', '') * 1 / 2;
     }
     var height = 0;
+
     if (rowsInTable > maxRows) {
         for (var i = 0; i < maxRows; i++) {
             height += table.rows[i].clientHeight + border;
-            //console.log("XXX " + height + " " + table.rows[i].clientHeight + " " + border);
+            //console.log('XXX ' + height + ' ' + table.rows[i].clientHeight + ' ' + border);
         }
-        wrapper.style.height = height + "px";
+        wrapper.style.height = height + 'px';
     }
 }
 
 function validateField(validatorName, value, obj) {
-    if (validatorName=="notBlank") {
-        if ((value==undefined) || (value=="")) {
-            return "can not be blank";
+    if (validatorName === 'notBlank') {
+        if (value === undefined || value === null || value === '') {
+            return 'can not be blank';
         }
     }
 
     // if notBlank wasn't set, and the field is blank, then we can return
-    if ((value==undefined) || (value=="")) {
+    if (value === undefined || value === null || value === '') {
         return true;
     }
-
+    /* eslint-disable default-case */
     switch (validatorName) {
-        case "url":
-            if (! /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value)) {
-                return "must be a valid url";
-            }
-            break;
+    case 'url':
+        if (! /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value)) {
+            return 'must be a valid url';
+        }
+        break;
 
-        case "portspec":
-            if (! $.trim(value).match(portlist_regexp())) {
-                return "must be a valid portspec (example: 'tcp 123, udp 456-789')"
-            }
-            break;
+    case 'portspec':
+        if (! $.trim(value).match(portlist_regexp())) {
+            return 'must be a valid portspec (example: \'tcp 123, udp 456-789\')';
+        }
+        break;
+    // TODO test this before add
+    // default:
+    //     return true;
+    //     break;
+    /* eslint-enable default-case */
     }
 
     return true;
 }
 
-function array_diff(a1, a2)
-{
-  var a=[], diff=[];
-  for(var i=0;i<a1.length;i++)
-    a[a1[i]]=true;
-  for(var i=0;i<a2.length;i++)
-    if(a[a2[i]]) delete a[a2[i]];
-    else a[a2[i]]=true;
-  for(var k in a)
-    diff.push(k);
-  return diff;
+function array_diff(a1, a2) {
+    var a = [], diff = [];
+
+    for(var i = 0;i < a1.length;i++) {
+        a[a1[i]] = true;
+    }
+
+    for(var i = 0;i < a2.length;i++) {
+        if(a[a2[i]]) {
+            delete a[a2[i]];
+        }
+        else {
+            a[a2[i]] = true;
+        }
+    }
+
+    for(var k in a) {
+        // check that the property in not inherithed
+        if ({}.hasOwnProperty.call(a, k)) {
+            diff.push(k);
+        }
+    }
+
+    return diff;
 }
 
-function array_subtract(a1, a2)
-{
-    result=[]
-    for (index in a1) {
-        value = a1[index];
-        if (!$.inArray(value, a2) >= 0) {
-            result.push(value);
+function array_subtract(a1, a2) {
+    var result = [];
+
+    // why not for ... of, move to lodash instead
+    for (var index in a1) {
+        if ({}.hasOwnProperty.call(a1, index)) {
+            var value = a1[index];
+
+            if (!$.inArray(value, a2) >= 0) {
+                result.push(value);
+            }
         }
+
     }
     return result;
 }
 
-function array_same_elements(arr1, arr2)
-{
+function array_same_elements(arr1, arr2) {
     // return true if arrays have same elements, even if order is different
-    return ($(arr1).not(arr2).length == 0 && $(arr2).not(arr1).length == 0);
+    return $(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0;
 }
 
-function array_pair_lookup(x, names, values)
-{
-    for (index in values) {
-        if (values[index] == x) {
+function array_pair_lookup(x, names, values) {
+    for (var index in values) {
+        if (values[index] === x) {
             return names[index];
         }
     }
-    return "object #" + x;
+    return 'object #' + x;
 }
 
 function all_options(selector) {
-    el = $(selector);
-    result = [];
-    _.each(el.find("option"), function(option) {
+    var el = $(selector);
+    var result = [];
+
+    _.each(el.find('option'), function(option) {
         result.push($(option).val());
     });
     return result;
@@ -138,79 +168,93 @@
 
 function make_same_width(containerSelector, itemSelector) {
     var maxWidth = 0;
-    $(containerSelector).find(itemSelector).each( function(index) { maxWidth = Math.max(maxWidth, $(this).width()); });
-    console.log(maxWidth);
-    $(containerSelector).find(itemSelector).each( function(index) { $(this).width(maxWidth); });
+
+    $(containerSelector).find(itemSelector).each(function() {
+        maxWidth = Math.max(maxWidth, $(this).width());
+    });
+
+    $(containerSelector).find(itemSelector).each(function() {
+        $(this).width(maxWidth);
+    });
 }
 
 function strip_scripts(s) {
-    var div = document.createElement('div');
-    div.innerHTML = s;
-    var scripts = div.getElementsByTagName('script');
-    var i = scripts.length;
-    while (i--) {
-      scripts[i].parentNode.removeChild(scripts[i]);
-    }
-    return div.innerHTML;
-  }
+    var div = document.createElement('div');
+
+    div.innerHTML = s;
+    var scripts = div.getElementsByTagName('script');
+    var i = scripts.length;
+
+    while (i--) {
+        scripts[i].parentNode.removeChild(scripts[i]);
+    }
+    return div.innerHTML;
+}
 
 function parse_portlist(ports) {
-    /* Support a list of ports in the format "protocol:port, protocol:port, ..."
+    /* Support a list of ports in the format 'protocol:port, protocol:port, ...'
         examples:
             tcp 123
             tcp 123:133
             tcp 123, tcp 124, tcp 125, udp 201, udp 202
 
-        User can put either a "/" or a " " between protocol and ports
-        Port ranges can be specified with "-" or ":"
+        User can put either a '/' or a ' ' between protocol and ports
+        Port ranges can be specified with '-' or ':'
 
         This is a straightforward port of the code in core/models/network.py
     */
 
     var nats = [];
+
     if (ports) {
-        parts = ports.split(",")
+        var parts = ports.split(',');
+        var parts2, protocol, first, last, portStr;
+
         $.each(parts, function(index, part) {
             part = $.trim(part);
-            if (part.indexOf("/")>=0) {
-                parts2 = part.split("/",2);
-                protocol=parts2[0];
-                ports=parts2[1];
-            } else if (part.indexOf(" ")>=0) {
-                parts2 = part.split(" +",2);
-                protocol=parts2[0];
-                ports=parts2[1];
-            } else {
-                throw 'malformed port specifier ' + part + ', format example: "tcp 123, tcp 201:206, udp 333"';
+            if (part.indexOf('/') >= 0) {
+                parts2 = part.split('/',2);
+
+                protocol = parts2[0];
+                ports = parts2[1];
+            }
+            else if (part.indexOf(' ') >= 0) {
+                parts2 = part.split(' ',2);
+                protocol = parts2[0];
+                ports = parts2[1];
+            }
+            else {
+                throw 'malformed port specifier ' +
+                    part + ', format example: "tcp 123, tcp 201:206, udp 333"';
             }
 
             protocol = $.trim(protocol);
             ports = $.trim(ports);
 
-            console.log(ports);
-
-            if (protocol!="tcp" && protocol!="udp") {
+            if (protocol !== 'tcp' && protocol !== 'udp') {
                 throw 'unknown protocol ' + protocol;
             }
 
-            if (ports.indexOf("-")>=0) {
-                parts2 = ports.split("-");
+            if (ports.indexOf('-') >= 0) {
+                parts2 = ports.split('-');
                 first = parseInt($.trim(parts2[0]));
                 last = parseInt($.trim(parts2[1]));
-                portStr = first + ":" + last;
-            } else if (ports.indexOf(":")>=0) {
-                parts2 = ports.split(":");
+                portStr = first + ':' + last;
+            }
+            else if (ports.indexOf(':') >= 0) {
+                parts2 = ports.split(':');
                 first = parseInt($.trim(parts2[0]));
                 last = parseInt($.trim(parts2[1]));
-                portStr = first + ":" + last;
-            } else {
+                portStr = first + ':' + last;
+            }
+            else {
                 portStr = parseInt(ports).toString();
             }
 
-            nats.push( {l4_protocol: protocol, l4_port: portStr} );
+            nats.push({l4_protocol: protocol, l4_port: portStr});
         }); /* end $.each(ports) */
     }
-    return nats
+    return nats;
 }
 
 function portlist_regexp() {
@@ -218,23 +262,32 @@
        specifiers. Saved here in long form, in case we need to change it
        in the future.
     */
+    var paren, whitespace, protocol,
+        protocolSlash, numbers, range,
+        protoPorts, protoPortsCommas,
+        numbersOrRange, portSpec, multiProtoPorts;
 
-    paren = function(x) { return "(?:" + x + ")"; }
-    whitespace = " *";
-    protocol = paren("tcp|udp");
-    protocolSlash = protocol + paren(whitespace + "|\/");
-    numbers = paren("[0-9]+");
-    range = paren(numbers + paren("-|:") + numbers);
-    numbersOrRange = paren(numbers + "|" + range);
+    paren = function(x) {
+        return '(?:' + x + ')';
+    };
+
+    whitespace = ' *';
+    protocol = paren('tcp|udp');
+    protocolSlash = protocol + paren(whitespace + '|\/');
+    numbers = paren('[0-9]+');
+    range = paren(numbers + paren('-|:') + numbers);
+    numbersOrRange = paren(numbers + '|' + range);
     protoPorts = paren(protocolSlash + numbersOrRange);
-    protoPortsCommas = paren(paren(protoPorts + "," + whitespace)+"+");
+    protoPortsCommas = paren(paren(protoPorts + ',' + whitespace) + '+');
     multiProtoPorts = paren(protoPortsCommas + protoPorts);
-    portSpec = "^" + paren(protoPorts + "|" + multiProtoPorts) + "$";
+    portSpec = '^' + paren(protoPorts + '|' + multiProtoPorts) + '$';
     return RegExp(portSpec);
 }
 
 function portlist_selftest() {
-    r = portlist_regexp();
+    var r = portlist_regexp();
+
+/* eslint-disable quotes, max-len*/
     assert(! "tcp".match(r), 'should not have matched: "tcp"');
     assert("tcp 1".match(r), 'should have matched: "tcp 1"');
     assert("tcp 123".match(r), 'should have matched: "tcp 123"');
@@ -250,7 +303,8 @@
     assert("tcp 123,  udp 456".match(r), 'should have matched: "tcp 123,  udp 456"');
     assert("tcp 123-45, udp 456".match(r), 'should have matched: "tcp 123-45, udp 456"');
     assert("tcp 123-45, udp 456, tcp 11, tcp 22:45, udp 76, udp 47:49, udp 60-61".match(r), 'should have matched: "tcp 123-45, udp 456, tcp 11, tcp 22:45, udp 76, udp 47:49, udp 60-61"');
-    return "done";
+    /* eslint-enable quotes, max-len*/
+    return 'done';
 }
 
 //portlist_selftest();
diff --git a/xos/core/xoslib/static/js/xoslib/xos-validators.js b/xos/core/xoslib/static/js/xoslib/xos-validators.js
index bbba624..f762ef2 100644
--- a/xos/core/xoslib/static/js/xoslib/xos-validators.js
+++ b/xos/core/xoslib/static/js/xoslib/xos-validators.js
@@ -1,3 +1,11 @@
+/**
+* List of model validator
+*
+* @constructor
+*/
+
+/* eslint-disable quotes, no-undef, max-len, new-cap*/
+/* eslint indent: [2, 2]*/
 function xos_get_validators() {
   this.account = {"updated": [], "policed": [], "created": [], "deleted": [], "site": ["notBlank"], "lazy_blocked": [], "backend_register": ["notBlank"], "write_protect": [], "backend_status": ["notBlank"], "id": [], "no_sync": [], "enacted": []};
   this.charge = {"updated": [], "slice": [], "policed": [], "created": [], "deleted": [], "amount": ["notBlank"], "object": ["notBlank"], "account": ["notBlank"], "kind": ["notBlank"], "lazy_blocked": [], "backend_register": ["notBlank"], "write_protect": [], "state": ["notBlank"], "coreHours": ["notBlank"], "invoice": [], "date": ["notBlank"], "backend_status": ["notBlank"], "id": [], "no_sync": [], "enacted": []};
@@ -64,3 +72,4 @@
   this.userDashboardView = {"updated": [], "policed": [], "created": [], "deleted": [], "dashboardView": ["notBlank"], "lazy_blocked": [], "backend_register": ["notBlank"], "write_protect": [], "user": ["notBlank"], "backend_status": ["notBlank"], "order": ["notBlank"], "id": [], "no_sync": [], "enacted": []};
 };
 xosvalidators = new xos_get_validators();
+/* eslint-enable quotes, no-undef, max-len, new-cap*/
diff --git a/xos/core/xoslib/static/js/xoslib/xosHelper.js b/xos/core/xoslib/static/js/xoslib/xosHelper.js
index 1352c69..16046ae 100644
--- a/xos/core/xoslib/static/js/xoslib/xosHelper.js
+++ b/xos/core/xoslib/static/js/xoslib/xosHelper.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 HTMLView = Marionette.ItemView.extend({
   render: function() {
       this.$el.append(this.options.html);
@@ -55,16 +56,16 @@
 });
 
 XOSRouter = Marionette.AppRouter.extend({
-        initialize: function() {
-            this.routeStack=[];
-        },
-
-        onRoute: function(x,y,z) {
-             this.routeStack.push(Backbone.history.fragment);
-             this.routeStack = this.routeStack.slice(-32);   // limit the size of routeStack to something reasonable
-        },
-
-        prevPage: function() {
+        initialize: function() {
+            this.routeStack=[];
+        },
+
+        onRoute: function(x,y,z) {
+             this.routeStack.push(Backbone.history.fragment);
+             this.routeStack = this.routeStack.slice(-32);   // limit the size of routeStack to something reasonable
+        },
+
+        prevPage: function() {
              return this.routeStack.slice(-1)[0];
         },
 
@@ -83,14 +84,14 @@
             }
             Marionette.AppRouter.prototype.navigate.call(this, href, options);
         },
-    });
-
-// XXX - We import backbone multiple times (BAD!) since the import happens
-//   inside of the view's html. The second time it's imported (developer
-//   view), it wipes out Backbone.Syphon. So, save it as Backbone_Syphon for
-//   now.
-Backbone_Syphon = Backbone.Syphon
-Backbone_Syphon.InputReaders.register('select', function(el) {
+    });
+
+// XXX - We import backbone multiple times (BAD!) since the import happens
+//   inside of the view's html. The second time it's imported (developer
+//   view), it wipes out Backbone.Syphon. So, save it as Backbone_Syphon for
+//   now.
+Backbone_Syphon = Backbone.Syphon
+Backbone_Syphon.InputReaders.register('select', function(el) {
     // Modify syphon so that if a select has "syphonall" in the class, then
     // the value of every option will be returned, regardless of whether of
     // not it is selected.
@@ -564,7 +565,7 @@
                 var that = this;
                 var isNew = !this.model.id;
 
-                console.log(data);
+                console.log('data', data);
 
                 this.$el.find(".help-inline").remove();
 
@@ -572,7 +573,9 @@
                    model.save, we call it ourselves, so we can throw up our
                    validation error before creating the infoMsg in the log
                 */
+               
                 errors =  this.model.xosValidate(data);
+
                 if (errors) {
                     this.onFormDataInvalid(errors);
                     return;
@@ -982,77 +985,77 @@
                 };
 
                 //console.log(aoData);
-
-                // function used to populate the DataTable with the current
-                // content of the collection
-                var populateTable = function()
-                {
-                  //console.log("populatetable!");
-
-                  // clear out old row views
-                  rows = [];
-
-                  sSearch = null;
-                  iDisplayStart = 0;
-                  iDisplayLength = 1000;
-                  sortDirs = [];
-                  sortCols = [];
-                  _.each(aoData, function(param) {
-                      if (param.name == "sSortDir_0") {
-                          sortDirs = [param.value];
-                      } else if (param.name == "iSortCol_0") {
-                          sortCols = [view.columnsByIndex[param.value].mData];
-                      } else if (param.name == "iDisplayStart") {
-                          iDisplayStart = param.value;
-                      } else if (param.name == "iDisplayLength") {
-                          iDisplayLength = param.value;
-                      } else if (param.name == "sSearch") {
-                          sSearch = param.value;
-                      }
-                  });
-
-                  aaData = view.collection.toJSON();
-
-                  // apply backbone filtering on the models
-                  if (view.filter) {
-                      aaData = aaData.filter( function(row) { model = {}; model.attributes = row; return view.filter(model); } );
-                  }
-
-                  var totalSize = aaData.length;
-
-                  // turn the ForeignKey fields into human readable things
-                  for (rowIndex in aaData) {
-                      row = aaData[rowIndex];
-                      for (fieldName in row) {
-                          if (fieldName in view.columnsByFieldName) {
-                              mSearchText = view.columnsByFieldName[fieldName].mSearchText;
-                              if (mSearchText) {
-                                  row[fieldName] = mSearchText(row[fieldName]);
-                              }
-                          }
-                      }
-                  }
-
-                  // apply datatables search
-                  if (sSearch) {
-                      aaData = aaData.filter( function(row) { return searchMatch(row, sSearch); });
-                  }
-
-                  var filteredSize = aaData.length;
-
-                  // apply datatables sort
-                  aaData.sort(function(a,b) { return compareColumns(sortCols, sortDirs, a, b); });
-
-                  // slice it for pagination
-                  if (iDisplayLength >= 0) {
-                      aaData = aaData.slice(iDisplayStart, iDisplayStart+iDisplayLength);
-                  }
-
-                  return fnCallback({iTotalRecords: totalSize,
-                         iTotalDisplayRecords: filteredSize,
-                         aaData: aaData});
-                };
-
+
+                // function used to populate the DataTable with the current
+                // content of the collection
+                var populateTable = function()
+                {
+                  //console.log("populatetable!");
+
+                  // clear out old row views
+                  rows = [];
+
+                  sSearch = null;
+                  iDisplayStart = 0;
+                  iDisplayLength = 1000;
+                  sortDirs = [];
+                  sortCols = [];
+                  _.each(aoData, function(param) {
+                      if (param.name == "sSortDir_0") {
+                          sortDirs = [param.value];
+                      } else if (param.name == "iSortCol_0") {
+                          sortCols = [view.columnsByIndex[param.value].mData];
+                      } else if (param.name == "iDisplayStart") {
+                          iDisplayStart = param.value;
+                      } else if (param.name == "iDisplayLength") {
+                          iDisplayLength = param.value;
+                      } else if (param.name == "sSearch") {
+                          sSearch = param.value;
+                      }
+                  });
+
+                  aaData = view.collection.toJSON();
+
+                  // apply backbone filtering on the models
+                  if (view.filter) {
+                      aaData = aaData.filter( function(row) { model = {}; model.attributes = row; return view.filter(model); } );
+                  }
+
+                  var totalSize = aaData.length;
+
+                  // turn the ForeignKey fields into human readable things
+                  for (rowIndex in aaData) {
+                      row = aaData[rowIndex];
+                      for (fieldName in row) {
+                          if (fieldName in view.columnsByFieldName) {
+                              mSearchText = view.columnsByFieldName[fieldName].mSearchText;
+                              if (mSearchText) {
+                                  row[fieldName] = mSearchText(row[fieldName]);
+                              }
+                          }
+                      }
+                  }
+
+                  // apply datatables search
+                  if (sSearch) {
+                      aaData = aaData.filter( function(row) { return searchMatch(row, sSearch); });
+                  }
+
+                  var filteredSize = aaData.length;
+
+                  // apply datatables sort
+                  aaData.sort(function(a,b) { return compareColumns(sortCols, sortDirs, a, b); });
+
+                  // slice it for pagination
+                  if (iDisplayLength >= 0) {
+                      aaData = aaData.slice(iDisplayStart, iDisplayStart+iDisplayLength);
+                  }
+
+                  return fnCallback({iTotalRecords: totalSize,
+                         iTotalDisplayRecords: filteredSize,
+                         aaData: aaData});
+                };
+
                 aoData.shift(); // ignore sEcho
                 populateTable();
 
@@ -1172,3 +1175,4 @@
         return String(s).replace(/"/g,'&quot;')
     }
 }
+/* eslint-enable */
\ No newline at end of file
diff --git a/xos/templates/admin/base.html b/xos/templates/admin/base.html
index 7a957ac..d29456a 100644
--- a/xos/templates/admin/base.html
+++ b/xos/templates/admin/base.html
@@ -31,7 +31,6 @@
 {% load i18n %}
 
 <body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
-
 <div id="dialog-placeholder">
 <!-- This is a placeholder for dialog boxes, like the observer calendar -->
 </div>
