From fd2f54b3de006fab48becd2a0f39766c32ecffe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Tavares?= Date: Wed, 8 Apr 2015 15:17:00 +0100 Subject: [PATCH 001/168] Added Switch Payments to list of examples. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fbd68f49fbf..dadf610cd38 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ Examples of Slate in the Wild * [Buddycloud API](http://buddycloud.com/api) * [Crafty Clicks API](https://craftyclicks.co.uk/api/) * [Paracel API Reference](http://paracel.io/docs/api_reference.html) +* [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) (Feel free to add your site to this list in a pull request!) From f5dcc4efb85eab45fe8ec4a81a17edc76ca7976c Mon Sep 17 00:00:00 2001 From: Elliot Lee Date: Tue, 14 Apr 2015 20:24:31 -0700 Subject: [PATCH 002/168] Add Coinbase to list of examples --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dadf610cd38..b880cb3d2a4 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Examples of Slate in the Wild * [Crafty Clicks API](https://craftyclicks.co.uk/api/) * [Paracel API Reference](http://paracel.io/docs/api_reference.html) * [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) +* [Coinbase API Reference](https://developers.coinbase.com/api) (Feel free to add your site to this list in a pull request!) From 8e0396d7d3081df5c08dac6a762abfb351119756 Mon Sep 17 00:00:00 2001 From: Jordan Walsh Date: Tue, 21 Apr 2015 19:06:15 +1000 Subject: [PATCH 003/168] added whispir.io to the list of reference sites --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b880cb3d2a4..98d7e1ff633 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Examples of Slate in the Wild * [Paracel API Reference](http://paracel.io/docs/api_reference.html) * [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) * [Coinbase API Reference](https://developers.coinbase.com/api) +* [Whispir.io API](https://whispir.github.io/api) (Feel free to add your site to this list in a pull request!) From 0bb523732ec65251eb77b880e9861c848881c2c2 Mon Sep 17 00:00:00 2001 From: David Stanley Date: Tue, 21 Apr 2015 15:57:48 -0700 Subject: [PATCH 004/168] Update of Readme Just saw that freaking NASA is using this for docs! --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 98d7e1ff633..b53391bc2bc 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Examples of Slate in the Wild * [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) * [Coinbase API Reference](https://developers.coinbase.com/api) * [Whispir.io API](https://whispir.github.io/api) +* [Nasa API](https://data.nasa.gov/developer/external/planetary/) (Feel free to add your site to this list in a pull request!) From 923add84f644553519495cd0043241526aa51180 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 23 Apr 2015 21:33:40 +0300 Subject: [PATCH 005/168] added api example: developers.cardpay.com --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b53391bc2bc..c3c907b89a8 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ Examples of Slate in the Wild * [Coinbase API Reference](https://developers.coinbase.com/api) * [Whispir.io API](https://whispir.github.io/api) * [Nasa API](https://data.nasa.gov/developer/external/planetary/) +* [CardPay API](https://developers.cardpay.com/) (Feel free to add your site to this list in a pull request!) From 321a994cdc5b71bea23e9367fc5acff0a5d5b7dc Mon Sep 17 00:00:00 2001 From: Norton Wang Date: Wed, 29 Apr 2015 18:14:36 -0400 Subject: [PATCH 006/168] Fix typo --- source/includes/_errors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/includes/_errors.md b/source/includes/_errors.md index eeefbb5b777..56cffb34d22 100644 --- a/source/includes/_errors.md +++ b/source/includes/_errors.md @@ -15,6 +15,6 @@ Error Code | Meaning 406 | Not Acceptable -- You requested a format that isn't json 410 | Gone -- The kitten requested has been removed from our servers 418 | I'm a teapot -429 | Too Many Requests -- You're requesting too many kittens! Slown down! +429 | Too Many Requests -- You're requesting too many kittens! Slow down! 500 | Internal Server Error -- We had a problem with our server. Try again later. -503 | Service Unavailable -- We're temporarially offline for maintanance. Please try again later. \ No newline at end of file +503 | Service Unavailable -- We're temporarially offline for maintanance. Please try again later. From 506095a1ede15daa2f9aaec09b45910a0ef5a8b9 Mon Sep 17 00:00:00 2001 From: Matthias Kadenbach Date: Tue, 10 Feb 2015 21:38:14 +0100 Subject: [PATCH 007/168] Add git to allow rake build --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2908508ca42..8183c7a8b04 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:trusty RUN apt-get update -RUN apt-get install -yq ruby ruby-dev build-essential +RUN apt-get install -yq ruby ruby-dev build-essential git RUN gem install --no-ri --no-rdoc bundler ADD Gemfile /app/Gemfile ADD Gemfile.lock /app/Gemfile.lock @@ -9,4 +9,4 @@ RUN cd /app; bundle install ADD . /app EXPOSE 4567 WORKDIR /app -CMD ["bundle", "exec", "middleman", "server"] \ No newline at end of file +CMD ["bundle", "exec", "middleman", "server"] From 6062141cce7e87b74c7b9d0067825299152e0dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Thu, 12 Feb 2015 21:03:59 +0100 Subject: [PATCH 008/168] Update Rouge to Version 1.8 --- Gemfile | 4 ++-- Gemfile.lock | 4 ++-- source/javascripts/app/lang.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 1bb18a8af81..7ea1a883efd 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ # the following line to use "https" source 'http://rubygems.org' -gem "rouge", "1.7.2" +gem "rouge", "~> 1.8.0" gem "middleman", "~>3.3.0" @@ -27,4 +27,4 @@ end gem "rake", "~> 10.4.0" -gem 'therubyracer', :platforms => :ruby \ No newline at end of file +gem 'therubyracer', :platforms => :ruby diff --git a/Gemfile.lock b/Gemfile.lock index 023bfbe580b..4397878a67f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -104,7 +104,7 @@ GEM ffi (>= 0.5.0) redcarpet (3.2.2) ref (1.0.5) - rouge (1.7.2) + rouge (1.8.0) ruby18_source_location (0.2) sass (3.4.9) sprockets (2.12.3) @@ -142,7 +142,7 @@ DEPENDENCIES middleman-syntax rake (~> 10.4.0) redcarpet (~> 3.2.1) - rouge (= 1.7.2) + rouge (~> 1.8.0) ruby18_source_location therubyracer wdm (~> 0.1.0) diff --git a/source/javascripts/app/lang.js b/source/javascripts/app/lang.js index 90a31b9bbc3..c59a16b2311 100644 --- a/source/javascripts/app/lang.js +++ b/source/javascripts/app/lang.js @@ -26,9 +26,9 @@ under the License. $(".lang-selector a").removeClass('active'); $(".lang-selector a[data-language-name='" + language + "']").addClass('active'); for (var i=0; i < languages.length; i++) { - $(".highlight." + languages[i]).parent().hide(); + $(".highlight." + languages[i]).hide(); } - $(".highlight." + language).parent().show(); + $(".highlight." + language).show(); global.toc.calculateHeights(); From a60fd38cda7f3939eddeeb7c693d0e589aa57a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Thu, 12 Feb 2015 21:27:03 +0100 Subject: [PATCH 009/168] Use strict mode for JavaScript --- source/javascripts/app/lang.js | 2 ++ source/javascripts/app/search.js | 1 + source/javascripts/app/toc.js | 1 + 3 files changed, 4 insertions(+) diff --git a/source/javascripts/app/lang.js b/source/javascripts/app/lang.js index c59a16b2311..2683ef356db 100644 --- a/source/javascripts/app/lang.js +++ b/source/javascripts/app/lang.js @@ -14,6 +14,8 @@ License for the specific language governing permissions and limitations under the License. */ (function (global) { + 'use strict'; + var languages = []; global.setupLanguages = setupLanguages; diff --git a/source/javascripts/app/search.js b/source/javascripts/app/search.js index 8c527c715da..cf2eaf8cb63 100644 --- a/source/javascripts/app/search.js +++ b/source/javascripts/app/search.js @@ -1,4 +1,5 @@ (function (global) { + 'use strict'; var $global = $(global); var content, darkBox, searchResults; diff --git a/source/javascripts/app/toc.js b/source/javascripts/app/toc.js index 779e37e7655..c88b67f2b70 100644 --- a/source/javascripts/app/toc.js +++ b/source/javascripts/app/toc.js @@ -1,4 +1,5 @@ (function (global) { + 'use strict'; var closeToc = function() { $(".tocify-wrapper").removeClass('open'); From 3a236aa81eb40f677e51590fb0fff5039dee4d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Thu, 12 Feb 2015 21:48:03 +0100 Subject: [PATCH 010/168] Update jQuery to version 2.1.3 --- source/layouts/layout.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/layouts/layout.erb b/source/layouts/layout.erb index 915505b0405..36ae0f95f81 100644 --- a/source/layouts/layout.erb +++ b/source/layouts/layout.erb @@ -24,7 +24,7 @@ under the License. <%= stylesheet_link_tag :screen, media: :screen %> <%= stylesheet_link_tag :print, media: :print %> - + <% if current_page.data.search %> <%= javascript_include_tag "all" %> <% else %> From b1e0ff5d94bae05a47f8408214c9d870401ad3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Thu, 12 Feb 2015 21:48:59 +0100 Subject: [PATCH 011/168] Update lunr.js to version 0.5.7 --- source/javascripts/lib/lunr.js | 3258 ++++++++++++++++---------------- 1 file changed, 1644 insertions(+), 1614 deletions(-) diff --git a/source/javascripts/lib/lunr.js b/source/javascripts/lib/lunr.js index bd221b7e3ba..54457dab7a8 100644 --- a/source/javascripts/lib/lunr.js +++ b/source/javascripts/lib/lunr.js @@ -1,5 +1,5 @@ /** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.2 + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7 * Copyright (C) 2014 Oliver Nightingale * MIT Licensed * @license @@ -7,1851 +7,1881 @@ (function(){ -/** - * Convenience function for instantiating a new lunr index and configuring it - * with the default pipeline functions and the passed config function. - * - * When using this convenience function a new index will be created with the - * following functions already in the pipeline: - * - * lunr.StopWordFilter - filters out any stop words before they enter the - * index - * - * lunr.stemmer - stems the tokens before entering the index. - * - * Example: - * - * var idx = lunr(function () { + /** + * Convenience function for instantiating a new lunr index and configuring it + * with the default pipeline functions and the passed config function. + * + * When using this convenience function a new index will be created with the + * following functions already in the pipeline: + * + * lunr.StopWordFilter - filters out any stop words before they enter the + * index + * + * lunr.stemmer - stems the tokens before entering the index. + * + * Example: + * + * var idx = lunr(function () { * this.field('title', 10) * this.field('tags', 100) * this.field('body') - * + * * this.ref('cid') - * + * * this.pipeline.add(function () { * // some custom pipeline function * }) - * - * }) - * - * @param {Function} config A function that will be called with the new instance - * of the lunr.Index as both its context and first parameter. It can be used to - * customize the instance of new lunr.Index. - * @namespace - * @module - * @returns {lunr.Index} * - */ -var lunr = function (config) { - var idx = new lunr.Index + * }) + * + * @param {Function} config A function that will be called with the new instance + * of the lunr.Index as both its context and first parameter. It can be used to + * customize the instance of new lunr.Index. + * @namespace + * @module + * @returns {lunr.Index} + * + */ + var lunr = function (config) { + var idx = new lunr.Index - idx.pipeline.add( - lunr.trimmer, - lunr.stopWordFilter, - lunr.stemmer - ) + idx.pipeline.add( + lunr.trimmer, + lunr.stopWordFilter, + lunr.stemmer + ) - if (config) config.call(idx, idx) + if (config) config.call(idx, idx) - return idx -} + return idx + } -lunr.version = "0.5.2" -/*! - * lunr.utils - * Copyright (C) 2014 Oliver Nightingale - */ + lunr.version = "0.5.7" + /*! + * lunr.utils + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * A namespace containing utils for the rest of the lunr library - */ -lunr.utils = {} + /** + * A namespace containing utils for the rest of the lunr library + */ + lunr.utils = {} -/** - * Print a warning message to the console. - * - * @param {String} message The message to be printed. - * @memberOf Utils - */ -lunr.utils.warn = (function (global) { - return function (message) { - if (global.console && console.warn) { - console.warn(message) + /** + * Print a warning message to the console. + * + * @param {String} message The message to be printed. + * @memberOf Utils + */ + lunr.utils.warn = (function (global) { + return function (message) { + if (global.console && console.warn) { + console.warn(message) + } } - } -})(this) + })(this) -/*! - * lunr.EventEmitter - * Copyright (C) 2014 Oliver Nightingale - */ + /*! + * lunr.EventEmitter + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers. - * - * @constructor - */ -lunr.EventEmitter = function () { - this.events = {} -} + /** + * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers. + * + * @constructor + */ + lunr.EventEmitter = function () { + this.events = {} + } -/** - * Binds a handler function to a specific event(s). - * - * Can bind a single function to many different events in one call. - * - * @param {String} [eventName] The name(s) of events to bind this function to. - * @param {Function} handler The function to call when an event is fired. - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.addListener = function () { - var args = Array.prototype.slice.call(arguments), - fn = args.pop(), - names = args + /** + * Binds a handler function to a specific event(s). + * + * Can bind a single function to many different events in one call. + * + * @param {String} [eventName] The name(s) of events to bind this function to. + * @param {Function} handler The function to call when an event is fired. + * @memberOf EventEmitter + */ + lunr.EventEmitter.prototype.addListener = function () { + var args = Array.prototype.slice.call(arguments), + fn = args.pop(), + names = args - if (typeof fn !== "function") throw new TypeError ("last argument must be a function") + if (typeof fn !== "function") throw new TypeError ("last argument must be a function") - names.forEach(function (name) { - if (!this.hasHandler(name)) this.events[name] = [] - this.events[name].push(fn) - }, this) -} + names.forEach(function (name) { + if (!this.hasHandler(name)) this.events[name] = [] + this.events[name].push(fn) + }, this) + } -/** - * Removes a handler function from a specific event. - * - * @param {String} eventName The name of the event to remove this function from. - * @param {Function} handler The function to remove from an event. - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.removeListener = function (name, fn) { - if (!this.hasHandler(name)) return + /** + * Removes a handler function from a specific event. + * + * @param {String} eventName The name of the event to remove this function from. + * @param {Function} handler The function to remove from an event. + * @memberOf EventEmitter + */ + lunr.EventEmitter.prototype.removeListener = function (name, fn) { + if (!this.hasHandler(name)) return - var fnIndex = this.events[name].indexOf(fn) - this.events[name].splice(fnIndex, 1) + var fnIndex = this.events[name].indexOf(fn) + this.events[name].splice(fnIndex, 1) - if (!this.events[name].length) delete this.events[name] -} + if (!this.events[name].length) delete this.events[name] + } -/** - * Calls all functions bound to the given event. - * - * Additional data can be passed to the event handler as arguments to `emit` - * after the event name. - * - * @param {String} eventName The name of the event to emit. - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.emit = function (name) { - if (!this.hasHandler(name)) return + /** + * Calls all functions bound to the given event. + * + * Additional data can be passed to the event handler as arguments to `emit` + * after the event name. + * + * @param {String} eventName The name of the event to emit. + * @memberOf EventEmitter + */ + lunr.EventEmitter.prototype.emit = function (name) { + if (!this.hasHandler(name)) return - var args = Array.prototype.slice.call(arguments, 1) + var args = Array.prototype.slice.call(arguments, 1) - this.events[name].forEach(function (fn) { - fn.apply(undefined, args) - }) -} + this.events[name].forEach(function (fn) { + fn.apply(undefined, args) + }) + } -/** - * Checks whether a handler has ever been stored against an event. - * - * @param {String} eventName The name of the event to check. - * @private - * @memberOf EventEmitter - */ -lunr.EventEmitter.prototype.hasHandler = function (name) { - return name in this.events -} + /** + * Checks whether a handler has ever been stored against an event. + * + * @param {String} eventName The name of the event to check. + * @private + * @memberOf EventEmitter + */ + lunr.EventEmitter.prototype.hasHandler = function (name) { + return name in this.events + } -/*! - * lunr.tokenizer - * Copyright (C) 2014 Oliver Nightingale - */ + /*! + * lunr.tokenizer + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * A function for splitting a string into tokens ready to be inserted into - * the search index. - * - * @module - * @param {String} obj The string to convert into tokens - * @returns {Array} - */ -lunr.tokenizer = function (obj) { - if (!arguments.length || obj == null || obj == undefined) return [] - if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() }) + /** + * A function for splitting a string into tokens ready to be inserted into + * the search index. + * + * @module + * @param {String} obj The string to convert into tokens + * @returns {Array} + */ + lunr.tokenizer = function (obj) { + if (!arguments.length || obj == null || obj == undefined) return [] + if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() }) - var str = obj.toString().replace(/^\s+/, '') + var str = obj.toString().replace(/^\s+/, '') - for (var i = str.length - 1; i >= 0; i--) { - if (/\S/.test(str.charAt(i))) { - str = str.substring(0, i + 1) - break + for (var i = str.length - 1; i >= 0; i--) { + if (/\S/.test(str.charAt(i))) { + str = str.substring(0, i + 1) + break + } } + + return str + .split(/(?:\s+|\-)/) + .filter(function (token) { + return !!token + }) + .map(function (token) { + return token.toLowerCase() + }) } + /*! + * lunr.Pipeline + * Copyright (C) 2014 Oliver Nightingale + */ - return str - .split(/\s+/) - .map(function (token) { - return token.toLowerCase() - }) -} -/*! - * lunr.Pipeline - * Copyright (C) 2014 Oliver Nightingale - */ + /** + * lunr.Pipelines maintain an ordered list of functions to be applied to all + * tokens in documents entering the search index and queries being ran against + * the index. + * + * An instance of lunr.Index created with the lunr shortcut will contain a + * pipeline with a stop word filter and an English language stemmer. Extra + * functions can be added before or after either of these functions or these + * default functions can be removed. + * + * When run the pipeline will call each function in turn, passing a token, the + * index of that token in the original list of all tokens and finally a list of + * all the original tokens. + * + * The output of functions in the pipeline will be passed to the next function + * in the pipeline. To exclude a token from entering the index the function + * should return undefined, the rest of the pipeline will not be called with + * this token. + * + * For serialisation of pipelines to work, all functions used in an instance of + * a pipeline should be registered with lunr.Pipeline. Registered functions can + * then be loaded. If trying to load a serialised pipeline that uses functions + * that are not registered an error will be thrown. + * + * If not planning on serialising the pipeline then registering pipeline functions + * is not necessary. + * + * @constructor + */ + lunr.Pipeline = function () { + this._stack = [] + } -/** - * lunr.Pipelines maintain an ordered list of functions to be applied to all - * tokens in documents entering the search index and queries being ran against - * the index. - * - * An instance of lunr.Index created with the lunr shortcut will contain a - * pipeline with a stop word filter and an English language stemmer. Extra - * functions can be added before or after either of these functions or these - * default functions can be removed. - * - * When run the pipeline will call each function in turn, passing a token, the - * index of that token in the original list of all tokens and finally a list of - * all the original tokens. - * - * The output of functions in the pipeline will be passed to the next function - * in the pipeline. To exclude a token from entering the index the function - * should return undefined, the rest of the pipeline will not be called with - * this token. - * - * For serialisation of pipelines to work, all functions used in an instance of - * a pipeline should be registered with lunr.Pipeline. Registered functions can - * then be loaded. If trying to load a serialised pipeline that uses functions - * that are not registered an error will be thrown. - * - * If not planning on serialising the pipeline then registering pipeline functions - * is not necessary. - * - * @constructor - */ -lunr.Pipeline = function () { - this._stack = [] -} + lunr.Pipeline.registeredFunctions = {} -lunr.Pipeline.registeredFunctions = {} + /** + * Register a function with the pipeline. + * + * Functions that are used in the pipeline should be registered if the pipeline + * needs to be serialised, or a serialised pipeline needs to be loaded. + * + * Registering a function does not add it to a pipeline, functions must still be + * added to instances of the pipeline for them to be used when running a pipeline. + * + * @param {Function} fn The function to check for. + * @param {String} label The label to register this function with + * @memberOf Pipeline + */ + lunr.Pipeline.registerFunction = function (fn, label) { + if (label in this.registeredFunctions) { + lunr.utils.warn('Overwriting existing registered function: ' + label) + } -/** - * Register a function with the pipeline. - * - * Functions that are used in the pipeline should be registered if the pipeline - * needs to be serialised, or a serialised pipeline needs to be loaded. - * - * Registering a function does not add it to a pipeline, functions must still be - * added to instances of the pipeline for them to be used when running a pipeline. - * - * @param {Function} fn The function to check for. - * @param {String} label The label to register this function with - * @memberOf Pipeline - */ -lunr.Pipeline.registerFunction = function (fn, label) { - if (label in this.registeredFunctions) { - lunr.utils.warn('Overwriting existing registered function: ' + label) + fn.label = label + lunr.Pipeline.registeredFunctions[fn.label] = fn } - fn.label = label - lunr.Pipeline.registeredFunctions[fn.label] = fn -} - -/** - * Warns if the function is not registered as a Pipeline function. - * - * @param {Function} fn The function to check for. - * @private - * @memberOf Pipeline - */ -lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { - var isRegistered = fn.label && (fn.label in this.registeredFunctions) + /** + * Warns if the function is not registered as a Pipeline function. + * + * @param {Function} fn The function to check for. + * @private + * @memberOf Pipeline + */ + lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { + var isRegistered = fn.label && (fn.label in this.registeredFunctions) - if (!isRegistered) { - lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) + if (!isRegistered) { + lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) + } } -} -/** - * Loads a previously serialised pipeline. - * - * All functions to be loaded must already be registered with lunr.Pipeline. - * If any function from the serialised data has not been registered then an - * error will be thrown. - * - * @param {Object} serialised The serialised pipeline to load. - * @returns {lunr.Pipeline} - * @memberOf Pipeline - */ -lunr.Pipeline.load = function (serialised) { - var pipeline = new lunr.Pipeline + /** + * Loads a previously serialised pipeline. + * + * All functions to be loaded must already be registered with lunr.Pipeline. + * If any function from the serialised data has not been registered then an + * error will be thrown. + * + * @param {Object} serialised The serialised pipeline to load. + * @returns {lunr.Pipeline} + * @memberOf Pipeline + */ + lunr.Pipeline.load = function (serialised) { + var pipeline = new lunr.Pipeline - serialised.forEach(function (fnName) { - var fn = lunr.Pipeline.registeredFunctions[fnName] + serialised.forEach(function (fnName) { + var fn = lunr.Pipeline.registeredFunctions[fnName] - if (fn) { - pipeline.add(fn) - } else { - throw new Error ('Cannot load un-registered function: ' + fnName) - } - }) - - return pipeline -} + if (fn) { + pipeline.add(fn) + } else { + throw new Error ('Cannot load un-registered function: ' + fnName) + } + }) -/** - * Adds new functions to the end of the pipeline. - * - * Logs a warning if the function has not been registered. - * - * @param {Function} functions Any number of functions to add to the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.add = function () { - var fns = Array.prototype.slice.call(arguments) + return pipeline + } - fns.forEach(function (fn) { - lunr.Pipeline.warnIfFunctionNotRegistered(fn) - this._stack.push(fn) - }, this) -} + /** + * Adds new functions to the end of the pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {Function} functions Any number of functions to add to the pipeline. + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.add = function () { + var fns = Array.prototype.slice.call(arguments) -/** - * Adds a single function after a function that already exists in the - * pipeline. - * - * Logs a warning if the function has not been registered. - * - * @param {Function} existingFn A function that already exists in the pipeline. - * @param {Function} newFn The new function to add to the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.after = function (existingFn, newFn) { - lunr.Pipeline.warnIfFunctionNotRegistered(newFn) + fns.forEach(function (fn) { + lunr.Pipeline.warnIfFunctionNotRegistered(fn) + this._stack.push(fn) + }, this) + } - var pos = this._stack.indexOf(existingFn) + 1 - this._stack.splice(pos, 0, newFn) -} + /** + * Adds a single function after a function that already exists in the + * pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {Function} existingFn A function that already exists in the pipeline. + * @param {Function} newFn The new function to add to the pipeline. + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.after = function (existingFn, newFn) { + lunr.Pipeline.warnIfFunctionNotRegistered(newFn) -/** - * Adds a single function before a function that already exists in the - * pipeline. - * - * Logs a warning if the function has not been registered. - * - * @param {Function} existingFn A function that already exists in the pipeline. - * @param {Function} newFn The new function to add to the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.before = function (existingFn, newFn) { - lunr.Pipeline.warnIfFunctionNotRegistered(newFn) + var pos = this._stack.indexOf(existingFn) + 1 + this._stack.splice(pos, 0, newFn) + } - var pos = this._stack.indexOf(existingFn) - this._stack.splice(pos, 0, newFn) -} + /** + * Adds a single function before a function that already exists in the + * pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {Function} existingFn A function that already exists in the pipeline. + * @param {Function} newFn The new function to add to the pipeline. + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.before = function (existingFn, newFn) { + lunr.Pipeline.warnIfFunctionNotRegistered(newFn) -/** - * Removes a function from the pipeline. - * - * @param {Function} fn The function to remove from the pipeline. - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.remove = function (fn) { - var pos = this._stack.indexOf(fn) - this._stack.splice(pos, 1) -} + var pos = this._stack.indexOf(existingFn) + this._stack.splice(pos, 0, newFn) + } -/** - * Runs the current list of functions that make up the pipeline against the - * passed tokens. - * - * @param {Array} tokens The tokens to run through the pipeline. - * @returns {Array} - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.run = function (tokens) { - var out = [], - tokenLength = tokens.length, - stackLength = this._stack.length + /** + * Removes a function from the pipeline. + * + * @param {Function} fn The function to remove from the pipeline. + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.remove = function (fn) { + var pos = this._stack.indexOf(fn) + this._stack.splice(pos, 1) + } - for (var i = 0; i < tokenLength; i++) { - var token = tokens[i] + /** + * Runs the current list of functions that make up the pipeline against the + * passed tokens. + * + * @param {Array} tokens The tokens to run through the pipeline. + * @returns {Array} + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.run = function (tokens) { + var out = [], + tokenLength = tokens.length, + stackLength = this._stack.length - for (var j = 0; j < stackLength; j++) { - token = this._stack[j](token, i, tokens) - if (token === void 0) break - }; + for (var i = 0; i < tokenLength; i++) { + var token = tokens[i] - if (token !== void 0) out.push(token) - }; + for (var j = 0; j < stackLength; j++) { + token = this._stack[j](token, i, tokens) + if (token === void 0) break + }; - return out -} + if (token !== void 0) out.push(token) + }; -/** - * Resets the pipeline by removing any existing processors. - * - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.reset = function () { - this._stack = [] -} + return out + } -/** - * Returns a representation of the pipeline ready for serialisation. - * - * Logs a warning if the function has not been registered. - * - * @returns {Array} - * @memberOf Pipeline - */ -lunr.Pipeline.prototype.toJSON = function () { - return this._stack.map(function (fn) { - lunr.Pipeline.warnIfFunctionNotRegistered(fn) - - return fn.label - }) -} -/*! - * lunr.Vector - * Copyright (C) 2014 Oliver Nightingale - */ + /** + * Resets the pipeline by removing any existing processors. + * + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.reset = function () { + this._stack = [] + } -/** - * lunr.Vectors implement vector related operations for - * a series of elements. - * - * @constructor - */ -lunr.Vector = function () { - this._magnitude = null - this.list = undefined - this.length = 0 -} + /** + * Returns a representation of the pipeline ready for serialisation. + * + * Logs a warning if the function has not been registered. + * + * @returns {Array} + * @memberOf Pipeline + */ + lunr.Pipeline.prototype.toJSON = function () { + return this._stack.map(function (fn) { + lunr.Pipeline.warnIfFunctionNotRegistered(fn) -/** - * lunr.Vector.Node is a simple struct for each node - * in a lunr.Vector. - * - * @private - * @param {Number} The index of the node in the vector. - * @param {Object} The data at this node in the vector. - * @param {lunr.Vector.Node} The node directly after this node in the vector. - * @constructor - * @memberOf Vector - */ -lunr.Vector.Node = function (idx, val, next) { - this.idx = idx - this.val = val - this.next = next -} + return fn.label + }) + } + /*! + * lunr.Vector + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * Inserts a new value at a position in a vector. - * - * @param {Number} The index at which to insert a value. - * @param {Object} The object to insert in the vector. - * @memberOf Vector. - */ -lunr.Vector.prototype.insert = function (idx, val) { - var list = this.list + /** + * lunr.Vectors implement vector related operations for + * a series of elements. + * + * @constructor + */ + lunr.Vector = function () { + this._magnitude = null + this.list = undefined + this.length = 0 + } - if (!list) { - this.list = new lunr.Vector.Node (idx, val, list) - return this.length++ + /** + * lunr.Vector.Node is a simple struct for each node + * in a lunr.Vector. + * + * @private + * @param {Number} The index of the node in the vector. + * @param {Object} The data at this node in the vector. + * @param {lunr.Vector.Node} The node directly after this node in the vector. + * @constructor + * @memberOf Vector + */ + lunr.Vector.Node = function (idx, val, next) { + this.idx = idx + this.val = val + this.next = next } - var prev = list, - next = list.next + /** + * Inserts a new value at a position in a vector. + * + * @param {Number} The index at which to insert a value. + * @param {Object} The object to insert in the vector. + * @memberOf Vector. + */ + lunr.Vector.prototype.insert = function (idx, val) { + var list = this.list - while (next != undefined) { - if (idx < next.idx) { - prev.next = new lunr.Vector.Node (idx, val, next) + if (!list) { + this.list = new lunr.Vector.Node (idx, val, list) return this.length++ } - prev = next, next = next.next - } + var prev = list, + next = list.next - prev.next = new lunr.Vector.Node (idx, val, next) - return this.length++ -} + while (next != undefined) { + if (idx < next.idx) { + prev.next = new lunr.Vector.Node (idx, val, next) + return this.length++ + } -/** - * Calculates the magnitude of this vector. - * - * @returns {Number} - * @memberOf Vector - */ -lunr.Vector.prototype.magnitude = function () { - if (this._magniture) return this._magnitude - var node = this.list, - sumOfSquares = 0, - val + prev = next, next = next.next + } - while (node) { - val = node.val - sumOfSquares += val * val - node = node.next + prev.next = new lunr.Vector.Node (idx, val, next) + return this.length++ } - return this._magnitude = Math.sqrt(sumOfSquares) -} + /** + * Calculates the magnitude of this vector. + * + * @returns {Number} + * @memberOf Vector + */ + lunr.Vector.prototype.magnitude = function () { + if (this._magniture) return this._magnitude + var node = this.list, + sumOfSquares = 0, + val + + while (node) { + val = node.val + sumOfSquares += val * val + node = node.next + } -/** - * Calculates the dot product of this vector and another vector. - * - * @param {lunr.Vector} otherVector The vector to compute the dot product with. - * @returns {Number} - * @memberOf Vector - */ -lunr.Vector.prototype.dot = function (otherVector) { - var node = this.list, - otherNode = otherVector.list, - dotProduct = 0 + return this._magnitude = Math.sqrt(sumOfSquares) + } - while (node && otherNode) { - if (node.idx < otherNode.idx) { - node = node.next - } else if (node.idx > otherNode.idx) { - otherNode = otherNode.next - } else { - dotProduct += node.val * otherNode.val - node = node.next - otherNode = otherNode.next + /** + * Calculates the dot product of this vector and another vector. + * + * @param {lunr.Vector} otherVector The vector to compute the dot product with. + * @returns {Number} + * @memberOf Vector + */ + lunr.Vector.prototype.dot = function (otherVector) { + var node = this.list, + otherNode = otherVector.list, + dotProduct = 0 + + while (node && otherNode) { + if (node.idx < otherNode.idx) { + node = node.next + } else if (node.idx > otherNode.idx) { + otherNode = otherNode.next + } else { + dotProduct += node.val * otherNode.val + node = node.next + otherNode = otherNode.next + } } + + return dotProduct } - return dotProduct -} + /** + * Calculates the cosine similarity between this vector and another + * vector. + * + * @param {lunr.Vector} otherVector The other vector to calculate the + * similarity with. + * @returns {Number} + * @memberOf Vector + */ + lunr.Vector.prototype.similarity = function (otherVector) { + return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude()) + } + /*! + * lunr.SortedSet + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * Calculates the cosine similarity between this vector and another - * vector. - * - * @param {lunr.Vector} otherVector The other vector to calculate the - * similarity with. - * @returns {Number} - * @memberOf Vector - */ -lunr.Vector.prototype.similarity = function (otherVector) { - return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude()) -} -/*! - * lunr.SortedSet - * Copyright (C) 2014 Oliver Nightingale - */ + /** + * lunr.SortedSets are used to maintain an array of uniq values in a sorted + * order. + * + * @constructor + */ + lunr.SortedSet = function () { + this.length = 0 + this.elements = [] + } -/** - * lunr.SortedSets are used to maintain an array of uniq values in a sorted - * order. - * - * @constructor - */ -lunr.SortedSet = function () { - this.length = 0 - this.elements = [] -} + /** + * Loads a previously serialised sorted set. + * + * @param {Array} serialisedData The serialised set to load. + * @returns {lunr.SortedSet} + * @memberOf SortedSet + */ + lunr.SortedSet.load = function (serialisedData) { + var set = new this -/** - * Loads a previously serialised sorted set. - * - * @param {Array} serialisedData The serialised set to load. - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.load = function (serialisedData) { - var set = new this + set.elements = serialisedData + set.length = serialisedData.length - set.elements = serialisedData - set.length = serialisedData.length + return set + } - return set -} + /** + * Inserts new items into the set in the correct position to maintain the + * order. + * + * @param {Object} The objects to add to this set. + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.add = function () { + Array.prototype.slice.call(arguments).forEach(function (element) { + if (~this.indexOf(element)) return + this.elements.splice(this.locationFor(element), 0, element) + }, this) -/** - * Inserts new items into the set in the correct position to maintain the - * order. - * - * @param {Object} The objects to add to this set. - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.add = function () { - Array.prototype.slice.call(arguments).forEach(function (element) { - if (~this.indexOf(element)) return - this.elements.splice(this.locationFor(element), 0, element) - }, this) + this.length = this.elements.length + } - this.length = this.elements.length -} + /** + * Converts this sorted set into an array. + * + * @returns {Array} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.toArray = function () { + return this.elements.slice() + } -/** - * Converts this sorted set into an array. - * - * @returns {Array} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.toArray = function () { - return this.elements.slice() -} + /** + * Creates a new array with the results of calling a provided function on every + * element in this sorted set. + * + * Delegates to Array.prototype.map and has the same signature. + * + * @param {Function} fn The function that is called on each element of the + * set. + * @param {Object} ctx An optional object that can be used as the context + * for the function fn. + * @returns {Array} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.map = function (fn, ctx) { + return this.elements.map(fn, ctx) + } -/** - * Creates a new array with the results of calling a provided function on every - * element in this sorted set. - * - * Delegates to Array.prototype.map and has the same signature. - * - * @param {Function} fn The function that is called on each element of the - * set. - * @param {Object} ctx An optional object that can be used as the context - * for the function fn. - * @returns {Array} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.map = function (fn, ctx) { - return this.elements.map(fn, ctx) -} + /** + * Executes a provided function once per sorted set element. + * + * Delegates to Array.prototype.forEach and has the same signature. + * + * @param {Function} fn The function that is called on each element of the + * set. + * @param {Object} ctx An optional object that can be used as the context + * @memberOf SortedSet + * for the function fn. + */ + lunr.SortedSet.prototype.forEach = function (fn, ctx) { + return this.elements.forEach(fn, ctx) + } -/** - * Executes a provided function once per sorted set element. - * - * Delegates to Array.prototype.forEach and has the same signature. - * - * @param {Function} fn The function that is called on each element of the - * set. - * @param {Object} ctx An optional object that can be used as the context - * @memberOf SortedSet - * for the function fn. - */ -lunr.SortedSet.prototype.forEach = function (fn, ctx) { - return this.elements.forEach(fn, ctx) -} + /** + * Returns the index at which a given element can be found in the + * sorted set, or -1 if it is not present. + * + * @param {Object} elem The object to locate in the sorted set. + * @param {Number} start An optional index at which to start searching from + * within the set. + * @param {Number} end An optional index at which to stop search from within + * the set. + * @returns {Number} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.indexOf = function (elem, start, end) { + var start = start || 0, + end = end || this.elements.length, + sectionLength = end - start, + pivot = start + Math.floor(sectionLength / 2), + pivotElem = this.elements[pivot] + + if (sectionLength <= 1) { + if (pivotElem === elem) { + return pivot + } else { + return -1 + } + } -/** - * Returns the index at which a given element can be found in the - * sorted set, or -1 if it is not present. - * - * @param {Object} elem The object to locate in the sorted set. - * @param {Number} start An optional index at which to start searching from - * within the set. - * @param {Number} end An optional index at which to stop search from within - * the set. - * @returns {Number} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.indexOf = function (elem, start, end) { - var start = start || 0, - end = end || this.elements.length, - sectionLength = end - start, - pivot = start + Math.floor(sectionLength / 2), - pivotElem = this.elements[pivot] - - if (sectionLength <= 1) { - if (pivotElem === elem) { - return pivot - } else { - return -1 + if (pivotElem < elem) return this.indexOf(elem, pivot, end) + if (pivotElem > elem) return this.indexOf(elem, start, pivot) + if (pivotElem === elem) return pivot + } + + /** + * Returns the position within the sorted set that an element should be + * inserted at to maintain the current order of the set. + * + * This function assumes that the element to search for does not already exist + * in the sorted set. + * + * @param {Object} elem The elem to find the position for in the set + * @param {Number} start An optional index at which to start searching from + * within the set. + * @param {Number} end An optional index at which to stop search from within + * the set. + * @returns {Number} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.locationFor = function (elem, start, end) { + var start = start || 0, + end = end || this.elements.length, + sectionLength = end - start, + pivot = start + Math.floor(sectionLength / 2), + pivotElem = this.elements[pivot] + + if (sectionLength <= 1) { + if (pivotElem > elem) return pivot + if (pivotElem < elem) return pivot + 1 } + + if (pivotElem < elem) return this.locationFor(elem, pivot, end) + if (pivotElem > elem) return this.locationFor(elem, start, pivot) } - if (pivotElem < elem) return this.indexOf(elem, pivot, end) - if (pivotElem > elem) return this.indexOf(elem, start, pivot) - if (pivotElem === elem) return pivot -} + /** + * Creates a new lunr.SortedSet that contains the elements in the intersection + * of this set and the passed set. + * + * @param {lunr.SortedSet} otherSet The set to intersect with this set. + * @returns {lunr.SortedSet} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.intersect = function (otherSet) { + var intersectSet = new lunr.SortedSet, + i = 0, j = 0, + a_len = this.length, b_len = otherSet.length, + a = this.elements, b = otherSet.elements + + while (true) { + if (i > a_len - 1 || j > b_len - 1) break + + if (a[i] === b[j]) { + intersectSet.add(a[i]) + i++, j++ + continue + } -/** - * Returns the position within the sorted set that an element should be - * inserted at to maintain the current order of the set. - * - * This function assumes that the element to search for does not already exist - * in the sorted set. - * - * @param {Object} elem The elem to find the position for in the set - * @param {Number} start An optional index at which to start searching from - * within the set. - * @param {Number} end An optional index at which to stop search from within - * the set. - * @returns {Number} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.locationFor = function (elem, start, end) { - var start = start || 0, - end = end || this.elements.length, - sectionLength = end - start, - pivot = start + Math.floor(sectionLength / 2), - pivotElem = this.elements[pivot] + if (a[i] < b[j]) { + i++ + continue + } - if (sectionLength <= 1) { - if (pivotElem > elem) return pivot - if (pivotElem < elem) return pivot + 1 + if (a[i] > b[j]) { + j++ + continue + } + }; + + return intersectSet } - if (pivotElem < elem) return this.locationFor(elem, pivot, end) - if (pivotElem > elem) return this.locationFor(elem, start, pivot) -} + /** + * Makes a copy of this set + * + * @returns {lunr.SortedSet} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.clone = function () { + var clone = new lunr.SortedSet -/** - * Creates a new lunr.SortedSet that contains the elements in the intersection - * of this set and the passed set. - * - * @param {lunr.SortedSet} otherSet The set to intersect with this set. - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.intersect = function (otherSet) { - var intersectSet = new lunr.SortedSet, - i = 0, j = 0, - a_len = this.length, b_len = otherSet.length, - a = this.elements, b = otherSet.elements - - while (true) { - if (i > a_len - 1 || j > b_len - 1) break - - if (a[i] === b[j]) { - intersectSet.add(a[i]) - i++, j++ - continue - } + clone.elements = this.toArray() + clone.length = clone.elements.length - if (a[i] < b[j]) { - i++ - continue - } + return clone + } - if (a[i] > b[j]) { - j++ - continue + /** + * Creates a new lunr.SortedSet that contains the elements in the union + * of this set and the passed set. + * + * @param {lunr.SortedSet} otherSet The set to union with this set. + * @returns {lunr.SortedSet} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.union = function (otherSet) { + var longSet, shortSet, unionSet + + if (this.length >= otherSet.length) { + longSet = this, shortSet = otherSet + } else { + longSet = otherSet, shortSet = this } - }; - return intersectSet -} + unionSet = longSet.clone() -/** - * Makes a copy of this set - * - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.clone = function () { - var clone = new lunr.SortedSet + unionSet.add.apply(unionSet, shortSet.toArray()) - clone.elements = this.toArray() - clone.length = clone.elements.length + return unionSet + } - return clone -} + /** + * Returns a representation of the sorted set ready for serialisation. + * + * @returns {Array} + * @memberOf SortedSet + */ + lunr.SortedSet.prototype.toJSON = function () { + return this.toArray() + } + /*! + * lunr.Index + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * Creates a new lunr.SortedSet that contains the elements in the union - * of this set and the passed set. - * - * @param {lunr.SortedSet} otherSet The set to union with this set. - * @returns {lunr.SortedSet} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.union = function (otherSet) { - var longSet, shortSet, unionSet + /** + * lunr.Index is object that manages a search index. It contains the indexes + * and stores all the tokens and document lookups. It also provides the main + * user facing API for the library. + * + * @constructor + */ + lunr.Index = function () { + this._fields = [] + this._ref = 'id' + this.pipeline = new lunr.Pipeline + this.documentStore = new lunr.Store + this.tokenStore = new lunr.TokenStore + this.corpusTokens = new lunr.SortedSet + this.eventEmitter = new lunr.EventEmitter - if (this.length >= otherSet.length) { - longSet = this, shortSet = otherSet - } else { - longSet = otherSet, shortSet = this - } + this._idfCache = {} - unionSet = longSet.clone() + this.on('add', 'remove', 'update', (function () { + this._idfCache = {} + }).bind(this)) + } - unionSet.add.apply(unionSet, shortSet.toArray()) + /** + * Bind a handler to events being emitted by the index. + * + * The handler can be bound to many events at the same time. + * + * @param {String} [eventName] The name(s) of events to bind the function to. + * @param {Function} handler The serialised set to load. + * @memberOf Index + */ + lunr.Index.prototype.on = function () { + var args = Array.prototype.slice.call(arguments) + return this.eventEmitter.addListener.apply(this.eventEmitter, args) + } - return unionSet -} + /** + * Removes a handler from an event being emitted by the index. + * + * @param {String} eventName The name of events to remove the function from. + * @param {Function} handler The serialised set to load. + * @memberOf Index + */ + lunr.Index.prototype.off = function (name, fn) { + return this.eventEmitter.removeListener(name, fn) + } -/** - * Returns a representation of the sorted set ready for serialisation. - * - * @returns {Array} - * @memberOf SortedSet - */ -lunr.SortedSet.prototype.toJSON = function () { - return this.toArray() -} -/*! - * lunr.Index - * Copyright (C) 2014 Oliver Nightingale - */ + /** + * Loads a previously serialised index. + * + * Issues a warning if the index being imported was serialised + * by a different version of lunr. + * + * @param {Object} serialisedData The serialised set to load. + * @returns {lunr.Index} + * @memberOf Index + */ + lunr.Index.load = function (serialisedData) { + if (serialisedData.version !== lunr.version) { + lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version) + } -/** - * lunr.Index is object that manages a search index. It contains the indexes - * and stores all the tokens and document lookups. It also provides the main - * user facing API for the library. - * - * @constructor - */ -lunr.Index = function () { - this._fields = [] - this._ref = 'id' - this.pipeline = new lunr.Pipeline - this.documentStore = new lunr.Store - this.tokenStore = new lunr.TokenStore - this.corpusTokens = new lunr.SortedSet - this.eventEmitter = new lunr.EventEmitter - - this._idfCache = {} - - this.on('add', 'remove', 'update', (function () { - this._idfCache = {} - }).bind(this)) -} + var idx = new this -/** - * Bind a handler to events being emitted by the index. - * - * The handler can be bound to many events at the same time. - * - * @param {String} [eventName] The name(s) of events to bind the function to. - * @param {Function} handler The serialised set to load. - * @memberOf Index - */ -lunr.Index.prototype.on = function () { - var args = Array.prototype.slice.call(arguments) - return this.eventEmitter.addListener.apply(this.eventEmitter, args) -} + idx._fields = serialisedData.fields + idx._ref = serialisedData.ref -/** - * Removes a handler from an event being emitted by the index. - * - * @param {String} eventName The name of events to remove the function from. - * @param {Function} handler The serialised set to load. - * @memberOf Index - */ -lunr.Index.prototype.off = function (name, fn) { - return this.eventEmitter.removeListener(name, fn) -} + idx.documentStore = lunr.Store.load(serialisedData.documentStore) + idx.tokenStore = lunr.TokenStore.load(serialisedData.tokenStore) + idx.corpusTokens = lunr.SortedSet.load(serialisedData.corpusTokens) + idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline) -/** - * Loads a previously serialised index. - * - * Issues a warning if the index being imported was serialised - * by a different version of lunr. - * - * @param {Object} serialisedData The serialised set to load. - * @returns {lunr.Index} - * @memberOf Index - */ -lunr.Index.load = function (serialisedData) { - if (serialisedData.version !== lunr.version) { - lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version) + return idx } - var idx = new this - - idx._fields = serialisedData.fields - idx._ref = serialisedData.ref + /** + * Adds a field to the list of fields that will be searchable within documents + * in the index. + * + * An optional boost param can be passed to affect how much tokens in this field + * rank in search results, by default the boost value is 1. + * + * Fields should be added before any documents are added to the index, fields + * that are added after documents are added to the index will only apply to new + * documents added to the index. + * + * @param {String} fieldName The name of the field within the document that + * should be indexed + * @param {Number} boost An optional boost that can be applied to terms in this + * field. + * @returns {lunr.Index} + * @memberOf Index + */ + lunr.Index.prototype.field = function (fieldName, opts) { + var opts = opts || {}, + field = { name: fieldName, boost: opts.boost || 1 } - idx.documentStore = lunr.Store.load(serialisedData.documentStore) - idx.tokenStore = lunr.TokenStore.load(serialisedData.tokenStore) - idx.corpusTokens = lunr.SortedSet.load(serialisedData.corpusTokens) - idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline) + this._fields.push(field) + return this + } - return idx -} + /** + * Sets the property used to uniquely identify documents added to the index, + * by default this property is 'id'. + * + * This should only be changed before adding documents to the index, changing + * the ref property without resetting the index can lead to unexpected results. + * + * @param {String} refName The property to use to uniquely identify the + * documents in the index. + * @param {Boolean} emitEvent Whether to emit add events, defaults to true + * @returns {lunr.Index} + * @memberOf Index + */ + lunr.Index.prototype.ref = function (refName) { + this._ref = refName + return this + } -/** - * Adds a field to the list of fields that will be searchable within documents - * in the index. - * - * An optional boost param can be passed to affect how much tokens in this field - * rank in search results, by default the boost value is 1. - * - * Fields should be added before any documents are added to the index, fields - * that are added after documents are added to the index will only apply to new - * documents added to the index. - * - * @param {String} fieldName The name of the field within the document that - * should be indexed - * @param {Number} boost An optional boost that can be applied to terms in this - * field. - * @returns {lunr.Index} - * @memberOf Index - */ -lunr.Index.prototype.field = function (fieldName, opts) { - var opts = opts || {}, - field = { name: fieldName, boost: opts.boost || 1 } + /** + * Add a document to the index. + * + * This is the way new documents enter the index, this function will run the + * fields from the document through the index's pipeline and then add it to + * the index, it will then show up in search results. + * + * An 'add' event is emitted with the document that has been added and the index + * the document has been added to. This event can be silenced by passing false + * as the second argument to add. + * + * @param {Object} doc The document to add to the index. + * @param {Boolean} emitEvent Whether or not to emit events, default true. + * @memberOf Index + */ + lunr.Index.prototype.add = function (doc, emitEvent) { + var docTokens = {}, + allDocumentTokens = new lunr.SortedSet, + docRef = doc[this._ref], + emitEvent = emitEvent === undefined ? true : emitEvent - this._fields.push(field) - return this -} + this._fields.forEach(function (field) { + var fieldTokens = this.pipeline.run(lunr.tokenizer(doc[field.name])) -/** - * Sets the property used to uniquely identify documents added to the index, - * by default this property is 'id'. - * - * This should only be changed before adding documents to the index, changing - * the ref property without resetting the index can lead to unexpected results. - * - * @param {String} refName The property to use to uniquely identify the - * documents in the index. - * @param {Boolean} emitEvent Whether to emit add events, defaults to true - * @returns {lunr.Index} - * @memberOf Index - */ -lunr.Index.prototype.ref = function (refName) { - this._ref = refName - return this -} + docTokens[field.name] = fieldTokens + lunr.SortedSet.prototype.add.apply(allDocumentTokens, fieldTokens) + }, this) -/** - * Add a document to the index. - * - * This is the way new documents enter the index, this function will run the - * fields from the document through the index's pipeline and then add it to - * the index, it will then show up in search results. - * - * An 'add' event is emitted with the document that has been added and the index - * the document has been added to. This event can be silenced by passing false - * as the second argument to add. - * - * @param {Object} doc The document to add to the index. - * @param {Boolean} emitEvent Whether or not to emit events, default true. - * @memberOf Index - */ -lunr.Index.prototype.add = function (doc, emitEvent) { - var docTokens = {}, - allDocumentTokens = new lunr.SortedSet, - docRef = doc[this._ref], - emitEvent = emitEvent === undefined ? true : emitEvent + this.documentStore.set(docRef, allDocumentTokens) + lunr.SortedSet.prototype.add.apply(this.corpusTokens, allDocumentTokens.toArray()) - this._fields.forEach(function (field) { - var fieldTokens = this.pipeline.run(lunr.tokenizer(doc[field.name])) + for (var i = 0; i < allDocumentTokens.length; i++) { + var token = allDocumentTokens.elements[i] + var tf = this._fields.reduce(function (memo, field) { + var fieldLength = docTokens[field.name].length - docTokens[field.name] = fieldTokens - lunr.SortedSet.prototype.add.apply(allDocumentTokens, fieldTokens) - }, this) + if (!fieldLength) return memo - this.documentStore.set(docRef, allDocumentTokens) - lunr.SortedSet.prototype.add.apply(this.corpusTokens, allDocumentTokens.toArray()) + var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length - for (var i = 0; i < allDocumentTokens.length; i++) { - var token = allDocumentTokens.elements[i] - var tf = this._fields.reduce(function (memo, field) { - var fieldLength = docTokens[field.name].length + return memo + (tokenCount / fieldLength * field.boost) + }, 0) - if (!fieldLength) return memo + this.tokenStore.add(token, { ref: docRef, tf: tf }) + }; - var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length + if (emitEvent) this.eventEmitter.emit('add', doc, this) + } - return memo + (tokenCount / fieldLength * field.boost) - }, 0) + /** + * Removes a document from the index. + * + * To make sure documents no longer show up in search results they can be + * removed from the index using this method. + * + * The document passed only needs to have the same ref property value as the + * document that was added to the index, they could be completely different + * objects. + * + * A 'remove' event is emitted with the document that has been removed and the index + * the document has been removed from. This event can be silenced by passing false + * as the second argument to remove. + * + * @param {Object} doc The document to remove from the index. + * @param {Boolean} emitEvent Whether to emit remove events, defaults to true + * @memberOf Index + */ + lunr.Index.prototype.remove = function (doc, emitEvent) { + var docRef = doc[this._ref], + emitEvent = emitEvent === undefined ? true : emitEvent - this.tokenStore.add(token, { ref: docRef, tf: tf }) - }; + if (!this.documentStore.has(docRef)) return - if (emitEvent) this.eventEmitter.emit('add', doc, this) -} + var docTokens = this.documentStore.get(docRef) -/** - * Removes a document from the index. - * - * To make sure documents no longer show up in search results they can be - * removed from the index using this method. - * - * The document passed only needs to have the same ref property value as the - * document that was added to the index, they could be completely different - * objects. - * - * A 'remove' event is emitted with the document that has been removed and the index - * the document has been removed from. This event can be silenced by passing false - * as the second argument to remove. - * - * @param {Object} doc The document to remove from the index. - * @param {Boolean} emitEvent Whether to emit remove events, defaults to true - * @memberOf Index - */ -lunr.Index.prototype.remove = function (doc, emitEvent) { - var docRef = doc[this._ref], - emitEvent = emitEvent === undefined ? true : emitEvent + this.documentStore.remove(docRef) - if (!this.documentStore.has(docRef)) return + docTokens.forEach(function (token) { + this.tokenStore.remove(token, docRef) + }, this) - var docTokens = this.documentStore.get(docRef) + if (emitEvent) this.eventEmitter.emit('remove', doc, this) + } - this.documentStore.remove(docRef) + /** + * Updates a document in the index. + * + * When a document contained within the index gets updated, fields changed, + * added or removed, to make sure it correctly matched against search queries, + * it should be updated in the index. + * + * This method is just a wrapper around `remove` and `add` + * + * An 'update' event is emitted with the document that has been updated and the index. + * This event can be silenced by passing false as the second argument to update. Only + * an update event will be fired, the 'add' and 'remove' events of the underlying calls + * are silenced. + * + * @param {Object} doc The document to update in the index. + * @param {Boolean} emitEvent Whether to emit update events, defaults to true + * @see Index.prototype.remove + * @see Index.prototype.add + * @memberOf Index + */ + lunr.Index.prototype.update = function (doc, emitEvent) { + var emitEvent = emitEvent === undefined ? true : emitEvent - docTokens.forEach(function (token) { - this.tokenStore.remove(token, docRef) - }, this) + this.remove(doc, false) + this.add(doc, false) - if (emitEvent) this.eventEmitter.emit('remove', doc, this) -} + if (emitEvent) this.eventEmitter.emit('update', doc, this) + } -/** - * Updates a document in the index. - * - * When a document contained within the index gets updated, fields changed, - * added or removed, to make sure it correctly matched against search queries, - * it should be updated in the index. - * - * This method is just a wrapper around `remove` and `add` - * - * An 'update' event is emitted with the document that has been updated and the index. - * This event can be silenced by passing false as the second argument to update. Only - * an update event will be fired, the 'add' and 'remove' events of the underlying calls - * are silenced. - * - * @param {Object} doc The document to update in the index. - * @param {Boolean} emitEvent Whether to emit update events, defaults to true - * @see Index.prototype.remove - * @see Index.prototype.add - * @memberOf Index - */ -lunr.Index.prototype.update = function (doc, emitEvent) { - var emitEvent = emitEvent === undefined ? true : emitEvent + /** + * Calculates the inverse document frequency for a token within the index. + * + * @param {String} token The token to calculate the idf of. + * @see Index.prototype.idf + * @private + * @memberOf Index + */ + lunr.Index.prototype.idf = function (term) { + var cacheKey = "@" + term + if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey] - this.remove(doc, false) - this.add(doc, false) + var documentFrequency = this.tokenStore.count(term), + idf = 1 - if (emitEvent) this.eventEmitter.emit('update', doc, this) -} + if (documentFrequency > 0) { + idf = 1 + Math.log(this.tokenStore.length / documentFrequency) + } -/** - * Calculates the inverse document frequency for a token within the index. - * - * @param {String} token The token to calculate the idf of. - * @see Index.prototype.idf - * @private - * @memberOf Index - */ -lunr.Index.prototype.idf = function (term) { - var cacheKey = "@" + term - if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey] + return this._idfCache[cacheKey] = idf + } - var documentFrequency = this.tokenStore.count(term), - idf = 1 + /** + * Searches the index using the passed query. + * + * Queries should be a string, multiple words are allowed and will lead to an + * AND based query, e.g. `idx.search('foo bar')` will run a search for + * documents containing both 'foo' and 'bar'. + * + * All query tokens are passed through the same pipeline that document tokens + * are passed through, so any language processing involved will be run on every + * query term. + * + * Each query term is expanded, so that the term 'he' might be expanded to + * 'hello' and 'help' if those terms were already included in the index. + * + * Matching documents are returned as an array of objects, each object contains + * the matching document ref, as set for this index, and the similarity score + * for this document against the query. + * + * @param {String} query The query to search the index with. + * @returns {Object} + * @see Index.prototype.idf + * @see Index.prototype.documentVector + * @memberOf Index + */ + lunr.Index.prototype.search = function (query) { + var queryTokens = this.pipeline.run(lunr.tokenizer(query)), + queryVector = new lunr.Vector, + documentSets = [], + fieldBoosts = this._fields.reduce(function (memo, f) { return memo + f.boost }, 0) + + var hasSomeToken = queryTokens.some(function (token) { + return this.tokenStore.has(token) + }, this) - if (documentFrequency > 0) { - idf = 1 + Math.log(this.tokenStore.length / documentFrequency) - } + if (!hasSomeToken) return [] - return this._idfCache[cacheKey] = idf -} + queryTokens + .forEach(function (token, i, tokens) { + var tf = 1 / tokens.length * this._fields.length * fieldBoosts, + self = this -/** - * Searches the index using the passed query. - * - * Queries should be a string, multiple words are allowed and will lead to an - * AND based query, e.g. `idx.search('foo bar')` will run a search for - * documents containing both 'foo' and 'bar'. - * - * All query tokens are passed through the same pipeline that document tokens - * are passed through, so any language processing involved will be run on every - * query term. - * - * Each query term is expanded, so that the term 'he' might be expanded to - * 'hello' and 'help' if those terms were already included in the index. - * - * Matching documents are returned as an array of objects, each object contains - * the matching document ref, as set for this index, and the similarity score - * for this document against the query. - * - * @param {String} query The query to search the index with. - * @returns {Object} - * @see Index.prototype.idf - * @see Index.prototype.documentVector - * @memberOf Index - */ -lunr.Index.prototype.search = function (query) { - var queryTokens = this.pipeline.run(lunr.tokenizer(query)), - queryVector = new lunr.Vector, - documentSets = [], - fieldBoosts = this._fields.reduce(function (memo, f) { return memo + f.boost }, 0) - - var hasSomeToken = queryTokens.some(function (token) { - return this.tokenStore.has(token) - }, this) - - if (!hasSomeToken) return [] - - queryTokens - .forEach(function (token, i, tokens) { - var tf = 1 / tokens.length * this._fields.length * fieldBoosts, - self = this - - var set = this.tokenStore.expand(token).reduce(function (memo, key) { - var pos = self.corpusTokens.indexOf(key), - idf = self.idf(key), - similarityBoost = 1, - set = new lunr.SortedSet - - // if the expanded key is not an exact match to the token then - // penalise the score for this key by how different the key is - // to the token. - if (key !== token) { - var diff = Math.max(3, key.length - token.length) - similarityBoost = 1 / Math.log(diff) - } + var set = this.tokenStore.expand(token).reduce(function (memo, key) { + var pos = self.corpusTokens.indexOf(key), + idf = self.idf(key), + similarityBoost = 1, + set = new lunr.SortedSet - // calculate the query tf-idf score for this token - // applying an similarityBoost to ensure exact matches - // these rank higher than expanded terms - if (pos > -1) queryVector.insert(pos, tf * idf * similarityBoost) + // if the expanded key is not an exact match to the token then + // penalise the score for this key by how different the key is + // to the token. + if (key !== token) { + var diff = Math.max(3, key.length - token.length) + similarityBoost = 1 / Math.log(diff) + } - // add all the documents that have this key into a set - Object.keys(self.tokenStore.get(key)).forEach(function (ref) { set.add(ref) }) + // calculate the query tf-idf score for this token + // applying an similarityBoost to ensure exact matches + // these rank higher than expanded terms + if (pos > -1) queryVector.insert(pos, tf * idf * similarityBoost) - return memo.union(set) - }, new lunr.SortedSet) + // add all the documents that have this key into a set + Object.keys(self.tokenStore.get(key)).forEach(function (ref) { set.add(ref) }) - documentSets.push(set) - }, this) + return memo.union(set) + }, new lunr.SortedSet) - var documentSet = documentSets.reduce(function (memo, set) { - return memo.intersect(set) - }) + documentSets.push(set) + }, this) - return documentSet - .map(function (ref) { - return { ref: ref, score: queryVector.similarity(this.documentVector(ref)) } - }, this) - .sort(function (a, b) { - return b.score - a.score + var documentSet = documentSets.reduce(function (memo, set) { + return memo.intersect(set) }) -} -/** - * Generates a vector containing all the tokens in the document matching the - * passed documentRef. - * - * The vector contains the tf-idf score for each token contained in the - * document with the passed documentRef. The vector will contain an element - * for every token in the indexes corpus, if the document does not contain that - * token the element will be 0. - * - * @param {Object} documentRef The ref to find the document with. - * @returns {lunr.Vector} - * @private - * @memberOf Index - */ -lunr.Index.prototype.documentVector = function (documentRef) { - var documentTokens = this.documentStore.get(documentRef), - documentTokensLength = documentTokens.length, - documentVector = new lunr.Vector + return documentSet + .map(function (ref) { + return { ref: ref, score: queryVector.similarity(this.documentVector(ref)) } + }, this) + .sort(function (a, b) { + return b.score - a.score + }) + } - for (var i = 0; i < documentTokensLength; i++) { - var token = documentTokens.elements[i], - tf = this.tokenStore.get(token)[documentRef].tf, - idf = this.idf(token) + /** + * Generates a vector containing all the tokens in the document matching the + * passed documentRef. + * + * The vector contains the tf-idf score for each token contained in the + * document with the passed documentRef. The vector will contain an element + * for every token in the indexes corpus, if the document does not contain that + * token the element will be 0. + * + * @param {Object} documentRef The ref to find the document with. + * @returns {lunr.Vector} + * @private + * @memberOf Index + */ + lunr.Index.prototype.documentVector = function (documentRef) { + var documentTokens = this.documentStore.get(documentRef), + documentTokensLength = documentTokens.length, + documentVector = new lunr.Vector - documentVector.insert(this.corpusTokens.indexOf(token), tf * idf) - }; + for (var i = 0; i < documentTokensLength; i++) { + var token = documentTokens.elements[i], + tf = this.tokenStore.get(token)[documentRef].tf, + idf = this.idf(token) - return documentVector -} + documentVector.insert(this.corpusTokens.indexOf(token), tf * idf) + }; -/** - * Returns a representation of the index ready for serialisation. - * - * @returns {Object} - * @memberOf Index - */ -lunr.Index.prototype.toJSON = function () { - return { - version: lunr.version, - fields: this._fields, - ref: this._ref, - documentStore: this.documentStore.toJSON(), - tokenStore: this.tokenStore.toJSON(), - corpusTokens: this.corpusTokens.toJSON(), - pipeline: this.pipeline.toJSON() - } -} + return documentVector + } -/** - * Applies a plugin to the current index. - * - * A plugin is a function that is called with the index as its context. - * Plugins can be used to customise or extend the behaviour the index - * in some way. A plugin is just a function, that encapsulated the custom - * behaviour that should be applied to the index. - * - * The plugin function will be called with the index as its argument, additional - * arguments can also be passed when calling use. The function will be called - * with the index as its context. - * - * Example: - * - * var myPlugin = function (idx, arg1, arg2) { + /** + * Returns a representation of the index ready for serialisation. + * + * @returns {Object} + * @memberOf Index + */ + lunr.Index.prototype.toJSON = function () { + return { + version: lunr.version, + fields: this._fields, + ref: this._ref, + documentStore: this.documentStore.toJSON(), + tokenStore: this.tokenStore.toJSON(), + corpusTokens: this.corpusTokens.toJSON(), + pipeline: this.pipeline.toJSON() + } + } + + /** + * Applies a plugin to the current index. + * + * A plugin is a function that is called with the index as its context. + * Plugins can be used to customise or extend the behaviour the index + * in some way. A plugin is just a function, that encapsulated the custom + * behaviour that should be applied to the index. + * + * The plugin function will be called with the index as its argument, additional + * arguments can also be passed when calling use. The function will be called + * with the index as its context. + * + * Example: + * + * var myPlugin = function (idx, arg1, arg2) { * // `this` is the index to be extended * // apply any extensions etc here. * } - * - * var idx = lunr(function () { + * + * var idx = lunr(function () { * this.use(myPlugin, 'arg1', 'arg2') * }) - * - * @param {Function} plugin The plugin to apply. - * @memberOf Index - */ -lunr.Index.prototype.use = function (plugin) { - var args = Array.prototype.slice.call(arguments, 1) - args.unshift(this) - plugin.apply(this, args) -} -/*! - * lunr.Store - * Copyright (C) 2014 Oliver Nightingale - */ + * + * @param {Function} plugin The plugin to apply. + * @memberOf Index + */ + lunr.Index.prototype.use = function (plugin) { + var args = Array.prototype.slice.call(arguments, 1) + args.unshift(this) + plugin.apply(this, args) + } + /*! + * lunr.Store + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * lunr.Store is a simple key-value store used for storing sets of tokens for - * documents stored in index. - * - * @constructor - * @module - */ -lunr.Store = function () { - this.store = {} - this.length = 0 -} + /** + * lunr.Store is a simple key-value store used for storing sets of tokens for + * documents stored in index. + * + * @constructor + * @module + */ + lunr.Store = function () { + this.store = {} + this.length = 0 + } -/** - * Loads a previously serialised store - * - * @param {Object} serialisedData The serialised store to load. - * @returns {lunr.Store} - * @memberOf Store - */ -lunr.Store.load = function (serialisedData) { - var store = new this + /** + * Loads a previously serialised store + * + * @param {Object} serialisedData The serialised store to load. + * @returns {lunr.Store} + * @memberOf Store + */ + lunr.Store.load = function (serialisedData) { + var store = new this - store.length = serialisedData.length - store.store = Object.keys(serialisedData.store).reduce(function (memo, key) { - memo[key] = lunr.SortedSet.load(serialisedData.store[key]) - return memo - }, {}) + store.length = serialisedData.length + store.store = Object.keys(serialisedData.store).reduce(function (memo, key) { + memo[key] = lunr.SortedSet.load(serialisedData.store[key]) + return memo + }, {}) - return store -} + return store + } -/** - * Stores the given tokens in the store against the given id. - * - * @param {Object} id The key used to store the tokens against. - * @param {Object} tokens The tokens to store against the key. - * @memberOf Store - */ -lunr.Store.prototype.set = function (id, tokens) { - this.store[id] = tokens - this.length = Object.keys(this.store).length -} + /** + * Stores the given tokens in the store against the given id. + * + * @param {Object} id The key used to store the tokens against. + * @param {Object} tokens The tokens to store against the key. + * @memberOf Store + */ + lunr.Store.prototype.set = function (id, tokens) { + if (!this.has(id)) this.length++ + this.store[id] = tokens + } -/** - * Retrieves the tokens from the store for a given key. - * - * @param {Object} id The key to lookup and retrieve from the store. - * @returns {Object} - * @memberOf Store - */ -lunr.Store.prototype.get = function (id) { - return this.store[id] -} + /** + * Retrieves the tokens from the store for a given key. + * + * @param {Object} id The key to lookup and retrieve from the store. + * @returns {Object} + * @memberOf Store + */ + lunr.Store.prototype.get = function (id) { + return this.store[id] + } -/** - * Checks whether the store contains a key. - * - * @param {Object} id The id to look up in the store. - * @returns {Boolean} - * @memberOf Store - */ -lunr.Store.prototype.has = function (id) { - return id in this.store -} + /** + * Checks whether the store contains a key. + * + * @param {Object} id The id to look up in the store. + * @returns {Boolean} + * @memberOf Store + */ + lunr.Store.prototype.has = function (id) { + return id in this.store + } -/** - * Removes the value for a key in the store. - * - * @param {Object} id The id to remove from the store. - * @memberOf Store - */ -lunr.Store.prototype.remove = function (id) { - if (!this.has(id)) return + /** + * Removes the value for a key in the store. + * + * @param {Object} id The id to remove from the store. + * @memberOf Store + */ + lunr.Store.prototype.remove = function (id) { + if (!this.has(id)) return - delete this.store[id] - this.length-- -} + delete this.store[id] + this.length-- + } -/** - * Returns a representation of the store ready for serialisation. - * - * @returns {Object} - * @memberOf Store - */ -lunr.Store.prototype.toJSON = function () { - return { - store: this.store, - length: this.length + /** + * Returns a representation of the store ready for serialisation. + * + * @returns {Object} + * @memberOf Store + */ + lunr.Store.prototype.toJSON = function () { + return { + store: this.store, + length: this.length + } } -} -/*! - * lunr.stemmer - * Copyright (C) 2014 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ + /*! + * lunr.stemmer + * Copyright (C) 2014 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ -/** - * lunr.stemmer is an english language stemmer, this is a JavaScript - * implementation of the PorterStemmer taken from http://tartaurs.org/~martin - * - * @module - * @param {String} str The string to stem - * @returns {String} - * @see lunr.Pipeline - */ -lunr.stemmer = (function(){ - var step2list = { - "ational" : "ate", - "tional" : "tion", - "enci" : "ence", - "anci" : "ance", - "izer" : "ize", - "bli" : "ble", - "alli" : "al", - "entli" : "ent", - "eli" : "e", - "ousli" : "ous", - "ization" : "ize", - "ation" : "ate", - "ator" : "ate", - "alism" : "al", - "iveness" : "ive", - "fulness" : "ful", - "ousness" : "ous", - "aliti" : "al", - "iviti" : "ive", - "biliti" : "ble", - "logi" : "log" - }, - - step3list = { - "icate" : "ic", - "ative" : "", - "alize" : "al", - "iciti" : "ic", - "ical" : "ic", - "ful" : "", - "ness" : "" - }, - - c = "[^aeiou]", // consonant - v = "[aeiouy]", // vowel - C = c + "[^aeiouy]*", // consonant sequence - V = v + "[aeiou]*", // vowel sequence - - mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 - meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 - mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 - s_v = "^(" + C + ")?" + v; // vowel in stem - - return function (w) { - var stem, - suffix, - firstch, - re, - re2, - re3, - re4; - - if (w.length < 3) { return w; } - - firstch = w.substr(0,1); - if (firstch == "y") { - w = firstch.toUpperCase() + w.substr(1); - } + /** + * lunr.stemmer is an english language stemmer, this is a JavaScript + * implementation of the PorterStemmer taken from http://tartaurs.org/~martin + * + * @module + * @param {String} str The string to stem + * @returns {String} + * @see lunr.Pipeline + */ + lunr.stemmer = (function(){ + var step2list = { + "ational" : "ate", + "tional" : "tion", + "enci" : "ence", + "anci" : "ance", + "izer" : "ize", + "bli" : "ble", + "alli" : "al", + "entli" : "ent", + "eli" : "e", + "ousli" : "ous", + "ization" : "ize", + "ation" : "ate", + "ator" : "ate", + "alism" : "al", + "iveness" : "ive", + "fulness" : "ful", + "ousness" : "ous", + "aliti" : "al", + "iviti" : "ive", + "biliti" : "ble", + "logi" : "log" + }, + + step3list = { + "icate" : "ic", + "ative" : "", + "alize" : "al", + "iciti" : "ic", + "ical" : "ic", + "ful" : "", + "ness" : "" + }, + + c = "[^aeiou]", // consonant + v = "[aeiouy]", // vowel + C = c + "[^aeiouy]*", // consonant sequence + V = v + "[aeiou]*", // vowel sequence + + mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 + meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 + mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 + s_v = "^(" + C + ")?" + v; // vowel in stem + + var re_mgr0 = new RegExp(mgr0); + var re_mgr1 = new RegExp(mgr1); + var re_meq1 = new RegExp(meq1); + var re_s_v = new RegExp(s_v); + + var re_1a = /^(.+?)(ss|i)es$/; + var re2_1a = /^(.+?)([^s])s$/; + var re_1b = /^(.+?)eed$/; + var re2_1b = /^(.+?)(ed|ing)$/; + var re_1b_2 = /.$/; + var re2_1b_2 = /(at|bl|iz)$/; + var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$"); + var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + + var re_1c = /^(.+?[^aeiou])y$/; + var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + + var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + + var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + var re2_4 = /^(.+?)(s|t)(ion)$/; + + var re_5 = /^(.+?)e$/; + var re_5_1 = /ll$/; + var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + + var porterStemmer = function porterStemmer(w) { + var stem, + suffix, + firstch, + re, + re2, + re3, + re4; + + if (w.length < 3) { return w; } + + firstch = w.substr(0,1); + if (firstch == "y") { + w = firstch.toUpperCase() + w.substr(1); + } - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) { w = w.replace(re,"$1$2"); } - else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); + // Step 1a + re = re_1a + re2 = re2_1a; + + if (re.test(w)) { w = w.replace(re,"$1$2"); } + else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } + + // Step 1b + re = re_1b; + re2 = re2_1b; + if (re.test(w)) { + var fp = re.exec(w); + re = re_mgr0; + if (re.test(fp[1])) { + re = re_1b_2; + w = w.replace(re,""); + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = re_s_v; + if (re2.test(stem)) { + w = stem; + re2 = re2_1b_2; + re3 = re3_1b_2; + re4 = re4_1b_2; + if (re2.test(w)) { w = w + "e"; } + else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); } + else if (re4.test(w)) { w = w + "e"; } + } } - } else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) { w = w + "e"; } - else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } - else if (re4.test(w)) { w = w + "e"; } + + // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say) + re = re_1c; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem + "i"; } - } - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) { w = stem + "i"; } - } + // Step 2 + re = re_2; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = re_mgr0; + if (re.test(stem)) { + w = stem + step2list[suffix]; + } + } - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) { - w = stem + step2list[suffix]; + // Step 3 + re = re_3; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = re_mgr0; + if (re.test(stem)) { + w = stem + step3list[suffix]; + } } - } - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) { - w = stem + step3list[suffix]; + // Step 4 + re = re_4; + re2 = re2_4; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = re_mgr1; + if (re.test(stem)) { + w = stem; + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = re_mgr1; + if (re2.test(stem)) { + w = stem; + } } - } - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) { - w = stem; + // Step 5 + re = re_5; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = re_mgr1; + re2 = re_meq1; + re3 = re3_5; + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { + w = stem; + } } - } else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) { - w = stem; + + re = re_5_1; + re2 = re_mgr1; + if (re.test(w) && re2.test(w)) { + re = re_1b_2; + w = w.replace(re,""); } - } - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { - w = stem; + // and turn initial Y back to y + + if (firstch == "y") { + w = firstch.toLowerCase() + w.substr(1); } - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } + return w; + }; - // and turn initial Y back to y + return porterStemmer; + })(); - if (firstch == "y") { - w = firstch.toLowerCase() + w.substr(1); - } + lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') + /*! + * lunr.stopWordFilter + * Copyright (C) 2014 Oliver Nightingale + */ - return w; + /** + * lunr.stopWordFilter is an English language stop word list filter, any words + * contained in the list will not be passed through the filter. + * + * This is intended to be used in the Pipeline. If the token does not pass the + * filter then undefined will be returned. + * + * @module + * @param {String} token The token to pass through the filter + * @returns {String} + * @see lunr.Pipeline + */ + lunr.stopWordFilter = function (token) { + if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token } -})(); -lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') -/*! - * lunr.stopWordFilter - * Copyright (C) 2014 Oliver Nightingale - */ + lunr.stopWordFilter.stopWords = new lunr.SortedSet + lunr.stopWordFilter.stopWords.length = 119 + lunr.stopWordFilter.stopWords.elements = [ + "", + "a", + "able", + "about", + "across", + "after", + "all", + "almost", + "also", + "am", + "among", + "an", + "and", + "any", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "do", + "does", + "either", + "else", + "ever", + "every", + "for", + "from", + "get", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "in", + "into", + "is", + "it", + "its", + "just", + "least", + "let", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "only", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "where", + "which", + "while", + "who", + "whom", + "why", + "will", + "with", + "would", + "yet", + "you", + "your" + ] + + lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') + /*! + * lunr.trimmer + * Copyright (C) 2014 Oliver Nightingale + */ -/** - * lunr.stopWordFilter is an English language stop word list filter, any words - * contained in the list will not be passed through the filter. - * - * This is intended to be used in the Pipeline. If the token does not pass the - * filter then undefined will be returned. - * - * @module - * @param {String} token The token to pass through the filter - * @returns {String} - * @see lunr.Pipeline - */ -lunr.stopWordFilter = function (token) { - if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token -} - -lunr.stopWordFilter.stopWords = new lunr.SortedSet -lunr.stopWordFilter.stopWords.length = 119 -lunr.stopWordFilter.stopWords.elements = [ - "", - "a", - "able", - "about", - "across", - "after", - "all", - "almost", - "also", - "am", - "among", - "an", - "and", - "any", - "are", - "as", - "at", - "be", - "because", - "been", - "but", - "by", - "can", - "cannot", - "could", - "dear", - "did", - "do", - "does", - "either", - "else", - "ever", - "every", - "for", - "from", - "get", - "got", - "had", - "has", - "have", - "he", - "her", - "hers", - "him", - "his", - "how", - "however", - "i", - "if", - "in", - "into", - "is", - "it", - "its", - "just", - "least", - "let", - "like", - "likely", - "may", - "me", - "might", - "most", - "must", - "my", - "neither", - "no", - "nor", - "not", - "of", - "off", - "often", - "on", - "only", - "or", - "other", - "our", - "own", - "rather", - "said", - "say", - "says", - "she", - "should", - "since", - "so", - "some", - "than", - "that", - "the", - "their", - "them", - "then", - "there", - "these", - "they", - "this", - "tis", - "to", - "too", - "twas", - "us", - "wants", - "was", - "we", - "were", - "what", - "when", - "where", - "which", - "while", - "who", - "whom", - "why", - "will", - "with", - "would", - "yet", - "you", - "your" -] - -lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') -/*! - * lunr.trimmer - * Copyright (C) 2014 Oliver Nightingale - */ + /** + * lunr.trimmer is a pipeline function for trimming non word + * characters from the begining and end of tokens before they + * enter the index. + * + * This implementation may not work correctly for non latin + * characters and should either be removed or adapted for use + * with languages with non-latin characters. + * + * @module + * @param {String} token The token to pass through the filter + * @returns {String} + * @see lunr.Pipeline + */ + lunr.trimmer = function (token) { + return token + .replace(/^\W+/, '') + .replace(/\W+$/, '') + } -/** - * lunr.trimmer is a pipeline function for trimming non word - * characters from the begining and end of tokens before they - * enter the index. - * - * This implementation may not work correctly for non latin - * characters and should either be removed or adapted for use - * with languages with non-latin characters. - * - * @module - * @param {String} token The token to pass through the filter - * @returns {String} - * @see lunr.Pipeline - */ -lunr.trimmer = function (token) { - return token - .replace(/^\W+/, '') - .replace(/\W+$/, '') -} - -lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') -/*! - * lunr.stemmer - * Copyright (C) 2014 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ + lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') + /*! + * lunr.stemmer + * Copyright (C) 2014 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ -/** - * lunr.TokenStore is used for efficient storing and lookup of the reverse - * index of token to document ref. - * - * @constructor - */ -lunr.TokenStore = function () { - this.root = { docs: {} } - this.length = 0 -} + /** + * lunr.TokenStore is used for efficient storing and lookup of the reverse + * index of token to document ref. + * + * @constructor + */ + lunr.TokenStore = function () { + this.root = { docs: {} } + this.length = 0 + } -/** - * Loads a previously serialised token store - * - * @param {Object} serialisedData The serialised token store to load. - * @returns {lunr.TokenStore} - * @memberOf TokenStore - */ -lunr.TokenStore.load = function (serialisedData) { - var store = new this + /** + * Loads a previously serialised token store + * + * @param {Object} serialisedData The serialised token store to load. + * @returns {lunr.TokenStore} + * @memberOf TokenStore + */ + lunr.TokenStore.load = function (serialisedData) { + var store = new this - store.root = serialisedData.root - store.length = serialisedData.length + store.root = serialisedData.root + store.length = serialisedData.length - return store -} + return store + } -/** - * Adds a new token doc pair to the store. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to store the doc under - * @param {Object} doc The doc to store against the token - * @param {Object} root An optional node at which to start looking for the - * correct place to enter the doc, by default the root of this lunr.TokenStore - * is used. - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.add = function (token, doc, root) { - var root = root || this.root, - key = token[0], - rest = token.slice(1) + /** + * Adds a new token doc pair to the store. + * + * By default this function starts at the root of the current store, however + * it can start at any node of any token store if required. + * + * @param {String} token The token to store the doc under + * @param {Object} doc The doc to store against the token + * @param {Object} root An optional node at which to start looking for the + * correct place to enter the doc, by default the root of this lunr.TokenStore + * is used. + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.add = function (token, doc, root) { + var root = root || this.root, + key = token[0], + rest = token.slice(1) - if (!(key in root)) root[key] = {docs: {}} + if (!(key in root)) root[key] = {docs: {}} - if (rest.length === 0) { - root[key].docs[doc.ref] = doc - this.length += 1 - return - } else { - return this.add(rest, doc, root[key]) + if (rest.length === 0) { + root[key].docs[doc.ref] = doc + this.length += 1 + return + } else { + return this.add(rest, doc, root[key]) + } } -} -/** - * Checks whether this key is contained within this lunr.TokenStore. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to check for - * @param {Object} root An optional node at which to start - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.has = function (token) { - if (!token) return false + /** + * Checks whether this key is contained within this lunr.TokenStore. + * + * By default this function starts at the root of the current store, however + * it can start at any node of any token store if required. + * + * @param {String} token The token to check for + * @param {Object} root An optional node at which to start + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.has = function (token) { + if (!token) return false + + var node = this.root - var node = this.root + for (var i = 0; i < token.length; i++) { + if (!node[token[i]]) return false - for (var i = 0; i < token.length; i++) { - if (!node[token[i]]) return false + node = node[token[i]] + } - node = node[token[i]] + return true } - return true -} + /** + * Retrieve a node from the token store for a given token. + * + * By default this function starts at the root of the current store, however + * it can start at any node of any token store if required. + * + * @param {String} token The token to get the node for. + * @param {Object} root An optional node at which to start. + * @returns {Object} + * @see TokenStore.prototype.get + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.getNode = function (token) { + if (!token) return {} -/** - * Retrieve a node from the token store for a given token. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to get the node for. - * @param {Object} root An optional node at which to start. - * @returns {Object} - * @see TokenStore.prototype.get - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.getNode = function (token) { - if (!token) return {} + var node = this.root - var node = this.root + for (var i = 0; i < token.length; i++) { + if (!node[token[i]]) return {} - for (var i = 0; i < token.length; i++) { - if (!node[token[i]]) return {} + node = node[token[i]] + } - node = node[token[i]] + return node } - return node -} + /** + * Retrieve the documents for a node for the given token. + * + * By default this function starts at the root of the current store, however + * it can start at any node of any token store if required. + * + * @param {String} token The token to get the documents for. + * @param {Object} root An optional node at which to start. + * @returns {Object} + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.get = function (token, root) { + return this.getNode(token, root).docs || {} + } -/** - * Retrieve the documents for a node for the given token. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to get the documents for. - * @param {Object} root An optional node at which to start. - * @returns {Object} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.get = function (token, root) { - return this.getNode(token, root).docs || {} -} + lunr.TokenStore.prototype.count = function (token, root) { + return Object.keys(this.get(token, root)).length + } -lunr.TokenStore.prototype.count = function (token, root) { - return Object.keys(this.get(token, root)).length -} + /** + * Remove the document identified by ref from the token in the store. + * + * By default this function starts at the root of the current store, however + * it can start at any node of any token store if required. + * + * @param {String} token The token to get the documents for. + * @param {String} ref The ref of the document to remove from this token. + * @param {Object} root An optional node at which to start. + * @returns {Object} + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.remove = function (token, ref) { + if (!token) return + var node = this.root -/** - * Remove the document identified by ref from the token in the store. - * - * By default this function starts at the root of the current store, however - * it can start at any node of any token store if required. - * - * @param {String} token The token to get the documents for. - * @param {String} ref The ref of the document to remove from this token. - * @param {Object} root An optional node at which to start. - * @returns {Object} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.remove = function (token, ref) { - if (!token) return - var node = this.root + for (var i = 0; i < token.length; i++) { + if (!(token[i] in node)) return + node = node[token[i]] + } - for (var i = 0; i < token.length; i++) { - if (!(token[i] in node)) return - node = node[token[i]] + delete node.docs[ref] } - delete node.docs[ref] -} - -/** - * Find all the possible suffixes of the passed token using tokens - * currently in the store. - * - * @param {String} token The token to expand. - * @returns {Array} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.expand = function (token, memo) { - var root = this.getNode(token), - docs = root.docs || {}, - memo = memo || [] + /** + * Find all the possible suffixes of the passed token using tokens + * currently in the store. + * + * @param {String} token The token to expand. + * @returns {Array} + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.expand = function (token, memo) { + var root = this.getNode(token), + docs = root.docs || {}, + memo = memo || [] - if (Object.keys(docs).length) memo.push(token) + if (Object.keys(docs).length) memo.push(token) - Object.keys(root) - .forEach(function (key) { - if (key === 'docs') return + Object.keys(root) + .forEach(function (key) { + if (key === 'docs') return - memo.concat(this.expand(token + key, memo)) - }, this) + memo.concat(this.expand(token + key, memo)) + }, this) - return memo -} + return memo + } -/** - * Returns a representation of the token store ready for serialisation. - * - * @returns {Object} - * @memberOf TokenStore - */ -lunr.TokenStore.prototype.toJSON = function () { - return { - root: this.root, - length: this.length + /** + * Returns a representation of the token store ready for serialisation. + * + * @returns {Object} + * @memberOf TokenStore + */ + lunr.TokenStore.prototype.toJSON = function () { + return { + root: this.root, + length: this.length + } } -} /** - * export the module via AMD, CommonnJS or as a browser global + * export the module via AMD, CommonJS or as a browser global * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js */ ;(function (root, factory) { From b550f04dae22f2f1dd0b13a4c954c897ba6b3abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Thu, 12 Feb 2015 21:55:58 +0100 Subject: [PATCH 012/168] Update jQuery UI to version 1.11.3 --- source/javascripts/lib/jquery_ui.js | 570 +++++++++++++++++++++++++++- 1 file changed, 565 insertions(+), 5 deletions(-) diff --git a/source/javascripts/lib/jquery_ui.js b/source/javascripts/lib/jquery_ui.js index 3ff9191f42b..637e9c14254 100644 --- a/source/javascripts/lib/jquery_ui.js +++ b/source/javascripts/lib/jquery_ui.js @@ -1,6 +1,566 @@ -/*! jQuery UI - v1.10.3 - 2013-09-16 -* http://jqueryui.com -* Includes: jquery.ui.widget.js -* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ +/*! jQuery UI - v1.11.3 - 2015-02-12 + * http://jqueryui.com + * Includes: widget.js + * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ -(function(e,t){var i=0,s=Array.prototype.slice,a=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(n){}a(t)},e.widget=function(i,s,a){var n,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],n=u+"-"+i,a||(a=s,s=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:a.version,_proto:e.extend({},a),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(a,function(i,a){return e.isFunction(a)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,n=this._superApply;return this._super=e,this._superApply=t,i=a.apply(this,arguments),this._super=s,this._superApply=n,i}}(),t):(l[i]=a,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:n}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var a,n,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(a in r[o])n=r[o][a],r[o].hasOwnProperty(a)&&n!==t&&(i[a]=e.isPlainObject(n)?e.isPlainObject(i[a])?e.widget.extend({},i[a],n):e.widget.extend({},n):n);return i},e.widget.bridge=function(i,a){var n=a.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,a=e.data(this,n);return a?e.isFunction(a[r])&&"_"!==r.charAt(0)?(s=a[r].apply(a,h),s!==a&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,n);t?t.option(r||{})._init():e.data(this,n,new a(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var a,n,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},a=i.split("."),i=a.shift(),a.length){for(n=o[i]=e.widget.extend({},this.options[i]),r=0;a.length-1>r;r++)n[a[r]]=n[a[r]]||{},n=n[a[r]];if(i=a.pop(),s===t)return n[i]===t?null:n[i];n[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,a){var n,r=this;"boolean"!=typeof i&&(a=s,s=i,i=!1),a?(s=n=e(s),this.bindings=this.bindings.add(s)):(a=s,s=this.element,n=this.widget()),e.each(a,function(a,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=a.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?n.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var a,n,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],n=i.originalEvent)for(a in n)a in i||(i[a]=n[a]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,a,n){"string"==typeof a&&(a={effect:a});var r,o=a?a===!0||"number"==typeof a?i:a.effect||i:t;a=a||{},"number"==typeof a&&(a={duration:a}),r=!e.isEmptyObject(a),a.complete=n,a.delay&&s.delay(a.delay),r&&e.effects&&e.effects.effect[o]?s[t](a):o!==t&&s[o]?s[o](a.duration,a.easing,n):s.queue(function(i){e(this)[t](),n&&n.call(s[0]),i()})}})})(jQuery); \ No newline at end of file +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + /*! + * jQuery UI Widget 1.11.3 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ + + + var widget_uuid = 0, + widget_slice = Array.prototype.slice; + + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { + try { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} + } + orig( elems ); + }; + })( $.cleanData ); + + $.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; + }; + + $.widget.extend = function( target ) { + var input = widget_slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; + }; + + $.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = widget_slice.call( arguments, 1 ), + returnValue = this; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( options === "instance" ) { + returnValue = instance; + return false; + } + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat(args) ); + } + + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; + }; + + $.Widget = function( /* options, element */ ) {}; + $.Widget._childConstructors = []; + + $.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widget_uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled", !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + } + + return this; + }, + + enable: function() { + return this._setOptions({ disabled: false }); + }, + disable: function() { + return this._setOptions({ disabled: true }); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } + }; + + $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; + }); + + var widget = $.widget; + + + +})); From 1d13e198d0e06e3d09228d851c8e6880c2c1d199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sat, 14 Feb 2015 00:31:09 +0100 Subject: [PATCH 013/168] Update normalize.css to version 3.0.2 --- source/stylesheets/normalize.css | 380 ++++++++++++++++++------------- 1 file changed, 216 insertions(+), 164 deletions(-) diff --git a/source/stylesheets/normalize.css b/source/stylesheets/normalize.css index 73abb76fa41..46f646a5c00 100644 --- a/source/stylesheets/normalize.css +++ b/source/stylesheets/normalize.css @@ -1,11 +1,33 @@ -/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ -/* ========================================================================== - HTML5 display definitions +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions ========================================================================== */ -/* - * Corrects `block` display not defined in IE 8/9. +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. */ article, @@ -16,24 +38,29 @@ figure, footer, header, hgroup, +main, +menu, nav, section, summary { display: block; } -/* - * Corrects `inline-block` display not defined in IE 8/9. +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. */ audio, canvas, +progress, video { - display: inline-block; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } -/* - * Prevents modern browsers from displaying `audio` without controls. +/** + * Prevent modern browsers from displaying `audio` without controls. * Remove excess height in iOS 5 devices. */ @@ -42,52 +69,29 @@ audio:not([controls]) { height: 0; } -/* - * Addresses styling for `hidden` attribute not present in IE 8/9. +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. */ -[hidden] { +[hidden], +template { display: none; } -/* ========================================================================== - Base +/* Links ========================================================================== */ -/* - * 1. Sets default font family to sans-serif. - * 2. Prevents iOS text size adjust after orientation change, without disabling - * user zoom. +/** + * Remove the gray background color from active links in IE 10. */ -html { - font-family: sans-serif; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ - -ms-text-size-adjust: 100%; /* 2 */ +a { + background-color: transparent; } -/* - * Removes default margin. - */ - -body { - margin: 0; -} - -/* ========================================================================== - Links - ========================================================================== */ - -/* - * Addresses `outline` inconsistency between Chrome and other browsers. - */ - -a:focus { - outline: thin dotted; -} - -/* - * Improves readability when focused and also mouse hovered in all browsers. +/** + * Improve readability when focused and also mouse hovered in all browsers. */ a:active, @@ -95,29 +99,19 @@ a:hover { outline: 0; } -/* ========================================================================== - Typography +/* Text-level semantics ========================================================================== */ -/* - * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, - * Safari 5, and Chrome. - */ - -h1 { - font-size: 2em; -} - -/* - * Addresses styling not present in IE 8/9, Safari 5, and Chrome. +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. */ abbr[title] { border-bottom: 1px dotted; } -/* - * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. */ b, @@ -125,64 +119,43 @@ strong { font-weight: bold; } -/* - * Addresses styling not present in Safari 5 and Chrome. +/** + * Address styling not present in Safari and Chrome. */ dfn { font-style: italic; } -/* - * Addresses styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - - -/* - * Corrects font family set oddly in Safari 5 and Chrome. +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. */ -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -/* - * Improves readability of pre-formatted text in all browsers. - */ - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; +h1 { + font-size: 2em; + margin: 0.67em 0; } -/* - * Sets consistent quote types. +/** + * Address styling not present in IE 8/9. */ -q { - quotes: "\201C" "\201D" "\2018" "\2019"; +mark { + background: #ff0; + color: #000; } -/* - * Addresses inconsistent and variable font size in all browsers. +/** + * Address inconsistent and variable font size in all browsers. */ small { font-size: 80%; } -/* - * Prevents `sub` and `sup` affecting `line-height` in all browsers. +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. */ sub, @@ -201,92 +174,116 @@ sub { bottom: -0.25em; } -/* ========================================================================== - Embedded content +/* Embedded content ========================================================================== */ -/* - * Removes border when inside `a` element in IE 8/9. +/** + * Remove border when inside `a` element in IE 8/9/10. */ img { border: 0; } -/* - * Corrects overflow displayed oddly in IE 9. +/** + * Correct overflow not hidden in IE 9/10/11. */ svg:not(:root) { overflow: hidden; } -/* ========================================================================== - Figures +/* Grouping content ========================================================================== */ -/* - * Addresses margin not present in IE 8/9 and Safari 5. +/** + * Address margin not present in IE 8/9 and Safari. */ figure { - margin: 0; + margin: 1em 40px; } -/* ========================================================================== - Forms - ========================================================================== */ +/** + * Address differences between Firefox and other browsers. + */ -/* - * Define consistent border, margin, and padding. +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. */ -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; +pre { + overflow: auto; } -/* - * 1. Corrects color not being inherited in IE 8/9. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. +/** + * Address odd `em`-unit font size rendering in all browsers. */ -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; } -/* - * 1. Corrects font family not being inherited in all browsers. - * 2. Corrects font size not being inherited in all browsers. - * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. */ button, input, +optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 2 */ + color: inherit; /* 1 */ + font: inherit; /* 2 */ margin: 0; /* 3 */ } -/* - * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. */ button, -input { - line-height: normal; +select { + text-transform: none; } -/* +/** * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` * and `video` controls. - * 2. Corrects inability to style clickable `input` types in iOS. - * 3. Improves usability and consistency of cursor style between image-type + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type * `input` and others. */ @@ -298,18 +295,40 @@ input[type="submit"] { cursor: pointer; /* 3 */ } -/* +/** * Re-set default cursor for disabled elements. */ button[disabled], -input[disabled] { +html input[disabled] { cursor: default; } -/* - * 1. Addresses box sizing set to `content-box` in IE 8/9. - * 2. Removes excess padding in IE 8/9. +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. */ input[type="checkbox"], @@ -318,9 +337,20 @@ input[type="radio"] { padding: 0; /* 2 */ } -/* - * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome * (include `-moz` to future-proof). */ @@ -331,9 +361,10 @@ input[type="search"] { box-sizing: content-box; } -/* - * Removes inner padding and search cancel button in Safari 5 and Chrome - * on OS X. +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). */ input[type="search"]::-webkit-search-cancel-button, @@ -341,35 +372,56 @@ input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } -/* - * Removes inner padding and border in Firefox 4+. +/** + * Define consistent border, margin, and padding. */ -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } -/* - * 1. Removes default vertical scrollbar in IE 8/9. - * 2. Improves readability and alignment in all browsers. +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. */ textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ + overflow: auto; } -/* ========================================================================== - Tables +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables ========================================================================== */ -/* +/** * Remove most spacing between table cells. */ table { border-collapse: collapse; border-spacing: 0; -} \ No newline at end of file +} + +td, +th { + padding: 0; +} From f2ebab932517ec3c50c514ba23572c26b9ae5e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Fri, 20 Feb 2015 22:58:30 +0100 Subject: [PATCH 014/168] Rename SCSS files, so no unnecessary stylesheets are generated. --- source/stylesheets/{icon-font.scss => _icon-font.scss} | 0 source/stylesheets/{normalize.css => _normalize.css} | 0 source/stylesheets/{syntax.css.scss.erb => _syntax.scss.erb} | 0 source/stylesheets/{variables.scss => _variables.scss} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename source/stylesheets/{icon-font.scss => _icon-font.scss} (100%) rename source/stylesheets/{normalize.css => _normalize.css} (100%) rename source/stylesheets/{syntax.css.scss.erb => _syntax.scss.erb} (100%) rename source/stylesheets/{variables.scss => _variables.scss} (100%) diff --git a/source/stylesheets/icon-font.scss b/source/stylesheets/_icon-font.scss similarity index 100% rename from source/stylesheets/icon-font.scss rename to source/stylesheets/_icon-font.scss diff --git a/source/stylesheets/normalize.css b/source/stylesheets/_normalize.css similarity index 100% rename from source/stylesheets/normalize.css rename to source/stylesheets/_normalize.css diff --git a/source/stylesheets/syntax.css.scss.erb b/source/stylesheets/_syntax.scss.erb similarity index 100% rename from source/stylesheets/syntax.css.scss.erb rename to source/stylesheets/_syntax.scss.erb diff --git a/source/stylesheets/variables.scss b/source/stylesheets/_variables.scss similarity index 100% rename from source/stylesheets/variables.scss rename to source/stylesheets/_variables.scss From 0dac148f9506f60f6d345fa9878685e83982f940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Fri, 20 Feb 2015 23:15:47 +0100 Subject: [PATCH 015/168] Update Middleman to version 3.3.9 --- Gemfile.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4397878a67f..3e8f4177d52 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,19 +9,19 @@ GEM tzinfo (~> 1.1) celluloid (0.16.0) timers (~> 4.0.0) - chunky_png (1.3.3) + chunky_png (1.3.4) coffee-script (2.3.0) coffee-script-source execjs - coffee-script-source (1.8.0) - compass (1.0.1) + coffee-script-source (1.9.1) + compass (1.0.3) chunky_png (~> 1.2) - compass-core (~> 1.0.1) + compass-core (~> 1.0.2) compass-import-once (~> 1.0.5) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) sass (>= 3.3.13, < 3.5) - compass-core (1.0.1) + compass-core (1.0.3) multi_json (~> 1.0) sass (>= 3.3.0, < 3.5) compass-import-once (1.0.5) @@ -31,7 +31,7 @@ GEM http_parser.rb (~> 0.6.0) erubis (2.7.0) eventmachine (1.0.4) - execjs (2.2.2) + execjs (2.3.0) ffi (1.9.6) haml (4.0.6) tilt @@ -40,7 +40,7 @@ GEM hooks (0.4.0) uber (~> 0.0.4) http_parser.rb (0.6.0) - i18n (0.6.11) + i18n (0.7.0) json (1.8.2) kramdown (1.5.0) libv8 (3.16.14.7) @@ -48,23 +48,23 @@ GEM celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - middleman (3.3.7) + middleman (3.3.9) coffee-script (~> 2.2) compass (>= 1.0.0, < 2.0.0) compass-import-once (= 1.0.5) execjs (~> 2.0) haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.3.7) + middleman-core (= 3.3.9) middleman-sprockets (>= 3.1.2) sass (>= 3.4.0, < 4.0) uglifier (~> 2.5) - middleman-core (3.3.7) + middleman-core (3.3.9) activesupport (~> 4.1.0) bundler (~> 1.1) erubis hooks (~> 0.3) - i18n (~> 0.6.9) + i18n (~> 0.7.0) listen (>= 2.7.9, < 3.0) padrino-helpers (~> 0.12.3) rack (>= 1.4.5, < 2.0) @@ -106,7 +106,7 @@ GEM ref (1.0.5) rouge (1.8.0) ruby18_source_location (0.2) - sass (3.4.9) + sass (3.4.12) sprockets (2.12.3) hike (~> 1.2) multi_json (~> 1.0) From c8e7c646dc8f54830e367b47a1d635321f7c9d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sat, 21 Feb 2015 00:51:04 +0100 Subject: [PATCH 016/168] Optimize images Saves 26,9% on logo png and a whopping 96,6% on navbar.png --- source/images/logo.png | Bin 4796 -> 3507 bytes source/images/navbar.png | Bin 2790 -> 96 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/source/images/logo.png b/source/images/logo.png index 24e509952c50a098b4736d2d1fbdb5e99558f3f4..fa1f13da8193dacca747df56cc1f7bb0bc111a7e 100644 GIT binary patch delta 3506 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 diff --git a/source/images/navbar.png b/source/images/navbar.png index 32e70e14fb45cbf6a64b00115c78c4b8dfee4981..df38e90d87e1a215371b4977e18cde90f8832537 100644 GIT binary patch delta 77 zcmaDRnlM4qodF2K1XVSF6jMo%UoZnh+2pepK%S(hi(^OyW3q(K0U?eJ8{O741+p&Y bVv}QF@V(=ps4wXI52V%8)z4*}Q$iB}%X1U2 literal 2790 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 From a9d8b9b3b178269d81c5e73ba98bbdb62d0a74bf Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:04:41 +0200 Subject: [PATCH 017/168] Cleanup config.rb --- config.rb | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/config.rb b/config.rb index 9cc61f076fa..cd9a362f6ad 100644 --- a/config.rb +++ b/config.rb @@ -1,37 +1,32 @@ +# Markdown +set :markdown_engine, :redcarpet +set :markdown, + fenced_code_blocks: true, + smartypants: true, + disable_indented_code_blocks: true, + prettify: true, + tables: true, + with_toc_data: true, + no_intra_emphasis: true + +# Assets set :css_dir, 'stylesheets' - set :js_dir, 'javascripts' - set :images_dir, 'images' - set :fonts_dir, 'fonts' -set :markdown_engine, :redcarpet - -set :markdown, :fenced_code_blocks => true, :smartypants => true, :disable_indented_code_blocks => true, :prettify => true, :tables => true, :with_toc_data => true, :no_intra_emphasis => true - # Activate the syntax highlighter activate :syntax -# This is needed for Github pages, since they're hosted on a subdomain +# Github pages require relative links activate :relative_assets set :relative_links, true -# Build-specific configuration +# Build Configuration configure :build do - # For example, change the Compass output style for deployment activate :minify_css - - # Minify Javascript on build activate :minify_javascript - - # Enable cache buster - # activate :asset_hash - - # Use relative URLs # activate :relative_assets - - # Or use a different image path - # set :http_prefix, "/Content/images/" + # activate :asset_hash + # activate :gzip end - From a7596ff0a5e9fbfbc4a0cb7f6a2d02b589d63141 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 19:58:59 +0200 Subject: [PATCH 018/168] Cleanup Gemfile --- Gemfile | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/Gemfile b/Gemfile index 7ea1a883efd..6923c3e0b62 100644 --- a/Gemfile +++ b/Gemfile @@ -1,30 +1,18 @@ -# If you have OpenSSL installed, we recommend updating -# the following line to use "https" source 'http://rubygems.org' -gem "rouge", "~> 1.8.0" - -gem "middleman", "~>3.3.0" - -# For syntax highlighting -gem "middleman-syntax" - -# Plugin for middleman to generate Github pages +# Middleman +gem 'middleman', '~>3.3.0' +gem 'middleman-livereload', '~> 3.3.0' gem 'middleman-gh-pages' - -# Live-reloading plugin -gem "middleman-livereload", "~> 3.3.0" - +gem 'middleman-syntax' +gem 'rouge', '~> 1.8.0' gem 'redcarpet', '~> 3.2.1' -# For faster file watcher updates on Windows: -gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw] +gem 'rake', '~> 10.4.0' +gem 'therubyracer', platforms: :ruby -# Cross-templating language block fix for Ruby 1.8 +# Trash +gem 'wdm', '~> 0.1.0', :platforms => [:mswin, :mingw] platforms :mri_18 do - gem "ruby18_source_location" + gem 'ruby18_source_location' end - -gem "rake", "~> 10.4.0" - -gem 'therubyracer', :platforms => :ruby From e3f36f90576ebb128d58a61d5e8d7d1e19a7c9f8 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:05:19 +0200 Subject: [PATCH 019/168] Remove wdm gem --- Gemfile | 1 - Gemfile.lock | 1 - 2 files changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index 6923c3e0b62..cee4da95312 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,6 @@ gem 'rake', '~> 10.4.0' gem 'therubyracer', platforms: :ruby # Trash -gem 'wdm', '~> 0.1.0', :platforms => [:mswin, :mingw] platforms :mri_18 do gem 'ruby18_source_location' end diff --git a/Gemfile.lock b/Gemfile.lock index 3e8f4177d52..649288f0bb6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -145,4 +145,3 @@ DEPENDENCIES rouge (~> 1.8.0) ruby18_source_location therubyracer - wdm (~> 0.1.0) From c39c82c917b2a49073cd557002df2e2080df5b30 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:07:06 +0200 Subject: [PATCH 020/168] Remove ruby18_source_location gem --- Gemfile | 5 ----- Gemfile.lock | 4 +--- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index cee4da95312..5b0aabb13cf 100644 --- a/Gemfile +++ b/Gemfile @@ -10,8 +10,3 @@ gem 'redcarpet', '~> 3.2.1' gem 'rake', '~> 10.4.0' gem 'therubyracer', platforms: :ruby - -# Trash -platforms :mri_18 do - gem 'ruby18_source_location' -end diff --git a/Gemfile.lock b/Gemfile.lock index 649288f0bb6..0a26c22871d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -105,7 +105,6 @@ GEM redcarpet (3.2.2) ref (1.0.5) rouge (1.8.0) - ruby18_source_location (0.2) sass (3.4.12) sprockets (2.12.3) hike (~> 1.2) @@ -142,6 +141,5 @@ DEPENDENCIES middleman-syntax rake (~> 10.4.0) redcarpet (~> 3.2.1) - rouge (~> 1.8.0) - ruby18_source_location + rouge (= 1.8.0) therubyracer From f5b34ba69a983adf54ea70ce9379b49b283d7e5f Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:12:05 +0200 Subject: [PATCH 021/168] Remove middleman-livereload gem --- Gemfile | 1 - Gemfile.lock | 14 +------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/Gemfile b/Gemfile index 5b0aabb13cf..8075a2e4a90 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,6 @@ source 'http://rubygems.org' # Middleman gem 'middleman', '~>3.3.0' -gem 'middleman-livereload', '~> 3.3.0' gem 'middleman-gh-pages' gem 'middleman-syntax' gem 'rouge', '~> 1.8.0' diff --git a/Gemfile.lock b/Gemfile.lock index 0a26c22871d..ade997d435f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,11 +26,7 @@ GEM sass (>= 3.3.0, < 3.5) compass-import-once (1.0.5) sass (>= 3.2, < 3.5) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) erubis (2.7.0) - eventmachine (1.0.4) execjs (2.3.0) ffi (1.9.6) haml (4.0.6) @@ -39,8 +35,7 @@ GEM hitimes (1.2.2) hooks (0.4.0) uber (~> 0.0.4) - http_parser.rb (0.6.0) - i18n (0.7.0) + i18n (v) json (1.8.2) kramdown (1.5.0) libv8 (3.16.14.7) @@ -73,10 +68,6 @@ GEM tilt (~> 1.4.1, < 2.0) middleman-gh-pages (0.0.3) rake (> 0.9.3) - middleman-livereload (3.3.4) - em-websocket (~> 0.5.1) - middleman-core (~> 3.2) - rack-livereload (~> 0.3.15) middleman-sprockets (3.4.1) middleman-core (>= 3.3) sprockets (~> 2.12.1) @@ -94,8 +85,6 @@ GEM padrino-support (0.12.4) activesupport (>= 3.1) rack (1.6.0) - rack-livereload (0.3.15) - rack rack-test (0.6.3) rack (>= 1.0) rake (10.4.2) @@ -137,7 +126,6 @@ PLATFORMS DEPENDENCIES middleman (~> 3.3.0) middleman-gh-pages - middleman-livereload (~> 3.3.0) middleman-syntax rake (~> 10.4.0) redcarpet (~> 3.2.1) From ec2415e31989aba90929d0f091738499d0182969 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:18:20 +0200 Subject: [PATCH 022/168] Update middleman gem to version 3.3.10 --- Gemfile | 2 +- Gemfile.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index 8075a2e4a90..808257f4b65 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'http://rubygems.org' # Middleman -gem 'middleman', '~>3.3.0' +gem 'middleman', '~>3.3.10' gem 'middleman-gh-pages' gem 'middleman-syntax' gem 'rouge', '~> 1.8.0' diff --git a/Gemfile.lock b/Gemfile.lock index ade997d435f..a8d83c27684 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,7 +27,7 @@ GEM compass-import-once (1.0.5) sass (>= 3.2, < 3.5) erubis (2.7.0) - execjs (2.3.0) + execjs (2.4.0) ffi (1.9.6) haml (4.0.6) tilt @@ -35,26 +35,26 @@ GEM hitimes (1.2.2) hooks (0.4.0) uber (~> 0.0.4) - i18n (v) + i18n (0.7.0) json (1.8.2) - kramdown (1.5.0) + kramdown (1.6.0) libv8 (3.16.14.7) listen (2.8.5) celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - middleman (3.3.9) + middleman (3.3.10) coffee-script (~> 2.2) compass (>= 1.0.0, < 2.0.0) compass-import-once (= 1.0.5) execjs (~> 2.0) haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.3.9) + middleman-core (= 3.3.10) middleman-sprockets (>= 3.1.2) sass (>= 3.4.0, < 4.0) uglifier (~> 2.5) - middleman-core (3.3.9) + middleman-core (3.3.10) activesupport (~> 4.1.0) bundler (~> 1.1) erubis @@ -68,7 +68,7 @@ GEM tilt (~> 1.4.1, < 2.0) middleman-gh-pages (0.0.3) rake (> 0.9.3) - middleman-sprockets (3.4.1) + middleman-sprockets (3.4.2) middleman-core (>= 3.3) sprockets (~> 2.12.1) sprockets-helpers (~> 1.1.0) @@ -77,12 +77,12 @@ GEM middleman-core (~> 3.2) rouge (~> 1.0) minitest (5.5.1) - multi_json (1.10.1) - padrino-helpers (0.12.4) + multi_json (1.11.0) + padrino-helpers (0.12.5) i18n (~> 0.6, >= 0.6.7) - padrino-support (= 0.12.4) + padrino-support (= 0.12.5) tilt (~> 1.4.1) - padrino-support (0.12.4) + padrino-support (0.12.5) activesupport (>= 3.1) rack (1.6.0) rack-test (0.6.3) @@ -94,7 +94,7 @@ GEM redcarpet (3.2.2) ref (1.0.5) rouge (1.8.0) - sass (3.4.12) + sass (3.4.13) sprockets (2.12.3) hike (~> 1.2) multi_json (~> 1.0) @@ -116,7 +116,7 @@ GEM tzinfo (1.2.2) thread_safe (~> 0.1) uber (0.0.13) - uglifier (2.7.0) + uglifier (2.7.1) execjs (>= 0.3.0) json (>= 1.8.0) @@ -124,7 +124,7 @@ PLATFORMS ruby DEPENDENCIES - middleman (~> 3.3.0) + middleman (~> 3.3.10) middleman-gh-pages middleman-syntax rake (~> 10.4.0) From 8276ba8ff482e5e8da6880653440a21684b27cd9 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:26:10 +0200 Subject: [PATCH 023/168] Specify version for middleman-gh-pages gem to 0.0.3 --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 808257f4b65..17250a57b3f 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'http://rubygems.org' # Middleman gem 'middleman', '~>3.3.10' -gem 'middleman-gh-pages' +gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax' gem 'rouge', '~> 1.8.0' gem 'redcarpet', '~> 3.2.1' diff --git a/Gemfile.lock b/Gemfile.lock index a8d83c27684..3d050ee434e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -125,7 +125,7 @@ PLATFORMS DEPENDENCIES middleman (~> 3.3.10) - middleman-gh-pages + middleman-gh-pages (~> 0.0.3) middleman-syntax rake (~> 10.4.0) redcarpet (~> 3.2.1) From e14878ff5644f807fc803a9c5f54cfbbee914a50 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 20:28:13 +0200 Subject: [PATCH 024/168] Specify version for middleman-syntax gem to 2.0.0 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 17250a57b3f..c01b18993e4 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'http://rubygems.org' # Middleman gem 'middleman', '~>3.3.10' gem 'middleman-gh-pages', '~> 0.0.3' -gem 'middleman-syntax' +gem 'middleman-syntax', '~> 2.0.0' gem 'rouge', '~> 1.8.0' gem 'redcarpet', '~> 3.2.1' diff --git a/Gemfile.lock b/Gemfile.lock index 3d050ee434e..b636d8ba391 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -126,8 +126,8 @@ PLATFORMS DEPENDENCIES middleman (~> 3.3.10) middleman-gh-pages (~> 0.0.3) - middleman-syntax + middleman-syntax (~> 2.0.0) rake (~> 10.4.0) redcarpet (~> 3.2.1) - rouge (= 1.8.0) + rouge (~> 1.8.0) therubyracer From a91ac15fab107b3bfca6267d48aca897889d1766 Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 21:51:43 +0200 Subject: [PATCH 025/168] Update redcarpet gem to version 3.2.2 --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index c01b18993e4..c61cd55484b 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem 'middleman', '~>3.3.10' gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax', '~> 2.0.0' gem 'rouge', '~> 1.8.0' -gem 'redcarpet', '~> 3.2.1' +gem 'redcarpet', '~> 3.2.2' gem 'rake', '~> 10.4.0' gem 'therubyracer', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index b636d8ba391..d802f83c3ea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -128,6 +128,6 @@ DEPENDENCIES middleman-gh-pages (~> 0.0.3) middleman-syntax (~> 2.0.0) rake (~> 10.4.0) - redcarpet (~> 3.2.1) + redcarpet (~> 3.2.2) rouge (~> 1.8.0) therubyracer From 6ea72a13fa5252e2034a7827004be641b895d67a Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 21:52:40 +0200 Subject: [PATCH 026/168] Update rake gem to version 10.4.2 --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index c61cd55484b..591e908d12b 100644 --- a/Gemfile +++ b/Gemfile @@ -7,5 +7,5 @@ gem 'middleman-syntax', '~> 2.0.0' gem 'rouge', '~> 1.8.0' gem 'redcarpet', '~> 3.2.2' -gem 'rake', '~> 10.4.0' +gem 'rake', '~> 10.4.2' gem 'therubyracer', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index d802f83c3ea..5080c7d6063 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -127,7 +127,7 @@ DEPENDENCIES middleman (~> 3.3.10) middleman-gh-pages (~> 0.0.3) middleman-syntax (~> 2.0.0) - rake (~> 10.4.0) + rake (~> 10.4.2) redcarpet (~> 3.2.2) rouge (~> 1.8.0) therubyracer From fd684122ddaa34da527c708ff5c8f1f1176d973f Mon Sep 17 00:00:00 2001 From: Chrisovalantis Kefalidis Date: Sat, 7 Mar 2015 21:55:32 +0200 Subject: [PATCH 027/168] Specify version for therubyracer gem to 0.12.1 --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 591e908d12b..df5651b2b81 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,4 @@ gem 'rouge', '~> 1.8.0' gem 'redcarpet', '~> 3.2.2' gem 'rake', '~> 10.4.2' -gem 'therubyracer', platforms: :ruby +gem 'therubyracer', '~> 0.12.1', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index 5080c7d6063..11aed001fde 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -130,4 +130,4 @@ DEPENDENCIES rake (~> 10.4.2) redcarpet (~> 3.2.2) rouge (~> 1.8.0) - therubyracer + therubyracer (~> 0.12.1) From 23eb3f433e17b0b2d97f14d9a6b549431adb4fcc Mon Sep 17 00:00:00 2001 From: German Attanasio Ruiz Date: Thu, 26 Mar 2015 15:05:55 -0400 Subject: [PATCH 028/168] Update README.md Adding IBM Cloudant to the example list --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c3c907b89a8..27d7b6b6792 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,9 @@ Examples of Slate in the Wild * [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) * [Coinbase API Reference](https://developers.coinbase.com/api) * [Whispir.io API](https://whispir.github.io/api) -* [Nasa API](https://data.nasa.gov/developer/external/planetary/) +* [NASA API](https://data.nasa.gov/developer/external/planetary/) * [CardPay API](https://developers.cardpay.com/) +* [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) (Feel free to add your site to this list in a pull request!) From 5da237e7fe9d7bfa654d5f81aabd7a79c997d8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sun, 29 Mar 2015 22:39:41 +0200 Subject: [PATCH 029/168] Don't use a selector to get the heading text for search results. Prevents bugs with special CSS characters. Closes #201. --- source/javascripts/app/search.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/javascripts/app/search.js b/source/javascripts/app/search.js index cf2eaf8cb63..3c22f714262 100644 --- a/source/javascripts/app/search.js +++ b/source/javascripts/app/search.js @@ -50,7 +50,8 @@ if (results.length) { searchResults.empty(); $.each(results, function (index, result) { - searchResults.append("
  • " + $('#'+result.ref).text() + "
  • "); + var elem = document.getElementById(result.ref); + searchResults.append("
  • " + $(elem).text() + "
  • "); }); highlight.call(this); } else { From 4fe37604b7aae06ec952dd9de116c6b0ca90e737 Mon Sep 17 00:00:00 2001 From: Nik Samokhvalov Date: Mon, 13 Apr 2015 14:19:08 +0300 Subject: [PATCH 030/168] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 27d7b6b6792..21ec87edac2 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Examples of Slate in the Wild * [NASA API](https://data.nasa.gov/developer/external/planetary/) * [CardPay API](https://developers.cardpay.com/) * [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) +* [Bitrix basis components](http://bbc.bitrix.expert/) (Feel free to add your site to this list in a pull request!) From f98914369265de851924b4b04bafe71719387045 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Thu, 30 Apr 2015 15:56:38 -0500 Subject: [PATCH 031/168] Fix styling bug in example index --- source/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/index.md b/source/index.md index 401ece5fcd9..ed5f6d63d0e 100644 --- a/source/index.md +++ b/source/index.md @@ -55,7 +55,7 @@ Kittn expects for the API key to be included in all API requests to the server i `Authorization: meowmeowmeow` # Kittens From 16dca4d00002fc8fce8cf1b78605a0bb297b6246 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Thu, 30 Apr 2015 15:58:11 -0500 Subject: [PATCH 032/168] Update gems --- Gemfile.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 11aed001fde..e3931cd63af 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: http://rubygems.org/ specs: - activesupport (4.1.9) + activesupport (4.1.10) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -10,10 +10,10 @@ GEM celluloid (0.16.0) timers (~> 4.0.0) chunky_png (1.3.4) - coffee-script (2.3.0) + coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.9.1) + coffee-script-source (1.9.1.1) compass (1.0.3) chunky_png (~> 1.2) compass-core (~> 1.0.2) @@ -27,8 +27,8 @@ GEM compass-import-once (1.0.5) sass (>= 3.2, < 3.5) erubis (2.7.0) - execjs (2.4.0) - ffi (1.9.6) + execjs (2.5.2) + ffi (1.9.8) haml (4.0.6) tilt hike (1.2.3) @@ -37,24 +37,24 @@ GEM uber (~> 0.0.4) i18n (0.7.0) json (1.8.2) - kramdown (1.6.0) + kramdown (1.7.0) libv8 (3.16.14.7) - listen (2.8.5) - celluloid (>= 0.15.2) + listen (2.10.0) + celluloid (~> 0.16.0) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - middleman (3.3.10) + middleman (3.3.11) coffee-script (~> 2.2) compass (>= 1.0.0, < 2.0.0) compass-import-once (= 1.0.5) execjs (~> 2.0) haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.3.10) + middleman-core (= 3.3.11) middleman-sprockets (>= 3.1.2) sass (>= 3.4.0, < 4.0) uglifier (~> 2.5) - middleman-core (3.3.10) + middleman-core (3.3.11) activesupport (~> 4.1.0) bundler (~> 1.1) erubis @@ -76,7 +76,7 @@ GEM middleman-syntax (2.0.0) middleman-core (~> 3.2) rouge (~> 1.0) - minitest (5.5.1) + minitest (5.6.1) multi_json (1.11.0) padrino-helpers (0.12.5) i18n (~> 0.6, >= 0.6.7) @@ -91,7 +91,7 @@ GEM rb-fsevent (0.9.4) rb-inotify (0.9.5) ffi (>= 0.5.0) - redcarpet (3.2.2) + redcarpet (3.2.3) ref (1.0.5) rouge (1.8.0) sass (3.4.13) @@ -105,11 +105,11 @@ GEM sprockets-sass (1.3.1) sprockets (~> 2.0) tilt (~> 1.1) - therubyracer (0.12.1) + therubyracer (0.12.2) libv8 (~> 3.16.14.0) ref thor (0.19.1) - thread_safe (0.3.4) + thread_safe (0.3.5) tilt (1.4.1) timers (4.0.1) hitimes From fddf3040878694f781bba00c307dccdef964e6a3 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 18 May 2015 09:58:08 +0200 Subject: [PATCH 033/168] Use HTTPS for fetch gems --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index df5651b2b81..73f7a16891c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'http://rubygems.org' +source 'https://rubygems.org' # Middleman gem 'middleman', '~>3.3.10' diff --git a/Gemfile.lock b/Gemfile.lock index e3931cd63af..c22d1d07291 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,5 +1,5 @@ GEM - remote: http://rubygems.org/ + remote: https://rubygems.org/ specs: activesupport (4.1.10) i18n (~> 0.6, >= 0.6.9) From 094c38223eacb9f40ac4fdb044e0b19efda4b892 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 18 May 2015 10:09:01 +0200 Subject: [PATCH 034/168] [Travis-CI] Use docker build infraestructure --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 46029affecf..035d7ebe7cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +sudo: false + rvm: - 1.9.3 - 2.0.0 From d7769c653d3cd35cfa8117a7207a0196668d7da5 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 18 May 2015 10:11:51 +0200 Subject: [PATCH 035/168] [Travis-CI] Specify language to test is ruby --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 035d7ebe7cc..16d6207dad1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ sudo: false +language: ruby + rvm: - 1.9.3 - 2.0.0 From d0e46a3894a2180d1ecc8fad09fa15968118d74c Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 18 May 2015 10:12:57 +0200 Subject: [PATCH 036/168] [Travis-CI] Enable bundler cache --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 16d6207dad1..3280d947c9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,5 @@ language: ruby rvm: - 1.9.3 - 2.0.0 + +cache: bundler From bdebff8250193ba2c479d2819092bab6c549e05c Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 18 May 2015 12:45:30 +0200 Subject: [PATCH 037/168] Add "rake clobber" for to remove generated files --- Rakefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Rakefile b/Rakefile index d6af6474b1d..6a952e1e914 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,6 @@ require 'middleman-gh-pages' +require 'rake/clean' + +CLOBBER.include('build') task :default => [:build] From 06c1641ad1965627ad0d01f1247fd4337f079c37 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 28 May 2015 18:41:56 -0400 Subject: [PATCH 038/168] Consistency fixes as discussed on commit 84b7705fd1b510bd79c69a030a754b8d6129ad34 --- source/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/index.md b/source/index.md index ed5f6d63d0e..4c1fa8c9f7d 100644 --- a/source/index.md +++ b/source/index.md @@ -106,7 +106,7 @@ This endpoint retrieves all kittens. ### HTTP Request -`GET http://example.com/kittens` +`GET http://example.com/api/kittens` ### Query Parameters @@ -136,7 +136,7 @@ api.kittens.get(2) ``` ```shell -curl "http://example.com/api/kittens/3" +curl "http://example.com/api/kittens/2" -H "Authorization: meowmeowmeow" ``` @@ -164,5 +164,5 @@ This endpoint retrieves a specific kitten. Parameter | Description --------- | ----------- -ID | The ID of the cat to retrieve +ID | The ID of the kitten to retrieve From 3a53a3c0291cb8d189794dd5cfe3cdb17edb9734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sun, 31 May 2015 20:20:58 +0200 Subject: [PATCH 039/168] Update rouge to version 1.9.0 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 73f7a16891c..755165be089 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ source 'https://rubygems.org' gem 'middleman', '~>3.3.10' gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax', '~> 2.0.0' -gem 'rouge', '~> 1.8.0' +gem 'rouge', '~> 1.9.0' gem 'redcarpet', '~> 3.2.2' gem 'rake', '~> 10.4.2' diff --git a/Gemfile.lock b/Gemfile.lock index c22d1d07291..ce2594750e3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,7 +93,7 @@ GEM ffi (>= 0.5.0) redcarpet (3.2.3) ref (1.0.5) - rouge (1.8.0) + rouge (1.9.0) sass (3.4.13) sprockets (2.12.3) hike (~> 1.2) @@ -129,5 +129,5 @@ DEPENDENCIES middleman-syntax (~> 2.0.0) rake (~> 10.4.2) redcarpet (~> 3.2.2) - rouge (~> 1.8.0) + rouge (~> 1.9.0) therubyracer (~> 0.12.1) From ab816e432a0c0356d111ce43d31148f68813e44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sun, 31 May 2015 23:33:37 +0200 Subject: [PATCH 040/168] Use Autoprefixer for vendor prefixes --- Gemfile | 1 + Gemfile.lock | 7 ++++ config.rb | 6 +++ source/stylesheets/_variables.scss | 3 -- source/stylesheets/screen.css.scss | 62 ++++++++++++------------------ 5 files changed, 39 insertions(+), 40 deletions(-) diff --git a/Gemfile b/Gemfile index 755165be089..5d8c0211b36 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ source 'https://rubygems.org' gem 'middleman', '~>3.3.10' gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax', '~> 2.0.0' +gem 'middleman-autoprefixer', '~> 2.4.4' gem 'rouge', '~> 1.9.0' gem 'redcarpet', '~> 3.2.2' diff --git a/Gemfile.lock b/Gemfile.lock index ce2594750e3..d29c7d0046c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,9 @@ GEM minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) + autoprefixer-rails (5.2.0) + execjs + json celluloid (0.16.0) timers (~> 4.0.0) chunky_png (1.3.4) @@ -54,6 +57,9 @@ GEM middleman-sprockets (>= 3.1.2) sass (>= 3.4.0, < 4.0) uglifier (~> 2.5) + middleman-autoprefixer (2.4.4) + autoprefixer-rails (~> 5.2.0) + middleman-core (>= 3.3.3) middleman-core (3.3.11) activesupport (~> 4.1.0) bundler (~> 1.1) @@ -125,6 +131,7 @@ PLATFORMS DEPENDENCIES middleman (~> 3.3.10) + middleman-autoprefixer (~> 2.4.4) middleman-gh-pages (~> 0.0.3) middleman-syntax (~> 2.0.0) rake (~> 10.4.2) diff --git a/config.rb b/config.rb index cd9a362f6ad..43bceaa5a43 100644 --- a/config.rb +++ b/config.rb @@ -18,6 +18,12 @@ # Activate the syntax highlighter activate :syntax +activate :autoprefixer do |config| + config.browsers = ['last 2 version', 'Firefox ESR'] + config.cascade = false + config.inline = true +end + # Github pages require relative links activate :relative_assets set :relative_links, true diff --git a/source/stylesheets/_variables.scss b/source/stylesheets/_variables.scss index 4c9bae05ee1..0957678427b 100644 --- a/source/stylesheets/_variables.scss +++ b/source/stylesheets/_variables.scss @@ -100,13 +100,10 @@ $search-box-border-color: #666; // These settings are probably best left alone. %break-words { - -ms-word-break: break-all; word-break: break-all; /* Non standard for webkit */ word-break: break-word; --webkit-hyphens: auto; - -moz-hyphens: auto; hyphens: auto; } diff --git a/source/stylesheets/screen.css.scss b/source/stylesheets/screen.css.scss index d64b3239574..1cbac164554 100644 --- a/source/stylesheets/screen.css.scss +++ b/source/stylesheets/screen.css.scss @@ -49,25 +49,17 @@ html, body { } @mixin embossed-bg { - @include background( - linear-gradient(top, - rgba(#000, 0.2), - rgba(#000, 0) 8px), - linear-gradient(bottom, - rgba(#000, 0.2), - rgba(#000, 0) 8px), - linear-gradient(top, - rgba($nav-embossed-border-top, 1), - rgba($nav-embossed-border-top, 0) 1.5px), - linear-gradient(bottom, - rgba($nav-embossed-border-bottom, 1), - rgba($nav-embossed-border-bottom, 0) 1.5px), - $nav-subitem-bg - ); + background: + linear-gradient(to bottom,rgba(#000, 0.2), rgba(#000, 0) 8px), + linear-gradient(to top, rgba(#000, 0.2), rgba(#000, 0) 8px), + linear-gradient(to bottom, rgba($nav-embossed-border-top, 1), rgba($nav-embossed-border-top, 0) 1.5px), + linear-gradient(to top, rgba($nav-embossed-border-bottom, 1), rgba($nav-embossed-border-bottom, 0) 1.5px), + #262626; } .tocify-wrapper { - @include transition(left ease-in-out 0.3s); + transition: left 0.3s ease-in-out; + overflow-y: auto; overflow-x: hidden; position: fixed; @@ -102,7 +94,7 @@ html, body { border-width: 0 0 1px 0; border-color: $search-box-border-color; padding: 6px 0 6px 20px; - @include box-sizing(border-box); + box-sizing: border-box; margin: $nav-v-padding $nav-padding; width: $nav-width - 30; outline: none; @@ -125,13 +117,13 @@ html, body { .search-results { margin-top: 0; - @include box-sizing(border-box); + box-sizing: border-box; height: 0; overflow-y: auto; overflow-x: hidden; - @include transition-property(height margin); - @include transition-duration(180ms); - @include transition-timing-function(ease-in-out); + transition-property: height, margin; + transition-duration: 180ms; + transition-timing-function: ease-in-out; &.visible { height: 30%; margin-bottom: 1em; @@ -175,14 +167,14 @@ html, body { li { color: $nav-text; - @include transition-property('background'); - @include transition-timing-function('linear'); - @include transition-duration(230ms); + transition-property: background; + transition-timing-function: linear; + transition-duration: 230ms; } // This is the currently selected ToC entry .tocify-focus { - @include box-shadow(0px 1px 0px $nav-active-shadow); + box-shadow: 0px 1px 0px $nav-active-shadow; background-color: $nav-active-bg; color: $nav-active-text; } @@ -235,8 +227,8 @@ html, body { $side-pad: $main-padding / 2 - 8px; padding: $side-pad $side-pad $side-pad; background-color: rgba($main-bg, 0.7); - @include transform-origin(0, 0); - @include transform(rotate(-90deg) translate(-100%, 0)); + transform-origin: 0 0; + transform: rotate(-90deg) translate(-100%, 0); border-radius: 0 0 0 5px; } padding: 0 1.5em 5em 0; // increase touch size area @@ -255,7 +247,7 @@ html, body { vertical-align: bottom; } - @include transition(left ease-in-out 0.3s); + transition: left 0.3s ease-in-out; &:hover { opacity: 1; } &.open {left: $nav-width} @@ -346,7 +338,7 @@ html, body { &>h1, &>h2, &>h3, &>h4, &>h5, &>h6, &>p, &>table, &>ul, &>ol, &>aside, &>dl { margin-right: $examples-width; padding: 0 $main-padding; - @include box-sizing(border-box); + box-sizing: border-box; display: block; @include text-shadow($main-embossed-text-shadow); @@ -371,9 +363,7 @@ html, body { margin-bottom: $h1-margin-bottom; margin-top: 2em; border-top: 1px solid #ddd; - @include background-image( - linear-gradient(top, #fff, #f9f9f9) - ); + background-image: linear-gradient(to bottom, #fff, #f9f9f9); } h1:first-child, div:first-child + h1 { @@ -389,9 +379,7 @@ html, body { border-top: 1px solid #ccc; padding-top: 1.2em; padding-bottom: 1.2em; - @include background-image( - linear-gradient(top, rgba(#fff,0.4), rgba(#fff, 0)) - ); + background-image: linear-gradient(to bottom, rgba(#fff, 0.4), rgba(#fff, 0)); } // h2s right after h1s should bump right up @@ -525,7 +513,7 @@ html, body { border-radius: 4px; border: 1px solid #F7E633; @include text-shadow(1px 1px 0 #666); - @include background(linear-gradient(bottom right, #F7E633 0%, #F1D32F 100%)); + background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%); } } @@ -546,7 +534,7 @@ html, body { float:right; clear:right; - @include box-sizing(border-box); + box-sizing: border-box; @include text-shadow(0px 1px 2px rgba(0,0,0,0.4)); @extend %right-col; From 384ffac2fd5138b95f315b4e50e07882066522b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Mon, 1 Jun 2015 00:29:57 +0200 Subject: [PATCH 041/168] Don't generate unnecessary JS files. Also exclude jquery.highlight from the nosearch version, as it's not needed there. --- source/javascripts/all.js | 6 ++++-- source/javascripts/all_nosearch.js | 7 +++---- source/javascripts/app/{lang.js => _lang.js} | 0 source/javascripts/app/{search.js => _search.js} | 2 ++ source/javascripts/app/{toc.js => _toc.js} | 2 ++ source/javascripts/lib/{energize.js => _energize.js} | 0 .../lib/{jquery.highlight.js => _jquery.highlight.js} | 0 .../lib/{jquery.tocify.js => _jquery.tocify.js} | 3 +-- source/javascripts/lib/{jquery_ui.js => _jquery_ui.js} | 0 source/javascripts/lib/{lunr.js => _lunr.js} | 0 10 files changed, 12 insertions(+), 8 deletions(-) rename source/javascripts/app/{lang.js => _lang.js} (100%) rename source/javascripts/app/{search.js => _search.js} (96%) rename source/javascripts/app/{toc.js => _toc.js} (94%) rename source/javascripts/lib/{energize.js => _energize.js} (100%) rename source/javascripts/lib/{jquery.highlight.js => _jquery.highlight.js} (100%) rename source/javascripts/lib/{jquery.tocify.js => _jquery.tocify.js} (99%) rename source/javascripts/lib/{jquery_ui.js => _jquery_ui.js} (100%) rename source/javascripts/lib/{lunr.js => _lunr.js} (100%) diff --git a/source/javascripts/all.js b/source/javascripts/all.js index 534eae93090..ffaa9b01307 100644 --- a/source/javascripts/all.js +++ b/source/javascripts/all.js @@ -1,2 +1,4 @@ -//= require_tree ./lib -//= require_tree ./app +//= require ./lib/_energize +//= require ./app/_lang +//= require ./app/_search +//= require ./app/_toc diff --git a/source/javascripts/all_nosearch.js b/source/javascripts/all_nosearch.js index 4610cabe62d..818bc4e5095 100644 --- a/source/javascripts/all_nosearch.js +++ b/source/javascripts/all_nosearch.js @@ -1,4 +1,3 @@ -//= require_tree ./lib -//= require_tree ./app -//= stub ./app/search.js -//= stub ./lib/lunr.js +//= require ./lib/_energize +//= require ./app/_lang +//= require ./app/_toc diff --git a/source/javascripts/app/lang.js b/source/javascripts/app/_lang.js similarity index 100% rename from source/javascripts/app/lang.js rename to source/javascripts/app/_lang.js diff --git a/source/javascripts/app/search.js b/source/javascripts/app/_search.js similarity index 96% rename from source/javascripts/app/search.js rename to source/javascripts/app/_search.js index 3c22f714262..550b1a30f61 100644 --- a/source/javascripts/app/search.js +++ b/source/javascripts/app/_search.js @@ -1,3 +1,5 @@ +//= require ../lib/_lunr +//= require ../lib/_jquery.highlight (function (global) { 'use strict'; diff --git a/source/javascripts/app/toc.js b/source/javascripts/app/_toc.js similarity index 94% rename from source/javascripts/app/toc.js rename to source/javascripts/app/_toc.js index c88b67f2b70..d84bf8e197a 100644 --- a/source/javascripts/app/toc.js +++ b/source/javascripts/app/_toc.js @@ -1,3 +1,5 @@ +//= require ../lib/_jquery_ui +//= require ../lib/_jquery.tocify (function (global) { 'use strict'; diff --git a/source/javascripts/lib/energize.js b/source/javascripts/lib/_energize.js similarity index 100% rename from source/javascripts/lib/energize.js rename to source/javascripts/lib/_energize.js diff --git a/source/javascripts/lib/jquery.highlight.js b/source/javascripts/lib/_jquery.highlight.js similarity index 100% rename from source/javascripts/lib/jquery.highlight.js rename to source/javascripts/lib/_jquery.highlight.js diff --git a/source/javascripts/lib/jquery.tocify.js b/source/javascripts/lib/_jquery.tocify.js similarity index 99% rename from source/javascripts/lib/jquery.tocify.js rename to source/javascripts/lib/_jquery.tocify.js index f791bf86246..91cf637913a 100644 --- a/source/javascripts/lib/jquery.tocify.js +++ b/source/javascripts/lib/_jquery.tocify.js @@ -1,4 +1,3 @@ -//= require ./jquery_ui /* jquery Tocify - v1.8.0 - 2013-09-16 * http://www.gregfranko.com/jquery.tocify.js/ * Copyright (c) 2013 Greg Franko; Licensed MIT @@ -1040,4 +1039,4 @@ }); -})); //end of plugin \ No newline at end of file +})); //end of plugin diff --git a/source/javascripts/lib/jquery_ui.js b/source/javascripts/lib/_jquery_ui.js similarity index 100% rename from source/javascripts/lib/jquery_ui.js rename to source/javascripts/lib/_jquery_ui.js diff --git a/source/javascripts/lib/lunr.js b/source/javascripts/lib/_lunr.js similarity index 100% rename from source/javascripts/lib/lunr.js rename to source/javascripts/lib/_lunr.js From d27f5c4b7d569cca6a205210ceeb467171d675ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sat, 21 Feb 2015 00:03:29 +0100 Subject: [PATCH 042/168] Remove unused icons from the font --- font-selection.json | 148 +++++++++++++++++++++++++++++ source/fonts/icomoon.eot | Bin 2780 -> 0 bytes source/fonts/icomoon.svg | 18 ---- source/fonts/icomoon.ttf | Bin 2616 -> 0 bytes source/fonts/icomoon.woff | Bin 2816 -> 0 bytes source/fonts/slate.eot | Bin 0 -> 1876 bytes source/fonts/slate.svg | 14 +++ source/fonts/slate.ttf | Bin 0 -> 1720 bytes source/fonts/slate.woff | Bin 0 -> 1796 bytes source/stylesheets/_icon-font.scss | 30 ++---- 10 files changed, 169 insertions(+), 41 deletions(-) create mode 100755 font-selection.json delete mode 100755 source/fonts/icomoon.eot delete mode 100755 source/fonts/icomoon.svg delete mode 100755 source/fonts/icomoon.ttf delete mode 100755 source/fonts/icomoon.woff create mode 100755 source/fonts/slate.eot create mode 100755 source/fonts/slate.svg create mode 100755 source/fonts/slate.ttf create mode 100755 source/fonts/slate.woff diff --git a/font-selection.json b/font-selection.json new file mode 100755 index 00000000000..5e78f5d8621 --- /dev/null +++ b/font-selection.json @@ -0,0 +1,148 @@ +{ + "IcoMoonType": "selection", + "icons": [ + { + "icon": { + "paths": [ + "M438.857 73.143q119.429 0 220.286 58.857t159.714 159.714 58.857 220.286-58.857 220.286-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857zM512 785.714v-108.571q0-8-5.143-13.429t-12.571-5.429h-109.714q-7.429 0-13.143 5.714t-5.714 13.143v108.571q0 7.429 5.714 13.143t13.143 5.714h109.714q7.429 0 12.571-5.429t5.143-13.429zM510.857 589.143l10.286-354.857q0-6.857-5.714-10.286-5.714-4.571-13.714-4.571h-125.714q-8 0-13.714 4.571-5.714 3.429-5.714 10.286l9.714 354.857q0 5.714 5.714 10t13.714 4.286h105.714q8 0 13.429-4.286t6-10z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "exclamation-circle" + ], + "defaultCode": 61546, + "grid": 14 + }, + "attrs": [], + "properties": { + "id": 100, + "order": 4, + "prevSize": 28, + "code": 58880, + "name": "exclamation-sign", + "ligatures": "" + }, + "setIdx": 0, + "iconIdx": 0 + }, + { + "icon": { + "paths": [ + "M585.143 786.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-54.857v-292.571q0-8-5.143-13.143t-13.143-5.143h-182.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h54.857v182.857h-54.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h256q8 0 13.143-5.143t5.143-13.143zM512 274.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-109.714q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h109.714q8 0 13.143-5.143t5.143-13.143zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "info-circle" + ], + "defaultCode": 61530, + "grid": 14 + }, + "attrs": [], + "properties": { + "id": 85, + "order": 3, + "name": "info-sign", + "prevSize": 28, + "code": 58882 + }, + "setIdx": 0, + "iconIdx": 2 + }, + { + "icon": { + "paths": [ + "M733.714 419.429q0-16-10.286-26.286l-52-51.429q-10.857-10.857-25.714-10.857t-25.714 10.857l-233.143 232.571-129.143-129.143q-10.857-10.857-25.714-10.857t-25.714 10.857l-52 51.429q-10.286 10.286-10.286 26.286 0 15.429 10.286 25.714l206.857 206.857q10.857 10.857 25.714 10.857 15.429 0 26.286-10.857l310.286-310.286q10.286-10.286 10.286-25.714zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "check-circle" + ], + "defaultCode": 61528, + "grid": 14 + }, + "attrs": [], + "properties": { + "id": 83, + "order": 9, + "prevSize": 28, + "code": 58886, + "name": "ok-sign" + }, + "setIdx": 0, + "iconIdx": 6 + }, + { + "icon": { + "paths": [ + "M658.286 475.429q0-105.714-75.143-180.857t-180.857-75.143-180.857 75.143-75.143 180.857 75.143 180.857 180.857 75.143 180.857-75.143 75.143-180.857zM950.857 950.857q0 29.714-21.714 51.429t-51.429 21.714q-30.857 0-51.429-21.714l-196-195.429q-102.286 70.857-228 70.857-81.714 0-156.286-31.714t-128.571-85.714-85.714-128.571-31.714-156.286 31.714-156.286 85.714-128.571 128.571-85.714 156.286-31.714 156.286 31.714 128.571 85.714 85.714 128.571 31.714 156.286q0 125.714-70.857 228l196 196q21.143 21.143 21.143 51.429z" + ], + "width": 951, + "attrs": [], + "isMulticolor": false, + "tags": [ + "search" + ], + "defaultCode": 61442, + "grid": 14 + }, + "attrs": [], + "properties": { + "id": 2, + "order": 1, + "prevSize": 28, + "code": 58887, + "name": "icon-search" + }, + "setIdx": 0, + "iconIdx": 7 + } + ], + "height": 1024, + "metadata": { + "name": "slate", + "license": "SIL OFL 1.1" + }, + "preferences": { + "showGlyphs": true, + "showQuickUse": true, + "showQuickUse2": true, + "showSVGs": true, + "fontPref": { + "prefix": "icon-", + "metadata": { + "fontFamily": "slate", + "majorVersion": 1, + "minorVersion": 0, + "description": "Based on FontAwesome", + "license": "SIL OFL 1.1" + }, + "metrics": { + "emSize": 1024, + "baseline": 6.25, + "whitespace": 50 + }, + "resetPoint": 58880, + "showSelector": false, + "selector": "class", + "classSelector": ".icon", + "showMetrics": false, + "showMetadata": true, + "showVersion": true, + "ie7": false + }, + "imagePref": { + "prefix": "icon-", + "png": true, + "useClassSelector": true, + "color": 4473924, + "bgColor": 16777215 + }, + "historySize": 100, + "showCodes": true, + "gridSize": 16, + "showLiga": false + } +} diff --git a/source/fonts/icomoon.eot b/source/fonts/icomoon.eot deleted file mode 100755 index 212835a5243aabdf5b8a4d029f41b6471ac38ff8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2780 zcmb7GOKg)z5T5xTyT9#VC&aG=+lg#!Bb7Sf-w&cZh$juMw=f1@e6zY-yV!UfISWx3^2#b0=6(JX<3)`3udZ+1 z2zdcI%Fdy+`clmom**k>3gglB+Ko+Ehiyl#KfY00Up^MUdmrNmSYvXtesv3eqWR-W zPNqS8i)_di`4TuMoA^16&}T}oqcPm>ZgWJBBtLB6#}8o*W;ztqn7oZsD~7SIl7`8m zBfx%gAj9%B{zx|dZZyCn(B#qF_-)i`&hP{PObo4%XGQZ+6xB&@$@aRh<|$9Ie2;f1 zPOsA&M8m~cG!~77rH~?%&gb&Ea;aLWR@~uoDW7|d(^4ck9E(nIv05qTtGmodti{}! zc8keWDp_==r`%#HnM@VksjO*ORnu!#%P?7(rghXZO&hqZ7(2cy88 z=s=|c6~nYH+%XL_^A1M%lec%;|1d40NGaRTP32`imx1qN9ChJ1;z67`%C3OCSe0D; z%CUc^L8pgNC|1={P5>F^!r)*mK5{&3iJW0sX2|Cc1^oeG2ls|TO%);hKHGL28}f~w z(&%snd z51ACBJ-*&QPLx8kjt|mtkfjNR!+<%N3vu3qA`%{B>A`5Ma+Fc%fR%F9+hvIg*)8^1 z#XAH%Z8S@Cq@@0G$Vw;B%a4jiLAtWJ( zJEQ1~PJO4^dlkkvN1xbyM;!m{`;PV*=#{><{rew2jgpH`tE!w#T2+pMx@O#>s+N}@ zg1SAbD&pFlz?np)tlH8Mx9$0U+2jI>Nrmq>M368I|fR7dW3y7mRXg7NQhXf<}g)ZreV;&k76; zh*assfdeN>DTVi@$C7*4u!OxLhK7cu5bVeozwRq!!r@F|-!4A5VhhXQJ;|~3-rcDR zi-Dnl1-tgPbXW)p6Jo1#qB79B2jf58zWY&V`Z)zu5fJ^d_Q!l1H>1Sm?A3@8;2u-= zsV*AO&pK{9B_|rtNJDk)@x7OKy(*OaxOY?Z2?zO8eqwxJd~G~6Ppir319VBh30hu& z*=j-hw&?@osibEp_kwh?$u~joZ_*a%GfmpYLn_#$1xYG4X+Isn6AZ5b%Lk6KscCIf z)7qw{wM|WHo0=AwJK3D8ZFWD-`aj~jbS^K|*X#9-o;P9ld$4N)f?mdpP`wUov;};T Y#_0lW11@;)$~Rl@%4SYmiR>l*0j~m3Z~y=R diff --git a/source/fonts/icomoon.svg b/source/fonts/icomoon.svg deleted file mode 100755 index 24493587d38..00000000000 --- a/source/fonts/icomoon.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - \ No newline at end of file diff --git a/source/fonts/icomoon.ttf b/source/fonts/icomoon.ttf deleted file mode 100755 index 360b3d751620cc106382cda4c2d548656db343f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2616 zcmb7GO>7%Q6n<}iX4ZCUCyoD-+D>FQb|s42?%H0W{4_%SNvZ%+p$OCpaMLuYl*AED z)#idK#E}EyS`G+t=1^7Y1q2e;N^t5W94aC8fJ)UvdxM&9b~dpS+#=T5_cw38dGF1e zoe&dIjBb)iN8ft;i0c&p`T>^j@qVQjUPV%8eqB{lul&eRVyYz)o79|dJQ~E4#u!NjXsp^zuRrt2r>mS zw|^hD!WqE;2ou9A5uj)ru>J91$fX3`Vv`i*+U-!`T)JI1X^&&?MKdDokq@Z3T^UvRyNG1IVo zGkAQ{JRXgJd8%Md`krZW|(vR{h930 z$uUcm4a+hUk!T_wjR`xxKamJsgos9L+i`4+uk9&LP_XL?r~~`cP%7OQn-U^tSc6hJ zG8&aqI0OBIG3_Uuh(PsVl(FbOe^2Ft8g|#GOcV6ZPJQ-PDW!_jwXx=22esQTF2@+Q z=m28BphL^$G{1?>3pTz}sk=Q>ufqRJ?WDx>fU0VhNf|o&_1<}+6~aC~OeZ1MjxYiS zEz5F(D*+X$j7A4-)cs(WB|2og*)xsc5b&&BtJ(Ij?MPAcgmfTwEM84p zTD>y*Q3|haMTE>sX6d?$W~GQ&^$>?yA%OyYMjewJb50$UsbjTVfw_>Y9h=f$3*Fy3 zFSRWdscBj5m<%Y+o}Wnt6n#6z8P&ZyuZrm8<>P3h?fEv4z;B+826d z^jJAFpAphxX3UsHN>-#4v5?y=Kw!0`ID?dg9PG}bJ3IBA>g-h#-yD5nD_wc~ckEj_ zX0VsW+KKOf#57DEKCP;AN=4NW6R*h0IZlsb0!*iz%UlfcH zE*K4enyXwHD^`tqZ5l%bxWtVTKiRY+(TEir=o5w7sY8cO)e4I5FOKB*v0({&Nem1O zNFmsf&wo8oEhUqs>Va*3c*z!)!Ta(f#r@k;6&HO2F$=i%rgT^c2?(*#Jy8Md+=JPl zZ{7JYG5L&QstJgGS@~nO!^13bIR`zW25^t5`&2g#&-li8VxCo#@%GVW{XfA@6fo{Qar!Qdfhi8FzG)4}r$gCB?!@JlpG V7ikl8E&zTbTs+8Xr-;3Te*iBhKi>cV diff --git a/source/fonts/icomoon.woff b/source/fonts/icomoon.woff deleted file mode 100755 index 9a213b112669b937374d2cd9030609d6041169ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2816 zcmcImYiv|S6rS7N+fGYqLA!*9nxbfoCbm?HV9=Oaiv~zZm?VEYdGMnOxroO^Rm?S9y@IrKCwXxLr53$_KYtrnEL8raqVBW$liUm?hM zLAut^)ZPi(KIp}Q@+HQaYC8p940@(ZxtmyXZ4>;;KFXN1R#5rkuP?L&_qQXai&#_W zk`FV??`M)E@y5DfQ!v=fqzu@ek3W>`3a9)m3*vlsCF5z|3;tz(M>aCoWPWlpn&qnI3N84Zo|&f~okbb?L{PaHWu zGJb3nY-A$(74eBgJU~CnWa@@yfFdgKYLYe5bPYq-NaeIeCQOKF5b?7ln`A^H5yOZW zWODslV8E%6$=$CR*g||G$tnQ_5Wvv5oxlP;f?2H6P2xY0jJ;`)2uEa5XI_BL3LI05 z-0}rD@I}{k2%M^AQX?9GJedFbGVN3cC>B1{^KtK?t`80j9T+@dy+=E!A=I{0RU(R| z@GpZh(BXp!!Z3$F8X6j~2dyD@9 zIrX^t5H7l*qo>3lsg%4_pYV8 zy>i?u-R(Ufa(G(g@U&M8xaZchg~)j#U1H=88kVLN!>YeDVvu~@PIA|8+j`edkBoM&8%*e0K<^b86t(v@Ma&l5OO~WSq zG)uL3>rq*?!bX_Fq-cu5YqoAZBcn-NOITAC-r6QBimqTmI1;v0K3P*!BP*&dwuIe& z8f}wJ1qT4sGAxUqIWxIcwiL^?*oJBG(W5fDz#^MFzH|3Bx<8%10DU2ot=o#}InK+7 zreP5Q!iG?IJ;`o>s){Hn%&DwQSVVw|szKniM<(RKQoT_4G*Owb2vAjo!Y4>}12j{i z(DZc5Vp(Pc(eo>Z?|*Cwbmd(gcd)=K#QpIq?sLutXaLDIdF$wGuejZl$WHJLKh3qF zf4rpAK_pYb-C-qF1tq`8;_l&Z)v9V z(sEi(rKMoYFO|-~bTT$RruW!b#;+&l%dyayemE98tdE6aJTc|)Ksi-S(Rn&QH3ddf zRa8#pRaNE0^WxEhIR58z-KT^PSD4LY+_)R1dfb=mQ{Nf3g!M!J_mIRhV9t1nvCCP~ z#Uy^xMfdi`y+1n&T`2<`H##c-7qbPpG1uUmgI7ideiAFZoR$1LnS_l&X09wHe_QHL z?Qkc+Bqm{1zKa6&_chy!-pXG$!{&)282fqOAL31t`X;YRH{g?a%XrgbKNG&<_J$eq zjWm+03YI%7K@iSLr|wK1%BJ+LJob4CPhxqg?c%6BwmxO|L0*xP{gAh$WSK33=4CDu zuZfbBoWq`Ebs`7;Y*+-QCwrKl>|uJchv~^4rYC1&@7mN}53>=tLDmEcvS#)M+s)e8 ze%9z}g={5z2Cuj|YtqlKIYw56jeA%J+sA4FFn4Y}=9*pLTGo#5E>_5PvUkB>a}R$# Lb+{W9*qz5e&1UyY diff --git a/source/fonts/slate.eot b/source/fonts/slate.eot new file mode 100755 index 0000000000000000000000000000000000000000..13c4839a1975d4c92d66753d75553f922743c6ef GIT binary patch literal 1876 zcmaJ?&2Jl35TEDWeRg&sP8)xqh$Kr)Yzaiu#`dnNaHtS!Xx9i53LF}#nAmmP`Xfq= z;s{Zte*qCEK;i~h4hYFPaA-x4sD#vVrBXQ{MIaD@1Ke8kn|8tnQ^fdI9N^x@? zd<=RUJW{D`U;b-v<0kYSA}zO8E|&DaCqF0BzlPme0}$TUZbAP8`m<~GR{K~75*dg= zcCEQu4DE@ZpmS=+>&5muJwb0nf0^x#V!izR7X1vpggLV7&CM3_1j&!tPMS_)mkgrN zC!rsJe5kniow8zt{RT+zltXle=pd}!=-!|+8X9a|iyqm&z#GOh#?Z4hMmoI$K1va6 zrUYgm&_U=R+`ZrJ0!LQ9E`42ef0@uHvC8U zo}w4%B?O&MCX$JGEG)w^HIqqa()pb0xK4IFpUb457c*fwDPqaQf|z%md}h1{#>ac0 zD>_@{@&c$_-fEYWRBE3yj7U8q4MTz%hA^cOxdwei%19MlXpM(P_)+e=@Rm}B>tXap zwoqO*DogaoKF+^`!zvX>{f10 zq*F6dk@0&Ok4=k2cHR|EKKaOn+_Q3KG-~~J-9n!;&D+d{W9=SQ|IqlDm9?y2uUl{( zi(0o$Q@Cby<g+B7U zE7gMM6{=S}Ps}C~lhg72%h#4X&vB-0d)je4Z)w>(?>M%-xE~jH;l@L}Lcyy(n4O9z z65lS`w&R>XbW_^$2bKN!lz(S%N3N!tcP>R={D&-^3rjyfS-aWi!AkH>sk+00G5&qW zC1%n(1Gmpd;5$IPUF_Lw@K%&WbbxEX?LgKcF9x!K$J`8LiMQ^#KsG5yOZ=|rBS1K&l2uG4tC&hwF_o-hDp_Le zTrgI}?0+pse + + +Generated by IcoMoon + + + + + + + + + + diff --git a/source/fonts/slate.ttf b/source/fonts/slate.ttf new file mode 100755 index 0000000000000000000000000000000000000000..ace9a46a7e1ed6b6ab3de2f30ef3e27c572f88d3 GIT binary patch literal 1720 zcmaJ>-D_KA7=PaL@t*V?ZMro%kz(6pV-rwZyCyk@Q7?wb>UJv9`gO6wj7^qiCTUqB zO%X@;7dX69!8^V6LWJzXiw!F%45qgVdLa}=5xvm6E&iVKo-9$jJ@CHI_viaTf`}a2 zC!H2wcyVDVd0amU$>&(FZ8pn0bm7yth{U7dH)`ef4)6r{E^wmO*t_`0^~*QG?-S|8 zt!lYq{5ky*k?|Sy{uTt*p8hrX-@re<)$DYS^+1t{800m!H_O^}@g4X@@W-3w?hZXf zuY!M;^{sNV`qeJ|2)=?Gg`Mqo2XzAEd#oqjAaRXMBJF+c79{T|EPkbe7-PE;5S;Q~ zaGL1Q(r@%{&}khDI-bPX!~GUGz-0@x9Aaiik?BxrHq?#(PnWnI%nYaReOv*$ZSm>?)ctla|1hAG;T1^YPnfOv{N&_J8ekcvoG^Cm?MLpzb znO-8ASEU{s)D{<<&JKz%JjTWAM|EWWzjHMajT;ECdZ?bsKw&|^tZONrkvOuIkI%De zUYTtG_26}0jYK0>4*B1QgBuPLXU?}t^*TiboK|r`R>P0_HD+(cdi{Ze{FKYDLBs0R~?v6B%Rx~Edo2aasT@IJ-vtfG(iE^ z$Awv_E5l{^C4s84a|;3+->t#z!u^V-9Nj!@+Ph(RslFP9tMyA^DCS*vdNzG<@yc2l z`u?ov&H8>AuC0gXeBbj{4$|U#n6XQ^x*FE+&d;P>_lp(J^Zj%8%oMl&cI_ZN6TKO{ zkvFp2-&{yO{TDd~50<`txN&oc<4*8TskuV~pXj~g5i{t$k=GYVU^@bQTx>a5uvcK? zADE$i`dge4A3((KH9;?{zv*7K*f>Jt^humckR5yQeHf=xv0R7Ti)jP&N=%#Ng5wPM z_VCv|5z{smX^sCCV+<0Gsc02b(JH2*RZK;zn2MJ0U5I^E%r-TsOdYDyD_EDQO?BF) z7OFc*Cuk9TtZz5Uo$8RKb(q)a%}C8|gD__z_YMNoV9|<#sst6tUZ*|mXK52w&tq|_ J6Wq-M;U6NW`v(93 literal 0 HcmV?d00001 diff --git a/source/fonts/slate.woff b/source/fonts/slate.woff new file mode 100755 index 0000000000000000000000000000000000000000..1e72e0ee0018119d7c814c2097cc60c0bcd05d84 GIT binary patch literal 1796 zcmaJ>&2Jl35TCanZ=GF;-Nqj%Qj#SmwgjS~vAs(b4i$%lc7v*fuR|jhlemtH?Nqf< z5&;$c3y8RZ#0{p83^QtGf$~^ZU#vdPL3b z4fcBr_DN>rKz!G#?&4f~pM4ZRM6a}~ts1aTadwIM%N_dh>UO7#K7YRFXF@YA68l_? z@xFm7>0K?wZ&VUvut!OxMlIIQ5*<0_&Hha~Yl49Y@PK@!7+CqFG*;eClSR)#j$=Xw zNnrjF9T`VX|4zRT99<||DqHk_nzSa(NzO5voBad{L?lOWoE4r?ZbRP(V_X@TZL>{} z(3A8mk}l-3xojrwNJr*pi-lsLQVxSKC{0w##ljO}){#>poy#tYg)pcTCk9|L<3To?f*omEO$b9ODUa}gVj!a zAvUB1l6OCpmTg;7PgnO)phbF-Xik@UVo+OLa3((}zVs*;Zywi?{r}GOL=0{q1ou!q ztD%;HAbGE?Z5HC#RzAMSTXWiN9ioS*i+Usm@#fI}eK@$`F!8DQHtAj`iEnm!UKH}P zNl{d*%%o>TwzLq6ppv_9BR_a$H<|Q)z2RXkyY6k4BJlQ)o4+xU@=Bif%MA~%sib$? zbw%hV*Y96nzi0MvpHdWZeO#D>x^i4rP!XsqKRYk5@ZB2RF5E9QWp(qg81F^VmBvaG ztu(Ggk(kS7r)DyTm#?ozQ4q}d{!9==(dt@sJ_vk&`7k5ChZ~1PD=Sgs?%Z@HoBe#* z_k-a4JvVKwyWWZ=q2@1#9uk~9EfrHBtA=!8%MC` zIGu@c6SyDi7WCy Date: Sat, 21 Feb 2015 00:22:58 +0100 Subject: [PATCH 043/168] Add WOFF2 version of the icon font --- source/fonts/slate.woff2 | Bin 0 -> 796 bytes source/stylesheets/_icon-font.scss | 1 + 2 files changed, 1 insertion(+) create mode 100755 source/fonts/slate.woff2 diff --git a/source/fonts/slate.woff2 b/source/fonts/slate.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..7c585a72737539240f1ec97a725eb6d7347d2bc5 GIT binary patch literal 796 zcmV+%1LOR6Pew8T0RR9100SHV3jhEB00yi800Pbc0RR9100000000000000000000 z00006U;tbZ2nvQMg+Bo{0we<<3labXAO(Um2Ot}71;`$!%XmzA7Qq8=XT3iY%ud$O zWX0S9ZjY*kHtiXmTBy7_umPvrP6Jzi{`Zd`tTPV^?c*5BT6)|dWhhwm@ z2-w*rE$c_UfviKEL=Vy>={0bo+(i5#P1q3$6VB``hVMrCzU@B6vbqKcPy}m-BtQn- zkylU>byNe6DE>18g5d9bm%bZqa|qF=7&3(|U!AY)%Yg-vOsqKIq$w0D$r*3}ks4=+ z>U6?w2xMd=B$;zQ9v)F1K7KwfQ9|)<9nl&i?6-rchs{I8LC1eK^@#(|^QwB-{VeQz zoHLn@cwG?Yo(X!F(Q8iBOqSNs${h}C*?qJYLuZAnVXqx{ww|}Ux0`ca^V#hz?c7{r z7ldYbmk!M1m3G+IYC6(!VcCzqp&pJkZ#1@kw2W<^EJMqOM;^&dq6ELC*|pK!(cC0< zbZtF%BzLsuTw5O*+eg;dX0a+hcfI=gj8a~qWYJoMamHAo)!Qq|6&~9S8`{d0T?L&% z@$R=P6H0rTp6V+-Dlb>EB67JEMQ>kk%`y}{hvBC(RNEw)*%|U|4>SL+B=3rE@y*rw zR_bLZr&~XN?C;+yx2IilcDnrb?M)}An;DsTe@^rq$9L-UWNqY_oTyWyYisN3CMIh; z*C)b12exYgK^2c4S}J#2YJ+00rUlj%+LqQ7E%lldEc`K|1Bky)iLkwF{Wltvj!{A+PBEzhE3BX) zFBgqmj@&z?N1*=OK?z54T7is8FiA(N66oe`X+cKl>`n&&000000HC;3 zk^ug-#56-JW5JAtMV6Rgj#+|9A(7;@^`+^dWy@Alt7D86w|;R>QMs>d+47HJVfKhH aD;vc&%m&dlj4($-ipx}q&#}A+00017%3vV? literal 0 HcmV?d00001 diff --git a/source/stylesheets/_icon-font.scss b/source/stylesheets/_icon-font.scss index d963b537f28..b5994839881 100644 --- a/source/stylesheets/_icon-font.scss +++ b/source/stylesheets/_icon-font.scss @@ -2,6 +2,7 @@ font-family: 'slate'; src:font-url('slate.eot?-syv14m'); src:font-url('slate.eot?#iefix-syv14m') format('embedded-opentype'), + font-url('slate.woff2?-syv14m') format('woff2'), font-url('slate.woff?-syv14m') format('woff'), font-url('slate.ttf?-syv14m') format('truetype'), font-url('slate.svg?-syv14m#slate') format('svg'); From 402f931fc90939b0440fb73a1e92a492098e888e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Mon, 1 Jun 2015 23:27:03 +0200 Subject: [PATCH 044/168] Fix minor SCSS issues introduced in ab816e432a0c0356d111ce43d31148f68813e44c. --- source/stylesheets/screen.css.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/stylesheets/screen.css.scss b/source/stylesheets/screen.css.scss index 1cbac164554..e7f87015d09 100644 --- a/source/stylesheets/screen.css.scss +++ b/source/stylesheets/screen.css.scss @@ -50,11 +50,11 @@ html, body { @mixin embossed-bg { background: - linear-gradient(to bottom,rgba(#000, 0.2), rgba(#000, 0) 8px), + linear-gradient(to bottom, rgba(#000, 0.2), rgba(#000, 0) 8px), linear-gradient(to top, rgba(#000, 0.2), rgba(#000, 0) 8px), linear-gradient(to bottom, rgba($nav-embossed-border-top, 1), rgba($nav-embossed-border-top, 0) 1.5px), linear-gradient(to top, rgba($nav-embossed-border-bottom, 1), rgba($nav-embossed-border-bottom, 0) 1.5px), - #262626; + $nav-subitem-bg; } .tocify-wrapper { From a38011b4a53b69bb381fb908cbda30d99a4aa11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Tue, 2 Jun 2015 22:53:41 +0200 Subject: [PATCH 045/168] Remove some unused JS. --- source/javascripts/app/_lang.js | 3 +-- source/javascripts/app/_search.js | 11 ++++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index 2683ef356db..c3b48edbdb4 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -54,7 +54,6 @@ under the License. } function setupLanguages(l) { - var currentLanguage = l[0]; var defaultLanguage = localStorage.getItem("language"); languages = l; @@ -81,7 +80,7 @@ under the License. activateLanguage(language); return false; }); - window.onpopstate = function(event) { + window.onpopstate = function() { activateLanguage(window.location.search.substr(1)); }; }); diff --git a/source/javascripts/app/_search.js b/source/javascripts/app/_search.js index 550b1a30f61..91f38a04edf 100644 --- a/source/javascripts/app/_search.js +++ b/source/javascripts/app/_search.js @@ -1,10 +1,9 @@ //= require ../lib/_lunr //= require ../lib/_jquery.highlight -(function (global) { +(function () { 'use strict'; - var $global = $(global); - var content, darkBox, searchResults; + var content, searchResults; var highlightOpts = { element: 'span', className: 'search-highlight' }; var index = new lunr.Index(); @@ -31,7 +30,6 @@ function bind() { content = $('.content'); - darkBox = $('.dark-box'); searchResults = $('.search-results'); $('#input-search').on('keyup', search); @@ -58,7 +56,7 @@ highlight.call(this); } else { searchResults.html('
  • '); - $('.search-results li').text('No Results Found for "' + this.value + '"'); + $('.search-results li').text('No Results Found for "' + this.value + '"'); } } else { unhighlight(); @@ -73,5 +71,4 @@ function unhighlight() { content.unhighlight(highlightOpts); } - -})(window); +})(); From 48c514abc75164b2079d00b8eadb344279d2a4a7 Mon Sep 17 00:00:00 2001 From: Akil Burgess Date: Wed, 10 Jun 2015 22:48:22 +0100 Subject: [PATCH 046/168] Update README with link to viagogo API docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 21ec87edac2..a43db7c2b2a 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Examples of Slate in the Wild * [CardPay API](https://developers.cardpay.com/) * [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) * [Bitrix basis components](http://bbc.bitrix.expert/) +* [viagogo API Documentation](http://developer.viagogo.net/) (Feel free to add your site to this list in a pull request!) From 685b1554e99f302ca2f62f8938a467da0ce583ea Mon Sep 17 00:00:00 2001 From: Rezan Achmad Date: Tue, 16 Jun 2015 14:47:17 +0700 Subject: [PATCH 047/168] Update README.md with link to Fidor Bank --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a43db7c2b2a..76fefd5e3b7 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Examples of Slate in the Wild * [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) * [Bitrix basis components](http://bbc.bitrix.expert/) * [viagogo API Documentation](http://developer.viagogo.net/) +* [Fidor Bank API Documentation](http://docs.fidor.de/) (Feel free to add your site to this list in a pull request!) From 1fe3ce6396a36650c20713f33fd8dc88a27ee353 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Fri, 19 Jun 2015 23:33:54 -0400 Subject: [PATCH 048/168] Update lord.io link to https --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 21ec87edac2..582f88b2c2d 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Just [submit a issue](https://github.com/tripit/slate/issues) to the Slate Githu Contributors -------------------- -Slate was built by [Robert Lord](http://lord.io) while at [TripIt](http://tripit.com). +Slate was built by [Robert Lord](https://lord.io) while at [TripIt](http://tripit.com). Thanks to the following people who have submitted major pull requests: From be57777a3de67cd0da83b663de82b9a6276e6ac1 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 00:05:46 -0400 Subject: [PATCH 049/168] Add chinese fonts, thanks to @JayMiao --- source/stylesheets/_variables.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/stylesheets/_variables.scss b/source/stylesheets/_variables.scss index 0957678427b..5fe64b1f302 100644 --- a/source/stylesheets/_variables.scss +++ b/source/stylesheets/_variables.scss @@ -68,7 +68,7 @@ $phone-width: $tablet-width - $nav-width; // min width before reverting to mobil // FONTS //////////////////// %default-font { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei","微软雅黑", STXihei, "华文细黑", sans-serif; font-size: 13px; } From 872550d0b7aa0fce48ec5c3303e5a46b11267e60 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 00:48:56 -0400 Subject: [PATCH 050/168] Update h3 fonts to work better for chinese, fixes #214 --- source/stylesheets/screen.css.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/stylesheets/screen.css.scss b/source/stylesheets/screen.css.scss index e7f87015d09..e4b3ef82b22 100644 --- a/source/stylesheets/screen.css.scss +++ b/source/stylesheets/screen.css.scss @@ -391,10 +391,9 @@ html, body { h3, h4, h5, h6 { @extend %header-font; - font-size: 12px; + font-size: 15px; margin-top: 2.5em; margin-bottom: 0.8em; - text-transform: uppercase; } h4, h5, h6 { From bb24528f851fdcb7db7016baa3a376926817dbf1 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 01:04:02 -0400 Subject: [PATCH 051/168] Update gems --- Gemfile | 2 +- Gemfile.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index 5d8c0211b36..3a2a2e01a82 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax', '~> 2.0.0' gem 'middleman-autoprefixer', '~> 2.4.4' gem 'rouge', '~> 1.9.0' -gem 'redcarpet', '~> 3.2.2' +gem 'redcarpet', '~> 3.3.1' gem 'rake', '~> 10.4.2' gem 'therubyracer', '~> 0.12.1', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index d29c7d0046c..f9978492816 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,13 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.1.10) + activesupport (4.1.11) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) - autoprefixer-rails (5.2.0) + autoprefixer-rails (5.2.0.1) execjs json celluloid (0.16.0) @@ -39,28 +39,28 @@ GEM hooks (0.4.0) uber (~> 0.0.4) i18n (0.7.0) - json (1.8.2) + json (1.8.3) kramdown (1.7.0) libv8 (3.16.14.7) - listen (2.10.0) + listen (2.10.1) celluloid (~> 0.16.0) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - middleman (3.3.11) + middleman (3.3.12) coffee-script (~> 2.2) compass (>= 1.0.0, < 2.0.0) compass-import-once (= 1.0.5) execjs (~> 2.0) haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.3.11) + middleman-core (= 3.3.12) middleman-sprockets (>= 3.1.2) sass (>= 3.4.0, < 4.0) uglifier (~> 2.5) middleman-autoprefixer (2.4.4) autoprefixer-rails (~> 5.2.0) middleman-core (>= 3.3.3) - middleman-core (3.3.11) + middleman-core (3.3.12) activesupport (~> 4.1.0) bundler (~> 1.1) erubis @@ -82,25 +82,25 @@ GEM middleman-syntax (2.0.0) middleman-core (~> 3.2) rouge (~> 1.0) - minitest (5.6.1) - multi_json (1.11.0) + minitest (5.7.0) + multi_json (1.11.1) padrino-helpers (0.12.5) i18n (~> 0.6, >= 0.6.7) padrino-support (= 0.12.5) tilt (~> 1.4.1) padrino-support (0.12.5) activesupport (>= 3.1) - rack (1.6.0) + rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) rake (10.4.2) - rb-fsevent (0.9.4) + rb-fsevent (0.9.5) rb-inotify (0.9.5) ffi (>= 0.5.0) - redcarpet (3.2.3) + redcarpet (3.3.1) ref (1.0.5) rouge (1.9.0) - sass (3.4.13) + sass (3.4.14) sprockets (2.12.3) hike (~> 1.2) multi_json (~> 1.0) @@ -135,6 +135,6 @@ DEPENDENCIES middleman-gh-pages (~> 0.0.3) middleman-syntax (~> 2.0.0) rake (~> 10.4.2) - redcarpet (~> 3.2.2) + redcarpet (~> 3.3.1) rouge (~> 1.9.0) therubyracer (~> 0.12.1) From d14fd0f70ed984c4c97e07215e5c9bdc344de4f1 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 01:49:25 -0400 Subject: [PATCH 052/168] Update language tabs to not disturb existing query strings, fixes #57 --- source/javascripts/app/_lang.js | 88 +++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index c3b48edbdb4..79d3903d2e4 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -40,6 +40,83 @@ under the License. } } + // parseURL and stringifyURL are from https://github.com/sindresorhus/query-string + // MIT licensed + // https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license + function parseURL(str) { + if (typeof str !== 'string') { + return {}; + } + + str = str.trim().replace(/^(\?|#|&)/, ''); + + if (!str) { + return {}; + } + + return str.split('&').reduce(function (ret, param) { + var parts = param.replace(/\+/g, ' ').split('='); + var key = parts[0]; + var val = parts[1]; + + key = decodeURIComponent(key); + // missing `=` should be `null`: + // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + val = val === undefined ? null : decodeURIComponent(val); + + if (!ret.hasOwnProperty(key)) { + ret[key] = val; + } else if (Array.isArray(ret[key])) { + ret[key].push(val); + } else { + ret[key] = [ret[key], val]; + } + + return ret; + }, {}); + }; + + function stringifyURL(obj) { + return obj ? Object.keys(obj).sort().map(function (key) { + var val = obj[key]; + + if (Array.isArray(val)) { + return val.sort().map(function (val2) { + return encodeURIComponent(key) + '=' + encodeURIComponent(val2); + }).join('&'); + } + + return encodeURIComponent(key) + '=' + encodeURIComponent(val); + }).join('&') : ''; + }; + + // gets the language set in the query string + function getLanguageFromQueryString() { + if (location.search.length >= 1) { + var language = parseURL(location.search).language + if (language) { + return language; + } else if (jQuery.inArray(location.search.substr(1), languages) != -1) { + return location.search.substr(1); + } + } + + return false; + } + + // returns a new query string with the new language in it + function generateNewQueryString(language) { + if (location.search.length >= 1) { + var url = parseURL(location.search); + if (url.language) { + url.language = language; + return stringifyURL(url); + } else { + return language + } + } + } + // if a button is clicked, add the state to the history function pushURL(language) { if (!history) { return; } @@ -47,7 +124,7 @@ under the License. if (hash) { hash = hash.replace(/^#+/, ''); } - history.pushState({}, '', '?' + language + '#' + hash); + history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash); // save language as next default localStorage.setItem("language", language); @@ -58,11 +135,12 @@ under the License. languages = l; - if ((location.search.substr(1) !== "") && (jQuery.inArray(location.search.substr(1), languages)) != -1) { + var presetLanguage = getLanguageFromQueryString(); + if (presetLanguage) { // the language is in the URL, so use that language! - activateLanguage(location.search.substr(1)); + activateLanguage(presetLanguage); - localStorage.setItem("language", location.search.substr(1)); + localStorage.setItem("language", presetLanguage); } else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) { // the language was the last selected one saved in localstorage, so use that language! activateLanguage(defaultLanguage); @@ -81,7 +159,7 @@ under the License. return false; }); window.onpopstate = function() { - activateLanguage(window.location.search.substr(1)); + activateLanguage(getLanguageFromQueryString()); }; }); })(window); From fd5cba00f0fc064d80dee75dc1630b02a7bc38b8 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 01:53:20 -0400 Subject: [PATCH 053/168] Fix small bug with new language tabs --- source/javascripts/app/_lang.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index 79d3903d2e4..1a124bb68ae 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -106,15 +106,12 @@ under the License. // returns a new query string with the new language in it function generateNewQueryString(language) { - if (location.search.length >= 1) { - var url = parseURL(location.search); - if (url.language) { - url.language = language; - return stringifyURL(url); - } else { - return language - } + var url = parseURL(location.search); + if (url.language) { + url.language = language; + return stringifyURL(url); } + return language; } // if a button is clicked, add the state to the history From 415dcf2c90d380011be9cf1ec5cc500574d64d46 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 01:54:06 -0400 Subject: [PATCH 054/168] Add changes to log from v1.2 --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8adca156616..59ee6a441e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## Version 1.2 + +*June 20, 2014* + +**Fixes:** + +- Remove crash on invalid languages +- Update Tocify to scroll to the highlighted header in the Table of Contents +- Fix variable leak and update search algorithms +- Update Python examples to be valid Python +- Update gems +- More misc. bugfixes of Javascript errors +- Add Dockerfile +- Remove unused gems +- Optimize images, fonts, and generated asset files +- Add chinese font support +- Remove RedCarpet header ID patch +- Update language tabs to not disturb existing query strings + ## Version 1.1 *July 27th, 2014* From f3591651f12446244a977b2389e2f681af316116 Mon Sep 17 00:00:00 2001 From: John Ferlito Date: Sat, 27 Jun 2015 16:33:07 +1000 Subject: [PATCH 055/168] Fix Changelog date Version 1.2 was released in 2015 not 2014 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59ee6a441e5..ee496db6c9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Version 1.2 -*June 20, 2014* +*June 20, 2015* **Fixes:** From ae3d50277ee81e837fd8f89726a213465cd43537 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sun, 28 Jun 2015 12:44:12 -0700 Subject: [PATCH 056/168] Update RedCarpet gem --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 3a2a2e01a82..0933b9d6839 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax', '~> 2.0.0' gem 'middleman-autoprefixer', '~> 2.4.4' gem 'rouge', '~> 1.9.0' -gem 'redcarpet', '~> 3.3.1' +gem 'redcarpet', '~> 3.3.2' gem 'rake', '~> 10.4.2' gem 'therubyracer', '~> 0.12.1', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index f9978492816..fff5ee10cb3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,7 +97,7 @@ GEM rb-fsevent (0.9.5) rb-inotify (0.9.5) ffi (>= 0.5.0) - redcarpet (3.3.1) + redcarpet (3.3.2) ref (1.0.5) rouge (1.9.0) sass (3.4.14) @@ -135,6 +135,6 @@ DEPENDENCIES middleman-gh-pages (~> 0.0.3) middleman-syntax (~> 2.0.0) rake (~> 10.4.2) - redcarpet (~> 3.3.1) + redcarpet (~> 3.3.2) rouge (~> 1.9.0) therubyracer (~> 0.12.1) From 7639ce60bc5e5e66eea1e43ec8a4758598bb58c9 Mon Sep 17 00:00:00 2001 From: niftylettuce Date: Thu, 2 Jul 2015 03:04:14 -0400 Subject: [PATCH 057/168] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d270a0c1ace..efb7e1eb8cd 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ Examples of Slate in the Wild * [Bitrix basis components](http://bbc.bitrix.expert/) * [viagogo API Documentation](http://developer.viagogo.net/) * [Fidor Bank API Documentation](http://docs.fidor.de/) +* [Market Prophit API Documentation](http://developer.marketprophit.com/) (Feel free to add your site to this list in a pull request!) From ad3b2769fe8e3be645314a09f32a169ff1dfbcbe Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Mon, 6 Jul 2015 18:54:45 -0700 Subject: [PATCH 058/168] Update tocify to recache headers on image load, fixes #293 --- source/javascripts/app/_toc.js | 13 +++++++++---- source/javascripts/lib/_imagesloaded.min.js | 7 +++++++ 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 source/javascripts/lib/_imagesloaded.min.js diff --git a/source/javascripts/app/_toc.js b/source/javascripts/app/_toc.js index d84bf8e197a..bc2aa3e1f11 100644 --- a/source/javascripts/app/_toc.js +++ b/source/javascripts/app/_toc.js @@ -1,5 +1,6 @@ //= require ../lib/_jquery_ui //= require ../lib/_jquery.tocify +//= require ../lib/_imagesloaded.min (function (global) { 'use strict'; @@ -37,14 +38,18 @@ // Hack to make already open sections to start opened, // instead of displaying an ugly animation - function animate () { + function animate() { setTimeout(function() { toc.setOption('showEffectSpeed', 180); }, 50); } - $(makeToc); - $(animate); - + $(function() { + makeToc(); + animate(); + $('.content').imagesLoaded( function() { + global.toc.calculateHeights(); + }); + }); })(window); diff --git a/source/javascripts/lib/_imagesloaded.min.js b/source/javascripts/lib/_imagesloaded.min.js new file mode 100644 index 00000000000..d66f658937d --- /dev/null +++ b/source/javascripts/lib/_imagesloaded.min.js @@ -0,0 +1,7 @@ +/*! + * imagesLoaded PACKAGED v3.1.8 + * JavaScript is all like "You images are done yet or what?" + * MIT License + */ + +(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s}); \ No newline at end of file From 0c37f0dfc4985fc8a9aad43a91bc5bd870d423c2 Mon Sep 17 00:00:00 2001 From: Rezan Achmad Date: Thu, 16 Jul 2015 15:09:59 +0800 Subject: [PATCH 059/168] Add OAuth.io to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index efb7e1eb8cd..0d89f86f1f5 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ Examples of Slate in the Wild * [viagogo API Documentation](http://developer.viagogo.net/) * [Fidor Bank API Documentation](http://docs.fidor.de/) * [Market Prophit API Documentation](http://developer.marketprophit.com/) +* [OAuth.io API Documentation](http://docs.oauth.io/) (Feel free to add your site to this list in a pull request!) From 5cfcbc7f7b786cc8fa0a2e643dfbdc34298c4eb8 Mon Sep 17 00:00:00 2001 From: Ivan Matyunin Date: Wed, 29 Jul 2015 16:50:28 -0400 Subject: [PATCH 060/168] Improved the appearance of code blocks when printing. --- source/stylesheets/print.css.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/stylesheets/print.css.scss b/source/stylesheets/print.css.scss index 4bda057f019..b328d05bac1 100644 --- a/source/stylesheets/print.css.scss +++ b/source/stylesheets/print.css.scss @@ -48,6 +48,12 @@ body { font-size: 0.8em; } + pre { + code { + border: 0; + } + } + pre { padding: 1.3em; } From 5e605079eb0f761fdb68d35605bc73bd074f5f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Baptiste=20B=C3=A9chu?= Date: Tue, 4 Aug 2015 02:42:21 -0700 Subject: [PATCH 061/168] Add Aircall.io to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0d89f86f1f5..541665b8810 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ Examples of Slate in the Wild * [Fidor Bank API Documentation](http://docs.fidor.de/) * [Market Prophit API Documentation](http://developer.marketprophit.com/) * [OAuth.io API Documentation](http://docs.oauth.io/) +* [Aircall for Developers](http://developer.aircall.io/) (Feel free to add your site to this list in a pull request!) From 87a2950adebca54352a6dac49e22bd764a45e93e Mon Sep 17 00:00:00 2001 From: Dhiren Audich Date: Wed, 5 Aug 2015 11:04:29 -0400 Subject: [PATCH 062/168] adding supporkit docs as an example of the slate docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 541665b8810..7f7e71f6b19 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ Examples of Slate in the Wild * [Market Prophit API Documentation](http://developer.marketprophit.com/) * [OAuth.io API Documentation](http://docs.oauth.io/) * [Aircall for Developers](http://developer.aircall.io/) +* [SupportKit API Docs](http://docs.supportkit.io/) (Feel free to add your site to this list in a pull request!) From befb8d6fac23a4db99746173e00ea637ecc6536f Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Wed, 5 Aug 2015 22:14:16 +0800 Subject: [PATCH 063/168] Remove therubyracer --- Gemfile | 1 - Gemfile.lock | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 0933b9d6839..ef9d21c44bb 100644 --- a/Gemfile +++ b/Gemfile @@ -9,4 +9,3 @@ gem 'rouge', '~> 1.9.0' gem 'redcarpet', '~> 3.3.2' gem 'rake', '~> 10.4.2' -gem 'therubyracer', '~> 0.12.1', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index fff5ee10cb3..d0250db6016 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,7 +41,6 @@ GEM i18n (0.7.0) json (1.8.3) kramdown (1.7.0) - libv8 (3.16.14.7) listen (2.10.1) celluloid (~> 0.16.0) rb-fsevent (>= 0.9.3) @@ -98,7 +97,6 @@ GEM rb-inotify (0.9.5) ffi (>= 0.5.0) redcarpet (3.3.2) - ref (1.0.5) rouge (1.9.0) sass (3.4.14) sprockets (2.12.3) @@ -111,9 +109,6 @@ GEM sprockets-sass (1.3.1) sprockets (~> 2.0) tilt (~> 1.1) - therubyracer (0.12.2) - libv8 (~> 3.16.14.0) - ref thor (0.19.1) thread_safe (0.3.5) tilt (1.4.1) @@ -137,4 +132,6 @@ DEPENDENCIES rake (~> 10.4.2) redcarpet (~> 3.3.2) rouge (~> 1.9.0) - therubyracer (~> 0.12.1) + +BUNDLED WITH + 1.10.5 From 83d655b55e55753da00ae0b67c7cb0501eaa6731 Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Thu, 6 Aug 2015 16:58:57 +0800 Subject: [PATCH 064/168] Update rouge and middleman-autoprefixer --- Gemfile | 4 ++-- Gemfile.lock | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index ef9d21c44bb..9a9931a5fab 100644 --- a/Gemfile +++ b/Gemfile @@ -4,8 +4,8 @@ source 'https://rubygems.org' gem 'middleman', '~>3.3.10' gem 'middleman-gh-pages', '~> 0.0.3' gem 'middleman-syntax', '~> 2.0.0' -gem 'middleman-autoprefixer', '~> 2.4.4' -gem 'rouge', '~> 1.9.0' +gem 'middleman-autoprefixer', '~> 2.5.0' +gem 'rouge', '~> 1.9.1' gem 'redcarpet', '~> 3.3.2' gem 'rake', '~> 10.4.2' diff --git a/Gemfile.lock b/Gemfile.lock index d0250db6016..32cb6411fae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,13 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.1.11) + activesupport (4.1.12) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) - autoprefixer-rails (5.2.0.1) + autoprefixer-rails (5.2.1.1) execjs json celluloid (0.16.0) @@ -31,7 +31,7 @@ GEM sass (>= 3.2, < 3.5) erubis (2.7.0) execjs (2.5.2) - ffi (1.9.8) + ffi (1.9.10) haml (4.0.6) tilt hike (1.2.3) @@ -56,7 +56,7 @@ GEM middleman-sprockets (>= 3.1.2) sass (>= 3.4.0, < 4.0) uglifier (~> 2.5) - middleman-autoprefixer (2.4.4) + middleman-autoprefixer (2.5.0) autoprefixer-rails (~> 5.2.0) middleman-core (>= 3.3.3) middleman-core (3.3.12) @@ -97,7 +97,7 @@ GEM rb-inotify (0.9.5) ffi (>= 0.5.0) redcarpet (3.3.2) - rouge (1.9.0) + rouge (1.9.1) sass (3.4.14) sprockets (2.12.3) hike (~> 1.2) @@ -126,12 +126,12 @@ PLATFORMS DEPENDENCIES middleman (~> 3.3.10) - middleman-autoprefixer (~> 2.4.4) + middleman-autoprefixer (~> 2.5.0) middleman-gh-pages (~> 0.0.3) middleman-syntax (~> 2.0.0) rake (~> 10.4.2) redcarpet (~> 3.3.2) - rouge (~> 1.9.0) + rouge (~> 1.9.1) BUNDLED WITH 1.10.5 From 47e18611f2ab66eaaa97c3fbc6b127226d25b795 Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Thu, 6 Aug 2015 18:40:17 +0800 Subject: [PATCH 065/168] Update other dependencies --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 32cb6411fae..f9400056dad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -40,7 +40,7 @@ GEM uber (~> 0.0.4) i18n (0.7.0) json (1.8.3) - kramdown (1.7.0) + kramdown (1.8.0) listen (2.10.1) celluloid (~> 0.16.0) rb-fsevent (>= 0.9.3) @@ -82,7 +82,7 @@ GEM middleman-core (~> 3.2) rouge (~> 1.0) minitest (5.7.0) - multi_json (1.11.1) + multi_json (1.11.2) padrino-helpers (0.12.5) i18n (~> 0.6, >= 0.6.7) padrino-support (= 0.12.5) @@ -98,8 +98,8 @@ GEM ffi (>= 0.5.0) redcarpet (3.3.2) rouge (1.9.1) - sass (3.4.14) - sprockets (2.12.3) + sass (3.4.16) + sprockets (2.12.4) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) From 5d27eaf9cf31b439b0733907e5a86cde08fcaee2 Mon Sep 17 00:00:00 2001 From: Gabriel Falkenberg Date: Sat, 8 Aug 2015 17:23:29 +0200 Subject: [PATCH 066/168] Use HTTPS for github urls. --- source/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/index.md b/source/index.md index 4c1fa8c9f7d..9ce6c96b606 100644 --- a/source/index.md +++ b/source/index.md @@ -8,7 +8,7 @@ language_tabs: toc_footers: - Sign Up for a Developer Key - - Documentation Powered by Slate + - Documentation Powered by Slate includes: - errors @@ -22,7 +22,7 @@ Welcome to the Kittn API! You can use our API to access Kittn API endpoints, whi We have language bindings in Shell, Ruby, and Python! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. -This example API documentation page was created with [Slate](http://github.com/tripit/slate). Feel free to edit it and use it as a base for your own API's documentation. +This example API documentation page was created with [Slate](https://github.com/tripit/slate). Feel free to edit it and use it as a base for your own API's documentation. # Authentication From ed9e958df75c0f1f6da4d9f1461a24f6ea31cf73 Mon Sep 17 00:00:00 2001 From: Victor Quinn Date: Thu, 13 Aug 2015 15:54:18 -0400 Subject: [PATCH 067/168] Add SocialRadar to the list of docs sites using Slate --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7f7e71f6b19..535960d1682 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ Examples of Slate in the Wild * [OAuth.io API Documentation](http://docs.oauth.io/) * [Aircall for Developers](http://developer.aircall.io/) * [SupportKit API Docs](http://docs.supportkit.io/) +* [SocialRadar's LocationKit Docs](https://docs.locationkit.io/ios) (Feel free to add your site to this list in a pull request!) From 977f2568d75f0b4026e91e3c711294ecf7a07df1 Mon Sep 17 00:00:00 2001 From: Victor Quinn Date: Thu, 13 Aug 2015 16:44:05 -0400 Subject: [PATCH 068/168] Fix path to iOS docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 535960d1682..e7a9fa72747 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ Examples of Slate in the Wild * [OAuth.io API Documentation](http://docs.oauth.io/) * [Aircall for Developers](http://developer.aircall.io/) * [SupportKit API Docs](http://docs.supportkit.io/) -* [SocialRadar's LocationKit Docs](https://docs.locationkit.io/ios) +* [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) (Feel free to add your site to this list in a pull request!) From 92d732f8a4e7d374ada4d778345d3fc403460a91 Mon Sep 17 00:00:00 2001 From: Romain Pomier Date: Thu, 27 Aug 2015 11:09:28 +0200 Subject: [PATCH 069/168] Install nodejs in Dockerfile to replace therubyracer --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8183c7a8b04..bb826dbf202 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:trusty RUN apt-get update -RUN apt-get install -yq ruby ruby-dev build-essential git +RUN apt-get install -yq ruby ruby-dev build-essential git nodejs RUN gem install --no-ri --no-rdoc bundler ADD Gemfile /app/Gemfile ADD Gemfile.lock /app/Gemfile.lock From 1c508a738f0ce51305a3c9148d519dcb0d3d516b Mon Sep 17 00:00:00 2001 From: Brett Porter Date: Wed, 23 Sep 2015 15:09:13 +1000 Subject: [PATCH 070/168] Add SafetyCulture API to the list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e7a9fa72747..98c03e4a6b1 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ Examples of Slate in the Wild * [Aircall for Developers](http://developer.aircall.io/) * [SupportKit API Docs](http://docs.supportkit.io/) * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) +* [SafetyCulture API Documentation](https://developer.safetyculture.io/) (Feel free to add your site to this list in a pull request!) From fcea9014d2710255ec4419d30f177abb94db6c29 Mon Sep 17 00:00:00 2001 From: Andreas Madsack Date: Mon, 28 Sep 2015 17:03:48 +0200 Subject: [PATCH 071/168] mount volume for live changes to Dockerfile --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 98c03e4a6b1..4351fdec6d5 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Or use the included Dockerfile! (must install Docker first) ```shell docker build -t slate . -docker run -d -p 4567:4567 slate +docker run -d -p 4567:4567 --name slate -v $(pwd)/source:/app/source slate ``` You can now see the docs at . Whoa! That was fast! From e0cdc7339e51826d1bc35196a6530e6a05bac31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Wed, 30 Sep 2015 17:56:34 +0200 Subject: [PATCH 072/168] Add hosting.de API docs to the list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4351fdec6d5..2f042e7f2c2 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Examples of Slate in the Wild * [SupportKit API Docs](http://docs.supportkit.io/) * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) * [SafetyCulture API Documentation](https://developer.safetyculture.io/) +* [hosting.de API Documentation](https://www.hosting.de/docs/api/) (Feel free to add your site to this list in a pull request!) From 57aa27c0eb0474733bb115b63991ba2509d2bedc Mon Sep 17 00:00:00 2001 From: Marc Guyer Date: Tue, 6 Oct 2015 10:51:23 -0400 Subject: [PATCH 073/168] Basic support for Vagrant --- .gitignore | 3 ++- README.md | 31 ++++++++++++++++++------------- Vagrantfile | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 Vagrantfile diff --git a/.gitignore b/.gitignore index f6fc8c00b25..f1953e3a979 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,10 @@ tmp *.DS_STORE build/ .cache +.vagrant # YARD artifacts .yardoc _yardoc doc/ -.idea/ \ No newline at end of file +.idea/ diff --git a/README.md b/README.md index 2f042e7f2c2..b2e4105aeb9 100644 --- a/README.md +++ b/README.md @@ -43,23 +43,27 @@ You're going to need: ### Getting Set Up - 1. Fork this repository on Github. - 2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` - 3. `cd slate` - 4. Install all dependencies: `bundle install` - 5. Start the test server: `bundle exec middleman server` - -Or use the included Dockerfile! (must install Docker first) - +1. Fork this repository on Github. +2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` +3. `cd slate` +4. Initialize and start + * Manually: +```shell +bundle install +bundle exec middleman server +``` + * Or via Docker (must install Docker first) ```shell docker build -t slate . docker run -d -p 4567:4567 --name slate -v $(pwd)/source:/app/source slate +``` + You can now see the docs at http://localhost:4567. Whoa! That was fast! Note: if you're using the Docker setup on OSX, the docs will be + availalable at the output of `boot2docker ip` instead of `localhost:4567`. + * Or via Vagrant +```shell +vagrant up ``` - -You can now see the docs at . Whoa! That was fast! - -*Note: if you're using the Docker setup on OSX, the docs will be -availalable at the output of `boot2docker ip` instead of `localhost:4567`.* + You can now see the docs at http://localhost:4567. Now that Slate is all set up your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/tripit/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/tripit/slate/wiki/Deploying-Slate). @@ -97,6 +101,7 @@ Examples of Slate in the Wild * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) +* [CheddarGetter API Documentation](http://docs.cheddargetter.com) (Feel free to add your site to this list in a pull request!) diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000000..f00c7d1b60d --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,37 @@ +Vagrant.configure(2) do |config| + config.vm.box = "ubuntu/trusty64" + config.vm.network :forwarded_port, guest: 4567, host: 4567 + config.vm.provider "virtualbox" do |vb| + vb.memory = "384" + end + + config.vm.provision "bootstrap", + type: "shell", + inline: <<-SHELL + sudo apt-get update + sudo apt-get install -yq ruby ruby-dev build-essential nodejs + sudo apt-get autoremove -yq + gem install --no-ri --no-rdoc bundler + SHELL + + config.vm.provision "install", + type: "shell", + privileged: false, + inline: <<-SHELL + echo "==============================================" + echo "Installing app dependencies" + cd /vagrant + bundle install + SHELL + + config.vm.provision "run", + type: "shell", + privileged: false, + inline: <<-SHELL + echo "==============================================" + echo "Starting up middleman at http://localhost:4567" + echo "If it does not come up, check the ~/middleman.log file for any error messages" + cd /vagrant + bundle exec middleman server --force-polling -l 1 &> ~/middleman.log & + SHELL +end From 4136f7b0f795e091c0e793e3b7d7580e7c7f465d Mon Sep 17 00:00:00 2001 From: Marc Guyer Date: Tue, 6 Oct 2015 16:48:51 -0400 Subject: [PATCH 074/168] Formatting fixes for README --- README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b2e4105aeb9..9384a576976 100644 --- a/README.md +++ b/README.md @@ -46,24 +46,31 @@ You're going to need: 1. Fork this repository on Github. 2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` 3. `cd slate` -4. Initialize and start - * Manually: +4. Initialize and start (there are a few options for this): + +#### Manual/local + ```shell bundle install bundle exec middleman server ``` - * Or via Docker (must install Docker first) +#### Via Docker (must install Docker first) + ```shell docker build -t slate . docker run -d -p 4567:4567 --name slate -v $(pwd)/source:/app/source slate ``` - You can now see the docs at http://localhost:4567. Whoa! That was fast! Note: if you're using the Docker setup on OSX, the docs will be - availalable at the output of `boot2docker ip` instead of `localhost:4567`. - * Or via Vagrant + +You can now see the docs at http://localhost:4567. Whoa! That was fast! + +*Note: if you're using the Docker setup on OSX, the docs will be availalable at the output of `boot2docker ip` instead of `localhost:4567`.* + +#### Via Vagrant ```shell vagrant up ``` - You can now see the docs at http://localhost:4567. + +You can now see the docs at http://localhost:4567. Now that Slate is all set up your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/tripit/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/tripit/slate/wiki/Deploying-Slate). From ce2f2ae8de02aeab1feaff0d3786d4afe8a2bf88 Mon Sep 17 00:00:00 2001 From: Marc Guyer Date: Tue, 6 Oct 2015 17:12:55 -0400 Subject: [PATCH 075/168] Update Vagrantfile Need git for `rake publish` --- Vagrantfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Vagrantfile b/Vagrantfile index f00c7d1b60d..713d88447c1 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -9,7 +9,7 @@ Vagrant.configure(2) do |config| type: "shell", inline: <<-SHELL sudo apt-get update - sudo apt-get install -yq ruby ruby-dev build-essential nodejs + sudo apt-get install -yq ruby ruby-dev build-essential nodejs git sudo apt-get autoremove -yq gem install --no-ri --no-rdoc bundler SHELL From 4a3fdfaea2e9f5017d9ed5cffbcbfae0630c5c76 Mon Sep 17 00:00:00 2001 From: Marc Guyer Date: Tue, 6 Oct 2015 17:21:17 -0400 Subject: [PATCH 076/168] Update Vagrantfile More memory needed for `rake publish` --- Vagrantfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index 713d88447c1..ba6b620bd7a 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,9 +1,6 @@ Vagrant.configure(2) do |config| config.vm.box = "ubuntu/trusty64" config.vm.network :forwarded_port, guest: 4567, host: 4567 - config.vm.provider "virtualbox" do |vb| - vb.memory = "384" - end config.vm.provision "bootstrap", type: "shell", From 3c1c9c49d54828fe9a7dd73edbbccef54bf52078 Mon Sep 17 00:00:00 2001 From: Marc Guyer Date: Thu, 8 Oct 2015 14:09:27 +0000 Subject: [PATCH 077/168] Add local git config to guest vm --- Vagrantfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Vagrantfile b/Vagrantfile index ba6b620bd7a..186654e0a3b 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -11,6 +11,9 @@ Vagrant.configure(2) do |config| gem install --no-ri --no-rdoc bundler SHELL + # add the local user git config to the vm + config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig" + config.vm.provision "install", type: "shell", privileged: false, From 150ff8a8009f32bb1d121daec9a05aa8282e111b Mon Sep 17 00:00:00 2001 From: Rex Posadas Date: Sun, 11 Oct 2015 14:57:44 -0500 Subject: [PATCH 078/168] upgraded to later ubuntu wily to remove error from version trusty --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8183c7a8b04..f5848e6fbd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:trusty +FROM ubuntu:wily RUN apt-get update RUN apt-get install -yq ruby ruby-dev build-essential git From f0a8dec91cebe6d7875002e16c28446cedaa94c3 Mon Sep 17 00:00:00 2001 From: Michael Flaxman Date: Thu, 22 Oct 2015 12:35:29 -0400 Subject: [PATCH 079/168] Add blockcypher to examples --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2f042e7f2c2..5ce6f864e43 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Examples of Slate in the Wild * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) +* [BlockCypher's API Documentation](https://dev.blockcypher.com) (Feel free to add your site to this list in a pull request!) From fb4c2a9ceb9000c1a3b2aad7507f404c2850e479 Mon Sep 17 00:00:00 2001 From: Dave Powers Date: Wed, 4 Nov 2015 14:15:23 -0500 Subject: [PATCH 080/168] Remove link to ChaiOne Gameplan (broken link) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 5ce6f864e43..b55fa7a62f6 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,6 @@ Examples of Slate in the Wild * [Travis-CI's API docs](http://docs.travis-ci.com/api/) * [Mozilla's localForage docs](http://mozilla.github.io/localForage/) * [Mozilla Recroom](http://mozilla.github.io/recroom/) -* [ChaiOne Gameplan API docs](http://chaione.github.io/gameplanb2b/#introduction) * [Drcaban's Build a Quine tutorial](http://drcabana.github.io/build-a-quine/#introduction) * [PricePlow API docs](https://www.priceplow.com/api/documentation) * [Emerging Threats API docs](http://apidocs.emergingthreats.net/) From 01fd02005a6e0d3fccff8bb3eaa2d00646247de8 Mon Sep 17 00:00:00 2001 From: Dave Powers Date: Wed, 4 Nov 2015 14:16:54 -0500 Subject: [PATCH 081/168] Fix link to IBM Cloudant (page has moved) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b55fa7a62f6..6f086f58a89 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Examples of Slate in the Wild * [Whispir.io API](https://whispir.github.io/api) * [NASA API](https://data.nasa.gov/developer/external/planetary/) * [CardPay API](https://developers.cardpay.com/) -* [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) +* [IBM Cloudant](https://docs.cloudant.com/api.html) * [Bitrix basis components](http://bbc.bitrix.expert/) * [viagogo API Documentation](http://developer.viagogo.net/) * [Fidor Bank API Documentation](http://docs.fidor.de/) From 1e86f824afd7e300239bc41f242e496a13a4d165 Mon Sep 17 00:00:00 2001 From: Dave Powers Date: Wed, 4 Nov 2015 14:18:08 -0500 Subject: [PATCH 082/168] Fix link to BlockCypher (does not work over HTTPS) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f086f58a89..5d2e7fe1c31 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ Examples of Slate in the Wild * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) -* [BlockCypher's API Documentation](https://dev.blockcypher.com) +* [BlockCypher's API Documentation](http://dev.blockcypher.com) (Feel free to add your site to this list in a pull request!) From c76359868a489e8706290fe7dbffce651339ceb3 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Thu, 12 Nov 2015 01:01:14 -0500 Subject: [PATCH 083/168] Added Links to InterServer Slate Implementation URL: https://my.interserver.net/apidoc/ Our implementation includes some minor customizations which others mind fight useful including icons for the Language tabs at the top right. Side Note: The document contents including sample scripts , input/output parameter+descriptions, etc are generated entirely from a script i wrote that parses my SOAP API WSDL file, PHP Source (parsing phpdoc comments), and MySQL Table defintions (parsing field comments) to generate and populate all the neccesary info. At some point (faster if i have any requests for it ) ill make those scripts publicly available after i clean up the source a bit and make it more portable. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5d2e7fe1c31..d3de33ba426 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Examples of Slate in the Wild * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) * [BlockCypher's API Documentation](http://dev.blockcypher.com) +* [InterServer API Documentation](https://my.interserver.net/apidoc/) (Feel free to add your site to this list in a pull request!) From 40443b32fd122fb2041db8689861bd8c03665c92 Mon Sep 17 00:00:00 2001 From: Evan Tahler Date: Mon, 16 Nov 2015 10:53:18 -0800 Subject: [PATCH 084/168] Update README.md add actionhero docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d3de33ba426..3e22c3c44f7 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Examples of Slate in the Wild * [hosting.de API Documentation](https://www.hosting.de/docs/api/) * [BlockCypher's API Documentation](http://dev.blockcypher.com) * [InterServer API Documentation](https://my.interserver.net/apidoc/) +* [ActionHeroJS's API Documentation](http://www.actionherojs.com/docs) (Feel free to add your site to this list in a pull request!) From 2618c77db0f46a55a608b5f47dd3815d35828d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20Gonz=C3=A1lez?= Date: Fri, 13 Nov 2015 17:28:45 +0100 Subject: [PATCH 085/168] Use base ruby image in Dockerfile & fix watcher It seems that the watcher will not work without the --force-polling option. --- Dockerfile | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 294c650d9e9..6938dfd13bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,6 @@ -FROM ubuntu:wily +FROM ruby:2.2.3-onbuild + +RUN ln -s /usr/src/app /app # Deprecated -RUN apt-get update -RUN apt-get install -yq ruby ruby-dev build-essential git nodejs -RUN gem install --no-ri --no-rdoc bundler -ADD Gemfile /app/Gemfile -ADD Gemfile.lock /app/Gemfile.lock -RUN cd /app; bundle install -ADD . /app EXPOSE 4567 -WORKDIR /app -CMD ["bundle", "exec", "middleman", "server"] +CMD ["bundle", "exec", "middleman", "server", "--force-polling"] From 82717e043db6743ca30ce8fb5475571d10e8465b Mon Sep 17 00:00:00 2001 From: Jared King Date: Wed, 18 Nov 2015 11:10:10 -0600 Subject: [PATCH 086/168] Added Invoiced to list of examples on README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9384a576976..333ad464447 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Examples of Slate in the Wild * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) * [CheddarGetter API Documentation](http://docs.cheddargetter.com) +* [Invoiced API](https://invoiced.com/docs/api) (Feel free to add your site to this list in a pull request!) From 97a4c89d0cc32c8609237b41acf5fcc043555480 Mon Sep 17 00:00:00 2001 From: ReadmeCritic Date: Tue, 8 Dec 2015 12:22:18 -0800 Subject: [PATCH 087/168] Update README URLs based on HTTP redirects --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 333ad464447..acb4a625f6b 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Now that Slate is all set up your machine, you'll probably want to learn more ab Examples of Slate in the Wild --------------------------------- -* [Travis-CI's API docs](http://docs.travis-ci.com/api/) +* [Travis-CI's API docs](https://docs.travis-ci.com/api/) * [Mozilla's localForage docs](http://mozilla.github.io/localForage/) * [Mozilla Recroom](http://mozilla.github.io/recroom/) * [ChaiOne Gameplan API docs](http://chaione.github.io/gameplanb2b/#introduction) @@ -104,12 +104,12 @@ Examples of Slate in the Wild * [Market Prophit API Documentation](http://developer.marketprophit.com/) * [OAuth.io API Documentation](http://docs.oauth.io/) * [Aircall for Developers](http://developer.aircall.io/) -* [SupportKit API Docs](http://docs.supportkit.io/) +* [SupportKit API Docs](http://docs.smooch.io/) * [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) * [SafetyCulture API Documentation](https://developer.safetyculture.io/) * [hosting.de API Documentation](https://www.hosting.de/docs/api/) * [CheddarGetter API Documentation](http://docs.cheddargetter.com) -* [Invoiced API](https://invoiced.com/docs/api) +* [Invoiced API](http://invoiced.com/docs/api/) (Feel free to add your site to this list in a pull request!) @@ -122,7 +122,7 @@ Just [submit a issue](https://github.com/tripit/slate/issues) to the Slate Githu Contributors -------------------- -Slate was built by [Robert Lord](https://lord.io) while at [TripIt](http://tripit.com). +Slate was built by [Robert Lord](https://lord.io) while at [TripIt](https://www.tripit.com/). Thanks to the following people who have submitted major pull requests: @@ -137,5 +137,5 @@ Special Thanks - [Middleman](https://github.com/middleman/middleman) - [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js) - [middleman-syntax](https://github.com/middleman/middleman-syntax) -- [middleman-gh-pages](https://github.com/neo/middleman-gh-pages) +- [middleman-gh-pages](https://github.com/edgecase/middleman-gh-pages) - [Font Awesome](http://fortawesome.github.io/Font-Awesome/) From 837a7e7873eba3b62fca36e54cd1cacf9c65fe02 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Fri, 18 Dec 2015 22:51:49 -0500 Subject: [PATCH 088/168] Change cat name After recent events it is probably better to use a different name for the cat. --- source/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/index.md b/source/index.md index 4c1fa8c9f7d..69a22ea6edd 100644 --- a/source/index.md +++ b/source/index.md @@ -94,7 +94,7 @@ curl "http://example.com/api/kittens" }, { "id": 2, - "name": "Isis", + "name": "Max", "breed": "unknown", "fluffiness": 5, "cuteness": 10 @@ -145,7 +145,7 @@ curl "http://example.com/api/kittens/2" ```json { "id": 2, - "name": "Isis", + "name": "Max", "breed": "unknown", "fluffiness": 5, "cuteness": 10 From f90e6b076d4147e303d6e6d6f980c37a261569c8 Mon Sep 17 00:00:00 2001 From: Adrian Perez Date: Fri, 1 Jan 2016 18:12:11 +0100 Subject: [PATCH 089/168] feat(docker): improve docker support This improves Docker support in the following ways: * Base image off `ruby:onbuild` to avoid unnecessary custom steps and ease derived images. * Adds `.dockerignore` to avoid sending large files to build. * Adds a `docker-compose.yml` so users can simply type `docker-compose up` to get it running. * Explicity sets the volume definition in the `Dockerfile`. * Volume is automatically mount by `docker-compose` (the `source` directory relative to the project's dir). * Workaround watcher failing to pick directory changes probably because of vboxsf and the `listen` gem failing to register filesystem changes. * Updates documentation. --- .dockerignore | 2 ++ Dockerfile | 7 +++---- README.md | 21 +++++++++++++-------- docker-compose.yml | 6 ++++++ 4 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 .dockerignore create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..6ef19c6fa7f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.git +source diff --git a/Dockerfile b/Dockerfile index 6938dfd13bf..5d1ea3df9f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,5 @@ -FROM ruby:2.2.3-onbuild - -RUN ln -s /usr/src/app /app # Deprecated - +FROM ruby:onbuild +MAINTAINER Adrian Perez +VOLUME /usr/src/app/source EXPOSE 4567 CMD ["bundle", "exec", "middleman", "server", "--force-polling"] diff --git a/README.md b/README.md index acb4a625f6b..8d20a84e910 100644 --- a/README.md +++ b/README.md @@ -47,23 +47,28 @@ You're going to need: 2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` 3. `cd slate` 4. Initialize and start (there are a few options for this): - + #### Manual/local ```shell bundle install bundle exec middleman server -``` -#### Via Docker (must install Docker first) +``` + +#### Via Docker (must install it first) ```shell -docker build -t slate . -docker run -d -p 4567:4567 --name slate -v $(pwd)/source:/app/source slate -``` +docker-compose up +``` + +will spin an environment for you, with the `source` directory mapped to the +container, so you can see your edits instantly after refreshing your browser. -You can now see the docs at http://localhost:4567. Whoa! That was fast! +You can now see the docs at http://localhost:4567. Whoa! That was fast! -*Note: if you're using the Docker setup on OSX, the docs will be availalable at the output of `boot2docker ip` instead of `localhost:4567`.* ++*Note: if you're not using Docker natively (i.e. on Linux), the docs will be ++available at the IP of your docker host. If you're using docker-machine you can ++retrieve it with `docker-machine ip `* #### Via Vagrant ```shell diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000000..7eeae41a09d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +app: + build: . + ports: + - 4567:4567 + volumes: + - ./source:/usr/src/app/source From 75f61557a281db16dadb8f88c505f538d83ff04f Mon Sep 17 00:00:00 2001 From: Adrian Perez Date: Sat, 2 Jan 2016 01:51:06 +0100 Subject: [PATCH 090/168] fix(docker): new middleman requires JS runtime --- Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Dockerfile b/Dockerfile index 5d1ea3df9f0..10150b56da3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,4 +2,8 @@ FROM ruby:onbuild MAINTAINER Adrian Perez VOLUME /usr/src/app/source EXPOSE 4567 + +RUN apt-get update && apt-get install -y nodejs \ +&& apt-get clean && rm -rf /var/lib/apt/lists/* + CMD ["bundle", "exec", "middleman", "server", "--force-polling"] From 65c3dbd5442b5abc856738a85220b9c1e03ad8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Benaiteau?= Date: Fri, 8 Jan 2016 12:31:33 +0100 Subject: [PATCH 091/168] Update Boot2docker information for OSX --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e22c3c44f7..d6a01c389b6 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ docker run -d -p 4567:4567 --name slate -v $(pwd)/source:/app/source slate You can now see the docs at . Whoa! That was fast! *Note: if you're using the Docker setup on OSX, the docs will be -availalable at the output of `boot2docker ip` instead of `localhost:4567`.* +available at the output of `docker-machine ip ` (port: 4567) instead of `localhost:4567`.* Now that Slate is all set up your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/tripit/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/tripit/slate/wiki/Deploying-Slate). From 35690907be70f411352a617eda46c5c7b72a1c0e Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Sun, 17 Jan 2016 14:34:19 -0800 Subject: [PATCH 092/168] Added Augur API to examples --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d6a01c389b6..0d556f0355f 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ Examples of Slate in the Wild * [BlockCypher's API Documentation](http://dev.blockcypher.com) * [InterServer API Documentation](https://my.interserver.net/apidoc/) * [ActionHeroJS's API Documentation](http://www.actionherojs.com/docs) +* [Augur API Documentation](http://docs.augur.net) (Feel free to add your site to this list in a pull request!) From 7f88aafcba83e6125ae7496495eccae3fb35f4d1 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 12:52:03 -0600 Subject: [PATCH 093/168] Upgrade to middleman 4 --- Gemfile | 9 +- Gemfile.lock | 154 +++++++++--------- source/{index.md => index.html.md} | 0 source/layouts/layout.erb | 3 + .../{_normalize.css => _normalize.scss} | 0 source/stylesheets/_syntax.scss.erb | 27 --- source/stylesheets/screen.css.scss | 22 ++- 7 files changed, 98 insertions(+), 117 deletions(-) rename source/{index.md => index.html.md} (100%) rename source/stylesheets/{_normalize.css => _normalize.scss} (100%) delete mode 100644 source/stylesheets/_syntax.scss.erb diff --git a/Gemfile b/Gemfile index 9a9931a5fab..527ab3ce0bc 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,12 @@ source 'https://rubygems.org' # Middleman -gem 'middleman', '~>3.3.10' +gem 'middleman', '~>4.0.0' gem 'middleman-gh-pages', '~> 0.0.3' -gem 'middleman-syntax', '~> 2.0.0' -gem 'middleman-autoprefixer', '~> 2.5.0' -gem 'rouge', '~> 1.9.1' +gem 'middleman-syntax', '~> 2.1.0' +gem 'middleman-autoprefixer', '~> 2.7.0' +gem "middleman-sprockets", "~> 4.0.0.rc" +gem 'rouge', '~> 1.10.1' gem 'redcarpet', '~> 3.3.2' gem 'rake', '~> 10.4.2' diff --git a/Gemfile.lock b/Gemfile.lock index f9400056dad..ced7a072291 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,137 +1,135 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.1.12) - i18n (~> 0.6, >= 0.6.9) + activesupport (4.2.5.1) + i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) - thread_safe (~> 0.1) + thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (5.2.1.1) + addressable (2.4.0) + autoprefixer-rails (6.3.1) execjs json - celluloid (0.16.0) - timers (~> 4.0.0) - chunky_png (1.3.4) + backports (3.6.7) + capybara (2.5.0) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.9.1.1) - compass (1.0.3) - chunky_png (~> 1.2) - compass-core (~> 1.0.2) - compass-import-once (~> 1.0.5) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - sass (>= 3.3.13, < 3.5) - compass-core (1.0.3) - multi_json (~> 1.0) - sass (>= 3.3.0, < 3.5) + coffee-script-source (1.10.0) compass-import-once (1.0.5) sass (>= 3.2, < 3.5) + concurrent-ruby (0.9.2) + contracts (0.12.0) erubis (2.7.0) - execjs (2.5.2) + execjs (2.6.0) + fastimage (1.8.1) + addressable (~> 2.3, >= 2.3.5) ffi (1.9.10) - haml (4.0.6) + haml (4.0.7) tilt - hike (1.2.3) - hitimes (1.2.2) - hooks (0.4.0) - uber (~> 0.0.4) + hamster (2.0.0) + concurrent-ruby (~> 0.8) + hashie (3.4.3) i18n (0.7.0) json (1.8.3) - kramdown (1.8.0) - listen (2.10.1) - celluloid (~> 0.16.0) + kramdown (1.9.0) + listen (3.0.5) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - middleman (3.3.12) + middleman (4.0.0) coffee-script (~> 2.2) - compass (>= 1.0.0, < 2.0.0) compass-import-once (= 1.0.5) - execjs (~> 2.0) haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.3.12) - middleman-sprockets (>= 3.1.2) + middleman-cli (= 4.0.0) + middleman-core (= 4.0.0) sass (>= 3.4.0, < 4.0) - uglifier (~> 2.5) - middleman-autoprefixer (2.5.0) - autoprefixer-rails (~> 5.2.0) + middleman-autoprefixer (2.7.0) + autoprefixer-rails (>= 6.3.1, < 7.0.0) middleman-core (>= 3.3.3) - middleman-core (3.3.12) - activesupport (~> 4.1.0) + middleman-cli (4.0.0) + thor (>= 0.17.0, < 2.0) + middleman-core (4.0.0) + activesupport (~> 4.2) + addressable (~> 2.4.0) + backports (~> 3.6) bundler (~> 1.1) + capybara (~> 2.5.0) + contracts (~> 0.12.0) erubis - hooks (~> 0.3) + execjs (~> 2.0) + fastimage (~> 1.8) + hamster (~> 2.0) + hashie (~> 3.4) i18n (~> 0.7.0) - listen (>= 2.7.9, < 3.0) - padrino-helpers (~> 0.12.3) + listen (~> 3.0) + padrino-helpers (~> 0.13.0) rack (>= 1.4.5, < 2.0) - rack-test (~> 0.6.2) - thor (>= 0.15.2, < 2.0) - tilt (~> 1.4.1, < 2.0) + sass (>= 3.4) + tilt (~> 1.4.1) + uglifier (~> 2.6) middleman-gh-pages (0.0.3) rake (> 0.9.3) - middleman-sprockets (3.4.2) - middleman-core (>= 3.3) - sprockets (~> 2.12.1) - sprockets-helpers (~> 1.1.0) - sprockets-sass (~> 1.3.0) - middleman-syntax (2.0.0) - middleman-core (~> 3.2) + middleman-sprockets (4.0.0.rc.1) + middleman-core (>= 4.0.0.rc.1) + sprockets (~> 3.0) + middleman-syntax (2.1.0) + middleman-core (>= 3.2) rouge (~> 1.0) - minitest (5.7.0) - multi_json (1.11.2) - padrino-helpers (0.12.5) + mime-types (3.0) + mime-types-data (~> 3.2015) + mime-types-data (3.2015.1120) + mini_portile2 (2.0.0) + minitest (5.8.4) + nokogiri (1.6.7.2) + mini_portile2 (~> 2.0.0.rc2) + padrino-helpers (0.13.1) i18n (~> 0.6, >= 0.6.7) - padrino-support (= 0.12.5) + padrino-support (= 0.13.1) tilt (~> 1.4.1) - padrino-support (0.12.5) + padrino-support (0.13.1) activesupport (>= 3.1) rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) rake (10.4.2) - rb-fsevent (0.9.5) + rb-fsevent (0.9.7) rb-inotify (0.9.5) ffi (>= 0.5.0) - redcarpet (3.3.2) - rouge (1.9.1) - sass (3.4.16) - sprockets (2.12.4) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-helpers (1.1.0) - sprockets (~> 2.0) - sprockets-sass (1.3.1) - sprockets (~> 2.0) - tilt (~> 1.1) + redcarpet (3.3.4) + rouge (1.10.1) + sass (3.4.21) + sprockets (3.4.1) + rack (> 1, < 3) thor (0.19.1) thread_safe (0.3.5) tilt (1.4.1) - timers (4.0.1) - hitimes tzinfo (1.2.2) thread_safe (~> 0.1) - uber (0.0.13) - uglifier (2.7.1) + uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) + xpath (2.0.0) + nokogiri (~> 1.3) PLATFORMS ruby DEPENDENCIES - middleman (~> 3.3.10) - middleman-autoprefixer (~> 2.5.0) + middleman (~> 4.0.0) + middleman-autoprefixer (~> 2.7.0) middleman-gh-pages (~> 0.0.3) - middleman-syntax (~> 2.0.0) + middleman-sprockets (~> 4.0.0.rc) + middleman-syntax (~> 2.1.0) rake (~> 10.4.2) redcarpet (~> 3.3.2) - rouge (~> 1.9.1) + rouge (~> 1.10.1) BUNDLED WITH - 1.10.5 + 1.10.6 diff --git a/source/index.md b/source/index.html.md similarity index 100% rename from source/index.md rename to source/index.html.md diff --git a/source/layouts/layout.erb b/source/layouts/layout.erb index 36ae0f95f81..a939e2d5503 100644 --- a/source/layouts/layout.erb +++ b/source/layouts/layout.erb @@ -24,6 +24,9 @@ under the License. <%= stylesheet_link_tag :screen, media: :screen %> <%= stylesheet_link_tag :print, media: :print %> + <% if current_page.data.search %> <%= javascript_include_tag "all" %> diff --git a/source/stylesheets/_normalize.css b/source/stylesheets/_normalize.scss similarity index 100% rename from source/stylesheets/_normalize.css rename to source/stylesheets/_normalize.scss diff --git a/source/stylesheets/_syntax.scss.erb b/source/stylesheets/_syntax.scss.erb deleted file mode 100644 index dfeb0c15240..00000000000 --- a/source/stylesheets/_syntax.scss.erb +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2008-2013 Concur Technologies, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); you may -not use this file except in compliance with the License. You may obtain -a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -License for the specific language governing permissions and limitations -under the License. -*/ - -@import 'variables'; - -<%= Rouge::Themes::Base16::Monokai.render(:scope => '.highlight') %> - -.highlight .c, .highlight .cm, .highlight .c1, .highlight .cs { - color: #909090; -} - -.highlight, .highlight .w { - background-color: $code-bg; -} \ No newline at end of file diff --git a/source/stylesheets/screen.css.scss b/source/stylesheets/screen.css.scss index e4b3ef82b22..0d62f9166a1 100644 --- a/source/stylesheets/screen.css.scss +++ b/source/stylesheets/screen.css.scss @@ -1,8 +1,6 @@ @charset "utf-8"; @import 'normalize'; -@import 'compass'; @import 'variables'; -@import 'syntax'; @import 'icon-font'; /* @@ -340,7 +338,7 @@ html, body { padding: 0 $main-padding; box-sizing: border-box; display: block; - @include text-shadow($main-embossed-text-shadow); + text-shadow: $main-embossed-text-shadow; @extend %left-col; } @@ -471,7 +469,7 @@ html, body { aside { padding-top: 1em; padding-bottom: 1em; - @include text-shadow(0 1px 0 lighten($aside-notice-bg, 15%)); + text-shadow: 0 1px 0 lighten($aside-notice-bg, 15%); margin-top: 1.5em; margin-bottom: 1.5em; background: $aside-notice-bg; @@ -479,12 +477,12 @@ html, body { &.warning { background-color: $aside-warning-bg; - @include text-shadow(0 1px 0 lighten($aside-warning-bg, 15%)); + text-shadow: 0 1px 0 lighten($aside-warning-bg, 15%); } &.success { background-color: $aside-success-bg; - @include text-shadow(0 1px 0 lighten($aside-success-bg, 15%)); + text-shadow: 0 1px 0 lighten($aside-success-bg, 15%); } } @@ -511,7 +509,7 @@ html, body { margin: -2px; border-radius: 4px; border: 1px solid #F7E633; - @include text-shadow(1px 1px 0 #666); + text-shadow: 1px 1px 0 #666; background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%); } } @@ -534,7 +532,7 @@ html, body { clear:right; box-sizing: border-box; - @include text-shadow(0px 1px 2px rgba(0,0,0,0.4)); + text-shadow: 0px 1px 2px rgba(0,0,0,0.4); @extend %right-col; @@ -618,3 +616,11 @@ html, body { margin-top: $main-padding; } } + +.highlight .c, .highlight .cm, .highlight .c1, .highlight .cs { + color: #909090; +} + +.highlight, .highlight .w { + background-color: $code-bg; +} \ No newline at end of file From 02428eb687e33e2900761144c8a94464889cc256 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 12:52:33 -0600 Subject: [PATCH 094/168] Ignore .sass-cache --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f1953e3a979..10501583560 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ tmp build/ .cache .vagrant +.sass-cache # YARD artifacts .yardoc From b6084cfd0ace748e4f3bd7c947e748d18ec4956c Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 12:52:42 -0600 Subject: [PATCH 095/168] Update readme styling --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 40af1a24208..7f386175f59 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ -Slate -======== +

    + Slate: API Documentation Generator +
    + Build Status +

    + [![Build Status](https://travis-ci.org/tripit/slate.svg?branch=master)](https://travis-ci.org/tripit/slate) [![Dependency Status](https://gemnasium.com/tripit/slate.png)](https://gemnasium.com/tripit/slate) -Slate helps you create beautiful API documentation. Think of it as an intelligent, responsive documentation template for your API. +

    Slate helps you create beautiful, intelligent, responsive API documentation.

    -Screenshot of Example Documentation created with Slate +

    Screenshot of Example Documentation created with Slate

    -*The example above was created with Slate. Check it out at [tripit.github.io/slate](http://tripit.github.io/slate).* +

    The example above was created with Slate. Check it out at tripit.github.io/slate.

    Features ------------ From 63e3e30bc562717a9105e3e29c7cfa09298a065f Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 12:53:06 -0600 Subject: [PATCH 096/168] Update readme styling again --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 7f386175f59..3525a529cad 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,6 @@ Build Status

    - -[![Build Status](https://travis-ci.org/tripit/slate.svg?branch=master)](https://travis-ci.org/tripit/slate) [![Dependency Status](https://gemnasium.com/tripit/slate.png)](https://gemnasium.com/tripit/slate) -

    Slate helps you create beautiful, intelligent, responsive API documentation.

    Screenshot of Example Documentation created with Slate

    From 44cf741f010808b6d19685d7c0c6403742bf9276 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 12:55:22 -0600 Subject: [PATCH 097/168] Add new logo --- source/images/logo.png | Bin 3507 -> 22317 bytes source/stylesheets/screen.css.scss | 1 + 2 files changed, 1 insertion(+) diff --git a/source/images/logo.png b/source/images/logo.png index fa1f13da8193dacca747df56cc1f7bb0bc111a7e..68a478fae3611d878af18c575cf8218b818f41db 100644 GIT binary patch literal 22317 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
    hg5Z+!{Sa)O9QNxi$tfwtDZos~b$g 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 F`9JqINYVfR literal 3507 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 diff --git a/source/stylesheets/screen.css.scss b/source/stylesheets/screen.css.scss index 0d62f9166a1..730a79d5aa9 100644 --- a/source/stylesheets/screen.css.scss +++ b/source/stylesheets/screen.css.scss @@ -82,6 +82,7 @@ html, body { // This is the logo at the top of the ToC &>img { display: block; + max-width: 100%; } &>.search { From c0dddf7560dac99e0d55db0eccbd3e22a648ba3b Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 13:03:37 -0600 Subject: [PATCH 098/168] Improve contribution guidelines --- CONTRIBUTING.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b04fc955ca5..cae4eeedddc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,15 @@ -# Contributing to Slate +# Before You Submit an Issue -Thanks for contributing to Slate! A couple of quick guidelines for submitting PRs: +- Are you using Windows? We unfortunately don't support Windows. You could try using Docker, as outlined in the `README`. +- Is your version of Slate out of date? We have [upgrade instructions](https://github.com/tripit/slate/wiki/Updating-Slate) in the wiki. You could also try seeing if your problem is reproducible on the latest version of Slate. -- Please point your pull requests at the `dev` branch, and keep your commit messages clear and informative. +If you answered "no" to each of the questions above, feel free to submit an issue! It's also helpful if you include a code example of your problem (if applicable), we can't help you if you just say "Slate stopped loading for me once I added my documentation" without telling us the problematic documentation. + +# Before You Submit a Pull Request + +Thanks for contributing to Slate! A couple of quick guidelines for submitting pull requests: + +- **Please point your pull requests at the `dev` branch.** We don't accept pull requests to `master`. - Please make sure your contributions work in the most recent version of Chrome, Firefox, and IE. - If you're implementing a new feature, even if it's relatively small, it's nice to open an issue before you start so that others know what you're working on and can help make sure you're on the right track. From 884cda666ab78debd4b230466be644a8aa610ad1 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 13:10:36 -0600 Subject: [PATCH 099/168] Update readme --- README.md | 51 ++++++++++++--------------------------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 3525a529cad..460de945ebf 100644 --- a/README.md +++ b/README.md @@ -84,52 +84,25 @@ You can now see the docs at http://localhost:4567. Now that Slate is all set up your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/tripit/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/tripit/slate/wiki/Deploying-Slate). -Examples of Slate in the Wild +Companies Using Slate --------------------------------- -* [Travis-CI's API docs](https://docs.travis-ci.com/api/) -* [Mozilla's localForage docs](http://mozilla.github.io/localForage/) -* [Mozilla Recroom](http://mozilla.github.io/recroom/) -* [Drcaban's Build a Quine tutorial](http://drcabana.github.io/build-a-quine/#introduction) -* [PricePlow API docs](https://www.priceplow.com/api/documentation) -* [Emerging Threats API docs](http://apidocs.emergingthreats.net/) -* [Appium docs](http://appium.io/slate/en/master) -* [Golazon Developer](http://developer.golazon.com) -* [Dwolla API docs](https://docs.dwolla.com/) -* [RozpisyZapasu API docs](http://www.rozpisyzapasu.cz/dev/api/) -* [Codestar Framework Docs](http://codestarframework.com/documentation/) -* [Buddycloud API](http://buddycloud.com/api) -* [Crafty Clicks API](https://craftyclicks.co.uk/api/) -* [Paracel API Reference](http://paracel.io/docs/api_reference.html) -* [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) -* [Coinbase API Reference](https://developers.coinbase.com/api) -* [Whispir.io API](https://whispir.github.io/api) -* [NASA API](https://data.nasa.gov/developer/external/planetary/) -* [CardPay API](https://developers.cardpay.com/) +* [NASA](https://api.nasa.gov) * [IBM Cloudant](https://docs.cloudant.com/api.html) -* [Bitrix basis components](http://bbc.bitrix.expert/) -* [viagogo API Documentation](http://developer.viagogo.net/) -* [Fidor Bank API Documentation](http://docs.fidor.de/) -* [Market Prophit API Documentation](http://developer.marketprophit.com/) -* [OAuth.io API Documentation](http://docs.oauth.io/) -* [Aircall for Developers](http://developer.aircall.io/) -* [SupportKit API Docs](http://docs.smooch.io/) -* [SocialRadar's LocationKit Docs](https://docs.locationkit.io/) -* [SafetyCulture API Documentation](https://developer.safetyculture.io/) -* [hosting.de API Documentation](https://www.hosting.de/docs/api/) -* [CheddarGetter API Documentation](http://docs.cheddargetter.com) -* [Invoiced API](http://invoiced.com/docs/api/) -* [BlockCypher's API Documentation](http://dev.blockcypher.com) -* [InterServer API Documentation](https://my.interserver.net/apidoc/) -* [ActionHeroJS's API Documentation](http://www.actionherojs.com/docs) -* [Augur API Documentation](http://docs.augur.net) - -(Feel free to add your site to this list in a pull request!) +* [Travis-CI](https://docs.travis-ci.com/api/) +* [Mozilla](http://mozilla.github.io/localForage/) +* [Appium](http://appium.io/slate/en/master) +* [Dwolla](https://docs.dwolla.com/) +* [Clearbit](https://clearbit.com/docs) +* [Coinbase](https://developers.coinbase.com/api) +* [Fidor Bank](http://docs.fidor.de/) + +You can view more in [the list on the wiki](https://github.com/tripit/slate/wiki/Slate-in-the-Wild). Need Help? Found a bug? -------------------- -Just [submit a issue](https://github.com/tripit/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. +Read our [contribution guidelines](https://github.com/tripit/slate/blob/master/CONTRIBUTING.md), and then [submit a issue](https://github.com/tripit/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. Contributors From 8cba35231544fc17cc5c584e56ccb41f3547c7af Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 15:39:37 -0600 Subject: [PATCH 100/168] Add lang-specific class --- source/javascripts/app/_lang.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index 1a124bb68ae..ae0d4e42f2f 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -29,8 +29,10 @@ under the License. $(".lang-selector a[data-language-name='" + language + "']").addClass('active'); for (var i=0; i < languages.length; i++) { $(".highlight." + languages[i]).hide(); + $(".lang-specific." + languages[i]).hide(); } $(".highlight." + language).show(); + $(".lang-specific." + language).show(); global.toc.calculateHeights(); From 79bb28c2f891196494e1eb42e55c8ce920ccc518 Mon Sep 17 00:00:00 2001 From: Eric Caron Date: Thu, 19 Nov 2015 21:26:34 -0600 Subject: [PATCH 101/168] README copy-editing changes Applying the copy-editing changes noticed by Ira Brooker (@IOB1979) to the current master branch --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 460de945ebf..c9cb497cf70 100644 --- a/README.md +++ b/README.md @@ -13,21 +13,21 @@ Features ------------ -* **Clean, intuitive design** — with Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [Paypal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even print. +* **Clean, intuitive design** — With Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [Paypal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even in print. -* **Everything on a single page** — gone are the days where your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy. +* **Everything on a single page** — Gone are the days when your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy. -* **Slate is just Markdown** — when you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks! +* **Slate is just Markdown** — When you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks. -* **Write code samples in multiple languages** — if your API has bindings in multiple programming languages, you easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown! +* **Write code samples in multiple languages** — If your API has bindings in multiple programming languages, you can easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown. * **Out-of-the-box syntax highlighting** for [almost 60 languages](http://rouge.jayferd.us/demo), no configuration required. * **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents. -* **Let your users update your documentation for you** — by default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it's simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to, you're welcome to not use Github and host your docs elsewhere! +* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes its simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere. -Getting starting with Slate is super easy! Simply fork this repository, and then follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://tripit.github.io/slate). +Getting started with Slate is super easy! Simply fork this repository and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://tripit.github.io/slate). @@ -104,7 +104,6 @@ Need Help? Found a bug? Read our [contribution guidelines](https://github.com/tripit/slate/blob/master/CONTRIBUTING.md), and then [submit a issue](https://github.com/tripit/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. - Contributors -------------------- From 4f5443ce06eeb07d1b15dcadbdc02b96277063a2 Mon Sep 17 00:00:00 2001 From: Eric Caron Date: Fri, 20 Nov 2015 21:26:34 -0600 Subject: [PATCH 102/168] It should have be it. It wasn't it. It was its. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9cb497cf70..cedc17c834c 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Features * **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents. -* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes its simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere. +* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere. Getting started with Slate is super easy! Simply fork this repository and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://tripit.github.io/slate). From 20d94974fa85a7c368946bb3442aa243f37dec7d Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Tue, 26 Jan 2016 18:41:22 -0600 Subject: [PATCH 103/168] Add parrot link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cedc17c834c..88ed261538d 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ Companies Using Slate * [Dwolla](https://docs.dwolla.com/) * [Clearbit](https://clearbit.com/docs) * [Coinbase](https://developers.coinbase.com/api) +* [Parrot Drones](http://developer.parrot.com/docs/bebop/) * [Fidor Bank](http://docs.fidor.de/) You can view more in [the list on the wiki](https://github.com/tripit/slate/wiki/Slate-in-the-Wild). From ccd158df4ff0b59bd53cfa1d8de978199df3ffc7 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Wed, 27 Jan 2016 00:45:32 -0600 Subject: [PATCH 104/168] Add code block warning --- source/index.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/index.html.md b/source/index.html.md index 893e0713e8e..49fd4a04e55 100644 --- a/source/index.html.md +++ b/source/index.html.md @@ -154,7 +154,7 @@ curl "http://example.com/api/kittens/2" This endpoint retrieves a specific kitten. - + ### HTTP Request From 5c87f10383da3c942dbefc2630b1dd2c6d82efbe Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Wed, 27 Jan 2016 00:53:24 -0600 Subject: [PATCH 105/168] Fix non-wrapping code in firefox --- source/stylesheets/_variables.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/source/stylesheets/_variables.scss b/source/stylesheets/_variables.scss index 5fe64b1f302..6ecbf88dae0 100644 --- a/source/stylesheets/_variables.scss +++ b/source/stylesheets/_variables.scss @@ -101,6 +101,7 @@ $search-box-border-color: #666; %break-words { word-break: break-all; + white-space: normal; /* Non standard for webkit */ word-break: break-word; From 9f83bbd15838958ec534f8c309512d6031c031d5 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Wed, 27 Jan 2016 01:18:58 -0600 Subject: [PATCH 106/168] Add comment about middleman hanging to config.rb --- config.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.rb b/config.rb index 43bceaa5a43..cac85f6ab20 100644 --- a/config.rb +++ b/config.rb @@ -30,6 +30,8 @@ # Build Configuration configure :build do + # If you're having trouble with Middleman hanging, commenting + # out the following two lines has been known to help activate :minify_css activate :minify_javascript # activate :relative_assets From a4b9208af0119ff851a2dc95968b89cf0c858062 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Wed, 27 Jan 2016 01:37:16 -0600 Subject: [PATCH 107/168] Move jquery to be local --- source/javascripts/app/_lang.js | 2 + source/javascripts/app/_search.js | 1 + source/javascripts/app/_toc.js | 1 + source/javascripts/lib/_jquery.js | 9831 +++++++++++++++++++++++++++++ source/layouts/layout.erb | 1 - 5 files changed, 9835 insertions(+), 1 deletion(-) create mode 100644 source/javascripts/lib/_jquery.js diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index ae0d4e42f2f..4c73da6e9c5 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -1,3 +1,5 @@ +//= require ../lib/_jquery + /* Copyright 2008-2013 Concur Technologies, Inc. diff --git a/source/javascripts/app/_search.js b/source/javascripts/app/_search.js index 91f38a04edf..5ace538d887 100644 --- a/source/javascripts/app/_search.js +++ b/source/javascripts/app/_search.js @@ -1,4 +1,5 @@ //= require ../lib/_lunr +//= require ../lib/_jquery //= require ../lib/_jquery.highlight (function () { 'use strict'; diff --git a/source/javascripts/app/_toc.js b/source/javascripts/app/_toc.js index bc2aa3e1f11..44f704f2549 100644 --- a/source/javascripts/app/_toc.js +++ b/source/javascripts/app/_toc.js @@ -1,3 +1,4 @@ +//= require ../lib/_jquery //= require ../lib/_jquery_ui //= require ../lib/_jquery.tocify //= require ../lib/_imagesloaded.min diff --git a/source/javascripts/lib/_jquery.js b/source/javascripts/lib/_jquery.js new file mode 100644 index 00000000000..b78120e6a1c --- /dev/null +++ b/source/javascripts/lib/_jquery.js @@ -0,0 +1,9831 @@ +/*! + * jQuery JavaScript Library v2.2.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-08T20:02Z + */ + +(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 have a `window` with a `document` + // (such as Node.js), expose a 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 ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +//"use strict"; +var arr = []; + +var document = window.document; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "2.2.0", + + // 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 + // 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. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + 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(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, 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() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + 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) + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + }, + + isPlainObject: function( obj ) { + + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android<4.0, iOS<6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf( "use strict" ) === 1 ) { + script = document.createElement( "script" ); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE9-11+ + // 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(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android<4.1 + 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 ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + 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 length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + 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 tmp, args, proxy; + + 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: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +// JSHint would error on this code due to the Symbol not being defined in ES5. +// Defining this global in .jshintrc would create a danger of using the global +// unguarded in another place, it seems safer to just disable JSHint for these +// three lines. +/* jshint ignore: start */ +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} +/* jshint ignore: end */ + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".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 = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.1 + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-10-17 + */ +(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 + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // 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( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "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 m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + 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 = arr.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; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* 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( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.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 !document.getElementsByName || !document.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 ); + return m ? [ 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 ( typeof context.getElementsByClassName !== "undefined" && 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( document.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 = "" + + ""; + + // 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.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + 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 = document.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 self-exclusive + // 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 === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || 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 === document ? -1 : + b === document ? 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 document; +}; + +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 && + !compilerCache[ expr + " " ] && + ( !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, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + 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 + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && 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 ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // 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 ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ 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, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator 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 ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ 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 + uniqueCache[ 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 || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, 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 ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + 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 only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound 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, + !context || 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 = ""; + 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 = ""; + 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.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +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 ( indexOf.call( qualifier, elem ) > -1 ) !== 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, + len = this.length, + ret = [], + self = this; + + 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, + + // A simple way to check for HTML strings + // Prioritize #id over 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, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ 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; + + // Option to run 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 ] ); + + // Support: Blackberry 4.6 + // gEBID returns nodes no longer in the document (#6963) + if ( elem && elem.parentNode ) { + + // 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 || root ).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 root.ready !== undefined ? + root.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.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; 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.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + 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 indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + 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 ) { + while ( ( cur = cur[ dir ] ) && 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 dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnotwhite = ( /\S+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + 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" ? + 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, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + 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.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + 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() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } 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() + .progress( updateFunc( i, progressContexts, progressValues ) ) + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ); + } 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; + } + + // 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" ); + } + } +} ); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + 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. + // Support: IE9-10 only + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + 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 < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[ 0 ], key ) : emptyGet; +}; +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + register: function( owner, initial ) { + var value = initial || {}; + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable, non-writable property + // configurability must be true to allow the property to be + // deleted with the delete operator + } else { + Object.defineProperty( owner, this.expando, { + value: value, + writable: true, + configurable: true + } ); + } + return owner[ this.expando ]; + }, + cache: function( owner ) { + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( !acceptData( owner ) ) { + return {}; + } + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + owner[ this.expando ] && owner[ this.expando ][ key ]; + }, + access: function( owner, key, value ) { + var stored; + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase( key ) ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key === undefined ) { + this.register( owner ); + + } else { + + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + + // 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 = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <= 35-45+ + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).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 + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + 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 ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data, camelKey; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // with the key as-is + data = dataUser.get( elem, key ) || + + // Try to find dashed key if it exists (gh-2779) + // This is for 2.2.x only + dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); + + if ( data !== undefined ) { + return data; + } + + camelKey = jQuery.camelCase( key ); + + // Attempt to get data from the cache + // with the key camelized + data = dataUser.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + camelKey = jQuery.camelCase( key ); + this.each( function() { + + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = dataUser.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + dataUser.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf( "-" ) > -1 && data !== undefined ) { + dataUser.set( this, key, value ); + } + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = dataPriv.access( 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 public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", 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 = dataPriv.get( 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 rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +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 ); + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([\w:-]+)/ ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE9 + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE9-11+ + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + 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 || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.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 ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0-4.3, Safari<=5.1 + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari<=5.1, Android<4.2 + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<=11+ + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE9 +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // 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 ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + 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 elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * 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 handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( 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 !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // 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 if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( 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; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( 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 data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( dataPriv.get( 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.rnamespace || event.rnamespace.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 i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Support (at least): Chrome, IE9 + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // 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 ) > -1 : + 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; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail 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 offsetX offsetY pageX pageY " + + "screenX screenY toElement" ).split( " " ), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // 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 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; + } + }, + + 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: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome<28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : 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 ) { + this.focus(); + return false; + } + }, + 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 ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + 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; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, 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: 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 = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://code.google.com/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +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 mouseenter/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; + } + }; +} ); + +jQuery.fn.extend( { + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, 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 ); + } ); + } +} ); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +function manipulationTarget( elem, content ) { + if ( jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "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; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + 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 collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + 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 ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ 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 || "" ) && + !dataPriv.access( 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.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !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 ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], 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, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + 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 ); + } + } + } + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, 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 domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + 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 && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + 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 ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); + + +var iframe, + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; + +/** + * 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 elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + 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( "