').hide().addClass(options.dotsClass).appendTo(this._controls.$container);\n\n this._controls.$indicators.on('click', 'div', $.proxy(function(e) {\n var index = $(e.target).parent().is(this._controls.$indicators)\n ? $(e.target).index() : $(e.target).parent().index();\n\n e.preventDefault();\n\n this.to(index, options.dotsSpeed);\n }, this));\n\n // create DOM structure for relative navigation\n $container = options.navContainer ? $(options.navContainer)\n : $('
').addClass(options.navContainerClass).prependTo(this._controls.$container);\n\n this._controls.$next = $('<' + options.navElement + '>');\n this._controls.$previous = this._controls.$next.clone();\n\n this._controls.$previous\n .addClass(options.navClass[0])\n .html(options.navText[0])\n .hide()\n .prependTo($container)\n .on('click', $.proxy(function(e) {\n this.prev(options.navSpeed);\n }, this));\n this._controls.$next\n .addClass(options.navClass[1])\n .html(options.navText[1])\n .hide()\n .appendTo($container)\n .on('click', $.proxy(function(e) {\n this.next(options.navSpeed);\n }, this));\n\n // override public methods of the carousel\n for (override in this._overrides) {\n this._core[override] = $.proxy(this[override], this);\n }\n }\n\n /**\n * Destroys the plugin.\n * @protected\n */\n Navigation.prototype.destroy = function() {\n var handler, control, property, override;\n\n for (handler in this._handlers) {\n this.$element.off(handler, this._handlers[handler]);\n }\n for (control in this._controls) {\n this._controls[control].remove();\n }\n for (override in this.overides) {\n this._core[override] = this._overrides[override];\n }\n for (property in Object.getOwnPropertyNames(this)) {\n typeof this[property] != 'function' && (this[property] = null);\n }\n }\n\n /**\n * Updates the internal state.\n * @protected\n */\n Navigation.prototype.update = function() {\n var i, j, k,\n options = this._core.settings,\n lower = this._core.clones().length / 2,\n upper = lower + this._core.items().length,\n size = options.center || options.autoWidth || options.dotData\n ? 1 : options.dotsEach || options.items;\n\n if (options.slideBy !== 'page') {\n options.slideBy = Math.min(options.slideBy, options.items);\n }\n\n if (options.dots || options.slideBy == 'page') {\n this._pages = [];\n\n for (i = lower, j = 0, k = 0; i < upper; i++) {\n if (j >= size || j === 0) {\n this._pages.push({\n start: i - lower,\n end: i - lower + size - 1\n });\n j = 0, ++k;\n }\n j += this._core.mergers(this._core.relative(i));\n }\n }\n }\n\n /**\n * Draws the user interface.\n * @todo The option `dotData` wont work.\n * @protected\n */\n Navigation.prototype.draw = function() {\n var difference, i, html = '',\n options = this._core.settings,\n $items = this._core.$stage.children(),\n index = this._core.relative(this._core.current());\n\n if (options.nav && !options.loop && !options.navRewind) {\n this._controls.$previous.toggleClass('disabled', index <= 0);\n this._controls.$next.toggleClass('disabled', index >= this._core.maximum());\n }\n\n this._controls.$previous.toggle(options.nav);\n this._controls.$next.toggle(options.nav);\n\n if (options.dots) {\n difference = this._pages.length - this._controls.$indicators.children().length;\n\n if (options.dotData && difference !== 0) {\n for (i = 0; i < this._controls.$indicators.children().length; i++) {\n html += this._templates[this._core.relative(i)];\n }\n this._controls.$indicators.html(html);\n } else if (difference > 0) {\n html = new Array(difference + 1).join(this._templates[0]);\n this._controls.$indicators.append(html);\n } else if (difference < 0) {\n this._controls.$indicators.children().slice(difference).remove();\n }\n\n this._controls.$indicators.find('.active').removeClass('active');\n this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active');\n }\n\n this._controls.$indicators.toggle(options.dots);\n }\n\n /**\n * Extends event data.\n * @protected\n * @param {Event} event - The event object which gets thrown.\n */\n Navigation.prototype.onTrigger = function(event) {\n var settings = this._core.settings;\n\n event.page = {\n index: $.inArray(this.current(), this._pages),\n count: this._pages.length,\n size: settings && (settings.center || settings.autoWidth || settings.dotData\n ? 1 : settings.dotsEach || settings.items)\n };\n }\n\n /**\n * Gets the current page position of the carousel.\n * @protected\n * @returns {Number}\n */\n Navigation.prototype.current = function() {\n var index = this._core.relative(this._core.current());\n return $.grep(this._pages, function(o) {\n return o.start <= index && o.end >= index;\n }).pop();\n }\n\n /**\n * Gets the current succesor/predecessor position.\n * @protected\n * @returns {Number}\n */\n Navigation.prototype.getPosition = function(successor) {\n var position, length,\n options = this._core.settings;\n\n if (options.slideBy == 'page') {\n position = $.inArray(this.current(), this._pages);\n length = this._pages.length;\n successor ? ++position : --position;\n position = this._pages[((position % length) + length) % length].start;\n } else {\n position = this._core.relative(this._core.current());\n length = this._core.items().length;\n successor ? position += options.slideBy : position -= options.slideBy;\n }\n return position;\n }\n\n /**\n * Slides to the next item or page.\n * @public\n * @param {Number} [speed=false] - The time in milliseconds for the transition.\n */\n Navigation.prototype.next = function(speed) {\n $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);\n }\n\n /**\n * Slides to the previous item or page.\n * @public\n * @param {Number} [speed=false] - The time in milliseconds for the transition.\n */\n Navigation.prototype.prev = function(speed) {\n $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);\n }\n\n /**\n * Slides to the specified item or page.\n * @public\n * @param {Number} position - The position of the item or page.\n * @param {Number} [speed] - The time in milliseconds for the transition.\n * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.\n */\n Navigation.prototype.to = function(position, speed, standard) {\n var length;\n\n if (!standard) {\n length = this._pages.length;\n $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);\n } else {\n $.proxy(this._overrides.to, this._core)(position, speed);\n }\n }\n\n $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;\n\n})(window.Zepto || window.jQuery, window, document);\n\n/**\n * Hash Plugin\n * @version 2.0.0\n * @author Artus Kolanowski\n * @license The MIT License (MIT)\n */\n;(function($, window, document, undefined) {\n 'use strict';\n\n /**\n * Creates the hash plugin.\n * @class The Hash Plugin\n * @param {Owl} carousel - The Owl Carousel\n */\n var Hash = function(carousel) {\n /**\n * Reference to the core.\n * @protected\n * @type {Owl}\n */\n this._core = carousel;\n\n /**\n * Hash table for the hashes.\n * @protected\n * @type {Object}\n */\n this._hashes = {};\n\n /**\n * The carousel element.\n * @type {jQuery}\n */\n this.$element = this._core.$element;\n\n /**\n * All event handlers.\n * @protected\n * @type {Object}\n */\n this._handlers = {\n 'initialized.owl.carousel': $.proxy(function() {\n if (this._core.settings.startPosition == 'URLHash') {\n $(window).trigger('hashchange.owl.navigation');\n }\n }, this),\n 'prepared.owl.carousel': $.proxy(function(e) {\n var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash');\n this._hashes[hash] = e.content;\n }, this)\n };\n\n // set default options\n this._core.options = $.extend({}, Hash.Defaults, this._core.options);\n\n // register the event handlers\n this.$element.on(this._handlers);\n\n // register event listener for hash navigation\n $(window).on('hashchange.owl.navigation', $.proxy(function() {\n var hash = window.location.hash.substring(1),\n items = this._core.$stage.children(),\n position = this._hashes[hash] && items.index(this._hashes[hash]) || 0;\n\n if (!hash) {\n return false;\n }\n\n this._core.to(position, false, true);\n }, this));\n }\n\n /**\n * Default options.\n * @public\n */\n Hash.Defaults = {\n URLhashListener: false\n }\n\n /**\n * Destroys the plugin.\n * @public\n */\n Hash.prototype.destroy = function() {\n var handler, property;\n\n $(window).off('hashchange.owl.navigation');\n\n for (handler in this._handlers) {\n this._core.$element.off(handler, this._handlers[handler]);\n }\n for (property in Object.getOwnPropertyNames(this)) {\n typeof this[property] != 'function' && (this[property] = null);\n }\n }\n\n $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;\n\n})(window.Zepto || window.jQuery, window, document);\n","// Underscore.js 1.4.4\r\n// ===================\r\n\r\n// > http://underscorejs.org\r\n// > (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.\r\n// > Underscore may be freely distributed under the MIT license.\r\n\r\n// Baseline setup\r\n// --------------\r\n(function() {\r\n\r\n // Establish the root object, `window` in the browser, or `global` on the server.\r\n var root = this;\r\n\r\n // Save the previous value of the `_` variable.\r\n var previousUnderscore = root._;\r\n\r\n // Establish the object that gets returned to break out of a loop iteration.\r\n var breaker = {};\r\n\r\n // Save bytes in the minified (but not gzipped) version:\r\n var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\r\n\r\n // Create quick reference variables for speed access to core prototypes.\r\n var push = ArrayProto.push,\r\n slice = ArrayProto.slice,\r\n concat = ArrayProto.concat,\r\n toString = ObjProto.toString,\r\n hasOwnProperty = ObjProto.hasOwnProperty;\r\n\r\n // All **ECMAScript 5** native function implementations that we hope to use\r\n // are declared here.\r\n var\r\n nativeForEach = ArrayProto.forEach,\r\n nativeMap = ArrayProto.map,\r\n nativeReduce = ArrayProto.reduce,\r\n nativeReduceRight = ArrayProto.reduceRight,\r\n nativeFilter = ArrayProto.filter,\r\n nativeEvery = ArrayProto.every,\r\n nativeSome = ArrayProto.some,\r\n nativeIndexOf = ArrayProto.indexOf,\r\n nativeLastIndexOf = ArrayProto.lastIndexOf,\r\n nativeIsArray = Array.isArray,\r\n nativeKeys = Object.keys,\r\n nativeBind = FuncProto.bind;\r\n\r\n // Create a safe reference to the Underscore object for use below.\r\n var _ = function(obj) {\r\n if (obj instanceof _) return obj;\r\n if (!(this instanceof _)) return new _(obj);\r\n this._wrapped = obj;\r\n };\r\n\r\n // Export the Underscore object for **Node.js**, with\r\n // backwards-compatibility for the old `require()` API. If we're in\r\n // the browser, add `_` as a global object via a string identifier,\r\n // for Closure Compiler \"advanced\" mode.\r\n if (typeof exports !== 'undefined') {\r\n if (typeof module !== 'undefined' && module.exports) {\r\n exports = module.exports = _;\r\n }\r\n exports._ = _;\r\n } else {\r\n root._ = _;\r\n }\r\n\r\n // Current version.\r\n _.VERSION = '1.4.4';\r\n\r\n // Collection Functions\r\n // --------------------\r\n\r\n // The cornerstone, an `each` implementation, aka `forEach`.\r\n // Handles objects with the built-in `forEach`, arrays, and raw objects.\r\n // Delegates to **ECMAScript 5**'s native `forEach` if available.\r\n var each = _.each = _.forEach = function(obj, iterator, context) {\r\n if (obj == null) return;\r\n if (nativeForEach && obj.forEach === nativeForEach) {\r\n obj.forEach(iterator, context);\r\n } else if (obj.length === +obj.length) {\r\n for (var i = 0, l = obj.length; i < l; i++) {\r\n if (iterator.call(context, obj[i], i, obj) === breaker) return;\r\n }\r\n } else {\r\n for (var key in obj) {\r\n if (_.has(obj, key)) {\r\n if (iterator.call(context, obj[key], key, obj) === breaker) return;\r\n }\r\n }\r\n }\r\n };\r\n\r\n // Return the results of applying the iterator to each element.\r\n // Delegates to **ECMAScript 5**'s native `map` if available.\r\n _.map = _.collect = function(obj, iterator, context) {\r\n var results = [];\r\n if (obj == null) return results;\r\n if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\r\n each(obj, function(value, index, list) {\r\n results[results.length] = iterator.call(context, value, index, list);\r\n });\r\n return results;\r\n };\r\n\r\n var reduceError = 'Reduce of empty array with no initial value';\r\n\r\n // **Reduce** builds up a single result from a list of values, aka `inject`,\r\n // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.\r\n _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {\r\n var initial = arguments.length > 2;\r\n if (obj == null) obj = [];\r\n if (nativeReduce && obj.reduce === nativeReduce) {\r\n if (context) iterator = _.bind(iterator, context);\r\n return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);\r\n }\r\n each(obj, function(value, index, list) {\r\n if (!initial) {\r\n memo = value;\r\n initial = true;\r\n } else {\r\n memo = iterator.call(context, memo, value, index, list);\r\n }\r\n });\r\n if (!initial) throw new TypeError(reduceError);\r\n return memo;\r\n };\r\n\r\n // The right-associative version of reduce, also known as `foldr`.\r\n // Delegates to **ECMAScript 5**'s native `reduceRight` if available.\r\n _.reduceRight = _.foldr = function(obj, iterator, memo, context) {\r\n var initial = arguments.length > 2;\r\n if (obj == null) obj = [];\r\n if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {\r\n if (context) iterator = _.bind(iterator, context);\r\n return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);\r\n }\r\n var length = obj.length;\r\n if (length !== +length) {\r\n var keys = _.keys(obj);\r\n length = keys.length;\r\n }\r\n each(obj, function(value, index, list) {\r\n index = keys ? keys[--length] : --length;\r\n if (!initial) {\r\n memo = obj[index];\r\n initial = true;\r\n } else {\r\n memo = iterator.call(context, memo, obj[index], index, list);\r\n }\r\n });\r\n if (!initial) throw new TypeError(reduceError);\r\n return memo;\r\n };\r\n\r\n // Return the first value which passes a truth test. Aliased as `detect`.\r\n _.find = _.detect = function(obj, iterator, context) {\r\n var result;\r\n any(obj, function(value, index, list) {\r\n if (iterator.call(context, value, index, list)) {\r\n result = value;\r\n return true;\r\n }\r\n });\r\n return result;\r\n };\r\n\r\n // Return all the elements that pass a truth test.\r\n // Delegates to **ECMAScript 5**'s native `filter` if available.\r\n // Aliased as `select`.\r\n _.filter = _.select = function(obj, iterator, context) {\r\n var results = [];\r\n if (obj == null) return results;\r\n if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);\r\n each(obj, function(value, index, list) {\r\n if (iterator.call(context, value, index, list)) results[results.length] = value;\r\n });\r\n return results;\r\n };\r\n\r\n // Return all the elements for which a truth test fails.\r\n _.reject = function(obj, iterator, context) {\r\n return _.filter(obj, function(value, index, list) {\r\n return !iterator.call(context, value, index, list);\r\n }, context);\r\n };\r\n\r\n // Determine whether all of the elements match a truth test.\r\n // Delegates to **ECMAScript 5**'s native `every` if available.\r\n // Aliased as `all`.\r\n _.every = _.all = function(obj, iterator, context) {\r\n iterator || (iterator = _.identity);\r\n var result = true;\r\n if (obj == null) return result;\r\n if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);\r\n each(obj, function(value, index, list) {\r\n if (!(result = result && iterator.call(context, value, index, list))) return breaker;\r\n });\r\n return !!result;\r\n };\r\n\r\n // Determine if at least one element in the object matches a truth test.\r\n // Delegates to **ECMAScript 5**'s native `some` if available.\r\n // Aliased as `any`.\r\n var any = _.some = _.any = function(obj, iterator, context) {\r\n iterator || (iterator = _.identity);\r\n var result = false;\r\n if (obj == null) return result;\r\n if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);\r\n each(obj, function(value, index, list) {\r\n if (result || (result = iterator.call(context, value, index, list))) return breaker;\r\n });\r\n return !!result;\r\n };\r\n\r\n // Determine if the array or object contains a given value (using `===`).\r\n // Aliased as `include`.\r\n _.contains = _.include = function(obj, target) {\r\n if (obj == null) return false;\r\n if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;\r\n return any(obj, function(value) {\r\n return value === target;\r\n });\r\n };\r\n\r\n // Invoke a method (with arguments) on every item in a collection.\r\n _.invoke = function(obj, method) {\r\n var args = slice.call(arguments, 2);\r\n var isFunc = _.isFunction(method);\r\n return _.map(obj, function(value) {\r\n return (isFunc ? method : value[method]).apply(value, args);\r\n });\r\n };\r\n\r\n // Convenience version of a common use case of `map`: fetching a property.\r\n _.pluck = function(obj, key) {\r\n return _.map(obj, function(value){ return value[key]; });\r\n };\r\n\r\n // Convenience version of a common use case of `filter`: selecting only objects\r\n // containing specific `key:value` pairs.\r\n _.where = function(obj, attrs, first) {\r\n if (_.isEmpty(attrs)) return first ? null : [];\r\n return _[first ? 'find' : 'filter'](obj, function(value) {\r\n for (var key in attrs) {\r\n if (attrs[key] !== value[key]) return false;\r\n }\r\n return true;\r\n });\r\n };\r\n\r\n // Convenience version of a common use case of `find`: getting the first object\r\n // containing specific `key:value` pairs.\r\n _.findWhere = function(obj, attrs) {\r\n return _.where(obj, attrs, true);\r\n };\r\n\r\n // Return the maximum element or (element-based computation).\r\n // Can't optimize arrays of integers longer than 65,535 elements.\r\n // See: https://bugs.webkit.org/show_bug.cgi?id=80797\r\n _.max = function(obj, iterator, context) {\r\n if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {\r\n return Math.max.apply(Math, obj);\r\n }\r\n if (!iterator && _.isEmpty(obj)) return -Infinity;\r\n var result = {computed : -Infinity, value: -Infinity};\r\n each(obj, function(value, index, list) {\r\n var computed = iterator ? iterator.call(context, value, index, list) : value;\r\n computed >= result.computed && (result = {value : value, computed : computed});\r\n });\r\n return result.value;\r\n };\r\n\r\n // Return the minimum element (or element-based computation).\r\n _.min = function(obj, iterator, context) {\r\n if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {\r\n return Math.min.apply(Math, obj);\r\n }\r\n if (!iterator && _.isEmpty(obj)) return Infinity;\r\n var result = {computed : Infinity, value: Infinity};\r\n each(obj, function(value, index, list) {\r\n var computed = iterator ? iterator.call(context, value, index, list) : value;\r\n computed < result.computed && (result = {value : value, computed : computed});\r\n });\r\n return result.value;\r\n };\r\n\r\n // Shuffle an array.\r\n _.shuffle = function(obj) {\r\n var rand;\r\n var index = 0;\r\n var shuffled = [];\r\n each(obj, function(value) {\r\n rand = _.random(index++);\r\n shuffled[index - 1] = shuffled[rand];\r\n shuffled[rand] = value;\r\n });\r\n return shuffled;\r\n };\r\n\r\n // An internal function to generate lookup iterators.\r\n var lookupIterator = function(value) {\r\n return _.isFunction(value) ? value : function(obj){ return obj[value]; };\r\n };\r\n\r\n // Sort the object's values by a criterion produced by an iterator.\r\n _.sortBy = function(obj, value, context) {\r\n var iterator = lookupIterator(value);\r\n return _.pluck(_.map(obj, function(value, index, list) {\r\n return {\r\n value : value,\r\n index : index,\r\n criteria : iterator.call(context, value, index, list)\r\n };\r\n }).sort(function(left, right) {\r\n var a = left.criteria;\r\n var b = right.criteria;\r\n if (a !== b) {\r\n if (a > b || a === void 0) return 1;\r\n if (a < b || b === void 0) return -1;\r\n }\r\n return left.index < right.index ? -1 : 1;\r\n }), 'value');\r\n };\r\n\r\n // An internal function used for aggregate \"group by\" operations.\r\n var group = function(obj, value, context, behavior) {\r\n var result = {};\r\n var iterator = lookupIterator(value || _.identity);\r\n each(obj, function(value, index) {\r\n var key = iterator.call(context, value, index, obj);\r\n behavior(result, key, value);\r\n });\r\n return result;\r\n };\r\n\r\n // Groups the object's values by a criterion. Pass either a string attribute\r\n // to group by, or a function that returns the criterion.\r\n _.groupBy = function(obj, value, context) {\r\n return group(obj, value, context, function(result, key, value) {\r\n (_.has(result, key) ? result[key] : (result[key] = [])).push(value);\r\n });\r\n };\r\n\r\n // Counts instances of an object that group by a certain criterion. Pass\r\n // either a string attribute to count by, or a function that returns the\r\n // criterion.\r\n _.countBy = function(obj, value, context) {\r\n return group(obj, value, context, function(result, key) {\r\n if (!_.has(result, key)) result[key] = 0;\r\n result[key]++;\r\n });\r\n };\r\n\r\n // Use a comparator function to figure out the smallest index at which\r\n // an object should be inserted so as to maintain order. Uses binary search.\r\n _.sortedIndex = function(array, obj, iterator, context) {\r\n iterator = iterator == null ? _.identity : lookupIterator(iterator);\r\n var value = iterator.call(context, obj);\r\n var low = 0, high = array.length;\r\n while (low < high) {\r\n var mid = (low + high) >>> 1;\r\n iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;\r\n }\r\n return low;\r\n };\r\n\r\n // Safely convert anything iterable into a real, live array.\r\n _.toArray = function(obj) {\r\n if (!obj) return [];\r\n if (_.isArray(obj)) return slice.call(obj);\r\n if (obj.length === +obj.length) return _.map(obj, _.identity);\r\n return _.values(obj);\r\n };\r\n\r\n // Return the number of elements in an object.\r\n _.size = function(obj) {\r\n if (obj == null) return 0;\r\n return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;\r\n };\r\n\r\n // Array Functions\r\n // ---------------\r\n\r\n // Get the first element of an array. Passing **n** will return the first N\r\n // values in the array. Aliased as `head` and `take`. The **guard** check\r\n // allows it to work with `_.map`.\r\n _.first = _.head = _.take = function(array, n, guard) {\r\n if (array == null) return void 0;\r\n return (n != null) && !guard ? slice.call(array, 0, n) : array[0];\r\n };\r\n\r\n // Returns everything but the last entry of the array. Especially useful on\r\n // the arguments object. Passing **n** will return all the values in\r\n // the array, excluding the last N. The **guard** check allows it to work with\r\n // `_.map`.\r\n _.initial = function(array, n, guard) {\r\n return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));\r\n };\r\n\r\n // Get the last element of an array. Passing **n** will return the last N\r\n // values in the array. The **guard** check allows it to work with `_.map`.\r\n _.last = function(array, n, guard) {\r\n if (array == null) return void 0;\r\n if ((n != null) && !guard) {\r\n return slice.call(array, Math.max(array.length - n, 0));\r\n } else {\r\n return array[array.length - 1];\r\n }\r\n };\r\n\r\n // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\r\n // Especially useful on the arguments object. Passing an **n** will return\r\n // the rest N values in the array. The **guard**\r\n // check allows it to work with `_.map`.\r\n _.rest = _.tail = _.drop = function(array, n, guard) {\r\n return slice.call(array, (n == null) || guard ? 1 : n);\r\n };\r\n\r\n // Trim out all falsy values from an array.\r\n _.compact = function(array) {\r\n return _.filter(array, _.identity);\r\n };\r\n\r\n // Internal implementation of a recursive `flatten` function.\r\n var flatten = function(input, shallow, output) {\r\n each(input, function(value) {\r\n if (_.isArray(value)) {\r\n shallow ? push.apply(output, value) : flatten(value, shallow, output);\r\n } else {\r\n output.push(value);\r\n }\r\n });\r\n return output;\r\n };\r\n\r\n // Return a completely flattened version of an array.\r\n _.flatten = function(array, shallow) {\r\n return flatten(array, shallow, []);\r\n };\r\n\r\n // Return a version of the array that does not contain the specified value(s).\r\n _.without = function(array) {\r\n return _.difference(array, slice.call(arguments, 1));\r\n };\r\n\r\n // Produce a duplicate-free version of the array. If the array has already\r\n // been sorted, you have the option of using a faster algorithm.\r\n // Aliased as `unique`.\r\n _.uniq = _.unique = function(array, isSorted, iterator, context) {\r\n if (_.isFunction(isSorted)) {\r\n context = iterator;\r\n iterator = isSorted;\r\n isSorted = false;\r\n }\r\n var initial = iterator ? _.map(array, iterator, context) : array;\r\n var results = [];\r\n var seen = [];\r\n each(initial, function(value, index) {\r\n if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {\r\n seen.push(value);\r\n results.push(array[index]);\r\n }\r\n });\r\n return results;\r\n };\r\n\r\n // Produce an array that contains the union: each distinct element from all of\r\n // the passed-in arrays.\r\n _.union = function() {\r\n return _.uniq(concat.apply(ArrayProto, arguments));\r\n };\r\n\r\n // Produce an array that contains every item shared between all the\r\n // passed-in arrays.\r\n _.intersection = function(array) {\r\n var rest = slice.call(arguments, 1);\r\n return _.filter(_.uniq(array), function(item) {\r\n return _.every(rest, function(other) {\r\n return _.indexOf(other, item) >= 0;\r\n });\r\n });\r\n };\r\n\r\n // Take the difference between one array and a number of other arrays.\r\n // Only the elements present in just the first array will remain.\r\n _.difference = function(array) {\r\n var rest = concat.apply(ArrayProto, slice.call(arguments, 1));\r\n return _.filter(array, function(value){ return !_.contains(rest, value); });\r\n };\r\n\r\n // Zip together multiple lists into a single array -- elements that share\r\n // an index go together.\r\n _.zip = function() {\r\n var args = slice.call(arguments);\r\n var length = _.max(_.pluck(args, 'length'));\r\n var results = new Array(length);\r\n for (var i = 0; i < length; i++) {\r\n results[i] = _.pluck(args, \"\" + i);\r\n }\r\n return results;\r\n };\r\n\r\n // Converts lists into objects. Pass either a single array of `[key, value]`\r\n // pairs, or two parallel arrays of the same length -- one of keys, and one of\r\n // the corresponding values.\r\n _.object = function(list, values) {\r\n if (list == null) return {};\r\n var result = {};\r\n for (var i = 0, l = list.length; i < l; i++) {\r\n if (values) {\r\n result[list[i]] = values[i];\r\n } else {\r\n result[list[i][0]] = list[i][1];\r\n }\r\n }\r\n return result;\r\n };\r\n\r\n // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),\r\n // we need this function. Return the position of the first occurrence of an\r\n // item in an array, or -1 if the item is not included in the array.\r\n // Delegates to **ECMAScript 5**'s native `indexOf` if available.\r\n // If the array is large and already in sort order, pass `true`\r\n // for **isSorted** to use binary search.\r\n _.indexOf = function(array, item, isSorted) {\r\n if (array == null) return -1;\r\n var i = 0, l = array.length;\r\n if (isSorted) {\r\n if (typeof isSorted == 'number') {\r\n i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);\r\n } else {\r\n i = _.sortedIndex(array, item);\r\n return array[i] === item ? i : -1;\r\n }\r\n }\r\n if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);\r\n for (; i < l; i++) if (array[i] === item) return i;\r\n return -1;\r\n };\r\n\r\n // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.\r\n _.lastIndexOf = function(array, item, from) {\r\n if (array == null) return -1;\r\n var hasIndex = from != null;\r\n if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {\r\n return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);\r\n }\r\n var i = (hasIndex ? from : array.length);\r\n while (i--) if (array[i] === item) return i;\r\n return -1;\r\n };\r\n\r\n // Generate an integer Array containing an arithmetic progression. A port of\r\n // the native Python `range()` function. See\r\n // [the Python documentation](http://docs.python.org/library/functions.html#range).\r\n _.range = function(start, stop, step) {\r\n if (arguments.length <= 1) {\r\n stop = start || 0;\r\n start = 0;\r\n }\r\n step = arguments[2] || 1;\r\n\r\n var len = Math.max(Math.ceil((stop - start) / step), 0);\r\n var idx = 0;\r\n var range = new Array(len);\r\n\r\n while(idx < len) {\r\n range[idx++] = start;\r\n start += step;\r\n }\r\n\r\n return range;\r\n };\r\n\r\n // Function (ahem) Functions\r\n // ------------------\r\n\r\n // Create a function bound to a given object (assigning `this`, and arguments,\r\n // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\r\n // available.\r\n _.bind = function(func, context) {\r\n if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\r\n var args = slice.call(arguments, 2);\r\n return function() {\r\n return func.apply(context, args.concat(slice.call(arguments)));\r\n };\r\n };\r\n\r\n // Partially apply a function by creating a version that has had some of its\r\n // arguments pre-filled, without changing its dynamic `this` context.\r\n _.partial = function(func) {\r\n var args = slice.call(arguments, 1);\r\n return function() {\r\n return func.apply(this, args.concat(slice.call(arguments)));\r\n };\r\n };\r\n\r\n // Bind all of an object's methods to that object. Useful for ensuring that\r\n // all callbacks defined on an object belong to it.\r\n _.bindAll = function(obj) {\r\n var funcs = slice.call(arguments, 1);\r\n if (funcs.length === 0) funcs = _.functions(obj);\r\n each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });\r\n return obj;\r\n };\r\n\r\n // Memoize an expensive function by storing its results.\r\n _.memoize = function(func, hasher) {\r\n var memo = {};\r\n hasher || (hasher = _.identity);\r\n return function() {\r\n var key = hasher.apply(this, arguments);\r\n return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));\r\n };\r\n };\r\n\r\n // Delays a function for the given number of milliseconds, and then calls\r\n // it with the arguments supplied.\r\n _.delay = function(func, wait) {\r\n var args = slice.call(arguments, 2);\r\n return setTimeout(function(){ return func.apply(null, args); }, wait);\r\n };\r\n\r\n // Defers a function, scheduling it to run after the current call stack has\r\n // cleared.\r\n _.defer = function(func) {\r\n return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));\r\n };\r\n\r\n // Returns a function, that, when invoked, will only be triggered at most once\r\n // during a given window of time.\r\n _.throttle = function(func, wait) {\r\n var context, args, timeout, result;\r\n var previous = 0;\r\n var later = function() {\r\n previous = new Date;\r\n timeout = null;\r\n result = func.apply(context, args);\r\n };\r\n return function() {\r\n var now = new Date;\r\n var remaining = wait - (now - previous);\r\n context = this;\r\n args = arguments;\r\n if (remaining <= 0) {\r\n clearTimeout(timeout);\r\n timeout = null;\r\n previous = now;\r\n result = func.apply(context, args);\r\n } else if (!timeout) {\r\n timeout = setTimeout(later, remaining);\r\n }\r\n return result;\r\n };\r\n };\r\n\r\n // Returns a function, that, as long as it continues to be invoked, will not\r\n // be triggered. The function will be called after it stops being called for\r\n // N milliseconds. If `immediate` is passed, trigger the function on the\r\n // leading edge, instead of the trailing.\r\n _.debounce = function(func, wait, immediate) {\r\n var timeout, result;\r\n return function() {\r\n var context = this, args = arguments;\r\n var later = function() {\r\n timeout = null;\r\n if (!immediate) result = func.apply(context, args);\r\n };\r\n var callNow = immediate && !timeout;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(later, wait);\r\n if (callNow) result = func.apply(context, args);\r\n return result;\r\n };\r\n };\r\n\r\n // Returns a function that will be executed at most one time, no matter how\r\n // often you call it. Useful for lazy initialization.\r\n _.once = function(func) {\r\n var ran = false, memo;\r\n return function() {\r\n if (ran) return memo;\r\n ran = true;\r\n memo = func.apply(this, arguments);\r\n func = null;\r\n return memo;\r\n };\r\n };\r\n\r\n // Returns the first function passed as an argument to the second,\r\n // allowing you to adjust arguments, run code before and after, and\r\n // conditionally execute the original function.\r\n _.wrap = function(func, wrapper) {\r\n return function() {\r\n var args = [func];\r\n push.apply(args, arguments);\r\n return wrapper.apply(this, args);\r\n };\r\n };\r\n\r\n // Returns a function that is the composition of a list of functions, each\r\n // consuming the return value of the function that follows.\r\n _.compose = function() {\r\n var funcs = arguments;\r\n return function() {\r\n var args = arguments;\r\n for (var i = funcs.length - 1; i >= 0; i--) {\r\n args = [funcs[i].apply(this, args)];\r\n }\r\n return args[0];\r\n };\r\n };\r\n\r\n // Returns a function that will only be executed after being called N times.\r\n _.after = function(times, func) {\r\n if (times <= 0) return func();\r\n return function() {\r\n if (--times < 1) {\r\n return func.apply(this, arguments);\r\n }\r\n };\r\n };\r\n\r\n // Object Functions\r\n // ----------------\r\n\r\n // Retrieve the names of an object's properties.\r\n // Delegates to **ECMAScript 5**'s native `Object.keys`\r\n _.keys = nativeKeys || function(obj) {\r\n if (obj !== Object(obj)) throw new TypeError('Invalid object');\r\n var keys = [];\r\n for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;\r\n return keys;\r\n };\r\n\r\n // Retrieve the values of an object's properties.\r\n _.values = function(obj) {\r\n var values = [];\r\n for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);\r\n return values;\r\n };\r\n\r\n // Convert an object into a list of `[key, value]` pairs.\r\n _.pairs = function(obj) {\r\n var pairs = [];\r\n for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);\r\n return pairs;\r\n };\r\n\r\n // Invert the keys and values of an object. The values must be serializable.\r\n _.invert = function(obj) {\r\n var result = {};\r\n for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;\r\n return result;\r\n };\r\n\r\n // Return a sorted list of the function names available on the object.\r\n // Aliased as `methods`\r\n _.functions = _.methods = function(obj) {\r\n var names = [];\r\n for (var key in obj) {\r\n if (_.isFunction(obj[key])) names.push(key);\r\n }\r\n return names.sort();\r\n };\r\n\r\n // Extend a given object with all the properties in passed-in object(s).\r\n _.extend = function(obj) {\r\n each(slice.call(arguments, 1), function(source) {\r\n if (source) {\r\n for (var prop in source) {\r\n obj[prop] = source[prop];\r\n }\r\n }\r\n });\r\n return obj;\r\n };\r\n\r\n // Return a copy of the object only containing the whitelisted properties.\r\n _.pick = function(obj) {\r\n var copy = {};\r\n var keys = concat.apply(ArrayProto, slice.call(arguments, 1));\r\n each(keys, function(key) {\r\n if (key in obj) copy[key] = obj[key];\r\n });\r\n return copy;\r\n };\r\n\r\n // Return a copy of the object without the blacklisted properties.\r\n _.omit = function(obj) {\r\n var copy = {};\r\n var keys = concat.apply(ArrayProto, slice.call(arguments, 1));\r\n for (var key in obj) {\r\n if (!_.contains(keys, key)) copy[key] = obj[key];\r\n }\r\n return copy;\r\n };\r\n\r\n // Fill in a given object with default properties.\r\n _.defaults = function(obj) {\r\n each(slice.call(arguments, 1), function(source) {\r\n if (source) {\r\n for (var prop in source) {\r\n if (obj[prop] == null) obj[prop] = source[prop];\r\n }\r\n }\r\n });\r\n return obj;\r\n };\r\n\r\n // Create a (shallow-cloned) duplicate of an object.\r\n _.clone = function(obj) {\r\n if (!_.isObject(obj)) return obj;\r\n return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\r\n };\r\n\r\n // Invokes interceptor with the obj, and then returns obj.\r\n // The primary purpose of this method is to \"tap into\" a method chain, in\r\n // order to perform operations on intermediate results within the chain.\r\n _.tap = function(obj, interceptor) {\r\n interceptor(obj);\r\n return obj;\r\n };\r\n\r\n // Internal recursive comparison function for `isEqual`.\r\n var eq = function(a, b, aStack, bStack) {\r\n // Identical objects are equal. `0 === -0`, but they aren't identical.\r\n // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.\r\n if (a === b) return a !== 0 || 1 / a == 1 / b;\r\n // A strict comparison is necessary because `null == undefined`.\r\n if (a == null || b == null) return a === b;\r\n // Unwrap any wrapped objects.\r\n if (a instanceof _) a = a._wrapped;\r\n if (b instanceof _) b = b._wrapped;\r\n // Compare `[[Class]]` names.\r\n var className = toString.call(a);\r\n if (className != toString.call(b)) return false;\r\n switch (className) {\r\n // Strings, numbers, dates, and booleans are compared by value.\r\n case '[object String]':\r\n // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\r\n // equivalent to `new String(\"5\")`.\r\n return a == String(b);\r\n case '[object Number]':\r\n // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\r\n // other numeric values.\r\n return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);\r\n case '[object Date]':\r\n case '[object Boolean]':\r\n // Coerce dates and booleans to numeric primitive values. Dates are compared by their\r\n // millisecond representations. Note that invalid dates with millisecond representations\r\n // of `NaN` are not equivalent.\r\n return +a == +b;\r\n // RegExps are compared by their source patterns and flags.\r\n case '[object RegExp]':\r\n return a.source == b.source &&\r\n a.global == b.global &&\r\n a.multiline == b.multiline &&\r\n a.ignoreCase == b.ignoreCase;\r\n }\r\n if (typeof a != 'object' || typeof b != 'object') return false;\r\n // Assume equality for cyclic structures. The algorithm for detecting cyclic\r\n // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\r\n var length = aStack.length;\r\n while (length--) {\r\n // Linear search. Performance is inversely proportional to the number of\r\n // unique nested structures.\r\n if (aStack[length] == a) return bStack[length] == b;\r\n }\r\n // Add the first object to the stack of traversed objects.\r\n aStack.push(a);\r\n bStack.push(b);\r\n var size = 0, result = true;\r\n // Recursively compare objects and arrays.\r\n if (className == '[object Array]') {\r\n // Compare array lengths to determine if a deep comparison is necessary.\r\n size = a.length;\r\n result = size == b.length;\r\n if (result) {\r\n // Deep compare the contents, ignoring non-numeric properties.\r\n while (size--) {\r\n if (!(result = eq(a[size], b[size], aStack, bStack))) break;\r\n }\r\n }\r\n } else {\r\n // Objects with different constructors are not equivalent, but `Object`s\r\n // from different frames are.\r\n var aCtor = a.constructor, bCtor = b.constructor;\r\n if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&\r\n _.isFunction(bCtor) && (bCtor instanceof bCtor))) {\r\n return false;\r\n }\r\n // Deep compare objects.\r\n for (var key in a) {\r\n if (_.has(a, key)) {\r\n // Count the expected number of properties.\r\n size++;\r\n // Deep compare each member.\r\n if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;\r\n }\r\n }\r\n // Ensure that both objects contain the same number of properties.\r\n if (result) {\r\n for (key in b) {\r\n if (_.has(b, key) && !(size--)) break;\r\n }\r\n result = !size;\r\n }\r\n }\r\n // Remove the first object from the stack of traversed objects.\r\n aStack.pop();\r\n bStack.pop();\r\n return result;\r\n };\r\n\r\n // Perform a deep comparison to check if two objects are equal.\r\n _.isEqual = function(a, b) {\r\n return eq(a, b, [], []);\r\n };\r\n\r\n // Is a given array, string, or object empty?\r\n // An \"empty\" object has no enumerable own-properties.\r\n _.isEmpty = function(obj) {\r\n if (obj == null) return true;\r\n if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;\r\n for (var key in obj) if (_.has(obj, key)) return false;\r\n return true;\r\n };\r\n\r\n // Is a given value a DOM element?\r\n _.isElement = function(obj) {\r\n return !!(obj && obj.nodeType === 1);\r\n };\r\n\r\n // Is a given value an array?\r\n // Delegates to ECMA5's native Array.isArray\r\n _.isArray = nativeIsArray || function(obj) {\r\n return toString.call(obj) == '[object Array]';\r\n };\r\n\r\n // Is a given variable an object?\r\n _.isObject = function(obj) {\r\n return obj === Object(obj);\r\n };\r\n\r\n // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.\r\n each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {\r\n _['is' + name] = function(obj) {\r\n return toString.call(obj) == '[object ' + name + ']';\r\n };\r\n });\r\n\r\n // Define a fallback version of the method in browsers (ahem, IE), where\r\n // there isn't any inspectable \"Arguments\" type.\r\n if (!_.isArguments(arguments)) {\r\n _.isArguments = function(obj) {\r\n return !!(obj && _.has(obj, 'callee'));\r\n };\r\n }\r\n\r\n // Optimize `isFunction` if appropriate.\r\n if (typeof (/./) !== 'function') {\r\n _.isFunction = function(obj) {\r\n return typeof obj === 'function';\r\n };\r\n }\r\n\r\n // Is a given object a finite number?\r\n _.isFinite = function(obj) {\r\n return isFinite(obj) && !isNaN(parseFloat(obj));\r\n };\r\n\r\n // Is the given value `NaN`? (NaN is the only number which does not equal itself).\r\n _.isNaN = function(obj) {\r\n return _.isNumber(obj) && obj != +obj;\r\n };\r\n\r\n // Is a given value a boolean?\r\n _.isBoolean = function(obj) {\r\n return obj === true || obj === false || toString.call(obj) == '[object Boolean]';\r\n };\r\n\r\n // Is a given value equal to null?\r\n _.isNull = function(obj) {\r\n return obj === null;\r\n };\r\n\r\n // Is a given variable undefined?\r\n _.isUndefined = function(obj) {\r\n return obj === void 0;\r\n };\r\n\r\n // Shortcut function for checking if an object has a given property directly\r\n // on itself (in other words, not on a prototype).\r\n _.has = function(obj, key) {\r\n return hasOwnProperty.call(obj, key);\r\n };\r\n\r\n // Utility Functions\r\n // -----------------\r\n\r\n // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\r\n // previous owner. Returns a reference to the Underscore object.\r\n _.noConflict = function() {\r\n root._ = previousUnderscore;\r\n return this;\r\n };\r\n\r\n // Keep the identity function around for default iterators.\r\n _.identity = function(value) {\r\n return value;\r\n };\r\n\r\n // Run a function **n** times.\r\n _.times = function(n, iterator, context) {\r\n var accum = Array(n);\r\n for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);\r\n return accum;\r\n };\r\n\r\n // Return a random integer between min and max (inclusive).\r\n _.random = function(min, max) {\r\n if (max == null) {\r\n max = min;\r\n min = 0;\r\n }\r\n return min + Math.floor(Math.random() * (max - min + 1));\r\n };\r\n\r\n // List of HTML entities for escaping.\r\n var entityMap = {\r\n escape: {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": ''',\r\n '/': '/'\r\n }\r\n };\r\n entityMap.unescape = _.invert(entityMap.escape);\r\n\r\n // Regexes containing the keys and values listed immediately above.\r\n var entityRegexes = {\r\n escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),\r\n unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')\r\n };\r\n\r\n // Functions for escaping and unescaping strings to/from HTML interpolation.\r\n _.each(['escape', 'unescape'], function(method) {\r\n _[method] = function(string) {\r\n if (string == null) return '';\r\n return ('' + string).replace(entityRegexes[method], function(match) {\r\n return entityMap[method][match];\r\n });\r\n };\r\n });\r\n\r\n // If the value of the named property is a function then invoke it;\r\n // otherwise, return it.\r\n _.result = function(object, property) {\r\n if (object == null) return null;\r\n var value = object[property];\r\n return _.isFunction(value) ? value.call(object) : value;\r\n };\r\n\r\n // Add your own custom functions to the Underscore object.\r\n _.mixin = function(obj) {\r\n each(_.functions(obj), function(name){\r\n var func = _[name] = obj[name];\r\n _.prototype[name] = function() {\r\n var args = [this._wrapped];\r\n push.apply(args, arguments);\r\n return result.call(this, func.apply(_, args));\r\n };\r\n });\r\n };\r\n\r\n // Generate a unique integer id (unique within the entire client session).\r\n // Useful for temporary DOM ids.\r\n var idCounter = 0;\r\n _.uniqueId = function(prefix) {\r\n var id = ++idCounter + '';\r\n return prefix ? prefix + id : id;\r\n };\r\n\r\n // By default, Underscore uses ERB-style template delimiters, change the\r\n // following template settings to use alternative delimiters.\r\n _.templateSettings = {\r\n evaluate : /<%([\\s\\S]+?)%>/g,\r\n interpolate : /<%=([\\s\\S]+?)%>/g,\r\n escape : /<%-([\\s\\S]+?)%>/g\r\n };\r\n\r\n // When customizing `templateSettings`, if you don't want to define an\r\n // interpolation, evaluation or escaping regex, we need one that is\r\n // guaranteed not to match.\r\n var noMatch = /(.)^/;\r\n\r\n // Certain characters need to be escaped so that they can be put into a\r\n // string literal.\r\n var escapes = {\r\n \"'\": \"'\",\r\n '\\\\': '\\\\',\r\n '\\r': 'r',\r\n '\\n': 'n',\r\n '\\t': 't',\r\n '\\u2028': 'u2028',\r\n '\\u2029': 'u2029'\r\n };\r\n\r\n var escaper = /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;\r\n\r\n // JavaScript micro-templating, similar to John Resig's implementation.\r\n // Underscore templating handles arbitrary delimiters, preserves whitespace,\r\n // and correctly escapes quotes within interpolated code.\r\n _.template = function(text, data, settings) {\r\n var render;\r\n settings = _.defaults({}, settings, _.templateSettings);\r\n\r\n // Combine delimiters into one regular expression via alternation.\r\n var matcher = new RegExp([\r\n (settings.escape || noMatch).source,\r\n (settings.interpolate || noMatch).source,\r\n (settings.evaluate || noMatch).source\r\n ].join('|') + '|$', 'g');\r\n\r\n // Compile the template source, escaping string literals appropriately.\r\n var index = 0;\r\n var source = \"__p+='\";\r\n text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\r\n source += text.slice(index, offset)\r\n .replace(escaper, function(match) { return '\\\\' + escapes[match]; });\r\n\r\n if (escape) {\r\n source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\r\n }\r\n if (interpolate) {\r\n source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\r\n }\r\n if (evaluate) {\r\n source += \"';\\n\" + evaluate + \"\\n__p+='\";\r\n }\r\n index = offset + match.length;\r\n return match;\r\n });\r\n source += \"';\\n\";\r\n\r\n // If a variable is not specified, place data values in local scope.\r\n if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\r\n\r\n source = \"var __t,__p='',__j=Array.prototype.join,\" +\r\n \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\r\n source + \"return __p;\\n\";\r\n\r\n try {\r\n render = new Function(settings.variable || 'obj', '_', source);\r\n } catch (e) {\r\n e.source = source;\r\n throw e;\r\n }\r\n\r\n if (data) return render(data, _);\r\n var template = function(data) {\r\n return render.call(this, data, _);\r\n };\r\n\r\n // Provide the compiled function source as a convenience for precompilation.\r\n template.source = 'function(' + (settings.variable || 'obj') + '){\\n' + source + '}';\r\n\r\n return template;\r\n };\r\n\r\n // Add a \"chain\" function, which will delegate to the wrapper.\r\n _.chain = function(obj) {\r\n return _(obj).chain();\r\n };\r\n\r\n // OOP\r\n // ---------------\r\n // If Underscore is called as a function, it returns a wrapped object that\r\n // can be used OO-style. This wrapper holds altered versions of all the\r\n // underscore functions. Wrapped objects may be chained.\r\n\r\n // Helper function to continue chaining intermediate results.\r\n var result = function(obj) {\r\n return this._chain ? _(obj).chain() : obj;\r\n };\r\n\r\n // Add all of the Underscore functions to the wrapper object.\r\n _.mixin(_);\r\n\r\n // Add all mutator Array functions to the wrapper.\r\n each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\r\n var method = ArrayProto[name];\r\n _.prototype[name] = function() {\r\n var obj = this._wrapped;\r\n method.apply(obj, arguments);\r\n if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];\r\n return result.call(this, obj);\r\n };\r\n });\r\n\r\n // Add all accessor Array functions to the wrapper.\r\n each(['concat', 'join', 'slice'], function(name) {\r\n var method = ArrayProto[name];\r\n _.prototype[name] = function() {\r\n return result.call(this, method.apply(this._wrapped, arguments));\r\n };\r\n });\r\n\r\n _.extend(_.prototype, {\r\n\r\n // Start chaining a wrapped Underscore object.\r\n chain: function() {\r\n this._chain = true;\r\n return this;\r\n },\r\n\r\n // Extracts the result from a wrapped and chained object.\r\n value: function() {\r\n return this._wrapped;\r\n }\r\n\r\n });\r\n\r\n}).call(this);\r\n\r\n//PLACEHOLDER\r\n/*! http://mths.be/placeholder v2.0.7 by @mathias */\r\n;(function(window, document, $) {\r\n\r\n\tvar isInputSupported = 'placeholder' in document.createElement('input'),\r\n\t isTextareaSupported = 'placeholder' in document.createElement('textarea'),\r\n\t prototype = $.fn,\r\n\t valHooks = $.valHooks,\r\n\t hooks,\r\n\t placeholder;\r\n\r\n\tif (isInputSupported && isTextareaSupported) {\r\n\r\n\t\tplaceholder = prototype.placeholder = function() {\r\n\t\t\treturn this;\r\n\t\t};\r\n\r\n\t\tplaceholder.input = placeholder.textarea = true;\r\n\r\n\t} else {\r\n\r\n\t\tplaceholder = prototype.placeholder = function() {\r\n\t\t\tvar $this = this;\r\n\t\t\t$this\r\n\t\t\t\t.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')\r\n\t\t\t\t.not('.placeholder')\r\n\t\t\t\t.bind({\r\n\t\t\t\t\t'focus.placeholder': clearPlaceholder,\r\n\t\t\t\t\t'blur.placeholder': setPlaceholder\r\n\t\t\t\t})\r\n\t\t\t\t.data('placeholder-enabled', true)\r\n\t\t\t\t.trigger('blur.placeholder');\r\n\t\t\treturn $this;\r\n\t\t};\r\n\r\n\t\tplaceholder.input = isInputSupported;\r\n\t\tplaceholder.textarea = isTextareaSupported;\r\n\r\n\t\thooks = {\r\n\t\t\t'get': function(element) {\r\n\t\t\t\tvar $element = $(element);\r\n\t\t\t\treturn $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;\r\n\t\t\t},\r\n\t\t\t'set': function(element, value) {\r\n\t\t\t\tvar $element = $(element);\r\n\t\t\t\tif (!$element.data('placeholder-enabled')) {\r\n\t\t\t\t\treturn element.value = value;\r\n\t\t\t\t}\r\n\t\t\t\tif (value == '') {\r\n\t\t\t\t\telement.value = value;\r\n\t\t\t\t\t// Issue #56: Setting the placeholder causes problems if the element continues to have focus.\r\n\t\t\t\t\tif (element != document.activeElement) {\r\n\t\t\t\t\t\t// We can't use `triggerHandler` here because of dummy text/password inputs :(\r\n\t\t\t\t\t\tsetPlaceholder.call(element);\r\n\t\t\t\t\t}\r\n\t\t\t\t} else if ($element.hasClass('placeholder')) {\r\n\t\t\t\t\tclearPlaceholder.call(element, true, value) || (element.value = value);\r\n\t\t\t\t} else {\r\n\t\t\t\t\telement.value = value;\r\n\t\t\t\t}\r\n\t\t\t\t// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363\r\n\t\t\t\treturn $element;\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tisInputSupported || (valHooks.input = hooks);\r\n\t\tisTextareaSupported || (valHooks.textarea = hooks);\r\n\r\n\t\t$(function() {\r\n\t\t\t// Look for forms\r\n\t\t\t$(document).delegate('form', 'submit.placeholder', function() {\r\n\t\t\t\t// Clear the placeholder values so they don't get submitted\r\n\t\t\t\tvar $inputs = $('.placeholder', this).each(clearPlaceholder);\r\n\t\t\t\tsetTimeout(function() {\r\n\t\t\t\t\t$inputs.each(setPlaceholder);\r\n\t\t\t\t}, 10);\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// Clear placeholder values upon page reload\r\n\t\t$(window).bind('beforeunload.placeholder', function() {\r\n\t\t\t$('.placeholder').each(function() {\r\n\t\t\t\tthis.value = '';\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t}\r\n\r\n\tfunction args(elem) {\r\n\t\t// Return an object of element attributes\r\n\t\tvar newAttrs = {},\r\n\t\t rinlinejQuery = /^jQuery\\d+$/;\r\n\t\t$.each(elem.attributes, function(i, attr) {\r\n\t\t\tif (attr.specified && !rinlinejQuery.test(attr.name)) {\r\n\t\t\t\tnewAttrs[attr.name] = attr.value;\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn newAttrs;\r\n\t}\r\n\r\n\tfunction clearPlaceholder(event, value) {\r\n\t\tvar input = this,\r\n\t\t $input = $(input);\r\n\t\tif (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {\r\n\t\t\tif ($input.data('placeholder-password')) {\r\n\t\t\t\t$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));\r\n\t\t\t\t// If `clearPlaceholder` was called from `$.valHooks.input.set`\r\n\t\t\t\tif (event === true) {\r\n\t\t\t\t\treturn $input[0].value = value;\r\n\t\t\t\t}\r\n\t\t\t\t$input.focus();\r\n\t\t\t} else {\r\n\t\t\t\tinput.value = '';\r\n\t\t\t\t$input.removeClass('placeholder');\r\n\t\t\t\tinput == document.activeElement && input.select();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfunction setPlaceholder() {\r\n\t\tvar $replacement,\r\n\t\t input = this,\r\n\t\t $input = $(input),\r\n\t\t $origInput = $input,\r\n\t\t id = this.id;\r\n\t\tif (input.value == '') {\r\n\t\t\tif (input.type == 'password') {\r\n\t\t\t\tif (!$input.data('placeholder-textinput')) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\t$replacement = $input.clone().attr({ 'type': 'text' });\r\n\t\t\t\t\t} catch(e) {\r\n\t\t\t\t\t\t$replacement = $('
').attr($.extend(args(this), { 'type': 'text' }));\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$replacement\r\n\t\t\t\t\t\t.removeAttr('name')\r\n\t\t\t\t\t\t.data({\r\n\t\t\t\t\t\t\t'placeholder-password': true,\r\n\t\t\t\t\t\t\t'placeholder-id': id\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\t.bind('focus.placeholder', clearPlaceholder);\r\n\t\t\t\t\t$input\r\n\t\t\t\t\t\t.data({\r\n\t\t\t\t\t\t\t'placeholder-textinput': $replacement,\r\n\t\t\t\t\t\t\t'placeholder-id': id\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\t.before($replacement);\r\n\t\t\t\t}\r\n\t\t\t\t$input = $input.removeAttr('id').hide().prev().attr('id', id).show();\r\n\t\t\t\t// Note: `$input[0] != input` now!\r\n\t\t\t}\r\n\t\t\t$input.addClass('placeholder');\r\n\t\t\t$input[0].value = $input.attr('placeholder');\r\n\t\t} else {\r\n\t\t\t$input.removeClass('placeholder');\r\n\t\t}\r\n\t}\r\n\r\n}(this, document, jQuery));\r\n\r\n// ColorBox v1.3.20.2 - jQuery lightbox plugin\r\n// (c) 2012 Jack Moore - jacklmoore.com\r\n// License: http://www.opensource.org/licenses/mit-license.php\r\n(function ($, document, window) {\r\n\tvar\r\n\t// Default settings object.\r\n\t// See http://jacklmoore.com/colorbox for details.\r\n\tdefaults = {\r\n\t\ttransition: \"elastic\",\r\n\t\tspeed: 300,\r\n\t\twidth: false,\r\n\t\tinitialWidth: \"600\",\r\n\t\tinnerWidth: false,\r\n\t\tmaxWidth: false,\r\n\t\theight: false,\r\n\t\tinitialHeight: \"450\",\r\n\t\tinnerHeight: false,\r\n\t\tmaxHeight: false,\r\n\t\tscalePhotos: true,\r\n\t\tscrolling: true,\r\n\t\tinline: false,\r\n\t\thtml: false,\r\n\t\tiframe: false,\r\n\t\tfastIframe: true,\r\n\t\tphoto: false,\r\n\t\thref: false,\r\n\t\ttitle: false,\r\n\t\trel: false,\r\n\t\topacity: 0.9,\r\n\t\tpreloading: true,\r\n\r\n\t\tcurrent: \"image {current} of {total}\",\r\n\t\tprevious: \"previous\",\r\n\t\tnext: \"next\",\r\n\t\tclose: \"close\",\r\n\t\txhrError: \"This content failed to load.\",\r\n\t\timgError: \"This image failed to load.\",\r\n\r\n\t\topen: false,\r\n\t\treturnFocus: true,\r\n\t\treposition: true,\r\n\t\tloop: true,\r\n\t\tslideshow: false,\r\n\t\tslideshowAuto: true,\r\n\t\tslideshowSpeed: 2500,\r\n\t\tslideshowStart: \"start slideshow\",\r\n\t\tslideshowStop: \"stop slideshow\",\r\n\t\tonOpen: false,\r\n\t\tonLoad: false,\r\n\t\tonComplete: false,\r\n\t\tonCleanup: false,\r\n\t\tonClosed: false,\r\n\t\toverlayClose: true,\r\n\t\tescKey: true,\r\n\t\tarrowKey: true,\r\n\t\ttop: false,\r\n\t\tbottom: false,\r\n\t\tleft: false,\r\n\t\tright: false,\r\n\t\tfixed: false,\r\n\t\tdata: undefined\r\n\t},\r\n\r\n\t// Abstracting the HTML and event identifiers for easy rebranding\r\n\tcolorbox = 'colorbox',\r\n\tprefix = 'cbox',\r\n\tboxElement = prefix + 'Element',\r\n\r\n\t// Events\r\n\tevent_open = prefix + '_open',\r\n\tevent_load = prefix + '_load',\r\n\tevent_complete = prefix + '_complete',\r\n\tevent_cleanup = prefix + '_cleanup',\r\n\tevent_closed = prefix + '_closed',\r\n\tevent_purge = prefix + '_purge',\r\n\r\n\t// Special Handling for IE\r\n\tisIE = !$.support.opacity && !$.support.style, // IE7 & IE8\r\n\tisIE6 = isIE && !window.XMLHttpRequest, // IE6\r\n\tevent_ie6 = prefix + '_IE6',\r\n\r\n\t// Cached jQuery Object Variables\r\n\t$overlay,\r\n\t$box,\r\n\t$wrap,\r\n\t$content,\r\n\t$topBorder,\r\n\t$leftBorder,\r\n\t$rightBorder,\r\n\t$bottomBorder,\r\n\t$related,\r\n\t$window,\r\n\t$loaded,\r\n\t$loadingBay,\r\n\t$loadingOverlay,\r\n\t$title,\r\n\t$current,\r\n\t$slideshow,\r\n\t$next,\r\n\t$prev,\r\n\t$close,\r\n\t$groupControls,\r\n\r\n\t// Variables for cached values or use across multiple functions\r\n\tsettings,\r\n\tinterfaceHeight,\r\n\tinterfaceWidth,\r\n\tloadedHeight,\r\n\tloadedWidth,\r\n\telement,\r\n\tindex,\r\n\tphoto,\r\n\topen,\r\n\tactive,\r\n\tclosing,\r\n\tloadingTimer,\r\n\tpublicMethod,\r\n\tdiv = \"div\",\r\n\tinit;\r\n\r\n\t// ****************\r\n\t// HELPER FUNCTIONS\r\n\t// ****************\r\n\r\n\t// Convience function for creating new jQuery objects\r\n\tfunction $tag(tag, id, css) {\r\n\t\tvar element = document.createElement(tag);\r\n\r\n\t\tif (id) {\r\n\t\t\telement.id = prefix + id;\r\n\t\t}\r\n\r\n\t\tif (css) {\r\n\t\t\telement.style.cssText = css;\r\n\t\t}\r\n\r\n\t\treturn $(element);\r\n\t}\r\n\r\n\t// Determine the next and previous members in a group.\r\n\tfunction getIndex(increment) {\r\n\t\tvar\r\n\t\tmax = $related.length,\r\n\t\tnewIndex = (index + increment) % max;\r\n\r\n\t\treturn (newIndex < 0) ? max + newIndex : newIndex;\r\n\t}\r\n\r\n\t// Convert '%' and 'px' values to integers\r\n\tfunction setSize(size, dimension) {\r\n\t\treturn Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : $window.height()) / 100) : 1) * parseInt(size, 10));\r\n\t}\r\n\r\n\t// Checks an href to see if it is a photo.\r\n\t// There is a force photo option (photo: true) for hrefs that cannot be matched by this regex.\r\n\tfunction isImage(url) {\r\n\t\treturn settings.photo || /\\.(gif|png|jp(e|g|eg)|bmp|ico)((#|\\?).*)?$/i.test(url);\r\n\t}\r\n\r\n\t// Assigns function results to their respective properties\r\n\tfunction makeSettings() {\r\n\t\tvar i,\r\n\t\t\tdata = $.data(element, colorbox);\r\n\r\n\t\tif (data == null) {\r\n\t\t\tsettings = $.extend({}, defaults);\r\n\t\t\tif (console && console.log) {\r\n\t\t\t\tconsole.log('Error: cboxElement missing settings object');\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tsettings = $.extend({}, data);\r\n\t\t}\r\n\r\n\t\tfor (i in settings) {\r\n\t\t\tif ($.isFunction(settings[i]) && i.slice(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.\r\n\t\t\t\tsettings[i] = settings[i].call(element);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tsettings.rel = settings.rel || element.rel || $(element).data('rel') || 'nofollow';\r\n\t\tsettings.href = settings.href || $(element).attr('href');\r\n\t\tsettings.title = settings.title || element.title;\r\n\r\n\t\tif (typeof settings.href === \"string\") {\r\n\t\t\tsettings.href = $.trim(settings.href);\r\n\t\t}\r\n\t}\r\n\r\n\tfunction trigger(event, callback) {\r\n\t\t$.event.trigger(event);\r\n\t\tif (callback) {\r\n\t\t\tcallback.call(element);\r\n\t\t}\r\n\t}\r\n\r\n\t// Slideshow functionality\r\n\tfunction slideshow() {\r\n\t\tvar\r\n\t\ttimeOut,\r\n\t\tclassName = prefix + \"Slideshow_\",\r\n\t\tclick = \"click.\" + prefix,\r\n\t\tstart,\r\n\t\tstop;\r\n\r\n\t\tif (settings.slideshow && $related[1]) {\r\n\t\t\tstart = function () {\r\n\t\t\t\t$slideshow\r\n\t\t\t\t\t.html(settings.slideshowStop)\r\n\t\t\t\t\t.unbind(click)\r\n\t\t\t\t\t.bind(event_complete, function () {\r\n\t\t\t\t\t\tif (settings.loop || $related[index + 1]) {\r\n\t\t\t\t\t\t\ttimeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.bind(event_load, function () {\r\n\t\t\t\t\t\tclearTimeout(timeOut);\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.one(click + ' ' + event_cleanup, stop);\r\n\t\t\t\t$box.removeClass(className + \"off\").addClass(className + \"on\");\r\n\t\t\t\ttimeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);\r\n\t\t\t};\r\n\r\n\t\t\tstop = function () {\r\n\t\t\t\tclearTimeout(timeOut);\r\n\t\t\t\t$slideshow\r\n\t\t\t\t\t.html(settings.slideshowStart)\r\n\t\t\t\t\t.unbind([event_complete, event_load, event_cleanup, click].join(' '))\r\n\t\t\t\t\t.one(click, function () {\r\n\t\t\t\t\t\tpublicMethod.next();\r\n\t\t\t\t\t\tstart();\r\n\t\t\t\t\t});\r\n\t\t\t\t$box.removeClass(className + \"on\").addClass(className + \"off\");\r\n\t\t\t};\r\n\r\n\t\t\tif (settings.slideshowAuto) {\r\n\t\t\t\tstart();\r\n\t\t\t} else {\r\n\t\t\t\tstop();\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t$box.removeClass(className + \"off \" + className + \"on\");\r\n\t\t}\r\n\t}\r\n\r\n\tfunction launch(target) {\r\n\t\tif (!closing) {\r\n\r\n\t\t\telement = target;\r\n\r\n\t\t\tmakeSettings();\r\n\r\n\t\t\t$related = $(element);\r\n\r\n\t\t\tindex = 0;\r\n\r\n\t\t\tif (settings.rel !== 'nofollow') {\r\n\t\t\t\t$related = $('.' + boxElement).filter(function () {\r\n\t\t\t\t\tvar data = $.data(this, colorbox),\r\n\t\t\t\t\t\trelRelated;\r\n\r\n\t\t\t\t\tif (data) {\r\n\t\t\t\t\t\trelRelated = $(this).data('rel') || data.rel || this.rel;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn (relRelated === settings.rel);\r\n\t\t\t\t});\r\n\t\t\t\tindex = $related.index(element);\r\n\r\n\t\t\t\t// Check direct calls to ColorBox.\r\n\t\t\t\tif (index === -1) {\r\n\t\t\t\t\t$related = $related.add(element);\r\n\t\t\t\t\tindex = $related.length - 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (!open) {\r\n\t\t\t\topen = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.\r\n\r\n\t\t\t\t$box.show();\r\n\r\n\t\t\t\tif (settings.returnFocus) {\r\n\t\t\t\t\t$(element).blur().one(event_closed, function () {\r\n\t\t\t\t\t\t$(this).focus();\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5'\r\n\t\t\t\t$overlay.css({\"opacity\": +settings.opacity, \"cursor\": settings.overlayClose ? \"pointer\" : \"auto\"}).show();\r\n\r\n\t\t\t\t// Opens inital empty ColorBox prior to content being loaded.\r\n\t\t\t\tsettings.w = setSize(settings.initialWidth, 'x');\r\n\t\t\t\tsettings.h = setSize(settings.initialHeight, 'y');\r\n\t\t\t\tpublicMethod.position();\r\n\r\n\t\t\t\tif (isIE6) {\r\n\t\t\t\t\t$window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () {\r\n\t\t\t\t\t\t$overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()});\r\n\t\t\t\t\t}).trigger('resize.' + event_ie6);\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttrigger(event_open, settings.onOpen);\r\n\r\n\t\t\t\t$groupControls.add($title).hide();\r\n\r\n\t\t\t\t$close.html(settings.close).show();\r\n\t\t\t}\r\n\r\n\t\t\tpublicMethod.load(true);\r\n\t\t}\r\n\t}\r\n\r\n\t// ColorBox's markup needs to be added to the DOM prior to being called\r\n\t// so that the browser will go ahead and load the CSS background images.\r\n\tfunction appendHTML() {\r\n\t\tif (!$box && document.body) {\r\n\t\t\tinit = false;\r\n\r\n\t\t\t$window = $(window);\r\n\t\t\t$box = $tag(div).attr({id: colorbox, 'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : ''}).hide();\r\n\t\t\t$overlay = $tag(div, \"Overlay\", isIE6 ? 'position:absolute' : '').hide();\r\n\t\t\t$loadingOverlay = $tag(div, \"LoadingOverlay\").add($tag(div, \"LoadingGraphic\"));\r\n\t\t\t$wrap = $tag(div, \"Wrapper\");\r\n\t\t\t$content = $tag(div, \"Content\").append(\r\n\t\t\t\t$loaded = $tag(div, \"LoadedContent\", 'width:0; height:0; overflow:hidden'),\r\n\t\t\t\t$title = $tag(div, \"Title\"),\r\n\t\t\t\t$current = $tag(div, \"Current\"),\r\n\t\t\t\t$next = $tag(div, \"Next\"),\r\n\t\t\t\t$prev = $tag(div, \"Previous\"),\r\n\t\t\t\t$slideshow = $tag(div, \"Slideshow\").bind(event_open, slideshow),\r\n\t\t\t\t$close = $tag(div, \"Close\")\r\n\t\t\t);\r\n\r\n\t\t\t$wrap.append( // The 3x3 Grid that makes up ColorBox\r\n\t\t\t\t$tag(div).append(\r\n\t\t\t\t\t$tag(div, \"TopLeft\"),\r\n\t\t\t\t\t$topBorder = $tag(div, \"TopCenter\"),\r\n\t\t\t\t\t$tag(div, \"TopRight\")\r\n\t\t\t\t),\r\n\t\t\t\t$tag(div, false, 'clear:left').append(\r\n\t\t\t\t\t$leftBorder = $tag(div, \"MiddleLeft\"),\r\n\t\t\t\t\t$content,\r\n\t\t\t\t\t$rightBorder = $tag(div, \"MiddleRight\")\r\n\t\t\t\t),\r\n\t\t\t\t$tag(div, false, 'clear:left').append(\r\n\t\t\t\t\t$tag(div, \"BottomLeft\"),\r\n\t\t\t\t\t$bottomBorder = $tag(div, \"BottomCenter\"),\r\n\t\t\t\t\t$tag(div, \"BottomRight\")\r\n\t\t\t\t)\r\n\t\t\t).find('div div').css({'float': 'left'});\r\n\r\n\t\t\t$loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');\r\n\r\n\t\t\t$groupControls = $next.add($prev).add($current).add($slideshow);\r\n\r\n\t\t\t$(document.body).append($overlay, $box.append($wrap, $loadingBay));\r\n\t\t}\r\n\t}\r\n\r\n\t// Add ColorBox's event bindings\r\n\tfunction addBindings() {\r\n\t\tif ($box) {\r\n\t\t\tif (!init) {\r\n\t\t\t\tinit = true;\r\n\r\n\t\t\t\t// Cache values needed for size calculations\r\n\t\t\t\tinterfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6\r\n\t\t\t\tinterfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();\r\n\t\t\t\tloadedHeight = $loaded.outerHeight(true);\r\n\t\t\t\tloadedWidth = $loaded.outerWidth(true);\r\n\r\n\t\t\t\t// Setting padding to remove the need to do size conversions during the animation step.\r\n\t\t\t\t$box.css({\"padding-bottom\": interfaceHeight, \"padding-right\": interfaceWidth});\r\n\r\n\t\t\t\t// Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.\r\n\t\t\t\t$next.click(function () {\r\n\t\t\t\t\tpublicMethod.next();\r\n\t\t\t\t});\r\n\t\t\t\t$prev.click(function () {\r\n\t\t\t\t\tpublicMethod.prev();\r\n\t\t\t\t});\r\n\t\t\t\t$close.click(function () {\r\n\t\t\t\t\tpublicMethod.close();\r\n\t\t\t\t});\r\n\t\t\t\t$overlay.click(function () {\r\n\t\t\t\t\tif (settings.overlayClose) {\r\n\t\t\t\t\t\tpublicMethod.close();\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// Key Bindings\r\n\t\t\t\t$(document).bind('keydown.' + prefix, function (e) {\r\n\t\t\t\t\tvar key = e.keyCode;\r\n\t\t\t\t\tif (open && settings.escKey && key === 27) {\r\n\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\tpublicMethod.close();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (open && settings.arrowKey && $related[1]) {\r\n\t\t\t\t\t\tif (key === 37) {\r\n\t\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\t\t$prev.click();\r\n\t\t\t\t\t\t} else if (key === 39) {\r\n\t\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\t\t$next.click();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$(document).delegate('.'+boxElement, 'click', function(e) {\r\n\t\t\t\t\t// ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.\r\n\t\t\t\t\t// See: http://jacklmoore.com/notes/click-events/\r\n\t\t\t\t\tif (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey)) {\r\n\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\tlaunch(this);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Don't do anything if ColorBox already exists.\r\n\tif ($.colorbox) {\r\n\t\treturn;\r\n\t}\r\n\r\n\t// Append the HTML when the DOM loads\r\n\t$(appendHTML);\r\n\r\n\r\n\t// ****************\r\n\t// PUBLIC FUNCTIONS\r\n\t// Usage format: $.fn.colorbox.close();\r\n\t// Usage from within an iframe: parent.$.fn.colorbox.close();\r\n\t// ****************\r\n\r\n\tpublicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {\r\n\t\tvar $this = this;\r\n\r\n\t\toptions = options || {};\r\n\r\n\t\tappendHTML();\r\n\r\n\t\tif (addBindings()) {\r\n\t\t\tif (!$this[0]) {\r\n\t\t\t\tif ($this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit.\r\n\t\t\t\t\treturn $this;\r\n\t\t\t\t}\r\n\t\t\t\t// if no selector was given (ie. $.colorbox()), create a temporary element to work with\r\n\t\t\t\t$this = $('
');\r\n\t\t\t\toptions.open = true; // assume an immediate open\r\n\t\t\t}\r\n\r\n\t\t\tif (callback) {\r\n\t\t\t\toptions.onComplete = callback;\r\n\t\t\t}\r\n\r\n\t\t\t$this.each(function () {\r\n\t\t\t\t$.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));\r\n\t\t\t}).addClass(boxElement);\r\n\r\n\t\t\tif (($.isFunction(options.open) && options.open.call($this)) || options.open) {\r\n\t\t\t\tlaunch($this[0]);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn $this;\r\n\t};\r\n\r\n\tpublicMethod.position = function (speed, loadedCallback) {\r\n\t\tvar\r\n\t\tcss,\r\n\t\ttop = 0,\r\n\t\tleft = 0,\r\n\t\toffset = $box.offset(),\r\n\t\tscrollTop,\r\n\t\tscrollLeft;\r\n\r\n\t\t$window.unbind('resize.' + prefix);\r\n\r\n\t\t// remove the modal so that it doesn't influence the document width/height\r\n\t\t$box.css({top: -9e4, left: -9e4});\r\n\r\n\t\tscrollTop = $window.scrollTop();\r\n\t\tscrollLeft = $window.scrollLeft();\r\n\r\n\t\tif (settings.fixed && !isIE6) {\r\n\t\t\toffset.top -= scrollTop;\r\n\t\t\toffset.left -= scrollLeft;\r\n\t\t\t$box.css({position: 'fixed'});\r\n\t\t} else {\r\n\t\t\ttop = scrollTop;\r\n\t\t\tleft = scrollLeft;\r\n\t\t\t$box.css({position: 'absolute'});\r\n\t\t}\r\n\r\n\t\t// keeps the top and left positions within the browser's viewport.\r\n\t\tif (settings.right !== false) {\r\n\t\t\tleft += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0);\r\n\t\t} else if (settings.left !== false) {\r\n\t\t\tleft += setSize(settings.left, 'x');\r\n\t\t} else {\r\n\t\t\tleft += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2);\r\n\t\t}\r\n\r\n\t\tif (settings.bottom !== false) {\r\n\t\t\ttop += Math.max($window.height() - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0);\r\n\t\t} else if (settings.top !== false) {\r\n\t\t\ttop += setSize(settings.top, 'y');\r\n\t\t} else {\r\n\t\t\ttop += Math.round(Math.max($window.height() - settings.h - loadedHeight - interfaceHeight, 0) / 2);\r\n\t\t}\r\n\r\n\t\t$box.css({top: offset.top, left: offset.left});\r\n\r\n\t\t// setting the speed to 0 to reduce the delay between same-sized content.\r\n\t\tspeed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed || 0;\r\n\r\n\t\t// this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,\r\n\t\t// but it has to be shrank down around the size of div#colorbox when it's done. If not,\r\n\t\t// it can invoke an obscure IE bug when using iframes.\r\n\t\t$wrap[0].style.width = $wrap[0].style.height = \"9999px\";\r\n\r\n\t\tfunction modalDimensions(that) {\r\n\t\t\t$topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width;\r\n\t\t\t$content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height;\r\n\t\t}\r\n\r\n\t\tcss = {width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: top, left: left};\r\n\t\tif(speed===0){ // temporary workaround to side-step jQuery-UI 1.8 bug (http://bugs.jquery.com/ticket/12273)\r\n\t\t\t$box.css(css);\r\n\t\t}\r\n\t\t$box.dequeue().animate(css, {\r\n\t\t\tduration: speed,\r\n\t\t\tcomplete: function () {\r\n\t\t\t\tmodalDimensions(this);\r\n\r\n\t\t\t\tactive = false;\r\n\r\n\t\t\t\t// shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.\r\n\t\t\t\t$wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + \"px\";\r\n\t\t\t\t$wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + \"px\";\r\n\r\n\t\t\t\tif (settings.reposition) {\r\n\t\t\t\t\tsetTimeout(function () { // small delay before binding onresize due to an IE8 bug.\r\n\t\t\t\t\t\t$window.bind('resize.' + prefix, publicMethod.position);\r\n\t\t\t\t\t}, 1);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (loadedCallback) {\r\n\t\t\t\t\tloadedCallback();\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tstep: function () {\r\n\t\t\t\tmodalDimensions(this);\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\tpublicMethod.resize = function (options) {\r\n\t\tif (open) {\r\n\t\t\toptions = options || {};\r\n\r\n\t\t\tif (options.width) {\r\n\t\t\t\tsettings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;\r\n\t\t\t}\r\n\t\t\tif (options.innerWidth) {\r\n\t\t\t\tsettings.w = setSize(options.innerWidth, 'x');\r\n\t\t\t}\r\n\t\t\t$loaded.css({width: settings.w});\r\n\r\n\t\t\tif (options.height) {\r\n\t\t\t\tsettings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;\r\n\t\t\t}\r\n\t\t\tif (options.innerHeight) {\r\n\t\t\t\tsettings.h = setSize(options.innerHeight, 'y');\r\n\t\t\t}\r\n\t\t\tif (!options.innerHeight && !options.height) {\r\n\t\t\t\t$loaded.css({height: \"auto\"});\r\n\t\t\t\tsettings.h = $loaded.height();\r\n\t\t\t}\r\n\t\t\t$loaded.css({height: settings.h});\r\n\r\n\t\t\tpublicMethod.position(settings.transition === \"none\" ? 0 : settings.speed);\r\n\t\t}\r\n\t};\r\n\r\n\tpublicMethod.prep = function (object) {\r\n\t\tif (!open) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar callback, speed = settings.transition === \"none\" ? 0 : settings.speed;\r\n\r\n\t\t$loaded.remove();\r\n\t\t$loaded = $tag(div, 'LoadedContent').append(object);\r\n\r\n\t\tfunction getWidth() {\r\n\t\t\tsettings.w = settings.w || $loaded.width();\r\n\t\t\tsettings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;\r\n\t\t\treturn settings.w;\r\n\t\t}\r\n\t\tfunction getHeight() {\r\n\t\t\tsettings.h = settings.h || $loaded.height();\r\n\t\t\tsettings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;\r\n\t\t\treturn settings.h;\r\n\t\t}\r\n\r\n\t\t$loaded.hide()\r\n\t\t.appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.\r\n\t\t.css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'})\r\n\t\t.css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.\r\n\t\t.prependTo($content);\r\n\r\n\t\t$loadingBay.hide();\r\n\r\n\t\t// floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.\r\n\t\t//$(photo).css({'float': 'none', marginLeft: 'auto', marginRight: 'auto'});\r\n\r\n\t\t$(photo).css({'float': 'none'});\r\n\r\n\t\t// Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay.\r\n\t\tif (isIE6) {\r\n\t\t\t$('select').not($box.find('select')).filter(function () {\r\n\t\t\t\treturn this.style.visibility !== 'hidden';\r\n\t\t\t}).css({'visibility': 'hidden'}).one(event_cleanup, function () {\r\n\t\t\t\tthis.style.visibility = 'inherit';\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tcallback = function () {\r\n\t\t\tvar preload,\r\n\t\t\t\ti,\r\n\t\t\t\ttotal = $related.length,\r\n\t\t\t\tiframe,\r\n\t\t\t\tframeBorder = 'frameBorder',\r\n\t\t\t\tallowTransparency = 'allowTransparency',\r\n\t\t\t\tcomplete,\r\n\t\t\t\tsrc,\r\n\t\t\t\timg,\r\n\t\t\t\tdata;\r\n\r\n\t\t\tif (!open) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tfunction removeFilter() {\r\n\t\t\t\tif (isIE) {\r\n\t\t\t\t\t$box[0].style.removeAttribute('filter');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tcomplete = function () {\r\n\t\t\t\tclearTimeout(loadingTimer);\r\n\t\t\t\t// Detaching forces Andriod stock browser to redraw the area underneat the loading overlay. Hiding alone isn't enough.\r\n\t\t\t\t$loadingOverlay.detach().hide();\r\n\t\t\t\ttrigger(event_complete, settings.onComplete);\r\n\t\t\t};\r\n\r\n\t\t\tif (isIE) {\r\n\t\t\t\t//This fadeIn helps the bicubic resampling to kick-in.\r\n\t\t\t\tif (photo) {\r\n\t\t\t\t\t$loaded.fadeIn(100);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t$title.html(settings.title).add($loaded).show();\r\n\r\n\t\t\tif (total > 1) { // handle grouping\r\n\t\t\t\tif (typeof settings.current === \"string\") {\r\n\t\t\t\t\t$current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$next[(settings.loop || index < total - 1) ? \"show\" : \"hide\"]().html(settings.next);\r\n\t\t\t\t$prev[(settings.loop || index) ? \"show\" : \"hide\"]().html(settings.previous);\r\n\r\n\t\t\t\tif (settings.slideshow) {\r\n\t\t\t\t\t$slideshow.show();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Preloads images within a rel group\r\n\t\t\t\tif (settings.preloading) {\r\n\t\t\t\t\tpreload = [\r\n\t\t\t\t\t\tgetIndex(-1),\r\n\t\t\t\t\t\tgetIndex(1)\r\n\t\t\t\t\t];\r\n\t\t\t\t\twhile (i = $related[preload.pop()]) {\r\n\t\t\t\t\t\tdata = $.data(i, colorbox);\r\n\r\n\t\t\t\t\t\tif (data && data.href) {\r\n\t\t\t\t\t\t\tsrc = data.href;\r\n\t\t\t\t\t\t\tif ($.isFunction(src)) {\r\n\t\t\t\t\t\t\t\tsrc = src.call(i);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tsrc = i.href;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (isImage(src)) {\r\n\t\t\t\t\t\t\timg = new Image();\r\n\t\t\t\t\t\t\timg.src = src;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t$groupControls.hide();\r\n\t\t\t}\r\n\r\n\t\t\tif (settings.iframe) {\r\n\t\t\t\tiframe = $tag('iframe')[0];\r\n\r\n\t\t\t\tif (frameBorder in iframe) {\r\n\t\t\t\t\tiframe[frameBorder] = 0;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (allowTransparency in iframe) {\r\n\t\t\t\t\tiframe[allowTransparency] = \"true\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!settings.scrolling) {\r\n\t\t\t\t\tiframe.scrolling = \"no\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$(iframe)\r\n\t\t\t\t\t.attr({\r\n\t\t\t\t\t\tsrc: settings.href,\r\n\t\t\t\t\t\tname: (new Date()).getTime(), // give the iframe a unique name to prevent caching\r\n\t\t\t\t\t\t'class': prefix + 'Iframe',\r\n\t\t\t\t\t\tallowFullScreen : true, // allow HTML5 video to go fullscreen\r\n\t\t\t\t\t\twebkitAllowFullScreen : true,\r\n\t\t\t\t\t\tmozallowfullscreen : true\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.one('load', complete)\r\n\t\t\t\t\t.one(event_purge, function () {\r\n\t\t\t\t\t\tiframe.src = \"//about:blank\";\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.appendTo($loaded);\r\n\r\n\t\t\t\tif (settings.fastIframe) {\r\n\t\t\t\t\t$(iframe).trigger('load');\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tcomplete();\r\n\t\t\t}\r\n\r\n\t\t\tif (settings.transition === 'fade') {\r\n\t\t\t\t$box.fadeTo(speed, 1, removeFilter);\r\n\t\t\t} else {\r\n\t\t\t\tremoveFilter();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tif (settings.transition === 'fade') {\r\n\t\t\t$box.fadeTo(speed, 0, function () {\r\n\t\t\t\tpublicMethod.position(0, callback);\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\tpublicMethod.position(speed, callback);\r\n\t\t}\r\n\t};\r\n\r\n\tpublicMethod.load = function (launched) {\r\n\t\tvar href, setResize, prep = publicMethod.prep;\r\n\r\n\t\tactive = true;\r\n\r\n\t\tphoto = false;\r\n\r\n\t\telement = $related[index];\r\n\r\n\t\tif (!launched) {\r\n\t\t\tmakeSettings();\r\n\t\t}\r\n\r\n\t\ttrigger(event_purge);\r\n\r\n\t\ttrigger(event_load, settings.onLoad);\r\n\r\n\t\tsettings.h = settings.height ?\r\n\t\t\t\tsetSize(settings.height, 'y') - loadedHeight - interfaceHeight :\r\n\t\t\t\tsettings.innerHeight && setSize(settings.innerHeight, 'y');\r\n\r\n\t\tsettings.w = settings.width ?\r\n\t\t\t\tsetSize(settings.width, 'x') - loadedWidth - interfaceWidth :\r\n\t\t\t\tsettings.innerWidth && setSize(settings.innerWidth, 'x');\r\n\r\n\t\t// Sets the minimum dimensions for use in image scaling\r\n\t\tsettings.mw = settings.w;\r\n\t\tsettings.mh = settings.h;\r\n\r\n\t\t// Re-evaluate the minimum width and height based on maxWidth and maxHeight values.\r\n\t\t// If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.\r\n\t\tif (settings.maxWidth) {\r\n\t\t\tsettings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;\r\n\t\t\tsettings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;\r\n\t\t}\r\n\t\tif (settings.maxHeight) {\r\n\t\t\tsettings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;\r\n\t\t\tsettings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;\r\n\t\t}\r\n\r\n\t\thref = settings.href;\r\n\r\n\t\tloadingTimer = setTimeout(function () {\r\n\t\t\t$loadingOverlay.show().appendTo($content);\r\n\t\t}, 100);\r\n\r\n\t\tif (settings.inline) {\r\n\t\t\t// Inserts an empty placeholder where inline content is being pulled from.\r\n\t\t\t// An event is bound to put inline content back when ColorBox closes or loads new content.\r\n\t\t\t$tag(div).hide().insertBefore($(href)[0]).one(event_purge, function () {\r\n\t\t\t\t$(this).replaceWith($loaded.children());\r\n\t\t\t});\r\n\t\t\tprep($(href));\r\n\t\t} else if (settings.iframe) {\r\n\t\t\t// IFrame element won't be added to the DOM until it is ready to be displayed,\r\n\t\t\t// to avoid problems with DOM-ready JS that might be trying to run in that iframe.\r\n\t\t\tprep(\" \");\r\n\t\t} else if (settings.html) {\r\n\t\t\tprep(settings.html);\r\n\t\t} else if (isImage(href)) {\r\n\t\t\t$(photo = new Image())\r\n\t\t\t.addClass(prefix + 'Photo')\r\n\t\t\t.error(function () {\r\n\t\t\t\tsettings.title = false;\r\n\t\t\t\tprep($tag(div, 'Error').html(settings.imgError));\r\n\t\t\t})\r\n\t\t\t.load(function () {\r\n\t\t\t\tvar percent;\r\n\t\t\t\tphoto.onload = null; //stops animated gifs from firing the onload repeatedly.\r\n\r\n\t\t\t\tif (settings.scalePhotos) {\r\n\t\t\t\t\tsetResize = function () {\r\n\t\t\t\t\t\tphoto.height -= photo.height * percent;\r\n\t\t\t\t\t\tphoto.width -= photo.width * percent;\r\n\t\t\t\t\t};\r\n\t\t\t\t\tif (settings.mw && photo.width > settings.mw) {\r\n\t\t\t\t\t\tpercent = (photo.width - settings.mw) / photo.width;\r\n\t\t\t\t\t\tsetResize();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (settings.mh && photo.height > settings.mh) {\r\n\t\t\t\t\t\tpercent = (photo.height - settings.mh) / photo.height;\r\n\t\t\t\t\t\tsetResize();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (settings.h) {\r\n\t\t\t\t\tphoto.style.marginTop = Math.max(settings.h - photo.height, 0) / 2 + 'px';\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ($related[1] && (settings.loop || $related[index + 1])) {\r\n\t\t\t\t\tphoto.style.cursor = 'pointer';\r\n\t\t\t\t\tphoto.onclick = function () {\r\n\t\t\t\t\t\tpublicMethod.next();\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (isIE) {\r\n\t\t\t\t\tphoto.style.msInterpolationMode = 'bicubic';\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsetTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise.\r\n\t\t\t\t\tprep(photo);\r\n\t\t\t\t}, 1);\r\n\t\t\t});\r\n\r\n\t\t\tsetTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise.\r\n\t\t\t\tphoto.src = href;\r\n\t\t\t}, 1);\r\n\t\t} else if (href) {\r\n\t\t\t$loadingBay.load(href, settings.data, function (data, status) {\r\n\t\t\t\tprep(status === 'error' ? $tag(div, 'Error').html(settings.xhrError) : $(this).contents());\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t// Navigates to the next page/image in a set.\r\n\tpublicMethod.next = function () {\r\n\t\tif (!active && $related[1] && (settings.loop || $related[index + 1])) {\r\n\t\t\tindex = getIndex(1);\r\n\t\t\tpublicMethod.load();\r\n\t\t}\r\n\t};\r\n\r\n\tpublicMethod.prev = function () {\r\n\t\tif (!active && $related[1] && (settings.loop || index)) {\r\n\t\t\tindex = getIndex(-1);\r\n\t\t\tpublicMethod.load();\r\n\t\t}\r\n\t};\r\n\r\n\t// Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close();\r\n\tpublicMethod.close = function () {\r\n\t\tif (open && !closing) {\r\n\r\n\t\t\tclosing = true;\r\n\r\n\t\t\topen = false;\r\n\r\n\t\t\ttrigger(event_cleanup, settings.onCleanup);\r\n\r\n\t\t\t$window.unbind('.' + prefix + ' .' + event_ie6);\r\n\r\n\t\t\t$overlay.fadeTo(200, 0);\r\n\r\n\t\t\t$box.stop().fadeTo(300, 0, function () {\r\n\r\n\t\t\t\t$box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide();\r\n\r\n\t\t\t\ttrigger(event_purge);\r\n\r\n\t\t\t\t$loaded.remove();\r\n\r\n\t\t\t\tsetTimeout(function () {\r\n\t\t\t\t\tclosing = false;\r\n\t\t\t\t\ttrigger(event_closed, settings.onClosed);\r\n\t\t\t\t}, 1);\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t// Removes changes ColorBox made to the document, but does not remove the plugin\r\n\t// from jQuery.\r\n\tpublicMethod.remove = function () {\r\n\t\t$([]).add($box).add($overlay).remove();\r\n\t\t$box = null;\r\n\t\t$('.' + boxElement)\r\n\t\t\t.removeData(colorbox)\r\n\t\t\t.removeClass(boxElement);\r\n\r\n\t\t$(document).undelegate('.'+boxElement);\r\n\t};\r\n\r\n\t// A method for fetching the current element ColorBox is referencing.\r\n\t// returns a jQuery object.\r\n\tpublicMethod.element = function () {\r\n\t\treturn $(element);\r\n\t};\r\n\r\n\tpublicMethod.settings = defaults;\r\n\r\n}(jQuery, document, window));\r\n","$(function(){\r\n\r\n\t// MOBILE MENU\r\n\t$(\".mobile-menu__item:has(ul)\")\r\n\t\t.find(\"a:first\")\r\n\t\t.addClass('mobile-menu__link--parent')\r\n\t\t.append(\"
\"+\r\n\t\t\t\t\t\"\"+\r\n\t\t\t\t\"\");\r\n\r\n\t$(\".mobile-menu--sub\").each(function() {\r\n\t\tvar title = $(this).parent(\"li\").find(\"a:first\").text();\r\n\t\t$(this).prepend(\"\");\r\n\t});\r\n\r\n\t$(\".open-sub\").each(function() {\r\n\t\t$(this).click(function(e) {\r\n\t\t\t$(this).closest(\".mobile-menu\").removeClass(\"show\").addClass(\"close\");\r\n\t\t\t$(this).closest(\".mobile-menu__item\").find(\".mobile-menu\").addClass(\"show\");\r\n\t\t\te.preventDefault();\r\n\t\t});\r\n\t});\r\n\r\n\r\n\t$(\".mobile-menu\").width($(\".mobile__wrapper\").width());\r\n\r\n\t$(\".mobile-menu__item--header a\").each(function() {\r\n\t\t$(this).click(function(e) {\r\n\r\n\t\t\tvar parentmenu = $(this).closest(\".mobile-menu\");\r\n\r\n\t\t\tparentmenu.removeClass(\"show\");\r\n\t\t\tparentmenu.closest(\".mobile-menu__item\").parent(\".mobile-menu--sub\").addClass(\"show\");\r\n\t\t\tparentmenu.closest(\".mobile-menu__item\").parent(\".mobile-menu\").removeClass(\"close\");\r\n\t\t\te.preventDefault();\r\n\t\t});\r\n\t});\r\n\r\n\t$('.colorbox').colorbox({\r\n\t\trel:'gallery',\r\n\t\tmaxWidth:\"80%\",\r\n\t\tmaxHeight:\"80%\"\r\n\t});\r\n\r\n\t$('.extranetmenu li:not([data-icon=\"\"])').each(function() {\r\n\t\t\tvar icon = $(this).attr('data-icon');\r\n\t\t\t$(this).first(\"a\").prepend('
');\r\n\t\t$(this).addClass(\"list--icon\");\r\n\t\t});\r\n\r\n\t$('.menu--main .menu__link').each(function(){\r\n\t\t$(this).find('i.fa-chevron-down').appendTo($(this).find('a').first());\r\n\t});\r\n\r\n\tif ($('html.lt_ie9').length === 0) {\r\n\t\t$('.header').clone().addClass('sticky').prependTo('body');\r\n\t}\r\n\r\n\r\n\t$(window).on('scroll', function(e){\r\n\t\tclearTimeout(t);\r\n\t\tvar t = setTimeout(function(){\r\n\r\n\t\t\tif ($('body.vervolg').length > 0) {\r\n\t\t\t\thHeight = 360;\r\n\t\t\t} else {\r\n\t\t\t\thHeight = 480;\r\n\t\t\t}\r\n\r\n\t\t\tif ($(window).scrollTop() >= hHeight) {\r\n\t\t\t\t$('.header.sticky').addClass('visible');\r\n\t\t\t} else {\r\n\t\t\t\t$('.header.sticky').removeClass('visible');\r\n\t\t\t}\r\n\t\t}, 100);\r\n\t});\r\n\r\n\t\t// TOGGLE MOBILE MENU\r\n\t$(\".menu__link--menu, .toggle-menu\").click(function(e) {\r\n\t\t$(\"body\").toggleClass(\"show-menu\");\r\n\t\t$(this).toggleClass(\"active\");\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t// $('.sidebar .titlelink').each(function(){\r\n\t// \t$(this).clone().addClass('clone cta cta--big').insertAfter('.header:not(.sticky)');\r\n\t// });\r\n\r\n\t// $('.titlelink.clone').wrapAll('
');\r\n\t// $('.titlelink.clone:eq(1)').addClass('cta--grey');\r\n\t// $('.titlelink.clone:eq(2)').addClass('cta--red');\r\n\r\n\t// cta_holder = $('.cta--big:first').closest('section');\r\n\t// cta_holder.addClass('cta__holder').clone().addClass('cta__holder cta__holder--mobile clone').insertAfter('.header:not(.sticky)');\r\n\r\n\t$('.content .project-contact').each(function(){\r\n\t\t$(this).prependTo('.sidebar').wrapAll('
');\r\n\t});\r\n\r\n\r\n\r\n\r\n\t$('.menu__link--phone').on('click', function(){\r\n\t\tif ($(window).width() < 768) {\r\n\t\t\tdocument.location = \"/contact\";\r\n\t\t}\r\n\t});\r\n\r\n\tvar owl = $(\".partners__slider\").owlCarousel({\r\n\t\tautoWidth: true,\r\n\t\tmargin: 10,\r\n\t\tloop: true,\r\n\t\titems: 4,\r\n\t\tautoplay: true,\r\n\t\tautoplayTimeout: 6000,\r\n\t\tautoplayHoverPause: true\r\n\t});\r\n\r\n\t$('.menu__link--phone').on('click', function(){\r\n\t\tif ($(window).width() >= 768) {\r\n\t\t\t$(this).find('.menu--phone').toggleClass('open');\r\n\t\t}\r\n\t});\r\n\r\n\t$('.menu__link--menu, .menu--open').on('click', function(e){\r\n\t\t$('.menu--main').addClass('open');\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t$('.menu__close').on('click', function(e){\r\n\t\t$('.menu--main').removeClass('open');\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t$('.menu--phone li').on('click', function(e){\r\n\t\t// console.log($(this).find('a').attr('data-value'));\r\n\t\t$(this).closest('.menu__link--phone').find('> ul > li > span').text($(this).find('a').attr('data-value'));\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t$('.partners__slider__btn--next').click(function(e) {\r\n\t\towl.trigger('next.owl.carousel');\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t$('.partners__slider__btn--prev').click(function(e) {\r\n\t\towl.trigger('prev.owl.carousel');\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t//FILTER\r\n\t$(\".filter .options li\").click(function() {\r\n\t\t$(this).toggleClass(\"selected\");\r\n\r\n\t\tvar cRequest = $(this).closest(\".filters\").attr(\"data-value\")\r\n\r\n\t\tvar cRegioFilter = \"\";\r\n\t\t$(\".filter .options li.selected[data-regio]\").each(function() {\r\n\t\t\tcRegioFilter += (cRegioFilter === \"\" ? \"\" : \",\") + $(this).attr(\"data-regio\");\r\n\t\t});\r\n\r\n\t\tvar cVakgebiedFilter = \"\";\r\n\t\t$(\".filter .options li.selected[data-vakgebied]\").each(function() {\r\n\t\t\tcVakgebiedFilter += (cVakgebiedFilter === \"\" ? \"\" : \",\") + $(this).attr(\"data-vakgebied\");\r\n\t\t});\r\n\r\n\t\tvar cExpertiseFilter = \"\";\r\n\t\t$(\".filter .options li.selected[data-expertise]\").each(function() {\r\n\t\t\tcExpertiseFilter += (cExpertiseFilter === \"\" ? \"\" : \",\") + $(this).attr(\"data-expertise\");\r\n\t\t});\r\n\r\n\t\tcRequest = (cRegioFilter === \"\" ? cRequest : cRequest + \"®io=\" + cRegioFilter.split(\" \").join(\"\"));\r\n\t\tcRequest = (cVakgebiedFilter === \"\" ? cRequest : cRequest + \"&vakgebied=\" + cVakgebiedFilter.split(\" \").join(\"\").replace(\"&\", \"\"));\r\n\t\tcRequest = (cExpertiseFilter === \"\" ? cRequest : cRequest + \"&expertise=\" + cExpertiseFilter.split(\" \").join(\"\"));\r\n\r\n\t\t$(this).closest(\".filters\").next(\"ul.productlijst\").load(cRequest);\r\n\t\t$(this).closest(\".filters\").next(\"ul.productoverzicht\").load(cRequest);\r\n\t\t$(this).closest(\".filters\").parent().find(\".paging\").hide();\r\n\t});\r\n\r\n\t$(\".filter .toggle\").click(function() {\r\n\t\t$(this).closest(\".filter\").toggleClass(\"active\");\r\n\t});\r\n\t$(\".filter\").mouseleave(function() {\r\n\t\t$(this).removeClass(\"active\");\r\n\t});\r\n\r\n\t//BREADCRUMB\r\n\t$(\"div#breadcrumb ul li:last\").addClass('last');\r\n\r\n\t// TABS IN FOOTER\r\n\t$(\".tab_content\").hide();\r\n\t$(\"ul.tabs li:first\").addClass(\"active\").show();\r\n\t$(\"ul.tabs li:last\").addClass('last');\r\n\t$(\".tab_content:first\").show();\r\n\r\n\t$(\"ul.tabs li\").click(function(e){\r\n\t\t$(\"ul.tabs li\").removeClass(\"active\");\r\n\t\t$(this).addClass(\"active\");\r\n\t\t$(\".tab_content\").hide();\r\n\r\n\t\tvar index = $(\"ul.tabs li\").index($(this));\r\n\t\t$(\".tab_container .tab_content:eq(\"+ index +\")\").show();\r\n\r\n\t\te.preventDefault();\r\n\t});\r\n\r\n\t//VERWIJDER LEGE TAB CONTAINERS\r\n\t$(\"#tab1, #tab2, #tab3, .tabs\").each( function() {\r\n\t\tif ($(this).children().length == 0) {\r\n\t\t\t$(this).remove();\r\n\t\t}\r\n\t});\r\n\r\n\t//TABELLEN\r\n\t$(\"table.standaard tr\").each(function(){\r\n\t\t$(this).find(\"td:first\").addClass(\"first\");\r\n\t});\r\n\t$(\"table.rij\").each(function(){\r\n\t\t$(this).find(\"tr:odd\").addClass(\"odd\");\r\n\t});\r\n\t$(\"table.kolom tr\").each(function(){\r\n\t\t$(this).find(\"td:even\").addClass(\"even\");\r\n\t});\r\n\r\n\t//SEARCH\r\n\t/*\r\n\t$('.search a').clickToggle(function(){\r\n\t\t$('#search').slideDown(300);\r\n\t\t//$('body').animate({'background-position-y': '248'}, 0);\r\n\t}, function(){\r\n\t\t$('#search').slideUp(300);\r\n\t\t//$('body').animate({'background-position-y': '198'}, 0);\r\n\t});\r\n\t*/\r\n\r\n\t$('.search a').click(function(e){\r\n\t\t$('#search').slideToggle(300);\r\n\t\te.preventDefault();\r\n\t\t});\r\n\r\n\t//DROPDOWNMENU\r\n\t$(\"#menu ul li\").hover(function(){\r\n\t\t$(this).addClass(\"hover\");\r\n\t\t$('ul:first',this).css('visibility', 'visible');\r\n\t}, function(){\r\n\t\t$(this).removeClass(\"hover\");\r\n\t\t$('ul:first',this).css('visibility', 'hidden');\r\n\t});\r\n\r\n\r\n\r\n\t// REMOVE MARGIN BIJ OPEENVOLGENDE AFBEELDINGEN\r\n\t$(\"#content figure.left, #content figure.right, .kolom1 figure.left, .kolom1 figure.right, section figure.left, section figure.right\").each(function() {\r\n\t\tif ($(this).next(\"figure.left, figure.right\").length >= 1) {\r\n\t\t\tif (!$(this).hasClass(\"noMargin\")) {\r\n\t\t\t\t$(this).next().addClass(\"noMargin\");\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n\r\n\t//CLEAR CALL TO ACTIONS\r\n\t$(\"a.btn\").each(function(){\r\n\t\t$(this).before(\"
\");\r\n\t\t$(this).after(\"
\");\r\n\t});\r\n\r\n\t$('[placeholder]').placeholder();\r\n\r\n\t// LOGO\r\n\t$(\".samenwerken\").delay(5000).fadeIn(5000);\r\n\t$(\".ingenieus\").delay(1500).animate({ top: \"70px\"}, 2000 );\r\n\t$('.ingenieurs').delay(3500).fadeIn(2000).delay(6000).fadeOut(2000);\r\n\r\n});\r\n\r\n$(window).load(function(){\r\n\r\n\t//BREEDTE AFBEELDING = MAXIMALE BREEDTE VOOR ONDERSCHRIFT\r\n\t$(\"figure\").each(function(){\r\n\t\t$(this).find(\"figcaption\").show().css(\"max-width\", $(this).find(\"img\").width());\r\n\t});\r\n\r\n\t$(window).on(\"resize\", function() {\r\n\t\t$('.content .container').css({ minHeight: $('.sidebar').outerHeight() });\r\n\t}).trigger(\"resize\");\r\n\r\n\t$(\".link--download\").on(\"click\", function(){\r\n\t\ttry{\r\n\t\t\tgaDocName=$(this).text();\r\n\t\t\tgaDocName=(gaDocName==\"\"?$(this).parent().text():gaDocName);\r\n\t\t\tgaDocName=(gaDocName==\"\"?($(this).find('img').attr('alt')):gaDocName);\r\n\t\t\tconsole.log(gaDocName);\r\n\t\t\tga('send', 'event', 'Bestand gedownload', 'download', gaDocName);\r\n\t\t}catch(e){console.log(e);}\r\n\t});\r\n\r\n});\r\n"]}