From 8d8af0ce7f151670fa8601f47999375c5aaba6f8 Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Tue, 23 Jun 2020 15:51:28 -0300 Subject: [PATCH] v2.0.0 --- CHANGELOG.md | 4 + build/universe.js | 14308 ++++++++++++++++++++++---------------------- package.json | 2 +- 3 files changed, 7172 insertions(+), 7142 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e940f..83759ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0 (Jun 23, 2020) + + - JWT [[4d3db83](https://github.com/sparkartgroup/universe-js/commit/4d3db83e7b29db89484a8124ffdfc117a51e57ba)] + ## 1.2.6 (Jun 4, 2018) - Adjust popup height to accommodate new GDPR disclaimer [[0ffcb93](https://github.com/sparkartgroup/universe-js/commit/0ffcb937db9f8ddd6396b2d28d2c98c55aa1e98e)] diff --git a/build/universe.js b/build/universe.js index 6fe145e..84a20f6 100644 --- a/build/universe.js +++ b/build/universe.js @@ -1,7 +1,6 @@ !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Universe=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= (localStorage.getItem('universeRefreshTokenExpiration') || 0)) { + // Missing or expired refresh token + localStorage.removeItem('universeRefreshToken'); + localStorage.removeItem('universeRefreshTokenExpiration'); + return callback(true); + } + + // Refresh the access token + const resource = new Resource(this.resource('/refresh'), this.resources_options); + resource.post({refresh_token: localStorage.getItem('universeRefreshToken')}, function (err, response) { + if (err) { + if (response && response.data && response.data.status === 'error') { + // Invalid refresh token + localStorage.removeItem('universeRefreshToken'); + localStorage.removeItem('universeRefreshTokenExpiration'); + } + callback(err); + } else { + localStorage.setItem('universeAccessToken', response.data.access.access_token); + localStorage.setItem('universeAccessTokenExpiration', response.data.access.access_token_expiration * 1000); + localStorage.setItem('universeRefreshToken', response.data.access.refresh_token); + localStorage.setItem('universeRefreshTokenExpiration', response.data.access.refresh_token_expiration * 1000); + callback(); + } + }); +} + module.exports = Universe; -},{"solidus-client":15,"solidus-client/lib/resource":17}],2:[function(_dereq_,module,exports){ +},{"solidus-client":73,"solidus-client/lib/resource":75}],2:[function(_dereq_,module,exports){ + +/** + * Expose `Emitter`. + */ + +if (typeof module !== 'undefined') { + module.exports = Emitter; +} + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + + // Remove event specific arrays for event types that no + // one is subscribed for to avoid memory leak. + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + + var args = new Array(arguments.length - 1) + , callbacks = this._callbacks['$' + event]; + + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],3:[function(_dereq_,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -429,2354 +653,2632 @@ function isUndefined(arg) { return arg === void 0; } -},{}],3:[function(_dereq_,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - },{}],4:[function(_dereq_,module,exports){ -// shim for using process in browser +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; +var defineProperty = Object.defineProperty; +var gOPD = Object.getOwnPropertyDescriptor; -var process = module.exports = {}; +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; + return toStr.call(arr) === '[object Array]'; +}; - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -function noop() {} +var isPlainObject = function isPlainObject(obj) { + 'use strict'; -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } -process.binding = function (name) { - throw new Error('process.binding is not supported'); -} + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) { /**/ } + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target +var setProperty = function setProperty(target, options) { + if (defineProperty && options.name === '__proto__') { + defineProperty(target, options.name, { + enumerable: true, + configurable: true, + value: options.newValue, + writable: true + }); + } else { + target[options.name] = options.newValue; + } }; -},{}],5:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } - - var regexp = /\+/g; - qs = qs.split(sep); - - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; - } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; - } - - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; - } - - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); - - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; - } - } - - return obj; -}; +// Return undefined instead of __proto__ if '__proto__' is not an own property +var getProperty = function getProperty(obj, name) { + if (name === '__proto__') { + if (!hasOwn.call(obj, name)) { + return void 0; + } else if (gOPD) { + // In early versions of node, obj['__proto__'] is buggy when obj has + // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. + return gOPD(obj, name).value; + } + } -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; + return obj[name]; }; -},{}],6:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +module.exports = function extend() { + 'use strict'; -'use strict'; + var options, name, src, copy, copyIsArray, clone; + var target = arguments[0]; + var i = 1; + var length = arguments.length; + var deep = false; -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { + target = {}; + } - case 'boolean': - return v ? 'true' : 'false'; + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = getProperty(target, name); + copy = getProperty(options, name); - case 'number': - return isFinite(v) ? v : ''; + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + setProperty(target, { name: name, newValue: copy }); + } + } + } + } + } - default: - return ''; - } + // Return the modified object + return target; }; -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).join(sep); - - } - - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); +},{}],5:[function(_dereq_,module,exports){ +module.exports = _dereq_('./lib'); +},{"./lib":30}],6:[function(_dereq_,module,exports){ +module.exports = function(){ + var numbers = Array.prototype.slice.call( arguments, 0, -1 ); + var result = 0; + for( var i = numbers.length - 1; i >= 0; i-- ){ + result += parseFloat( numbers[i], 10 ) || 0; + } + return result; }; +},{}],7:[function(_dereq_,module,exports){ +// Modified form of `timeago` helper from https://github.com/assemble/handlebars-helpers -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; +var newDate = _dereq_('new-date'); -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} +var YEAR = 60 * 60 * 24 * 365; +var MONTH = 60 * 60 * 24 * 30; +var DAY = 60 * 60 * 24; +var HOUR = 60 * 60; -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; +module.exports = function( date ){ + date = newDate( date ); + var seconds = Math.floor( ( new Date() - date ) / 1000 ); + var interval = Math.floor( seconds / YEAR ); + if( interval > 1 ) return interval +' years ago'; + interval = Math.floor( seconds / MONTH ); + if( interval > 1 ) return interval +' months ago'; + interval = Math.floor( seconds / DAY ); + if( interval > 1 ) return interval +' days ago'; + interval = Math.floor( seconds / HOUR ); + if( interval > 1 ) return interval +' hours ago'; + interval = Math.floor( seconds / 60 ); + if( interval > 1 ) return interval +' minutes ago'; + if( Math.floor( seconds ) <= 1 ) return 'Just now'; + else return Math.floor( seconds ) +' seconds ago'; +}; +},{"new-date":61}],8:[function(_dereq_,module,exports){ +module.exports = function( collection, start, end, options ){ + options = options || end; + if( typeof start !== 'number' ) return; + end = ( typeof end !== 'number' ) ? collection.length : ( end > 0 )? end + 1 : end; + collection = collection.slice( start, end ); + var result = ''; + for( var i = 0; i < collection.length; i++ ){ + result += options.fn( collection[i] ); + } + return result; }; - -},{}],7:[function(_dereq_,module,exports){ -'use strict'; - -exports.decode = exports.parse = _dereq_('./decode'); -exports.encode = exports.stringify = _dereq_('./encode'); - -},{"./decode":5,"./encode":6}],8:[function(_dereq_,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} },{}],9:[function(_dereq_,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; +module.exports = function( collection, item, options ){ + // string check + if( typeof collection === 'string' ){ + if( collection.search( item ) >= 0 ){ + return options.fn(this); + } + else { + return options.inverse(this); + } + } + // "collection" check (objects & arrays) + for( var prop in collection ){ + if( collection.hasOwnProperty( prop ) ){ + if( collection[prop] == item ) return options.fn(this); + } + } + return options.inverse(this); }; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; +},{}],10:[function(_dereq_,module,exports){ +module.exports = function(){ + var numbers = Array.prototype.slice.call( arguments, 1, -1 ); + var result = arguments[0]; + for( var i = numbers.length - 1; i >= 0; i-- ){ + result /= parseFloat( numbers[i], 10 ) || 0; + } + return result; }; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; +},{}],11:[function(_dereq_,module,exports){ +module.exports = function( string ){ + return encodeURIComponent( string ); }; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] +},{}],12:[function(_dereq_,module,exports){ +module.exports = function( left, right, exact, options ){ + options = options || exact; + exact = ( exact === 'exact' ) ? true : false; + var is_equal = exact ? ( left === right ) : ( left == right ); + if( is_equal ) return options.fn(this); + return options.inverse(this); +}; +},{}],13:[function(_dereq_,module,exports){ +module.exports = function( collection, count, options ){ + options = options || count; + count = ( typeof count === 'number' ) ? count : 1; + var result = ''; + var i = 0; + for( var key in collection ){ + if( collection.hasOwnProperty( key ) ){ + result += options.fn( collection[key] ); + i++; + if( i == count ) break; + } + } + return result; }; +},{}],14:[function(_dereq_,module,exports){ +var strftimeTZ = _dereq_('strftime').strftimeTZ; +var newDate = _dereq_('new-date'); -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' +module.exports = function( date_string, format, offset ){ + offset = ( typeof offset === 'number' ) ? offset : null; + var date = newDate( date_string ); + return strftimeTZ( format, date, offset ); +}; +},{"new-date":61,"strftime":79}],15:[function(_dereq_,module,exports){ +module.exports = function( left, right, equal, options ){ + options = options || equal; + equal = ( equal === 'equal' ) ? true : false; + var is_greater = equal ? ( left >= right ) : ( left > right ); + if( is_greater ) return options.fn( this ); + return options.inverse( this ); +}; +},{}],16:[function(_dereq_,module,exports){ +module.exports = function( collection, separator ){ + separator = ( typeof separator === 'string' ) ? separator : ''; + // if the collectoin is an array this is easy + if( collection.join ) return collection.join( separator ); + // if it's not we actually have to write code. + var result = ''; + for( var property in collection ){ + if( collection.hasOwnProperty(property) ){ + result += collection[property] + separator; + } + } + return result.slice( 0, -separator.length ); }; +},{}],17:[function(_dereq_,module,exports){ +var _isArray = _dereq_('lodash.isarray'); +var _reduce = _dereq_('lodash.reduce'); +module.exports = function( collection, count, options ){ + options = options || count; + count = ( typeof count === 'number' ) ? count : 1; + // if collection is an object, make it an array + // otherwise we have no way to clip off the "end" + if( !_isArray( collection ) ){ + var collection_array = []; + for( var key in collection ){ + if( collection.hasOwnProperty( key ) ){ + collection_array.push( collection[key] ); + } + } + collection = collection_array; + } + var collection_last = collection.slice( -1 * count ); + var result = _reduce( collection_last, function( previous, current ){ + return previous + options.fn( current ); + }, '' ); + return result; +}; +},{"lodash.isarray":53,"lodash.reduce":59}],18:[function(_dereq_,module,exports){ +module.exports = function( collection ){ + if( collection.length ) return collection.length; + var length = 0; + for( var prop in collection ){ + if( collection.hasOwnProperty( prop ) ){ + length++; + } + } + return length; +}; +},{}],19:[function(_dereq_,module,exports){ +module.exports = function( left, right, equal, options ){ + options = options || equal; + equal = ( equal === 'equal' ) ? true : false; + var is_greater = equal ? ( left <= right ) : ( left < right ); + if( is_greater ) return options.fn( this ); + return options.inverse( this ); +}; +},{}],20:[function(_dereq_,module,exports){ +module.exports = function( string ){ + return ( string || '' ).toLowerCase(); +}; +},{}],21:[function(_dereq_,module,exports){ +module.exports = function(){ + var numbers = Array.prototype.slice.call( arguments, 1, -1 ); + var result = arguments[0]; + for( var i = numbers.length - 1; i >= 0; i-- ){ + result *= parseFloat( numbers[i], 10 ) || 0; + } + return result; +}; +},{}],22:[function(_dereq_,module,exports){ +module.exports = function( collection, start, amount, options ){ + options = options || amount; + if( typeof start !== 'number' ) return; + var end = ( typeof amount !== 'number' ) ? collection.length : start + amount; + collection = collection.slice( start, end ); + var result = ''; + for( var i = 0; i < collection.length; i++ ){ + result += options.fn( collection[i] ); + } + return result; +}; +},{}],23:[function(_dereq_,module,exports){ +module.exports = function( string, to_replace, replacement ){ + return ( string || '' ).replace( to_replace, replacement ); +}; +},{}],24:[function(_dereq_,module,exports){ +module.exports = function( collection, options ){ + var result = ''; + for( var i = collection.length - 1; i >= 0; i-- ){ + result += options.fn( collection[i] ); + } + return result; +}; +},{}],25:[function(_dereq_,module,exports){ +// Simple shuffling method based off of http://bost.ocks.org/mike/shuffle/ +var shuffle = function( array ){ + var i = array.length, j, swap; + while( i ){ + j = Math.floor( Math.random() * i-- ); + swap = array[i]; + array[i] = array[j]; + array[j] = swap; + } + return array; +}; -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; +module.exports = function( collection, options ){ + var shuffled = shuffle( collection ); + var result = ''; + for( var i = 0; i < shuffled.length; i++ ){ + result += options.fn( shuffled[i] ); + } + return result; +}; +},{}],26:[function(_dereq_,module,exports){ +module.exports = function(){ + var numbers = Array.prototype.slice.call( arguments, 1, -1 ); + var result = parseFloat( arguments[0], 10 ); + for( var i = numbers.length - 1; i >= 0; i-- ){ + result -= parseFloat( numbers[i], 10 ) || 0; + } + return result; +}; +},{}],27:[function(_dereq_,module,exports){ +module.exports = function( number, zero, options ){ + options = options || zero; + zero = ( zero === 'zero' ) ? true : false; + var result = ''; + var i; + if( zero ){ + for( i = 0; i < number; i++ ) result += options.fn( i ); + } + else { + for( i = 1; i <= number; i++ ) result += options.fn( i ); + } + return result; +}; +},{}],28:[function(_dereq_,module,exports){ +module.exports = function( string ){ + return ( string || '' ).toUpperCase(); +}; +},{}],29:[function(_dereq_,module,exports){ +module.exports = function( collection, key, value, limit, options ){ + options = options || limit; + if( typeof limit !== 'number' ) limit = Infinity; + var matches = 0; + var result = ''; + for( var i = 0; i < collection.length; i++ ){ + if( collection[i][key] === value ){ + result += options.fn( collection[i] ); + matches++; + if( matches === limit ) return result; + } + } + return result; +}; +},{}],30:[function(_dereq_,module,exports){ +var helpers = { + // string + lowercase: _dereq_('./helpers/lowercase.js'), + uppercase: _dereq_('./helpers/uppercase.js'), + replace: _dereq_('./helpers/replace.js'), + encode: _dereq_('./helpers/encode.js'), + // collection + length: _dereq_('./helpers/length.js'), + contains: _dereq_('./helpers/contains.js'), + first: _dereq_('./helpers/first.js'), + last: _dereq_('./helpers/last.js'), + between: _dereq_('./helpers/between.js'), + range: _dereq_('./helpers/range.js'), + where: _dereq_('./helpers/where.js'), + shuffle: _dereq_('./helpers/shuffle.js'), + reverse: _dereq_('./helpers/reverse.js'), + join: _dereq_('./helpers/join.js'), + // date + ago: _dereq_('./helpers/ago.js'), + formatDate: _dereq_('./helpers/formatDate.js'), + // equality + equal: _dereq_('./helpers/equal.js'), + greater: _dereq_('./helpers/greater.js'), + less: _dereq_('./helpers/less.js'), + // numbers + times: _dereq_('./helpers/times.js'), + add: _dereq_('./helpers/add.js'), + subtract: _dereq_('./helpers/subtract.js'), + multiply: _dereq_('./helpers/multiply.js'), + divide: _dereq_('./helpers/divide.js') +}; - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} +module.exports.help = function( Handlebars ){ + for( var name in helpers ){ + Handlebars.registerHelper( name, helpers[name] ); + } +}; +module.exports.helpers = helpers; -function stylizeNoColor(str, styleType) { - return str; -} +},{"./helpers/add.js":6,"./helpers/ago.js":7,"./helpers/between.js":8,"./helpers/contains.js":9,"./helpers/divide.js":10,"./helpers/encode.js":11,"./helpers/equal.js":12,"./helpers/first.js":13,"./helpers/formatDate.js":14,"./helpers/greater.js":15,"./helpers/join.js":16,"./helpers/last.js":17,"./helpers/length.js":18,"./helpers/less.js":19,"./helpers/lowercase.js":20,"./helpers/multiply.js":21,"./helpers/range.js":22,"./helpers/replace.js":23,"./helpers/reverse.js":24,"./helpers/shuffle.js":25,"./helpers/subtract.js":26,"./helpers/times.js":27,"./helpers/uppercase.js":28,"./helpers/where.js":29}],31:[function(_dereq_,module,exports){ +/**! + * is + * the definitive JavaScript type testing library + * + * @copyright 2013 Enrico Marino + * @license MIT + */ -function arrayToHash(array) { - var hash = {}; +var objProto = Object.prototype; +var owns = objProto.hasOwnProperty; +var toString = objProto.toString; +var isActualNaN = function (value) { + return value !== value; +}; +var NON_HOST_TYPES = { + "boolean": 1, + "number": 1, + "string": 1, + "undefined": 1 +}; - array.forEach(function(val, idx) { - hash[val] = true; - }); +/** + * Expose `is` + */ - return hash; -} +var is = module.exports = {}; +/** + * Test general. + */ -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } +/** + * is.type + * Test if `value` is a type of `type`. + * + * @param {Mixed} value value to test + * @param {String} type type + * @return {Boolean} true if `value` is a type of `type`, false otherwise + * @api public + */ - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); +is.a = +is.type = function (value, type) { + return typeof value === type; +}; - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } +/** + * is.defined + * Test if `value` is defined. + * + * @param {Mixed} value value to test + * @return {Boolean} true if 'value' is defined, false otherwise + * @api public + */ - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } +is.defined = function (value) { + return value !== undefined; +}; - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } +/** + * is.empty + * Test if `value` is empty. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is empty, false otherwise + * @api public + */ - var base = '', array = false, braces = ['{', '}']; +is.empty = function (value) { + var type = toString.call(value); + var key; - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; + if ('[object Array]' === type || '[object Arguments]' === type) { + return value.length === 0; } - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; + if ('[object Object]' === type) { + for (key in value) if (owns.call(value, key)) return false; + return true; } - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); + if ('[object String]' === type) { + return '' === value; } - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } + return false; +}; - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); +/** + * is.equal + * Test if `value` is equal to `other`. + * + * @param {Mixed} value value to test + * @param {Mixed} other value to compare with + * @return {Boolean} true if `value` is equal to `other`, false otherwise + */ + +is.equal = function (value, other) { + var type = toString.call(value) + var key; + + if (type !== toString.call(other)) { + return false; } - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; + if ('[object Object]' === type) { + for (key in value) { + if (!is.equal(value[key], other[key])) { + return false; + } + } + return true; } - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); + if ('[object Array]' === type) { + key = value.length; + if (key !== other.length) { + return false; + } + while (--key) { + if (!is.equal(value[key], other[key])) { + return false; + } } + return true; } - ctx.seen.push(value); + if ('[object Function]' === type) { + return value.prototype === other.prototype; + } - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); + if ('[object Date]' === type) { + return value.getTime() === other.getTime(); } - ctx.seen.pop(); + return value === other; +}; - return reduceToSingleString(output, base, braces); -} +/** + * is.hosted + * Test if `value` is hosted by `host`. + * + * @param {Mixed} value to test + * @param {Mixed} host host to test with + * @return {Boolean} true if `value` is hosted by `host`, false otherwise + * @api public + */ +is.hosted = function (value, host) { + var type = typeof host[value]; + return type === 'object' ? !!host[value] : !NON_HOST_TYPES[type]; +}; -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} +/** + * is.instance + * Test if `value` is an instance of `constructor`. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an instance of `constructor` + * @api public + */ +is.instance = is['instanceof'] = function (value, constructor) { + return value instanceof constructor; +}; -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} +/** + * is.null + * Test if `value` is null. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is null, false otherwise + * @api public + */ +is['null'] = function (value) { + return value === null; +}; -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} +/** + * is.undefined + * Test if `value` is undefined. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is undefined, false otherwise + * @api public + */ +is.undefined = function (value) { + return value === undefined; +}; -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); +/** + * Test arguments. + */ - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } +/** + * is.arguments + * Test if `value` is an arguments object. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an arguments object, false otherwise + * @api public + */ - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} +is.arguments = function (value) { + var isStandardArguments = '[object Arguments]' === toString.call(value); + var isOldArguments = !is.array(value) && is.arraylike(value) && is.object(value) && is.fn(value.callee); + return isStandardArguments || isOldArguments; +}; +/** + * Test array. + */ -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; +/** + * is.array + * Test if 'value' is an array. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an array, false otherwise + * @api public + */ -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; +is.array = function (value) { + return '[object Array]' === toString.call(value); +}; -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; +/** + * is.arguments.empty + * Test if `value` is an empty arguments object. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an empty arguments object, false otherwise + * @api public + */ +is.arguments.empty = function (value) { + return is.arguments(value) && value.length === 0; +}; -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; +/** + * is.array.empty + * Test if `value` is an empty array. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an empty array, false otherwise + * @api public + */ +is.array.empty = function (value) { + return is.array(value) && value.length === 0; +}; -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; +/** + * is.arraylike + * Test if `value` is an arraylike object. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an arguments object, false otherwise + * @api public + */ -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; +is.arraylike = function (value) { + return !!value && !is.boolean(value) + && owns.call(value, 'length') + && isFinite(value.length) + && is.number(value.length) + && value.length >= 0; +}; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; +/** + * Test boolean. + */ -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; +/** + * is.boolean + * Test if `value` is a boolean. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a boolean, false otherwise + * @api public + */ -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; +is.boolean = function (value) { + return '[object Boolean]' === toString.call(value); +}; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; +/** + * is.false + * Test if `value` is false. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is false, false otherwise + * @api public + */ -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; +is['false'] = function (value) { + return is.boolean(value) && (value === false || value.valueOf() === false); +}; -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; +/** + * is.true + * Test if `value` is true. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is true, false otherwise + * @api public + */ -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; +is['true'] = function (value) { + return is.boolean(value) && (value === true || value.valueOf() === true); +}; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; +/** + * Test date. + */ -exports.isBuffer = _dereq_('./support/isBuffer'); +/** + * is.date + * Test if `value` is a date. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a date, false otherwise + * @api public + */ -function objectToString(o) { - return Object.prototype.toString.call(o); -} +is.date = function (value) { + return '[object Date]' === toString.call(value); +}; +/** + * Test element. + */ -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - +/** + * is.element + * Test if `value` is an html element. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an HTML Element, false otherwise + * @api public + */ -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +is.element = function (value) { + return value !== undefined + && typeof HTMLElement !== 'undefined' + && value instanceof HTMLElement + && value.nodeType === 1; }; +/** + * Test error. + */ /** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). + * is.error + * Test if `value` is an error object. * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an error object, false otherwise + * @api public */ -exports.inherits = _dereq_('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; +is.error = function (value) { + return '[object Error]' === toString.call(value); }; -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} +/** + * Test function. + */ -}).call(this,_dereq_("IrXUsu"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":8,"IrXUsu":4,"inherits":3}],10:[function(_dereq_,module,exports){ -module.exports = _dereq_('./lib/'); +/** + * is.fn / is.function (deprecated) + * Test if `value` is a function. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a function, false otherwise + * @api public + */ -},{"./lib/":11}],11:[function(_dereq_,module,exports){ -// Load modules +is.fn = is['function'] = function (value) { + var isAlert = typeof window !== 'undefined' && value === window.alert; + return isAlert || '[object Function]' === toString.call(value); +}; -var Stringify = _dereq_('./stringify'); -var Parse = _dereq_('./parse'); +/** + * Test number. + */ +/** + * is.number + * Test if `value` is a number. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a number, false otherwise + * @api public + */ -// Declare internals +is.number = function (value) { + return '[object Number]' === toString.call(value); +}; -var internals = {}; +/** + * is.infinite + * Test if `value` is positive or negative infinity. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is positive or negative Infinity, false otherwise + * @api public + */ +is.infinite = function (value) { + return value === Infinity || value === -Infinity; +}; +/** + * is.decimal + * Test if `value` is a decimal number. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a decimal number, false otherwise + * @api public + */ -module.exports = { - stringify: Stringify, - parse: Parse +is.decimal = function (value) { + return is.number(value) && !isActualNaN(value) && value % 1 !== 0; }; -},{"./parse":12,"./stringify":13}],12:[function(_dereq_,module,exports){ -// Load modules - -var Utils = _dereq_('./utils'); +/** + * is.divisibleBy + * Test if `value` is divisible by `n`. + * + * @param {Number} value value to test + * @param {Number} n dividend + * @return {Boolean} true if `value` is divisible by `n`, false otherwise + * @api public + */ +is.divisibleBy = function (value, n) { + var isDividendInfinite = is.infinite(value); + var isDivisorInfinite = is.infinite(n); + var isNonZeroNumber = is.number(value) && !isActualNaN(value) && is.number(n) && !isActualNaN(n) && n !== 0; + return isDividendInfinite || isDivisorInfinite || (isNonZeroNumber && value % n === 0); +}; -// Declare internals +/** + * is.int + * Test if `value` is an integer. + * + * @param value to test + * @return {Boolean} true if `value` is an integer, false otherwise + * @api public + */ -var internals = { - delimiter: '&', - depth: 5, - arrayLimit: 20, - parameterLimit: 1000 +is.int = function (value) { + return is.number(value) && !isActualNaN(value) && value % 1 === 0; }; +/** + * is.maximum + * Test if `value` is greater than 'others' values. + * + * @param {Number} value value to test + * @param {Array} others values to compare with + * @return {Boolean} true if `value` is greater than `others` values + * @api public + */ -internals.parseValues = function (str, options) { +is.maximum = function (value, others) { + if (isActualNaN(value)) { + throw new TypeError('NaN is not a valid value'); + } else if (!is.arraylike(others)) { + throw new TypeError('second argument must be array-like'); + } + var len = others.length; - var obj = {}; - var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + while (--len >= 0) { + if (value < others[len]) { + return false; + } + } - for (var i = 0, il = parts.length; i < il; ++i) { - var part = parts[i]; - var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + return true; +}; - if (pos === -1) { - obj[Utils.decode(part)] = ''; - } - else { - var key = Utils.decode(part.slice(0, pos)); - var val = Utils.decode(part.slice(pos + 1)); +/** + * is.minimum + * Test if `value` is less than `others` values. + * + * @param {Number} value value to test + * @param {Array} others values to compare with + * @return {Boolean} true if `value` is less than `others` values + * @api public + */ - if (!Object.prototype.hasOwnProperty.call(obj, key)) { - obj[key] = val; - } - else { - obj[key] = [].concat(obj[key]).concat(val); - } - } +is.minimum = function (value, others) { + if (isActualNaN(value)) { + throw new TypeError('NaN is not a valid value'); + } else if (!is.arraylike(others)) { + throw new TypeError('second argument must be array-like'); + } + var len = others.length; + + while (--len >= 0) { + if (value > others[len]) { + return false; } + } - return obj; + return true; }; +/** + * is.nan + * Test if `value` is not a number. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is not a number, false otherwise + * @api public + */ -internals.parseObject = function (chain, val, options) { +is.nan = function (value) { + return !is.number(value) || value !== value; +}; - if (!chain.length) { - return val; - } +/** + * is.even + * Test if `value` is an even number. + * + * @param {Number} value value to test + * @return {Boolean} true if `value` is an even number, false otherwise + * @api public + */ - var root = chain.shift(); +is.even = function (value) { + return is.infinite(value) || (is.number(value) && value === value && value % 2 === 0); +}; - var obj = {}; - if (root === '[]') { - obj = []; - obj = obj.concat(internals.parseObject(chain, val, options)); - } - else { - var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; - var index = parseInt(cleanRoot, 10); - var indexString = '' + index; - if (!isNaN(index) && - root !== cleanRoot && - indexString === cleanRoot && - index >= 0 && - index <= options.arrayLimit) { +/** + * is.odd + * Test if `value` is an odd number. + * + * @param {Number} value value to test + * @return {Boolean} true if `value` is an odd number, false otherwise + * @api public + */ - obj = []; - obj[index] = internals.parseObject(chain, val, options); - } - else { - obj[cleanRoot] = internals.parseObject(chain, val, options); - } - } +is.odd = function (value) { + return is.infinite(value) || (is.number(value) && value === value && value % 2 !== 0); +}; - return obj; +/** + * is.ge + * Test if `value` is greater than or equal to `other`. + * + * @param {Number} value value to test + * @param {Number} other value to compare with + * @return {Boolean} + * @api public + */ + +is.ge = function (value, other) { + if (isActualNaN(value) || isActualNaN(other)) { + throw new TypeError('NaN is not a valid value'); + } + return !is.infinite(value) && !is.infinite(other) && value >= other; }; +/** + * is.gt + * Test if `value` is greater than `other`. + * + * @param {Number} value value to test + * @param {Number} other value to compare with + * @return {Boolean} + * @api public + */ -internals.parseKeys = function (key, val, options) { +is.gt = function (value, other) { + if (isActualNaN(value) || isActualNaN(other)) { + throw new TypeError('NaN is not a valid value'); + } + return !is.infinite(value) && !is.infinite(other) && value > other; +}; - if (!key) { - return; - } +/** + * is.le + * Test if `value` is less than or equal to `other`. + * + * @param {Number} value value to test + * @param {Number} other value to compare with + * @return {Boolean} if 'value' is less than or equal to 'other' + * @api public + */ - // The regex chunks +is.le = function (value, other) { + if (isActualNaN(value) || isActualNaN(other)) { + throw new TypeError('NaN is not a valid value'); + } + return !is.infinite(value) && !is.infinite(other) && value <= other; +}; - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; +/** + * is.lt + * Test if `value` is less than `other`. + * + * @param {Number} value value to test + * @param {Number} other value to compare with + * @return {Boolean} if `value` is less than `other` + * @api public + */ - // Get the parent +is.lt = function (value, other) { + if (isActualNaN(value) || isActualNaN(other)) { + throw new TypeError('NaN is not a valid value'); + } + return !is.infinite(value) && !is.infinite(other) && value < other; +}; - var segment = parent.exec(key); +/** + * is.within + * Test if `value` is within `start` and `finish`. + * + * @param {Number} value value to test + * @param {Number} start lower bound + * @param {Number} finish upper bound + * @return {Boolean} true if 'value' is is within 'start' and 'finish' + * @api public + */ +is.within = function (value, start, finish) { + if (isActualNaN(value) || isActualNaN(start) || isActualNaN(finish)) { + throw new TypeError('NaN is not a valid value'); + } else if (!is.number(value) || !is.number(start) || !is.number(finish)) { + throw new TypeError('all arguments must be numbers'); + } + var isAnyInfinite = is.infinite(value) || is.infinite(start) || is.infinite(finish); + return isAnyInfinite || (value >= start && value <= finish); +}; - // Don't allow them to overwrite object prototype properties +/** + * Test object. + */ - if (Object.prototype.hasOwnProperty(segment[1])) { - return; - } +/** + * is.object + * Test if `value` is an object. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is an object, false otherwise + * @api public + */ - // Stash the parent if it exists +is.object = function (value) { + return value && '[object Object]' === toString.call(value); +}; - var keys = []; - if (segment[1]) { - keys.push(segment[1]); - } +/** + * is.hash + * Test if `value` is a hash - a plain object literal. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a hash, false otherwise + * @api public + */ - // Loop through children appending to the array until we hit depth +is.hash = function (value) { + return is.object(value) && value.constructor === Object && !value.nodeType && !value.setInterval; +}; - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { +/** + * Test regexp. + */ - ++i; - if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { - keys.push(segment[1]); - } - } +/** + * is.regexp + * Test if `value` is a regular expression. + * + * @param {Mixed} value value to test + * @return {Boolean} true if `value` is a regexp, false otherwise + * @api public + */ - // If there's a remainder, just add whatever is left +is.regexp = function (value) { + return '[object RegExp]' === toString.call(value); +}; - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } +/** + * Test string. + */ - return internals.parseObject(keys, val, options); +/** + * is.string + * Test if `value` is a string. + * + * @param {Mixed} value value to test + * @return {Boolean} true if 'value' is a string, false otherwise + * @api public + */ + +is.string = function (value) { + return '[object String]' === toString.call(value); }; -module.exports = function (str, options) { +},{}],32:[function(_dereq_,module,exports){ - if (str === '' || - str === null || - typeof str === 'undefined') { +/** + * Matcher, slightly modified from: + * + * https://github.com/csnover/js-iso8601/blob/lax/iso8601.js + */ - return {}; - } +var matcher = /^(\d{4})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:([ T])(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/; - options = options || {}; - options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; - options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; - options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; - options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; - var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; - var obj = {}; +/** + * Convert an ISO date string to a date. Fallback to native `Date.parse`. + * + * https://github.com/csnover/js-iso8601/blob/lax/iso8601.js + * + * @param {String} iso + * @return {Date} + */ - // Iterate over the keys and setup the new object +exports.parse = function (iso) { + var numericKeys = [1, 5, 6, 7, 8, 11, 12]; + var arr = matcher.exec(iso); + var offset = 0; - var keys = Object.keys(tempObj); - for (var i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - var newObj = internals.parseKeys(key, tempObj[key], options); - obj = Utils.merge(obj, newObj); - } + // fallback to native parsing + if (!arr) return new Date(iso); - return Utils.compact(obj); -}; + // remove undefined values + for (var i = 0, val; val = numericKeys[i]; i++) { + arr[val] = parseInt(arr[val], 10) || 0; + } -},{"./utils":14}],13:[function(_dereq_,module,exports){ -// Load modules + // allow undefined days and months + arr[2] = parseInt(arr[2], 10) || 1; + arr[3] = parseInt(arr[3], 10) || 1; -var Utils = _dereq_('./utils'); + // month is 0-11 + arr[2]--; + // allow abitrary sub-second precision + if (arr[8]) arr[8] = (arr[8] + '00').substring(0, 3); -// Declare internals + // apply timezone if one exists + if (arr[4] == ' ') { + offset = new Date().getTimezoneOffset(); + } else if (arr[9] !== 'Z' && arr[10]) { + offset = arr[11] * 60 + arr[12]; + if ('+' == arr[10]) offset = 0 - offset; + } -var internals = { - delimiter: '&', - arrayPrefixGenerators: { - brackets: function (prefix, key) { - return prefix + '[]'; - }, - indices: function (prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function (prefix, key) { - return prefix; - } - } + var millis = Date.UTC(arr[1], arr[2], arr[3], arr[5], arr[6] + offset, arr[7], arr[8]); + return new Date(millis); }; -internals.stringify = function (obj, prefix, generateArrayPrefix) { - - if (Utils.isBuffer(obj)) { - obj = obj.toString(); - } - else if (obj instanceof Date) { - obj = obj.toISOString(); - } - else if (obj === null) { - obj = ''; - } - - if (typeof obj === 'string' || - typeof obj === 'number' || - typeof obj === 'boolean') { - - return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; - } - - var values = []; - - if (typeof obj === 'undefined') { - return values; - } - - var objKeys = Object.keys(obj); - for (var i = 0, il = objKeys.length; i < il; ++i) { - var key = objKeys[i]; - if (Array.isArray(obj)) { - values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix)); - } - else { - values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix)); - } - } +/** + * Checks whether a `string` is an ISO date string. `strict` mode requires that + * the date string at least have a year, month and date. + * + * @param {String} string + * @param {Boolean} strict + * @return {Boolean} + */ - return values; +exports.is = function (string, strict) { + if (strict && false === /^\d{4}-\d{2}-\d{2}/.test(string)) return false; + return matcher.test(string); }; +},{}],33:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +/** Used to pool arrays and objects used internally */ +var arrayPool = []; -module.exports = function (obj, options) { +module.exports = arrayPool; - options = options || {}; - var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; +},{}],34:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCreate = _dereq_('lodash._basecreate'), + isObject = _dereq_('lodash.isobject'), + setBindData = _dereq_('lodash._setbinddata'), + slice = _dereq_('lodash._slice'); - var keys = []; +/** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ +var arrayRef = []; - if (typeof obj !== 'object' || - obj === null) { +/** Native method shortcuts */ +var push = arrayRef.push; - return ''; - } +/** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ +function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; - var arrayFormat; - if (options.arrayFormat in internals.arrayPrefixGenerators) { - arrayFormat = options.arrayFormat; - } - else if ('indices' in options) { - arrayFormat = options.indices ? 'indices' : 'repeat'; - } - else { - arrayFormat = 'indices'; + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); } - - var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat]; - - var objKeys = Object.keys(obj); - for (var i = 0, il = objKeys.length; i < il; ++i) { - var key = objKeys[i]; - keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix)); + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; +} - return keys.join(delimiter); -}; - -},{"./utils":14}],14:[function(_dereq_,module,exports){ -// Load modules - - -// Declare internals +module.exports = baseBind; -var internals = {}; +},{"lodash._basecreate":35,"lodash._setbinddata":45,"lodash._slice":47,"lodash.isobject":55}],35:[function(_dereq_,module,exports){ +(function (global){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var isNative = _dereq_('lodash._isnative'), + isObject = _dereq_('lodash.isobject'), + noop = _dereq_('lodash.noop'); +/* Native method shortcuts for methods with the same name as other `lodash` methods */ +var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate; -exports.arrayToObject = function (source) { +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; +} +// fallback for browsers without `Object.create` +if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || global.Object(); + }; + }()); +} - var obj = {}; - for (var i = 0, il = source.length; i < il; ++i) { - if (typeof source[i] !== 'undefined') { +module.exports = baseCreate; - obj[i] = source[i]; - } - } +}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"lodash._isnative":41,"lodash.isobject":55,"lodash.noop":57}],36:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var bind = _dereq_('lodash.bind'), + identity = _dereq_('lodash.identity'), + setBindData = _dereq_('lodash._setbinddata'), + support = _dereq_('lodash.support'); - return obj; -}; +/** Used to detected named functions */ +var reFuncName = /^\s*function[ \n\r\t]+\w/; +/** Used to detect functions containing a `this` reference */ +var reThis = /\bthis\b/; -exports.merge = function (target, source) { +/** Native method shortcuts */ +var fnToString = Function.prototype.toString; - if (!source) { - return target; +/** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ +function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; } - - if (typeof source !== 'object') { - if (Array.isArray(target)) { - target.push(source); - } - else { - target[source] = true; - } - - return target; - } - - if (typeof target !== 'object') { - target = [target].concat(source); - return target; - } - - if (Array.isArray(target) && - !Array.isArray(source)) { - - target = exports.arrayToObject(target); - } - - var keys = Object.keys(source); - for (var k = 0, kl = keys.length; k < kl; ++k) { - var key = keys[k]; - var value = source[key]; - - if (!target[key]) { - target[key] = value; - } - else { - target[key] = exports.merge(target[key], value); - } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); +} - return target; -}; - +module.exports = baseCreateCallback; -exports.decode = function (str) { +},{"lodash._setbinddata":45,"lodash.bind":48,"lodash.identity":52,"lodash.support":60}],37:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCreate = _dereq_('lodash._basecreate'), + isObject = _dereq_('lodash.isobject'), + setBindData = _dereq_('lodash._setbinddata'), + slice = _dereq_('lodash._slice'); - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; - } -}; +/** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ +var arrayRef = []; +/** Native method shortcuts */ +var push = arrayRef.push; -exports.compact = function (obj, refs) { +/** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ +function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; - if (typeof obj !== 'object' || - obj === null) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; - return obj; + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); } - - refs = refs || []; - var lookup = refs.indexOf(obj); - if (lookup !== -1) { - return refs[lookup]; + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } } - - refs.push(obj); - - if (Array.isArray(obj)) { - var compacted = []; - - for (var i = 0, il = obj.length; i < il; ++i) { - if (typeof obj[i] !== 'undefined') { - compacted.push(obj[i]); - } - } - - return compacted; + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; } - - var keys = Object.keys(obj); - for (i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - obj[key] = exports.compact(obj[key], refs); + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; +} - return obj; -}; +module.exports = baseCreateWrapper; +},{"lodash._basecreate":35,"lodash._setbinddata":45,"lodash._slice":47,"lodash.isobject":55}],38:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var forIn = _dereq_('lodash.forin'), + getArray = _dereq_('lodash._getarray'), + isFunction = _dereq_('lodash.isfunction'), + objectTypes = _dereq_('lodash._objecttypes'), + releaseArray = _dereq_('lodash._releasearray'); -exports.isRegExp = function (obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; +/** `Object#toString` result shortcuts */ +var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; +/** Used for native method references */ +var objectProto = Object.prototype; -exports.isBuffer = function (obj) { +/** Used to resolve the internal [[Class]] of values */ +var toString = objectProto.toString; - if (obj === null || - typeof obj === 'undefined') { +/** Native method shortcuts */ +var hasOwnProperty = objectProto.hasOwnProperty; - return false; +/** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; - return !!(obj.constructor && - obj.constructor.isBuffer && - obj.constructor.isBuffer(obj)); -}; - -},{}],15:[function(_dereq_,module,exports){ -var _ = _dereq_('underscore'); -var handlebars_helper = _dereq_('handlebars-helper'); -var EventEmitter = _dereq_('events').EventEmitter; -var util = _dereq_('util'); + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); -var Resource = _dereq_('./lib/resource.js'); -var View = _dereq_('./lib/view.js'); - -var SolidusClient = function(options) { - if (!(this instanceof SolidusClient)) return new SolidusClient(options); - - options || (options = {}); - this.resources_options = options.resources_options; - this.context = options.context || {}; -}; - -// HACK: needed by universe.js... -util.inherits(SolidusClient, EventEmitter); - -SolidusClient.prototype.getResource = function(options, params, callback) { - var resource = new Resource(options, this.resources_options, params); - resource.get(function(err, response) { - callback(err, response ? response.data : null); - }); -}; - -SolidusClient.prototype.getResources = function(resources, params, callback) { - var self = this; - var errors = null; - var result = {}; - var remaining = _.size(resources); + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; - if (!remaining) return callback(errors, result); + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); - _.each(resources, function(options, name) { - self.getResource(options, params, function(err, data) { - if (err) { - errors = errors || {}; - errors[name] = err; - } else { - result[name] = data; - } - if (!--remaining) callback(errors, result); - }); - }); -}; + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); -SolidusClient.prototype.renderTemplate = function(template, context, template_options, callback) { - var html, err; + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = a.constructor, + ctorB = b.constructor; - template_options = template_options || {}; - template_options.helpers = _.extend(handlebars_helper.helpers, template_options.helpers || {}); + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); - try { - html = template(context, template_options); - } catch (error) { - err = error; + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } } + var size = 0; + result = true; - callback(err, html); -}; + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); -SolidusClient.prototype.view = function(view) { - var self = this; + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; - view.render = function() { - var args = Array.prototype.slice.call(arguments); - args.unshift(this); - return self.render.apply(self, args); - }; + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; - return view; -}; + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); -SolidusClient.prototype.render = function(view, params, callback) { - var renderer = new View(this, view); - if (!callback && _.isFunction(params)) { - callback = params; - params = null; + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } } - if (params) { - renderer.params(params); + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); } - return callback ? renderer.end(callback) : renderer; -}; + return result; +} -module.exports = SolidusClient; +module.exports = baseIsEqual; -},{"./lib/resource.js":17,"./lib/view.js":19,"events":2,"handlebars-helper":21,"underscore":126,"util":9}],16:[function(_dereq_,module,exports){ -/* - * Copyright (c) 2010 Nick Galbreath - * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. +},{"lodash._getarray":40,"lodash._objecttypes":43,"lodash._releasearray":44,"lodash.forin":50,"lodash.isfunction":54}],39:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license */ +var baseBind = _dereq_('lodash._basebind'), + baseCreateWrapper = _dereq_('lodash._basecreatewrapper'), + isFunction = _dereq_('lodash.isfunction'), + slice = _dereq_('lodash._slice'); -/* base64 encode/decode compatible with window.btoa/atob - * - * window.atob/btoa is a Firefox extension to convert binary data (the "b") - * to base64 (ascii, the "a"). - * - * It is also found in Safari and Chrome. It is not available in IE. - * - * if (!window.btoa) window.btoa = base64.encode - * if (!window.atob) window.atob = base64.decode - * - * The original spec's for atob/btoa are a bit lacking - * https://developer.mozilla.org/en/DOM/window.atob - * https://developer.mozilla.org/en/DOM/window.btoa - * - * window.btoa and base64.encode takes a string where charCodeAt is [0,255] - * If any character is not [0,255], then an DOMException(5) is thrown. +/** + * Used for `Array` method references. * - * window.atob and base64.decode take a base64-encoded string - * If the input length is not a multiple of 4, or contains invalid characters - * then an DOMException(5) is thrown. + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. */ -var base64 = {}; -base64.PADCHAR = '='; -base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +var arrayRef = []; -base64.makeDOMException = function() { - // sadly in FF,Safari,Chrome you can't make a DOMException - var e, tmp; +/** Native method shortcuts */ +var push = arrayRef.push, + unshift = arrayRef.unshift; - try { - return new DOMException(DOMException.INVALID_CHARACTER_ERR); - } catch (tmp) { - // not available, just passback a duck-typed equiv - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype - var ex = new Error("DOM Exception 5"); - - // ex.number and ex.description is IE-specific. - ex.code = ex.number = 5; - ex.name = ex.description = "INVALID_CHARACTER_ERR"; +/** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ +function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; - // Safari/Chrome output format - ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; }; - return ex; + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); } -} - -base64.getbyte = function(s,i) { - var x = s.charCodeAt(i); - if (x > 255) { - throw base64.makeDOMException(); + if (bindData[3]) { + bindData[3] = slice(bindData[3]); } - return x; -} - -base64.encode = function(s) { - if (arguments.length !== 1) { - throw new SyntaxError("Not enough arguments"); + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; } - var padchar = base64.PADCHAR; - var alpha = base64.ALPHA; - var getbyte = base64.getbyte; - - var i, b10; - var x = []; - - // convert to string - s = '' + s; - - var imax = s.length - s.length % 3; - - if (s.length === 0) { - return s; + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; } - for (i = 0; i < imax; i += 3) { - b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2); - x.push(alpha.charAt(b10 >> 18)); - x.push(alpha.charAt((b10 >> 12) & 0x3F)); - x.push(alpha.charAt((b10 >> 6) & 0x3f)); - x.push(alpha.charAt(b10 & 0x3f)); + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; } - switch (s.length - imax) { - case 1: - b10 = getbyte(s,i) << 16; - x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + - padchar + padchar); - break; - case 2: - b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8); - x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + - alpha.charAt((b10 >> 6) & 0x3f) + padchar); - break; + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); } - return x.join(''); + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); } -module.exports = base64; +module.exports = createWrapper; -},{}],17:[function(_dereq_,module,exports){ -var DYNAMIC_SEGMENTS = /\{([^\}]*)\}/ig; -var DEFAULT_ENCODING = 'UTF8'; -var DEFAULT_SOLIDUS_API_ROUTE = '/api/'; -var DEFAULT_TIMEOUT = 20000; -var NOT_FOUND = /(404|not[ -_]?found|not[ -_]?find|no[ -_]?\w+?[ -_]?found|invalid[ -_]?\w+|unknown[ -_]?\w+|do(es)?[ -_]?not[ -_]?exist|empty)/i; +},{"lodash._basebind":34,"lodash._basecreatewrapper":37,"lodash._slice":47,"lodash.isfunction":54}],40:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var arrayPool = _dereq_('lodash._arraypool'); -var _ = _dereq_('underscore'); -var qs = _dereq_('qs'); -var superagent = _dereq_('superagent'); -var extend = _dereq_('extend'); +/** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ +function getArray() { + return arrayPool.pop() || []; +} -var util = _dereq_('./util'); +module.exports = getArray; -// SuperAgent uses btoa for auth encoding on the client, which is missing from + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ -var Resource = function(options, resources_options, params) { - if (_.isString(options)) { - initializeUrl.call(this, options, params || {}); - initializeOptions.call(this, {}, resources_options || {}, params || {}); - } else { - initializeUrl.call(this, options.url, params || {}); - initializeOptions.call(this, _.omit(options, 'url'), resources_options || {}, params || {}); - } -}; +/** Used for native method references */ +var objectProto = Object.prototype; -Resource.prototype.requestType = function() { - if (!util.isNode) { - if (this.options.proxy) return 'proxy'; - if (this.options.jsonp || (this.options.with_credentials && !util.supportsCORS)) return 'jsonp'; - } - return 'client'; -}; +/** Used to resolve the internal [[Class]] of values */ +var toString = objectProto.toString; -Resource.prototype.requestUrl = function() { - if (!this.url) return; +/** Used to detect if a method is native */ +var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' +); - switch (this.requestType()) { - case 'proxy': - return proxyRequestUrl.call(this); - case 'jsonp': - return jsonpRequestUrl.call(this); - case 'client': - return clientRequestUrl.call(this); - } -}; +/** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ +function isNative(value) { + return typeof value == 'function' && reNative.test(value); +} -Resource.prototype.get = function(callback) { - request.call(this, 'get', null, callback); -}; +module.exports = isNative; -Resource.prototype.post = function(data, callback) { - request.call(this, 'post', data, callback); -}; +},{}],42:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ -// PRIVATE +/** Used as the max size of the `arrayPool` and `objectPool` */ +var maxPoolSize = 40; -var initializeUrl = function(url, params) { - if (validUrl(url)) { - var expanded = expandVariables(url, params); - this.url = expanded[0]; - this.dynamic = expanded[1]; - } else { - this.url = null; - this.dynamic = false; - } -}; +module.exports = maxPoolSize; -var initializeOptions = function(options, resources_options, params) { - var self = this; - self.options = {timeout: DEFAULT_TIMEOUT}; +},{}],43:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ - // Find all the matching global options - _.each(resources_options, function(options, match) { - var matcher = new RegExp(match, 'ig'); - if (matcher.test(self.url)) extend(true, self.options, options); - }); - - // Merge the resource options - extend(true, self.options, options); - - // Expand the query options - _.each(self.options.query, function(value, name) { - if (!_.isString(value)) return; - var expanded = expandVariables(value, params); - self.options.query[name] = expanded[0]; - if (expanded[1]) self.dynamic = true; - }); -}; - -var validUrl = function(url) { - return /^https?:\/\/.+/.test(url); +/** Used to determine if values are of the language type Object */ +var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false }; -var expandVariables = function(string, params) { - var expanded = false; - var result = string.replace(DYNAMIC_SEGMENTS, function(match, capture) { - expanded = true; - return params[capture] || ''; - }); - return [result, expanded]; -}; +module.exports = objectTypes; -var request = function(method, data, callback) { - if (!this.url) return callback(null, {}); +},{}],44:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var arrayPool = _dereq_('lodash._arraypool'), + maxPoolSize = _dereq_('lodash._maxpoolsize'); - var request_type; - switch (this.requestType()) { - case 'proxy': - request_type = proxyRequest; - break; - case 'jsonp': - request_type = jsonpRequest; - break; - case 'client': - request_type = clientRequest; - break; +/** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ +function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); } +} - var result = {request_time: new Date().getTime()}; - request_type.call(this, method, data, function(err, res, data) { - result.response_time = new Date().getTime(); - result.response = res; - result.data = data; - callback(err, result); - }); -}; - -var proxyRequest = function(method, data, callback) { - if (method != 'get') return callback('Invalid proxy method: ' + method); - - var request = superagent.get(proxyRequestUrl.call(this)); +module.exports = releaseArray; - if (this.options.timeout) request.timeout(this.options.timeout); +},{"lodash._arraypool":33,"lodash._maxpoolsize":42}],45:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var isNative = _dereq_('lodash._isnative'), + noop = _dereq_('lodash.noop'); - superAgentRequest(request, callback); +/** Used as the property descriptor for `__bindData__` */ +var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false }; -var proxyRequestUrl = function() { - var route = (this.options.solidus_api_route || DEFAULT_SOLIDUS_API_ROUTE) + 'resource.json'; - var url = buildUrl.call(this, this.url); - return route + '?url=' + encodeURIComponent(url); -}; +/** Used to set meta data on functions */ +var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; +}()); -var jsonpRequest = function(method, data, callback) { - if (method != 'get' & method != 'post') return callback('Invalid JSONP method: ' + method); +/** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ +var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); +}; - var self = this; - var callbackName = 'solidus_client_jsonp_callback_' + Math.round(100000 * Math.random()); - var url = buildUrl.call(self, jsonpRequestUrl.call(self), {callback: callbackName}, _.isObject(data) ? data : {}); - if (_.isString(data)) url += '&' + data; +module.exports = setBindData; - var script = document.createElement('script'); - script.src = url; +},{"lodash._isnative":41,"lodash.noop":57}],46:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var objectTypes = _dereq_('lodash._objecttypes'); - var timer; - var first = true; +/** Used for native method references */ +var objectProto = Object.prototype; - window[callbackName] = function(data) { - var timedout = data instanceof Error; +/** Native method shortcuts */ +var hasOwnProperty = objectProto.hasOwnProperty; - // Cancel timeout - if (timer) { - clearTimeout(timer); - timer = null; +/** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ +var shimKeys = function(object) { + var index, iterable = object, result = []; + if (!iterable) return result; + if (!(objectTypes[typeof object])) return result; + for (index in iterable) { + if (hasOwnProperty.call(iterable, index)) { + result.push(index); + } } + return result +}; - // Do not cleanup if there was a timeout, in case the real request ever comes back - if (!timedout) { - document.getElementsByTagName('head')[0].removeChild(script); - delete window[callbackName]; - } +module.exports = shimKeys; - // Only run user callback once - if (first) { - first = false; - timedout ? callback(data) : processResponse({status: 200}, data, callback); - } - }; +},{"lodash._objecttypes":43}],47:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ - if (self.options.timeout) { - timer = setTimeout(function() { - timer = null; - var err = new Error('Timeout of ' + self.options.timeout + 'ms exceeded'); - err.callbackName = callbackName; // For testing purposes - window[callbackName](err); - }, self.options.timeout); +/** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ +function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); - document.getElementsByTagName('head')[0].appendChild(script); -}; - -var jsonpRequestUrl = function(data) { - return buildUrl.call(this, this.url); -}; - -var clientRequest = function(method, data, callback) { - if (method != 'get' & method != 'post') return callback('Invalid method: ' + method); - - var url = clientRequestUrl.call(this); - var request = method == 'get' ? superagent.get(url) : superagent.post(url).send(data); + while (++index < length) { + result[index] = array[start + index]; + } + return result; +} - if (this.options.headers) request.set(this.options.headers); - if (this.options.auth) request.auth(this.options.auth.user, this.options.auth.pass); - if (this.options.with_credentials && !util.isNode) request.withCredentials(); - if (this.options.timeout) request.timeout(this.options.timeout); +module.exports = slice; - superAgentRequest(request, callback); -}; +},{}],48:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var createWrapper = _dereq_('lodash._createwrapper'), + slice = _dereq_('lodash._slice'); -var clientRequestUrl = function() { - return buildUrl.call(this, this.url); -}; - -var buildUrl = function(url) { - var start = url.indexOf('?') + 1; - var query = []; - if (start > 0) query.push(qs.parse(url.substring(start))); - if (this.options.query) query.push(this.options.query); - query = query.concat(Array.prototype.slice.call(arguments, 1)); - query = _.extend.apply(_, query); - - if (this.options.query_options && this.options.query_options['objectFormat'] === 'json') { - _.each(query, function(value, key) { - if (_.isObject(value) && !_.isArray(value)) query[key] = JSON.stringify(value); - }); - } +/** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ +function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); +} - query = qs.stringify(query, this.options.query_options); - if (query) { - return (start > 0 ? url.substring(0, start - 1) : url) + '?' + query; - } else { - return url; - } -}; +module.exports = bind; -var superAgentRequest = function(request, callback) { - // Force buffering of response bodies as res.text - // http://visionmedia.github.io/superagent/#buffering-responses - if (util.isNode) request.buffer(); +},{"lodash._createwrapper":39,"lodash._slice":47}],49:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.4 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCreateCallback = _dereq_('lodash._basecreatecallback'), + baseIsEqual = _dereq_('lodash._baseisequal'), + isObject = _dereq_('lodash.isobject'), + keys = _dereq_('lodash.keys'), + property = _dereq_('lodash.property'); - // Not all weird browser errors are catched by SuperAgent - try { - request.end(function(err, res) { - // In case the request is not async, we don't want to catch the callback exceptions - setTimeout(function() { - // SuperAgent considers statuses <200 and >=300 as errors - // http://visionmedia.github.io/superagent/#error-handling - if (err) return callback(err, res); - processResponse(res, null, callback); - }, 0); - }); - } catch (err) { - callback(err); +/** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ +function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); } -} - -var processResponse = function(res, data, callback) { - processData(res, data, function(err, data) { - if (err) return callback(err, res); - processDataStatus(data, function(err) { - callback(err, res, data); - }); - }); -}; - -var processData = function(res, data, callback) { - var err; - if (!_.isObject(data)) { - try { - data = JSON.parse(res.text.toString(DEFAULT_ENCODING)); - } catch (error) { - err = new Error('Invalid JSON'); - err.error = error.message; - } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); } - callback(err, data); -}; + var props = keys(func), + key = props[0], + a = func[key]; -var processDataStatus = function(data, callback) { - var err; - if (String(data.status).toLowerCase() == 'error') { - var message = (data.messages || []).concat([data.error, data.message, data.response, data.body]).join(' '); - err = new Error('Invalid data status'); - err.status = message.match(NOT_FOUND) ? 404 : 500; + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; } - callback(err); -}; - -module.exports = Resource; - -},{"./base64":16,"./util":18,"extend":20,"qs":10,"superagent":120,"underscore":126}],18:[function(_dereq_,module,exports){ -var qs = _dereq_('querystring'); - -module.exports.isNode = !(typeof window !== 'undefined' && window !== null); - -module.exports.supportsCORS = !module.exports.isNode && (typeof XMLHttpRequest !== 'undefined') && ('withCredentials' in new XMLHttpRequest()); - -module.exports.params = !module.exports.isNode?qs.parse(window.location.search.split('?').pop()):{}; - -},{"querystring":7}],19:[function(_dereq_,module,exports){ -var _ = _dereq_('underscore'); + return function(object) { + var length = props.length, + result = false; -var util = _dereq_('./util'); + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; +} -var View = function(solidus_client, view) { - this.solidus_client = solidus_client; +module.exports = createCallback; - if (_.isFunction(view)) { - this.template = view; - } else { - this.resources = view.resources; - this.resources_params = view.params; - this.preprocessor = view.preprocessor; - this.template = view.template; - this.template_options = view.template_options; - } +},{"lodash._basecreatecallback":36,"lodash._baseisequal":38,"lodash.isobject":55,"lodash.keys":56,"lodash.property":58}],50:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCreateCallback = _dereq_('lodash._basecreatecallback'), + objectTypes = _dereq_('lodash._objecttypes'); - this.resources = this.resources || {}; - this.resources_params = this.resources_params || {}; - this.template_options = this.template_options || {}; +/** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ +var forIn = function(collection, callback, thisArg) { + var index, iterable = collection, result = iterable; + if (!iterable) return result; + if (!objectTypes[typeof iterable]) return result; + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + for (index in iterable) { + if (callback(iterable[index], index, collection) === false) return result; + } + return result }; -View.prototype.params = function(params) { - this.resources_params = params; - return this; -}; +module.exports = forIn; -View.prototype.templateOptions = function(template_options) { - this.template_options = template_options; - return this; -}; - -View.prototype.get = function(resources) { - this.resources = resources; - return this; -}; - -View.prototype.then = function(preprocessor) { - this.preprocessor = preprocessor; - return this; -}; - -View.prototype.end = function(callback) { - var self = this; - - getResources.call(self, function(err, resources) { - if (err) return callback(err); - - addResourcesToContext.call(self, resources); - - preprocessContext.call(self, function(err) { - if (err) return callback(err); - - self.solidus_client.renderTemplate(self.template, self.solidus_client.context, self.template_options, callback); - }); - }); -}; - -// Hacks for easier testing -View.redirect = function(url) { - window.location.href = url; -}; -View.preprocessor_timeout = 10000; +},{"lodash._basecreatecallback":36,"lodash._objecttypes":43}],51:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCreateCallback = _dereq_('lodash._basecreatecallback'), + keys = _dereq_('lodash.keys'), + objectTypes = _dereq_('lodash._objecttypes'); -// PRIVATE +/** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ +var forOwn = function(collection, callback, thisArg) { + var index, iterable = collection, result = iterable; + if (!iterable) return result; + if (!objectTypes[typeof iterable]) return result; + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + var ownIndex = -1, + ownProps = objectTypes[typeof iterable] && keys(iterable), + length = ownProps ? ownProps.length : 0; -var getResources = function(callback) { - var self = this; - self.solidus_client.getResources(self.resources, self.resources_params, function(err, resources) { - if (err) { - err = _.find(err, function(err, resource) { - return !self.resources[resource].optional - }); + while (++ownIndex < length) { + index = ownProps[ownIndex]; + if (callback(iterable[index], index, collection) === false) return result; } - callback(err, resources); - }); + return result }; -var addResourcesToContext = function(resources) { - this.solidus_client.context.resources || (this.solidus_client.context.resources = {}); - for (var name in resources) { - this.solidus_client.context.resources[name] = resources[name]; - } -}; +module.exports = forOwn; -var preprocessContext = function(callback) { - var self = this; - if (!self.preprocessor) return callback(); +},{"lodash._basecreatecallback":36,"lodash._objecttypes":43,"lodash.keys":56}],52:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ - var preprocessor_type = self.preprocessor.length === 1 ? preprocessContextSync : preprocessContextAsync; +/** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ +function identity(value) { + return value; +} - preprocessor_type.call(self, function(err, context) { - if (err) { - callback(err); - } else if (_.isString(context)) { - if (util.isNode) return callback(new Error('Cannot redirect')); - View.redirect(context); - } else if (_.isArray(context) && context.length === 2 && _.isNumber(context[0]) && _.isString(context[1])) { - if (util.isNode) return callback(new Error('Cannot redirect')); - View.redirect(context[1]); - } else if (!_.isObject(context)) { - callback(new Error('Preprocessor returned invalid context')); - } else { - self.solidus_client.context = context; - callback(); - } - }); -}; +module.exports = identity; -var preprocessContextSync = function(callback) { - var context, err; +},{}],53:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var isNative = _dereq_('lodash._isnative'); - try { - context = this.preprocessor(this.solidus_client.context); - } catch (error) { - err = error; - } +/** `Object#toString` result shortcuts */ +var arrayClass = '[object Array]'; - callback(err, context); -}; +/** Used for native method references */ +var objectProto = Object.prototype; -var preprocessContextAsync = function(callback) { - var done = _.once(callback); +/** Used to resolve the internal [[Class]] of values */ +var toString = objectProto.toString; - setTimeout(function() { - done(new Error('Preprocessor timeout')); - }, View.preprocessor_timeout); +/* Native method shortcuts for methods with the same name as other `lodash` methods */ +var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray; - try { - this.preprocessor(this.solidus_client.context, function(context) { - // In case the preprocessor is not async, we don't want to catch the callback exceptions - setTimeout(function() { - done(null, context); - }, 0); - }); - } catch (err) { - done(err); - } +/** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ +var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; }; -module.exports = View; - -},{"./util":18,"underscore":126}],20:[function(_dereq_,module,exports){ -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; -var undefined; +module.exports = isArray; -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } +},{"lodash._isnative":41}],54:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ - return toStr.call(arr) === '[object Array]'; -}; +/** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ +function isFunction(value) { + return typeof value == 'function'; +} -var isPlainObject = function isPlainObject(obj) { - 'use strict'; - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } +module.exports = isFunction; - var has_own_constructor = hasOwn.call(obj, 'constructor'); - var has_is_property_of_method = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !has_own_constructor && !has_is_property_of_method) { - return false; - } +},{}],55:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var objectTypes = _dereq_('lodash._objecttypes'); - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) {} - - return key === undefined || hasOwn.call(obj, key); -}; - -module.exports = function extend() { - 'use strict'; - var options, name, src, copy, copyIsArray, clone, - target = arguments[0], - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target === copy) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[name] = extend(deep, clone, copy); - - // Don't bring in undefined values - } else if (copy !== undefined) { - target[name] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - - -},{}],21:[function(_dereq_,module,exports){ -module.exports = _dereq_('./lib'); -},{"./lib":46}],22:[function(_dereq_,module,exports){ -module.exports = function(){ - var numbers = Array.prototype.slice.call( arguments, 0, -1 ); - var result = 0; - for( var i = numbers.length - 1; i >= 0; i-- ){ - result += parseFloat( numbers[i], 10 ) || 0; - } - return result; -}; -},{}],23:[function(_dereq_,module,exports){ -// Modified form of `timeago` helper from https://github.com/assemble/handlebars-helpers - -var newDate = _dereq_('new-date'); - -var YEAR = 60 * 60 * 24 * 365; -var MONTH = 60 * 60 * 24 * 30; -var DAY = 60 * 60 * 24; -var HOUR = 60 * 60; - -module.exports = function( date ){ - date = newDate( date ); - var seconds = Math.floor( ( new Date() - date ) / 1000 ); - var interval = Math.floor( seconds / YEAR ); - if( interval > 1 ) return interval +' years ago'; - interval = Math.floor( seconds / MONTH ); - if( interval > 1 ) return interval +' months ago'; - interval = Math.floor( seconds / DAY ); - if( interval > 1 ) return interval +' days ago'; - interval = Math.floor( seconds / HOUR ); - if( interval > 1 ) return interval +' hours ago'; - interval = Math.floor( seconds / 60 ); - if( interval > 1 ) return interval +' minutes ago'; - if( Math.floor( seconds ) <= 1 ) return 'Just now'; - else return Math.floor( seconds ) +' seconds ago'; -}; -},{"new-date":113}],24:[function(_dereq_,module,exports){ -module.exports = function( collection, start, end, options ){ - options = options || end; - if( typeof start !== 'number' ) return; - end = ( typeof end !== 'number' ) ? collection.length : ( end > 0 )? end + 1 : end; - collection = collection.slice( start, end ); - var result = ''; - for( var i = 0; i < collection.length; i++ ){ - result += options.fn( collection[i] ); - } - return result; -}; -},{}],25:[function(_dereq_,module,exports){ -module.exports = function( collection, item, options ){ - // string check - if( typeof collection === 'string' ){ - if( collection.search( item ) >= 0 ){ - return options.fn(this); - } - else { - return options.inverse(this); - } - } - // "collection" check (objects & arrays) - for( var prop in collection ){ - if( collection.hasOwnProperty( prop ) ){ - if( collection[prop] == item ) return options.fn(this); - } - } - return options.inverse(this); -}; -},{}],26:[function(_dereq_,module,exports){ -module.exports = function(){ - var numbers = Array.prototype.slice.call( arguments, 1, -1 ); - var result = arguments[0]; - for( var i = numbers.length - 1; i >= 0; i-- ){ - result /= parseFloat( numbers[i], 10 ) || 0; - } - return result; -}; -},{}],27:[function(_dereq_,module,exports){ -module.exports = function( string ){ - return encodeURIComponent( string ); -}; -},{}],28:[function(_dereq_,module,exports){ -module.exports = function( left, right, exact, options ){ - options = options || exact; - exact = ( exact === 'exact' ) ? true : false; - var is_equal = exact ? ( left === right ) : ( left == right ); - if( is_equal ) return options.fn(this); - return options.inverse(this); -}; -},{}],29:[function(_dereq_,module,exports){ -module.exports = function( collection, count, options ){ - options = options || count; - count = ( typeof count === 'number' ) ? count : 1; - var result = ''; - var i = 0; - for( var key in collection ){ - if( collection.hasOwnProperty( key ) ){ - result += options.fn( collection[key] ); - i++; - if( i == count ) break; - } - } - return result; -}; -},{}],30:[function(_dereq_,module,exports){ -var strftimeTZ = _dereq_('strftime').strftimeTZ; -var newDate = _dereq_('new-date'); - -module.exports = function( date_string, format, offset ){ - offset = ( typeof offset === 'number' ) ? offset : null; - var date = newDate( date_string ); - return strftimeTZ( format, date, offset ); -}; -},{"new-date":113,"strftime":118}],31:[function(_dereq_,module,exports){ -module.exports = function( left, right, equal, options ){ - options = options || equal; - equal = ( equal === 'equal' ) ? true : false; - var is_greater = equal ? ( left >= right ) : ( left > right ); - if( is_greater ) return options.fn( this ); - return options.inverse( this ); -}; -},{}],32:[function(_dereq_,module,exports){ -module.exports = function( collection, separator ){ - separator = ( typeof separator === 'string' ) ? separator : ''; - // if the collectoin is an array this is easy - if( collection.join ) return collection.join( separator ); - // if it's not we actually have to write code. - var result = ''; - for( var property in collection ){ - if( collection.hasOwnProperty(property) ){ - result += collection[property] + separator; - } - } - return result.slice( 0, -separator.length ); -}; -},{}],33:[function(_dereq_,module,exports){ -var _isArray = _dereq_('lodash.isarray'); -var _reduce = _dereq_('lodash.reduce'); - -module.exports = function( collection, count, options ){ - options = options || count; - count = ( typeof count === 'number' ) ? count : 1; - // if collection is an object, make it an array - // otherwise we have no way to clip off the "end" - if( !_isArray( collection ) ){ - var collection_array = []; - for( var key in collection ){ - if( collection.hasOwnProperty( key ) ){ - collection_array.push( collection[key] ); - } - } - collection = collection_array; - } - var collection_last = collection.slice( -1 * count ); - var result = _reduce( collection_last, function( previous, current ){ - return previous + options.fn( current ); - }, '' ); - return result; -}; -},{"lodash.isarray":47,"lodash.reduce":49}],34:[function(_dereq_,module,exports){ -module.exports = function( collection ){ - if( collection.length ) return collection.length; - var length = 0; - for( var prop in collection ){ - if( collection.hasOwnProperty( prop ) ){ - length++; - } - } - return length; -}; -},{}],35:[function(_dereq_,module,exports){ -module.exports = function( left, right, equal, options ){ - options = options || equal; - equal = ( equal === 'equal' ) ? true : false; - var is_greater = equal ? ( left <= right ) : ( left < right ); - if( is_greater ) return options.fn( this ); - return options.inverse( this ); -}; -},{}],36:[function(_dereq_,module,exports){ -module.exports = function( string ){ - return ( string || '' ).toLowerCase(); -}; -},{}],37:[function(_dereq_,module,exports){ -module.exports = function(){ - var numbers = Array.prototype.slice.call( arguments, 1, -1 ); - var result = arguments[0]; - for( var i = numbers.length - 1; i >= 0; i-- ){ - result *= parseFloat( numbers[i], 10 ) || 0; - } - return result; -}; -},{}],38:[function(_dereq_,module,exports){ -module.exports = function( collection, start, amount, options ){ - options = options || amount; - if( typeof start !== 'number' ) return; - var end = ( typeof amount !== 'number' ) ? collection.length : start + amount; - collection = collection.slice( start, end ); - var result = ''; - for( var i = 0; i < collection.length; i++ ){ - result += options.fn( collection[i] ); - } - return result; -}; -},{}],39:[function(_dereq_,module,exports){ -module.exports = function( string, to_replace, replacement ){ - return ( string || '' ).replace( to_replace, replacement ); -}; -},{}],40:[function(_dereq_,module,exports){ -module.exports = function( collection, options ){ - var result = ''; - for( var i = collection.length - 1; i >= 0; i-- ){ - result += options.fn( collection[i] ); - } - return result; -}; -},{}],41:[function(_dereq_,module,exports){ -// Simple shuffling method based off of http://bost.ocks.org/mike/shuffle/ -var shuffle = function( array ){ - var i = array.length, j, swap; - while( i ){ - j = Math.floor( Math.random() * i-- ); - swap = array[i]; - array[i] = array[j]; - array[j] = swap; - } - return array; -}; - -module.exports = function( collection, options ){ - var shuffled = shuffle( collection ); - var result = ''; - for( var i = 0; i < shuffled.length; i++ ){ - result += options.fn( shuffled[i] ); - } - return result; -}; -},{}],42:[function(_dereq_,module,exports){ -module.exports = function(){ - var numbers = Array.prototype.slice.call( arguments, 1, -1 ); - var result = parseFloat( arguments[0], 10 ); - for( var i = numbers.length - 1; i >= 0; i-- ){ - result -= parseFloat( numbers[i], 10 ) || 0; - } - return result; -}; -},{}],43:[function(_dereq_,module,exports){ -module.exports = function( number, zero, options ){ - options = options || zero; - zero = ( zero === 'zero' ) ? true : false; - var result = ''; - var i; - if( zero ){ - for( i = 0; i < number; i++ ) result += options.fn( i ); - } - else { - for( i = 1; i <= number; i++ ) result += options.fn( i ); - } - return result; -}; -},{}],44:[function(_dereq_,module,exports){ -module.exports = function( string ){ - return ( string || '' ).toUpperCase(); -}; -},{}],45:[function(_dereq_,module,exports){ -module.exports = function( collection, key, value, limit, options ){ - options = options || limit; - if( typeof limit !== 'number' ) limit = Infinity; - var matches = 0; - var result = ''; - for( var i = 0; i < collection.length; i++ ){ - if( collection[i][key] === value ){ - result += options.fn( collection[i] ); - matches++; - if( matches === limit ) return result; - } - } - return result; -}; -},{}],46:[function(_dereq_,module,exports){ -var helpers = { - // string - lowercase: _dereq_('./helpers/lowercase.js'), - uppercase: _dereq_('./helpers/uppercase.js'), - replace: _dereq_('./helpers/replace.js'), - encode: _dereq_('./helpers/encode.js'), - // collection - length: _dereq_('./helpers/length.js'), - contains: _dereq_('./helpers/contains.js'), - first: _dereq_('./helpers/first.js'), - last: _dereq_('./helpers/last.js'), - between: _dereq_('./helpers/between.js'), - range: _dereq_('./helpers/range.js'), - where: _dereq_('./helpers/where.js'), - shuffle: _dereq_('./helpers/shuffle.js'), - reverse: _dereq_('./helpers/reverse.js'), - join: _dereq_('./helpers/join.js'), - // date - ago: _dereq_('./helpers/ago.js'), - formatDate: _dereq_('./helpers/formatDate.js'), - // equality - equal: _dereq_('./helpers/equal.js'), - greater: _dereq_('./helpers/greater.js'), - less: _dereq_('./helpers/less.js'), - // numbers - times: _dereq_('./helpers/times.js'), - add: _dereq_('./helpers/add.js'), - subtract: _dereq_('./helpers/subtract.js'), - multiply: _dereq_('./helpers/multiply.js'), - divide: _dereq_('./helpers/divide.js') -}; +/** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); +} -module.exports.help = function( Handlebars ){ - for( var name in helpers ){ - Handlebars.registerHelper( name, helpers[name] ); - } +module.exports = isObject; + +},{"lodash._objecttypes":43}],56:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var isNative = _dereq_('lodash._isnative'), + isObject = _dereq_('lodash.isobject'), + shimKeys = _dereq_('lodash._shimkeys'); + +/* Native method shortcuts for methods with the same name as other `lodash` methods */ +var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; + +/** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ +var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + return nativeKeys(object); }; -module.exports.helpers = helpers; +module.exports = keys; + +},{"lodash._isnative":41,"lodash._shimkeys":46,"lodash.isobject":55}],57:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ +function noop() { + // no operation performed +} + +module.exports = noop; + +},{}],58:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ +function property(key) { + return function(object) { + return object[key]; + }; +} + +module.exports = property; + +},{}],59:[function(_dereq_,module,exports){ +/** + * Lo-Dash 2.4.1 (Custom Build) + * Build: `lodash modularize modern exports="npm" -o ./npm/` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.5.2 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var createCallback = _dereq_('lodash.createcallback'), + forOwn = _dereq_('lodash.forown'); + +/** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ +function reduce(collection, callback, accumulator, thisArg) { + if (!collection) return accumulator; + var noaccum = arguments.length < 3; + callback = createCallback(callback, thisArg, 4); + + var index = -1, + length = collection.length; + + if (typeof length == 'number') { + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + forOwn(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; +} -},{"./helpers/add.js":22,"./helpers/ago.js":23,"./helpers/between.js":24,"./helpers/contains.js":25,"./helpers/divide.js":26,"./helpers/encode.js":27,"./helpers/equal.js":28,"./helpers/first.js":29,"./helpers/formatDate.js":30,"./helpers/greater.js":31,"./helpers/join.js":32,"./helpers/last.js":33,"./helpers/length.js":34,"./helpers/less.js":35,"./helpers/lowercase.js":36,"./helpers/multiply.js":37,"./helpers/range.js":38,"./helpers/replace.js":39,"./helpers/reverse.js":40,"./helpers/shuffle.js":41,"./helpers/subtract.js":42,"./helpers/times.js":43,"./helpers/uppercase.js":44,"./helpers/where.js":45}],47:[function(_dereq_,module,exports){ +module.exports = reduce; + +},{"lodash.createcallback":49,"lodash.forown":51}],60:[function(_dereq_,module,exports){ +(function (global){ /** * Lo-Dash 2.4.1 (Custom Build) * Build: `lodash modularize modern exports="npm" -o ./npm/` @@ -2785,4358 +3287,4071 @@ module.exports.helpers = helpers; * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ -var isNative = _dereq_('lodash._isnative'); +var isNative = _dereq_('lodash._isnative'); + +/** Used to detect functions containing a `this` reference */ +var reThis = /\bthis\b/; + +/** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ +var support = {}; + +/** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ +support.funcDecomp = !isNative(global.WinRTError) && reThis.test(function() { return this; }); + +/** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ +support.funcNames = typeof Function.name == 'string'; + +module.exports = support; + +}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"lodash._isnative":41}],61:[function(_dereq_,module,exports){ + +var is = _dereq_('is') + , isodate = _dereq_('isodate') + , milliseconds = _dereq_('./milliseconds') + , seconds = _dereq_('./seconds'); + + +/** + * Returns a new Javascript Date object, allowing a variety of extra input types + * over the native Date constructor. + * + * @param {Date|String|Number} val + */ + +module.exports = function newDate (val) { + if (is.number(val)) return new Date(toMs(val)); + if (is.date(val)) return new Date(val.getTime()); // firefox woulda floored + + // date strings + if (isodate.is(val)) return isodate.parse(val); + if (milliseconds.is(val)) return milliseconds.parse(val); + if (seconds.is(val)) return seconds.parse(val); + + // fallback to Date.parse + return new Date(val); +}; + + +/** + * If the number passed val is seconds from the epoch, turn it into milliseconds. + * Milliseconds would be greater than 31557600000 (December 31, 1970). + * + * @param {Number} num + */ -/** `Object#toString` result shortcuts */ -var arrayClass = '[object Array]'; +function toMs (num) { + if (num < 31557600000) return num * 1000; + return num; +} +},{"./milliseconds":62,"./seconds":63,"is":31,"isodate":32}],62:[function(_dereq_,module,exports){ -/** Used for native method references */ -var objectProto = Object.prototype; +/** + * Matcher. + */ -/** Used to resolve the internal [[Class]] of values */ -var toString = objectProto.toString; +var matcher = /\d{13}/; -/* Native method shortcuts for methods with the same name as other `lodash` methods */ -var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray; /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false + * Check whether a string is a millisecond date string. * - * _.isArray([1, 2, 3]); - * // => true + * @param {String} string + * @return {Boolean} */ -var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; + +exports.is = function (string) { + return matcher.test(string); }; -module.exports = isArray; -},{"lodash._isnative":48}],48:[function(_dereq_,module,exports){ /** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license + * Convert a millisecond string to a date. + * + * @param {String} millis + * @return {Date} */ -/** Used for native method references */ -var objectProto = Object.prototype; +exports.parse = function (millis) { + millis = parseInt(millis, 10); + return new Date(millis); +}; +},{}],63:[function(_dereq_,module,exports){ -/** Used to resolve the internal [[Class]] of values */ -var toString = objectProto.toString; +/** + * Matcher. + */ + +var matcher = /\d{10}/; -/** Used to detect if a method is native */ -var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' -); /** - * Checks if `value` is a native function. + * Check whether a string is a second date string. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + * @param {String} string + * @return {Boolean} */ -function isNative(value) { - return typeof value == 'function' && reNative.test(value); -} -module.exports = isNative; +exports.is = function (string) { + return matcher.test(string); +}; -},{}],49:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var createCallback = _dereq_('lodash.createcallback'), - forOwn = _dereq_('lodash.forown'); /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 + * Convert a second string to a date. * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } + * @param {String} seconds + * @return {Date} */ -function reduce(collection, callback, accumulator, thisArg) { - if (!collection) return accumulator; - var noaccum = arguments.length < 3; - callback = createCallback(callback, thisArg, 4); - var index = -1, - length = collection.length; +exports.parse = function (seconds) { + var millis = parseInt(seconds, 10) * 1000; + return new Date(millis); +}; +},{}],64:[function(_dereq_,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +},{}],65:[function(_dereq_,module,exports){ +module.exports = _dereq_('./lib/'); + +},{"./lib/":66}],66:[function(_dereq_,module,exports){ +// Load modules + +var Stringify = _dereq_('./stringify'); +var Parse = _dereq_('./parse'); + + +// Declare internals + +var internals = {}; + + +module.exports = { + stringify: Stringify, + parse: Parse +}; + +},{"./parse":67,"./stringify":68}],67:[function(_dereq_,module,exports){ +// Load modules + +var Utils = _dereq_('./utils'); + + +// Declare internals + +var internals = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000 +}; + + +internals.parseValues = function (str, options) { + + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0, il = parts.length; i < il; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[Utils.decode(part)] = ''; + } + else { + var key = Utils.decode(part.slice(0, pos)); + var val = Utils.decode(part.slice(pos + 1)); + + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = val; + } + else { + obj[key] = [].concat(obj[key]).concat(val); + } + } + } + + return obj; +}; - if (typeof length == 'number') { - if (noaccum) { - accumulator = collection[++index]; + +internals.parseObject = function (chain, val, options) { + + if (!chain.length) { + return val; } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); + + var root = chain.shift(); + + var obj = {}; + if (root === '[]') { + obj = []; + obj = obj.concat(internals.parseObject(chain, val, options)); } - } else { - forOwn(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; -} + else { + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + var indexString = '' + index; + if (!isNaN(index) && + root !== cleanRoot && + indexString === cleanRoot && + index >= 0 && + index <= options.arrayLimit) { -module.exports = reduce; + obj = []; + obj[index] = internals.parseObject(chain, val, options); + } + else { + obj[cleanRoot] = internals.parseObject(chain, val, options); + } + } -},{"lodash.createcallback":50,"lodash.forown":86}],50:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.4 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseCreateCallback = _dereq_('lodash._basecreatecallback'), - baseIsEqual = _dereq_('lodash._baseisequal'), - isObject = _dereq_('lodash.isobject'), - keys = _dereq_('lodash.keys'), - property = _dereq_('lodash.property'); + return obj; +}; -/** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ -function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; +internals.parseKeys = function (key, val, options) { - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } + if (!key) { + return; } - return result; - }; -} -module.exports = createCallback; + // The regex chunks -},{"lodash._basecreatecallback":51,"lodash._baseisequal":70,"lodash.isobject":79,"lodash.keys":81,"lodash.property":85}],51:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var bind = _dereq_('lodash.bind'), - identity = _dereq_('lodash.identity'), - setBindData = _dereq_('lodash._setbinddata'), - support = _dereq_('lodash.support'); + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; -/** Used to detected named functions */ -var reFuncName = /^\s*function[ \n\r\t]+\w/; + // Get the parent -/** Used to detect functions containing a `this` reference */ -var reThis = /\bthis\b/; + var segment = parent.exec(key); -/** Native method shortcuts */ -var fnToString = Function.prototype.toString; + // Don't allow them to overwrite object prototype properties -/** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ -function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; + if (Object.prototype.hasOwnProperty(segment[1])) { + return; } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + keys.push(segment[1]); } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); -} -module.exports = baseCreateCallback; + // Loop through children appending to the array until we hit depth -},{"lodash._setbinddata":52,"lodash.bind":55,"lodash.identity":67,"lodash.support":68}],52:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var isNative = _dereq_('lodash._isnative'), - noop = _dereq_('lodash.noop'); + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { -/** Used as the property descriptor for `__bindData__` */ -var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false -}; + ++i; + if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + keys.push(segment[1]); + } + } -/** Used to set meta data on functions */ -var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; -}()); + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } -/** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ -var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); + return internals.parseObject(keys, val, options); }; -module.exports = setBindData; -},{"lodash._isnative":53,"lodash.noop":54}],53:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],54:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ +module.exports = function (str, options) { -/** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ -function noop() { - // no operation performed -} + if (str === '' || + str === null || + typeof str === 'undefined') { -module.exports = noop; + return {}; + } -},{}],55:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var createWrapper = _dereq_('lodash._createwrapper'), - slice = _dereq_('lodash._slice'); + options = options || {}; + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; -/** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ -function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); -} + var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; + var obj = {}; -module.exports = bind; + // Iterate over the keys and setup the new object -},{"lodash._createwrapper":56,"lodash._slice":66}],56:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseBind = _dereq_('lodash._basebind'), - baseCreateWrapper = _dereq_('lodash._basecreatewrapper'), - isFunction = _dereq_('lodash.isfunction'), - slice = _dereq_('lodash._slice'); + var keys = Object.keys(tempObj); + for (var i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + var newObj = internals.parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj); + } -/** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ -var arrayRef = []; + return Utils.compact(obj); +}; -/** Native method shortcuts */ -var push = arrayRef.push, - unshift = arrayRef.unshift; +},{"./utils":69}],68:[function(_dereq_,module,exports){ +// Load modules -/** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ -function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; +var Utils = _dereq_('./utils'); - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); + +// Declare internals + +var internals = { + delimiter: '&', + arrayPrefixGenerators: { + brackets: function (prefix, key) { + return prefix + '[]'; + }, + indices: function (prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function (prefix, key) { + return prefix; + } } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; +}; + + +internals.stringify = function (obj, prefix, generateArrayPrefix) { + + if (Utils.isBuffer(obj)) { + obj = obj.toString(); } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; + else if (obj instanceof Date) { + obj = obj.toISOString(); } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; + else if (obj === null) { + obj = ''; } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); + + if (typeof obj === 'string' || + typeof obj === 'number' || + typeof obj === 'boolean') { + + return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + + var values = []; + + if (typeof obj === 'undefined') { + return values; } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); -} -module.exports = createWrapper; + var objKeys = Object.keys(obj); + for (var i = 0, il = objKeys.length; i < il; ++i) { + var key = objKeys[i]; + if (Array.isArray(obj)) { + values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix)); + } + else { + values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix)); + } + } -},{"lodash._basebind":57,"lodash._basecreatewrapper":61,"lodash._slice":66,"lodash.isfunction":65}],57:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseCreate = _dereq_('lodash._basecreate'), - isObject = _dereq_('lodash.isobject'), - setBindData = _dereq_('lodash._setbinddata'), - slice = _dereq_('lodash._slice'); + return values; +}; -/** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ -var arrayRef = []; -/** Native method shortcuts */ -var push = arrayRef.push; +module.exports = function (obj, options) { -/** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ -function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; + options = options || {}; + var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); + var keys = []; + + if (typeof obj !== 'object' || + obj === null) { + + return ''; } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; + + var arrayFormat; + if (options.arrayFormat in internals.arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } + else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } + else { + arrayFormat = 'indices'; } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; -} -module.exports = baseBind; + var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat]; -},{"lodash._basecreate":58,"lodash._setbinddata":52,"lodash._slice":66,"lodash.isobject":79}],58:[function(_dereq_,module,exports){ -(function (global){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var isNative = _dereq_('lodash._isnative'), - isObject = _dereq_('lodash.isobject'), - noop = _dereq_('lodash.noop'); + var objKeys = Object.keys(obj); + for (var i = 0, il = objKeys.length; i < il; ++i) { + var key = objKeys[i]; + keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix)); + } -/* Native method shortcuts for methods with the same name as other `lodash` methods */ -var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate; + return keys.join(delimiter); +}; -/** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ -function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; -} -// fallback for browsers without `Object.create` -if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || global.Object(); - }; - }()); -} +},{"./utils":69}],69:[function(_dereq_,module,exports){ +// Load modules -module.exports = baseCreate; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"lodash._isnative":59,"lodash.isobject":79,"lodash.noop":60}],59:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],60:[function(_dereq_,module,exports){ -module.exports=_dereq_(54) -},{}],61:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseCreate = _dereq_('lodash._basecreate'), - isObject = _dereq_('lodash.isobject'), - setBindData = _dereq_('lodash._setbinddata'), - slice = _dereq_('lodash._slice'); +// Declare internals -/** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ -var arrayRef = []; +var internals = {}; -/** Native method shortcuts */ -var push = arrayRef.push; -/** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ -function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; +exports.arrayToObject = function (source) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; + var obj = {}; + for (var i = 0, il = source.length; i < il; ++i) { + if (typeof source[i] !== 'undefined') { - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); + obj[i] = source[i]; + } } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } + + return obj; +}; + + +exports.merge = function (target, source) { + + if (!source) { + return target; } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; + + if (typeof source !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } + else { + target[source] = true; + } + + return target; } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; + + if (typeof target !== 'object') { + target = [target].concat(source); + return target; } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; -} -module.exports = baseCreateWrapper; + if (Array.isArray(target) && + !Array.isArray(source)) { -},{"lodash._basecreate":62,"lodash._setbinddata":52,"lodash._slice":66,"lodash.isobject":79}],62:[function(_dereq_,module,exports){ -module.exports=_dereq_(58) -},{"lodash._isnative":63,"lodash.isobject":79,"lodash.noop":64}],63:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],64:[function(_dereq_,module,exports){ -module.exports=_dereq_(54) -},{}],65:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + target = exports.arrayToObject(target); + } -/** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ -function isFunction(value) { - return typeof value == 'function'; -} + var keys = Object.keys(source); + for (var k = 0, kl = keys.length; k < kl; ++k) { + var key = keys[k]; + var value = source[key]; + + if (!target[key]) { + target[key] = value; + } + else { + target[key] = exports.merge(target[key], value); + } + } + + return target; +}; -module.exports = isFunction; -},{}],66:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ +exports.decode = function (str) { -/** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ -function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } +}; - while (++index < length) { - result[index] = array[start + index]; - } - return result; -} -module.exports = slice; +exports.compact = function (obj, refs) { -},{}],67:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + if (typeof obj !== 'object' || + obj === null) { -/** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ -function identity(value) { - return value; -} + return obj; + } -module.exports = identity; + refs = refs || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } -},{}],68:[function(_dereq_,module,exports){ -(function (global){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var isNative = _dereq_('lodash._isnative'); + refs.push(obj); -/** Used to detect functions containing a `this` reference */ -var reThis = /\bthis\b/; + if (Array.isArray(obj)) { + var compacted = []; -/** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ -var support = {}; + for (var i = 0, il = obj.length; i < il; ++i) { + if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } -/** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ -support.funcDecomp = !isNative(global.WinRTError) && reThis.test(function() { return this; }); + return compacted; + } -/** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ -support.funcNames = typeof Function.name == 'string'; + var keys = Object.keys(obj); + for (i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + obj[key] = exports.compact(obj[key], refs); + } -module.exports = support; + return obj; +}; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"lodash._isnative":69}],69:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],70:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var forIn = _dereq_('lodash.forin'), - getArray = _dereq_('lodash._getarray'), - isFunction = _dereq_('lodash.isfunction'), - objectTypes = _dereq_('lodash._objecttypes'), - releaseArray = _dereq_('lodash._releasearray'); -/** `Object#toString` result shortcuts */ -var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; +exports.isRegExp = function (obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; -/** Used for native method references */ -var objectProto = Object.prototype; -/** Used to resolve the internal [[Class]] of values */ -var toString = objectProto.toString; +exports.isBuffer = function (obj) { -/** Native method shortcuts */ -var hasOwnProperty = objectProto.hasOwnProperty; + if (obj === null || + typeof obj === 'undefined') { -/** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ -function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; + return false; } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); + return !!(obj.constructor && + obj.constructor.isBuffer && + obj.constructor.isBuffer(obj)); +}; - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; +},{}],70:[function(_dereq_,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); + if (typeof qs !== 'string' || qs.length === 0) { + return obj; } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = a.constructor, - ctorB = b.constructor; + var regexp = /\+/g; + qs = qs.split(sep); - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; } } - stackA.pop(); - stackB.pop(); - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; -} + return obj; +}; -module.exports = baseIsEqual; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; -},{"lodash._getarray":71,"lodash._objecttypes":73,"lodash._releasearray":74,"lodash.forin":77,"lodash.isfunction":78}],71:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var arrayPool = _dereq_('lodash._arraypool'); +},{}],71:[function(_dereq_,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -/** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ -function getArray() { - return arrayPool.pop() || []; -} +'use strict'; -module.exports = getArray; +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; -},{"lodash._arraypool":72}],72:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + case 'boolean': + return v ? 'true' : 'false'; -/** Used to pool arrays and objects used internally */ -var arrayPool = []; + case 'number': + return isFinite(v) ? v : ''; -module.exports = arrayPool; + default: + return ''; + } +}; -},{}],73:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } -/** Used to determine if values are of the language type Object */ -var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false -}; + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return obj[k].map(function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).join(sep); -module.exports = objectTypes; + } -},{}],74:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var arrayPool = _dereq_('lodash._arraypool'), - maxPoolSize = _dereq_('lodash._maxpoolsize'); + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; -/** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ -function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); } + return res; } -module.exports = releaseArray; +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; -},{"lodash._arraypool":75,"lodash._maxpoolsize":76}],75:[function(_dereq_,module,exports){ -module.exports=_dereq_(72) -},{}],76:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ +},{}],72:[function(_dereq_,module,exports){ +'use strict'; -/** Used as the max size of the `arrayPool` and `objectPool` */ -var maxPoolSize = 40; +exports.decode = exports.parse = _dereq_('./decode'); +exports.encode = exports.stringify = _dereq_('./encode'); -module.exports = maxPoolSize; +},{"./decode":70,"./encode":71}],73:[function(_dereq_,module,exports){ +var _ = _dereq_('underscore'); +var handlebars_helper = _dereq_('handlebars-helper'); +var EventEmitter = _dereq_('events').EventEmitter; +var util = _dereq_('util'); -},{}],77:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseCreateCallback = _dereq_('lodash._basecreatecallback'), - objectTypes = _dereq_('lodash._objecttypes'); +var Resource = _dereq_('./lib/resource.js'); +var View = _dereq_('./lib/view.js'); -/** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ -var forIn = function(collection, callback, thisArg) { - var index, iterable = collection, result = iterable; - if (!iterable) return result; - if (!objectTypes[typeof iterable]) return result; - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - for (index in iterable) { - if (callback(iterable[index], index, collection) === false) return result; - } - return result +var SolidusClient = function(options) { + if (!(this instanceof SolidusClient)) return new SolidusClient(options); + + options || (options = {}); + this.resources_options = options.resources_options; + this.context = options.context || {}; }; -module.exports = forIn; +// HACK: needed by universe.js... +util.inherits(SolidusClient, EventEmitter); -},{"lodash._basecreatecallback":51,"lodash._objecttypes":73}],78:[function(_dereq_,module,exports){ -module.exports=_dereq_(65) -},{}],79:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var objectTypes = _dereq_('lodash._objecttypes'); +SolidusClient.prototype.getResource = function(options, params, callback) { + var resource = new Resource(options, this.resources_options, params); + resource.get(function(err, response) { + callback(err, response ? response.data : null); + }); +}; -/** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); -} +SolidusClient.prototype.getResources = function(resources, params, callback) { + var self = this; + var errors = null; + var result = {}; + var remaining = _.size(resources); -module.exports = isObject; + if (!remaining) return callback(errors, result); -},{"lodash._objecttypes":80}],80:[function(_dereq_,module,exports){ -module.exports=_dereq_(73) -},{}],81:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var isNative = _dereq_('lodash._isnative'), - isObject = _dereq_('lodash.isobject'), - shimKeys = _dereq_('lodash._shimkeys'); + _.each(resources, function(options, name) { + self.getResource(options, params, function(err, data) { + if (err) { + errors = errors || {}; + errors[name] = err; + } else { + result[name] = data; + } + if (!--remaining) callback(errors, result); + }); + }); +}; -/* Native method shortcuts for methods with the same name as other `lodash` methods */ -var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; +SolidusClient.prototype.renderTemplate = function(template, context, template_options, callback) { + var html, err; -/** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ -var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; + template_options = template_options || {}; + template_options.helpers = _.extend(handlebars_helper.helpers, template_options.helpers || {}); + + try { + html = template(context, template_options); + } catch (error) { + err = error; } - return nativeKeys(object); -}; -module.exports = keys; + callback(err, html); +}; -},{"lodash._isnative":82,"lodash._shimkeys":83,"lodash.isobject":79}],82:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],83:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var objectTypes = _dereq_('lodash._objecttypes'); +SolidusClient.prototype.view = function(view) { + var self = this; -/** Used for native method references */ -var objectProto = Object.prototype; + view.render = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(this); + return self.render.apply(self, args); + }; -/** Native method shortcuts */ -var hasOwnProperty = objectProto.hasOwnProperty; + return view; +}; -/** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ -var shimKeys = function(object) { - var index, iterable = object, result = []; - if (!iterable) return result; - if (!(objectTypes[typeof object])) return result; - for (index in iterable) { - if (hasOwnProperty.call(iterable, index)) { - result.push(index); - } - } - return result +SolidusClient.prototype.render = function(view, params, callback) { + var renderer = new View(this, view); + if (!callback && _.isFunction(params)) { + callback = params; + params = null; + } + if (params) { + renderer.params(params); + } + return callback ? renderer.end(callback) : renderer; }; -module.exports = shimKeys; +module.exports = SolidusClient; -},{"lodash._objecttypes":84}],84:[function(_dereq_,module,exports){ -module.exports=_dereq_(73) -},{}],85:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license +},{"./lib/resource.js":75,"./lib/view.js":77,"events":3,"handlebars-helper":5,"underscore":78,"util":88}],74:[function(_dereq_,module,exports){ +/* + * Copyright (c) 2010 Nick Galbreath + * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ -/** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. +/* base64 encode/decode compatible with window.btoa/atob * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example + * window.atob/btoa is a Firefox extension to convert binary data (the "b") + * to base64 (ascii, the "a"). * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; + * It is also found in Safari and Chrome. It is not available in IE. * - * var getName = _.property('name'); + * if (!window.btoa) window.btoa = base64.encode + * if (!window.atob) window.atob = base64.decode * - * _.map(characters, getName); - * // => ['barney', 'fred'] + * The original spec's for atob/btoa are a bit lacking + * https://developer.mozilla.org/en/DOM/window.atob + * https://developer.mozilla.org/en/DOM/window.btoa * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + * window.btoa and base64.encode takes a string where charCodeAt is [0,255] + * If any character is not [0,255], then an DOMException(5) is thrown. + * + * window.atob and base64.decode take a base64-encoded string + * If the input length is not a multiple of 4, or contains invalid characters + * then an DOMException(5) is thrown. */ -function property(key) { - return function(object) { - return object[key]; - }; +var base64 = {}; +base64.PADCHAR = '='; +base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +base64.makeDOMException = function() { + // sadly in FF,Safari,Chrome you can't make a DOMException + var e, tmp; + + try { + return new DOMException(DOMException.INVALID_CHARACTER_ERR); + } catch (tmp) { + // not available, just passback a duck-typed equiv + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype + var ex = new Error("DOM Exception 5"); + + // ex.number and ex.description is IE-specific. + ex.code = ex.number = 5; + ex.name = ex.description = "INVALID_CHARACTER_ERR"; + + // Safari/Chrome output format + ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; }; + return ex; + } } -module.exports = property; +base64.getbyte = function(s,i) { + var x = s.charCodeAt(i); + if (x > 255) { + throw base64.makeDOMException(); + } + return x; +} -},{}],86:[function(_dereq_,module,exports){ -/** - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modularize modern exports="npm" -o ./npm/` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseCreateCallback = _dereq_('lodash._basecreatecallback'), - keys = _dereq_('lodash.keys'), - objectTypes = _dereq_('lodash._objecttypes'); +base64.encode = function(s) { + if (arguments.length !== 1) { + throw new SyntaxError("Not enough arguments"); + } + var padchar = base64.PADCHAR; + var alpha = base64.ALPHA; + var getbyte = base64.getbyte; -/** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ -var forOwn = function(collection, callback, thisArg) { - var index, iterable = collection, result = iterable; - if (!iterable) return result; - if (!objectTypes[typeof iterable]) return result; - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - var ownIndex = -1, - ownProps = objectTypes[typeof iterable] && keys(iterable), - length = ownProps ? ownProps.length : 0; + var i, b10; + var x = []; - while (++ownIndex < length) { - index = ownProps[ownIndex]; - if (callback(iterable[index], index, collection) === false) return result; + // convert to string + s = '' + s; + + var imax = s.length - s.length % 3; + + if (s.length === 0) { + return s; } - return result -}; + for (i = 0; i < imax; i += 3) { + b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2); + x.push(alpha.charAt(b10 >> 18)); + x.push(alpha.charAt((b10 >> 12) & 0x3F)); + x.push(alpha.charAt((b10 >> 6) & 0x3f)); + x.push(alpha.charAt(b10 & 0x3f)); + } + switch (s.length - imax) { + case 1: + b10 = getbyte(s,i) << 16; + x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + + padchar + padchar); + break; + case 2: + b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8); + x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + + alpha.charAt((b10 >> 6) & 0x3f) + padchar); + break; + } + return x.join(''); +} -module.exports = forOwn; +module.exports = base64; -},{"lodash._basecreatecallback":87,"lodash._objecttypes":108,"lodash.keys":109}],87:[function(_dereq_,module,exports){ -module.exports=_dereq_(51) -},{"lodash._setbinddata":88,"lodash.bind":91,"lodash.identity":105,"lodash.support":106}],88:[function(_dereq_,module,exports){ -module.exports=_dereq_(52) -},{"lodash._isnative":89,"lodash.noop":90}],89:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],90:[function(_dereq_,module,exports){ -module.exports=_dereq_(54) -},{}],91:[function(_dereq_,module,exports){ -module.exports=_dereq_(55) -},{"lodash._createwrapper":92,"lodash._slice":104}],92:[function(_dereq_,module,exports){ -module.exports=_dereq_(56) -},{"lodash._basebind":93,"lodash._basecreatewrapper":98,"lodash._slice":104,"lodash.isfunction":103}],93:[function(_dereq_,module,exports){ -module.exports=_dereq_(57) -},{"lodash._basecreate":94,"lodash._setbinddata":88,"lodash._slice":104,"lodash.isobject":97}],94:[function(_dereq_,module,exports){ -module.exports=_dereq_(58) -},{"lodash._isnative":95,"lodash.isobject":97,"lodash.noop":96}],95:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],96:[function(_dereq_,module,exports){ -module.exports=_dereq_(54) -},{}],97:[function(_dereq_,module,exports){ -module.exports=_dereq_(79) -},{"lodash._objecttypes":108}],98:[function(_dereq_,module,exports){ -module.exports=_dereq_(61) -},{"lodash._basecreate":99,"lodash._setbinddata":88,"lodash._slice":104,"lodash.isobject":102}],99:[function(_dereq_,module,exports){ -module.exports=_dereq_(58) -},{"lodash._isnative":100,"lodash.isobject":102,"lodash.noop":101}],100:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],101:[function(_dereq_,module,exports){ -module.exports=_dereq_(54) -},{}],102:[function(_dereq_,module,exports){ -module.exports=_dereq_(79) -},{"lodash._objecttypes":108}],103:[function(_dereq_,module,exports){ -module.exports=_dereq_(65) -},{}],104:[function(_dereq_,module,exports){ -module.exports=_dereq_(66) -},{}],105:[function(_dereq_,module,exports){ -module.exports=_dereq_(67) -},{}],106:[function(_dereq_,module,exports){ -module.exports=_dereq_(68) -},{"lodash._isnative":107}],107:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],108:[function(_dereq_,module,exports){ -module.exports=_dereq_(73) -},{}],109:[function(_dereq_,module,exports){ -module.exports=_dereq_(81) -},{"lodash._isnative":110,"lodash._shimkeys":111,"lodash.isobject":112}],110:[function(_dereq_,module,exports){ -module.exports=_dereq_(48) -},{}],111:[function(_dereq_,module,exports){ -module.exports=_dereq_(83) -},{"lodash._objecttypes":108}],112:[function(_dereq_,module,exports){ -module.exports=_dereq_(79) -},{"lodash._objecttypes":108}],113:[function(_dereq_,module,exports){ +},{}],75:[function(_dereq_,module,exports){ +var DYNAMIC_SEGMENTS = /\{([^\}]*)\}/ig; +var DEFAULT_ENCODING = 'UTF8'; +var DEFAULT_SOLIDUS_API_ROUTE = '/api/'; +var DEFAULT_TIMEOUT = 20000; +var NOT_FOUND = /(404|not[ -_]?found|not[ -_]?find|no[ -_]?\w+?[ -_]?found|invalid[ -_]?\w+|unknown[ -_]?\w+|do(es)?[ -_]?not[ -_]?exist|empty)/i; -var is = _dereq_('is') - , isodate = _dereq_('isodate') - , milliseconds = _dereq_('./milliseconds') - , seconds = _dereq_('./seconds'); +var _ = _dereq_('underscore'); +var qs = _dereq_('qs'); +var superagent = _dereq_('superagent'); +var extend = _dereq_('extend'); +var util = _dereq_('./util'); -/** - * Returns a new Javascript Date object, allowing a variety of extra input types - * over the native Date constructor. - * - * @param {Date|String|Number} val - */ +// SuperAgent uses btoa for auth encoding on the client, which is missing from 0) query.push(qs.parse(url.substring(start))); + if (this.options.query) query.push(this.options.query); + query = query.concat(Array.prototype.slice.call(arguments, 1)); + query = _.extend.apply(_, query); + + if (this.options.query_options && this.options.query_options['objectFormat'] === 'json') { + _.each(query, function(value, key) { + if (_.isObject(value) && !_.isArray(value)) query[key] = JSON.stringify(value); + }); } - if ('[object String]' === type) { - return '' === value; + query = qs.stringify(query, this.options.query_options); + if (query) { + return (start > 0 ? url.substring(0, start - 1) : url) + '?' + query; + } else { + return url; } - - return false; }; -/** - * is.equal - * Test if `value` is equal to `other`. - * - * @param {Mixed} value value to test - * @param {Mixed} other value to compare with - * @return {Boolean} true if `value` is equal to `other`, false otherwise - */ - -is.equal = function (value, other) { - var type = toString.call(value) - var key; +var superAgentRequest = function(request, callback) { + // Force buffering of response bodies as res.text + // http://visionmedia.github.io/superagent/#buffering-responses + if (util.isNode) request.buffer(); - if (type !== toString.call(other)) { - return false; + // Not all weird browser errors are catched by SuperAgent + try { + request.end(function(err, res) { + // In case the request is not async, we don't want to catch the callback exceptions + setTimeout(function() { + // SuperAgent considers statuses <200 and >=300 as errors + // http://visionmedia.github.io/superagent/#error-handling + if (err) return callback(err, res); + processResponse(res, null, callback); + }, 0); + }); + } catch (err) { + callback(err); } +} - if ('[object Object]' === type) { - for (key in value) { - if (!is.equal(value[key], other[key])) { - return false; - } - } - return true; - } +var processResponse = function(res, data, callback) { + processData(res, data, function(err, data) { + if (err) return callback(err, res); + processDataStatus(data, function(err) { + callback(err, res, data); + }); + }); +}; - if ('[object Array]' === type) { - key = value.length; - if (key !== other.length) { - return false; - } - while (--key) { - if (!is.equal(value[key], other[key])) { - return false; - } +var processData = function(res, data, callback) { + var err; + if (!_.isObject(data)) { + try { + data = JSON.parse(res.text.toString(DEFAULT_ENCODING)); + } catch (error) { + err = new Error('Invalid JSON'); + err.error = error.message; } - return true; } + callback(err, data); +}; - if ('[object Function]' === type) { - return value.prototype === other.prototype; +var processDataStatus = function(data, callback) { + var err; + if (String(data.status).toLowerCase() == 'error') { + var message = (data.messages || []).concat([data.error, data.message, data.response, data.body]).join(' '); + err = new Error('Invalid data status'); + err.status = message.match(NOT_FOUND) ? 404 : 500; } + callback(err); +}; - if ('[object Date]' === type) { - return value.getTime() === other.getTime(); - } +module.exports = Resource; - return value === other; -}; +},{"./base64":74,"./util":76,"extend":4,"qs":65,"superagent":81,"underscore":78}],76:[function(_dereq_,module,exports){ +var qs = _dereq_('querystring'); -/** - * is.hosted - * Test if `value` is hosted by `host`. - * - * @param {Mixed} value to test - * @param {Mixed} host host to test with - * @return {Boolean} true if `value` is hosted by `host`, false otherwise - * @api public - */ +module.exports.isNode = !(typeof window !== 'undefined' && window !== null); -is.hosted = function (value, host) { - var type = typeof host[value]; - return type === 'object' ? !!host[value] : !NON_HOST_TYPES[type]; -}; +module.exports.supportsCORS = !module.exports.isNode && (typeof XMLHttpRequest !== 'undefined') && ('withCredentials' in new XMLHttpRequest()); -/** - * is.instance - * Test if `value` is an instance of `constructor`. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an instance of `constructor` - * @api public - */ +module.exports.params = !module.exports.isNode?qs.parse(window.location.search.split('?').pop()):{}; -is.instance = is['instanceof'] = function (value, constructor) { - return value instanceof constructor; -}; +},{"querystring":72}],77:[function(_dereq_,module,exports){ +var _ = _dereq_('underscore'); -/** - * is.null - * Test if `value` is null. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is null, false otherwise - * @api public - */ +var util = _dereq_('./util'); -is['null'] = function (value) { - return value === null; -}; +var View = function(solidus_client, view) { + this.solidus_client = solidus_client; -/** - * is.undefined - * Test if `value` is undefined. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is undefined, false otherwise - * @api public - */ + if (_.isFunction(view)) { + this.template = view; + } else { + this.resources = view.resources; + this.resources_params = view.params; + this.preprocessor = view.preprocessor; + this.template = view.template; + this.template_options = view.template_options; + } -is.undefined = function (value) { - return value === undefined; + this.resources = this.resources || {}; + this.resources_params = this.resources_params || {}; + this.template_options = this.template_options || {}; }; -/** - * Test arguments. - */ +View.prototype.params = function(params) { + this.resources_params = params; + return this; +}; -/** - * is.arguments - * Test if `value` is an arguments object. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an arguments object, false otherwise - * @api public - */ +View.prototype.templateOptions = function(template_options) { + this.template_options = template_options; + return this; +}; -is.arguments = function (value) { - var isStandardArguments = '[object Arguments]' === toString.call(value); - var isOldArguments = !is.array(value) && is.arraylike(value) && is.object(value) && is.fn(value.callee); - return isStandardArguments || isOldArguments; +View.prototype.get = function(resources) { + this.resources = resources; + return this; }; -/** - * Test array. - */ +View.prototype.then = function(preprocessor) { + this.preprocessor = preprocessor; + return this; +}; -/** - * is.array - * Test if 'value' is an array. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an array, false otherwise - * @api public - */ +View.prototype.end = function(callback) { + var self = this; -is.array = function (value) { - return '[object Array]' === toString.call(value); -}; + getResources.call(self, function(err, resources) { + if (err) return callback(err); -/** - * is.arguments.empty - * Test if `value` is an empty arguments object. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an empty arguments object, false otherwise - * @api public - */ -is.arguments.empty = function (value) { - return is.arguments(value) && value.length === 0; + addResourcesToContext.call(self, resources); + + preprocessContext.call(self, function(err) { + if (err) return callback(err); + + self.solidus_client.renderTemplate(self.template, self.solidus_client.context, self.template_options, callback); + }); + }); }; -/** - * is.array.empty - * Test if `value` is an empty array. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an empty array, false otherwise - * @api public - */ -is.array.empty = function (value) { - return is.array(value) && value.length === 0; +// Hacks for easier testing +View.redirect = function(url) { + window.location.href = url; }; +View.preprocessor_timeout = 10000; -/** - * is.arraylike - * Test if `value` is an arraylike object. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an arguments object, false otherwise - * @api public - */ +// PRIVATE + +var getResources = function(callback) { + var self = this; + self.solidus_client.getResources(self.resources, self.resources_params, function(err, resources) { + if (err) { + err = _.find(err, function(err, resource) { + return !self.resources[resource].optional + }); + } + callback(err, resources); + }); +}; -is.arraylike = function (value) { - return !!value && !is.boolean(value) - && owns.call(value, 'length') - && isFinite(value.length) - && is.number(value.length) - && value.length >= 0; +var addResourcesToContext = function(resources) { + this.solidus_client.context.resources || (this.solidus_client.context.resources = {}); + for (var name in resources) { + this.solidus_client.context.resources[name] = resources[name]; + } }; -/** - * Test boolean. - */ +var preprocessContext = function(callback) { + var self = this; + if (!self.preprocessor) return callback(); -/** - * is.boolean - * Test if `value` is a boolean. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a boolean, false otherwise - * @api public - */ + var preprocessor_type = self.preprocessor.length === 1 ? preprocessContextSync : preprocessContextAsync; -is.boolean = function (value) { - return '[object Boolean]' === toString.call(value); + preprocessor_type.call(self, function(err, context) { + if (err) { + callback(err); + } else if (_.isString(context)) { + if (util.isNode) return callback(new Error('Cannot redirect')); + View.redirect(context); + } else if (_.isArray(context) && context.length === 2 && _.isNumber(context[0]) && _.isString(context[1])) { + if (util.isNode) return callback(new Error('Cannot redirect')); + View.redirect(context[1]); + } else if (!_.isObject(context)) { + callback(new Error('Preprocessor returned invalid context')); + } else { + self.solidus_client.context = context; + callback(); + } + }); }; -/** - * is.false - * Test if `value` is false. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is false, false otherwise - * @api public - */ +var preprocessContextSync = function(callback) { + var context, err; -is['false'] = function (value) { - return is.boolean(value) && (value === false || value.valueOf() === false); + try { + context = this.preprocessor(this.solidus_client.context); + } catch (error) { + err = error; + } + + callback(err, context); }; -/** - * is.true - * Test if `value` is true. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is true, false otherwise - * @api public - */ +var preprocessContextAsync = function(callback) { + var done = _.once(callback); -is['true'] = function (value) { - return is.boolean(value) && (value === true || value.valueOf() === true); + setTimeout(function() { + done(new Error('Preprocessor timeout')); + }, View.preprocessor_timeout); + + try { + this.preprocessor(this.solidus_client.context, function(context) { + // In case the preprocessor is not async, we don't want to catch the callback exceptions + setTimeout(function() { + done(null, context); + }, 0); + }); + } catch (err) { + done(err); + } }; -/** - * Test date. - */ +module.exports = View; -/** - * is.date - * Test if `value` is a date. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a date, false otherwise - * @api public - */ +},{"./util":76,"underscore":78}],78:[function(_dereq_,module,exports){ +// Underscore.js 1.6.0 +// http://underscorejs.org +// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. -is.date = function (value) { - return '[object Date]' === toString.call(value); -}; +(function() { -/** - * Test element. - */ + // Baseline setup + // -------------- -/** - * is.element - * Test if `value` is an html element. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an HTML Element, false otherwise - * @api public - */ + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; -is.element = function (value) { - return value !== undefined - && typeof HTMLElement !== 'undefined' - && value instanceof HTMLElement - && value.nodeType === 1; -}; + // Save the previous value of the `_` variable. + var previousUnderscore = root._; -/** - * Test error. - */ + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; -/** - * is.error - * Test if `value` is an error object. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an error object, false otherwise - * @api public - */ + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; -is.error = function (value) { - return '[object Error]' === toString.call(value); -}; + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + concat = ArrayProto.concat, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; -/** - * Test function. - */ + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; -/** - * is.fn / is.function (deprecated) - * Test if `value` is a function. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a function, false otherwise - * @api public - */ + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; -is.fn = is['function'] = function (value) { - var isAlert = typeof window !== 'undefined' && value === window.alert; - return isAlert || '[object Function]' === toString.call(value); -}; + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } -/** - * Test number. - */ + // Current version. + _.VERSION = '1.6.0'; -/** - * is.number - * Test if `value` is a number. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a number, false otherwise - * @api public - */ + // Collection Functions + // -------------------- -is.number = function (value) { - return '[object Number]' === toString.call(value); -}; + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return obj; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, length = obj.length; i < length; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; + } + } + return obj; + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results.push(iterator.call(context, value, index, list)); + }); + return results; + }; -/** - * is.infinite - * Test if `value` is positive or negative infinity. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is positive or negative Infinity, false otherwise - * @api public - */ -is.infinite = function (value) { - return value === Infinity || value === -Infinity; -}; + var reduceError = 'Reduce of empty array with no initial value'; -/** - * is.decimal - * Test if `value` is a decimal number. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a decimal number, false otherwise - * @api public - */ + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; -is.decimal = function (value) { - return is.number(value) && !isActualNaN(value) && value % 1 !== 0; -}; + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var length = obj.length; + if (length !== +length) { + var keys = _.keys(obj); + length = keys.length; + } + each(obj, function(value, index, list) { + index = keys ? keys[--length] : --length; + if (!initial) { + memo = obj[index]; + initial = true; + } else { + memo = iterator.call(context, memo, obj[index], index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; -/** - * is.divisibleBy - * Test if `value` is divisible by `n`. - * - * @param {Number} value value to test - * @param {Number} n dividend - * @return {Boolean} true if `value` is divisible by `n`, false otherwise - * @api public - */ + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var result; + any(obj, function(value, index, list) { + if (predicate.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; -is.divisibleBy = function (value, n) { - var isDividendInfinite = is.infinite(value); - var isDivisorInfinite = is.infinite(n); - var isNonZeroNumber = is.number(value) && !isActualNaN(value) && is.number(n) && !isActualNaN(n) && n !== 0; - return isDividendInfinite || isDivisorInfinite || (isNonZeroNumber && value % n === 0); -}; + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); + each(obj, function(value, index, list) { + if (predicate.call(context, value, index, list)) results.push(value); + }); + return results; + }; -/** - * is.int - * Test if `value` is an integer. - * - * @param value to test - * @return {Boolean} true if `value` is an integer, false otherwise - * @api public - */ + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, function(value, index, list) { + return !predicate.call(context, value, index, list); + }, context); + }; -is.int = function (value) { - return is.number(value) && !isActualNaN(value) && value % 1 === 0; -}; + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate || (predicate = _.identity); + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context); + each(obj, function(value, index, list) { + if (!(result = result && predicate.call(context, value, index, list))) return breaker; + }); + return !!result; + }; -/** - * is.maximum - * Test if `value` is greater than 'others' values. - * - * @param {Number} value value to test - * @param {Array} others values to compare with - * @return {Boolean} true if `value` is greater than `others` values - * @api public - */ + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, predicate, context) { + predicate || (predicate = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); + each(obj, function(value, index, list) { + if (result || (result = predicate.call(context, value, index, list))) return breaker; + }); + return !!result; + }; -is.maximum = function (value, others) { - if (isActualNaN(value)) { - throw new TypeError('NaN is not a valid value'); - } else if (!is.arraylike(others)) { - throw new TypeError('second argument must be array-like'); - } - var len = others.length; + // Determine if the array or object contains a given value (using `===`). + // Aliased as `include`. + _.contains = _.include = function(obj, target) { + if (obj == null) return false; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + return any(obj, function(value) { + return value === target; + }); + }; - while (--len >= 0) { - if (value < others[len]) { - return false; - } - } + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + return (isFunc ? method : value[method]).apply(value, args); + }); + }; - return true; -}; + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; -/** - * is.minimum - * Test if `value` is less than `others` values. - * - * @param {Number} value value to test - * @param {Array} others values to compare with - * @return {Boolean} true if `value` is less than `others` values - * @api public - */ + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matches(attrs)); + }; -is.minimum = function (value, others) { - if (isActualNaN(value)) { - throw new TypeError('NaN is not a valid value'); - } else if (!is.arraylike(others)) { - throw new TypeError('second argument must be array-like'); - } - var len = others.length; + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matches(attrs)); + }; - while (--len >= 0) { - if (value > others[len]) { - return false; + // Return the maximum element or (element-based computation). + // Can't optimize arrays of integers longer than 65,535 elements. + // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797) + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.max.apply(Math, obj); } - } - - return true; -}; + var result = -Infinity, lastComputed = -Infinity; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + if (computed > lastComputed) { + result = value; + lastComputed = computed; + } + }); + return result; + }; -/** - * is.nan - * Test if `value` is not a number. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is not a number, false otherwise - * @api public - */ + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.min.apply(Math, obj); + } + var result = Infinity, lastComputed = Infinity; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + if (computed < lastComputed) { + result = value; + lastComputed = computed; + } + }); + return result; + }; -is.nan = function (value) { - return !is.number(value) || value !== value; -}; + // Shuffle an array, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var rand; + var index = 0; + var shuffled = []; + each(obj, function(value) { + rand = _.random(index++); + shuffled[index - 1] = shuffled[rand]; + shuffled[rand] = value; + }); + return shuffled; + }; -/** - * is.even - * Test if `value` is an even number. - * - * @param {Number} value value to test - * @return {Boolean} true if `value` is an even number, false otherwise - * @api public - */ + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (obj.length !== +obj.length) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; -is.even = function (value) { - return is.infinite(value) || (is.number(value) && value === value && value % 2 === 0); -}; + // An internal function to generate lookup iterators. + var lookupIterator = function(value) { + if (value == null) return _.identity; + if (_.isFunction(value)) return value; + return _.property(value); + }; -/** - * is.odd - * Test if `value` is an odd number. - * - * @param {Number} value value to test - * @return {Boolean} true if `value` is an odd number, false otherwise - * @api public - */ + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + iterator = lookupIterator(iterator); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; -is.odd = function (value) { - return is.infinite(value) || (is.number(value) && value === value && value % 2 !== 0); -}; + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iterator, context) { + var result = {}; + iterator = lookupIterator(iterator); + each(obj, function(value, index) { + var key = iterator.call(context, value, index, obj); + behavior(result, key, value); + }); + return result; + }; + }; -/** - * is.ge - * Test if `value` is greater than or equal to `other`. - * - * @param {Number} value value to test - * @param {Number} other value to compare with - * @return {Boolean} - * @api public - */ + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, key, value) { + _.has(result, key) ? result[key].push(value) : result[key] = [value]; + }); -is.ge = function (value, other) { - if (isActualNaN(value) || isActualNaN(other)) { - throw new TypeError('NaN is not a valid value'); - } - return !is.infinite(value) && !is.infinite(other) && value >= other; -}; + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, key, value) { + result[key] = value; + }); -/** - * is.gt - * Test if `value` is greater than `other`. - * - * @param {Number} value value to test - * @param {Number} other value to compare with - * @return {Boolean} - * @api public - */ + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, key) { + _.has(result, key) ? result[key]++ : result[key] = 1; + }); -is.gt = function (value, other) { - if (isActualNaN(value) || isActualNaN(other)) { - throw new TypeError('NaN is not a valid value'); - } - return !is.infinite(value) && !is.infinite(other) && value > other; -}; + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator, context) { + iterator = lookupIterator(iterator); + var value = iterator.call(context, obj); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >>> 1; + iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; + } + return low; + }; -/** - * is.le - * Test if `value` is less than or equal to `other`. - * - * @param {Number} value value to test - * @param {Number} other value to compare with - * @return {Boolean} if 'value' is less than or equal to 'other' - * @api public - */ + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (obj.length === +obj.length) return _.map(obj, _.identity); + return _.values(obj); + }; -is.le = function (value, other) { - if (isActualNaN(value) || isActualNaN(other)) { - throw new TypeError('NaN is not a valid value'); - } - return !is.infinite(value) && !is.infinite(other) && value <= other; -}; + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; + }; -/** - * is.lt - * Test if `value` is less than `other`. - * - * @param {Number} value value to test - * @param {Number} other value to compare with - * @return {Boolean} if `value` is less than `other` - * @api public - */ + // Array Functions + // --------------- -is.lt = function (value, other) { - if (isActualNaN(value) || isActualNaN(other)) { - throw new TypeError('NaN is not a valid value'); - } - return !is.infinite(value) && !is.infinite(other) && value < other; -}; + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) return array[0]; + if (n < 0) return []; + return slice.call(array, 0, n); + }; -/** - * is.within - * Test if `value` is within `start` and `finish`. - * - * @param {Number} value value to test - * @param {Number} start lower bound - * @param {Number} finish upper bound - * @return {Boolean} true if 'value' is is within 'start' and 'finish' - * @api public - */ -is.within = function (value, start, finish) { - if (isActualNaN(value) || isActualNaN(start) || isActualNaN(finish)) { - throw new TypeError('NaN is not a valid value'); - } else if (!is.number(value) || !is.number(start) || !is.number(finish)) { - throw new TypeError('all arguments must be numbers'); - } - var isAnyInfinite = is.infinite(value) || is.infinite(start) || is.infinite(finish); - return isAnyInfinite || (value >= start && value <= finish); -}; + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; -/** - * Test object. - */ + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) return array[array.length - 1]; + return slice.call(array, Math.max(array.length - n, 0)); + }; -/** - * is.object - * Test if `value` is an object. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is an object, false otherwise - * @api public - */ + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, (n == null) || guard ? 1 : n); + }; -is.object = function (value) { - return value && '[object Object]' === toString.call(value); -}; + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; -/** - * is.hash - * Test if `value` is a hash - a plain object literal. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a hash, false otherwise - * @api public - */ + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, output) { + if (shallow && _.every(input, _.isArray)) { + return concat.apply(output, input); + } + each(input, function(value) { + if (_.isArray(value) || _.isArguments(value)) { + shallow ? push.apply(output, value) : flatten(value, shallow, output); + } else { + output.push(value); + } + }); + return output; + }; -is.hash = function (value) { - return is.object(value) && value.constructor === Object && !value.nodeType && !value.setInterval; -}; + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, []); + }; -/** - * Test regexp. - */ + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; -/** - * is.regexp - * Test if `value` is a regular expression. - * - * @param {Mixed} value value to test - * @return {Boolean} true if `value` is a regexp, false otherwise - * @api public - */ + // Split an array into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(array, predicate) { + var pass = [], fail = []; + each(array, function(elem) { + (predicate(elem) ? pass : fail).push(elem); + }); + return [pass, fail]; + }; -is.regexp = function (value) { - return '[object RegExp]' === toString.call(value); -}; + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator, context) { + if (_.isFunction(isSorted)) { + context = iterator; + iterator = isSorted; + isSorted = false; + } + var initial = iterator ? _.map(array, iterator, context) : array; + var results = []; + var seen = []; + each(initial, function(value, index) { + if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { + seen.push(value); + results.push(array[index]); + } + }); + return results; + }; -/** - * Test string. - */ + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; -/** - * is.string - * Test if `value` is a string. - * - * @param {Mixed} value value to test - * @return {Boolean} true if 'value' is a string, false otherwise - * @api public - */ + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.contains(other, item); + }); + }); + }; -is.string = function (value) { - return '[object String]' === toString.call(value); -}; + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.contains(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var length = _.max(_.pluck(arguments, 'length').concat(0)); + var results = new Array(length); + for (var i = 0; i < length; i++) { + results[i] = _.pluck(arguments, '' + i); + } + return results; + }; + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + if (list == null) return {}; + var result = {}; + for (var i = 0, length = list.length; i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; -},{}],117:[function(_dereq_,module,exports){ + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i = 0, length = array.length; + if (isSorted) { + if (typeof isSorted == 'number') { + i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted); + } else { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); + for (; i < length; i++) if (array[i] === item) return i; + return -1; + }; -/** - * Matcher, slightly modified from: - * - * https://github.com/csnover/js-iso8601/blob/lax/iso8601.js - */ + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item, from) { + if (array == null) return -1; + var hasIndex = from != null; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { + return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); + } + var i = (hasIndex ? from : array.length); + while (i--) if (array[i] === item) return i; + return -1; + }; -var matcher = /^(\d{4})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:([ T])(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/; + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + var length = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(length); -/** - * Convert an ISO date string to a date. Fallback to native `Date.parse`. - * - * https://github.com/csnover/js-iso8601/blob/lax/iso8601.js - * - * @param {String} iso - * @return {Date} - */ + while(idx < length) { + range[idx++] = start; + start += step; + } -exports.parse = function (iso) { - var numericKeys = [1, 5, 6, 7, 8, 11, 12]; - var arr = matcher.exec(iso); - var offset = 0; + return range; + }; - // fallback to native parsing - if (!arr) return new Date(iso); + // Function (ahem) Functions + // ------------------ - // remove undefined values - for (var i = 0, val; val = numericKeys[i]; i++) { - arr[val] = parseInt(arr[val], 10) || 0; - } + // Reusable constructor function for prototype setting. + var ctor = function(){}; - // allow undefined days and months - arr[2] = parseInt(arr[2], 10) || 1; - arr[3] = parseInt(arr[3], 10) || 1; + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + var args, bound; + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + ctor.prototype = null; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; - // month is 0-11 - arr[2]--; + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + return function() { + var position = 0; + var args = boundArgs.slice(); + for (var i = 0, length = args.length; i < length; i++) { + if (args[i] === _) args[i] = arguments[position++]; + } + while (position < arguments.length) args.push(arguments[position++]); + return func.apply(this, args); + }; + }; - // allow abitrary sub-second precision - if (arr[8]) arr[8] = (arr[8] + '00').substring(0, 3); + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length === 0) throw new Error('bindAll must be passed function names'); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; - // apply timezone if one exists - if (arr[4] == ' ') { - offset = new Date().getTimezoneOffset(); - } else if (arr[9] !== 'Z' && arr[10]) { - offset = arr[11] * 60 + arr[12]; - if ('+' == arr[10]) offset = 0 - offset; - } + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; - var millis = Date.UTC(arr[1], arr[2], arr[3], arr[5], arr[6] + offset, arr[7], arr[8]); - return new Date(millis); -}; + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(null, args); }, wait); + }; + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; -/** - * Checks whether a `string` is an ISO date string. `strict` mode requires that - * the date string at least have a year, month and date. - * - * @param {String} string - * @param {Boolean} strict - * @return {Boolean} - */ + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + options || (options = {}); + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; -exports.is = function (string, strict) { - if (strict && false === /^\d{4}-\d{2}-\d{2}/.test(string)) return false; - return matcher.test(string); -}; -},{}],118:[function(_dereq_,module,exports){ -// -// strftime -// github.com/samsonjs/strftime -// @_sjs -// -// Copyright 2010 - 2013 Sami Samhuri -// -// MIT License -// http://sjs.mit-license.org -// + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; -;(function() { + var later = function() { + var last = _.now() - timestamp; + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + context = args = null; + } + } + }; - //// Where to export the API - var namespace; + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) { + timeout = setTimeout(later, wait); + } + if (callNow) { + result = func.apply(context, args); + context = args = null; + } - // CommonJS / Node module - if (typeof module !== 'undefined') { - namespace = module.exports = strftime; - } + return result; + }; + }; - // Browsers and other environments - else { - // Get the global object. Works in ES3, ES5, and ES5 strict mode. - namespace = (function(){ return this || (1,eval)('this') }()); - } + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + memo = func.apply(this, arguments); + func = null; + return memo; + }; + }; - function words(s) { return (s || '').split(' '); } + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; - var DefaultLocale = - { days: words('Sunday Monday Tuesday Wednesday Thursday Friday Saturday') - , shortDays: words('Sun Mon Tue Wed Thu Fri Sat') - , months: words('January February March April May June July August September October November December') - , shortMonths: words('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec') - , AM: 'AM' - , PM: 'PM' - , am: 'am' - , pm: 'pm' + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; }; - namespace.strftime = strftime; - function strftime(fmt, d, locale) { - return _strftime(fmt, d, locale); - } + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; - // locale is optional - namespace.strftimeTZ = strftime.strftimeTZ = strftimeTZ; - function strftimeTZ(fmt, d, locale, timezone) { - if (typeof locale == 'number' && timezone == null) { - timezone = locale; - locale = undefined; - } - return _strftime(fmt, d, locale, { timezone: timezone }); - } + // Object Functions + // ---------------- - namespace.strftimeUTC = strftime.strftimeUTC = strftimeUTC; - function strftimeUTC(fmt, d, locale) { - return _strftime(fmt, d, locale, { utc: true }); - } + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + return keys; + }; - namespace.localizedStrftime = strftime.localizedStrftime = localizedStrftime; - function localizedStrftime(locale) { - return function(fmt, d, options) { - return strftime(fmt, d, locale, options); - }; - } + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = new Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; - // d, locale, and options are optional, but you can't leave - // holes in the argument list. If you pass options you have to pass - // in all the preceding args as well. - // - // options: - // - locale [object] an object with the same structure as DefaultLocale - // - timezone [number] timezone offset in minutes from GMT - function _strftime(fmt, d, locale, options) { - options = options || {}; + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = new Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; - // d and locale are optional so check if d is really the locale - if (d && !quacksLikeDate(d)) { - locale = d; - d = undefined; + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; } - d = d || new Date(); + return result; + }; - locale = locale || DefaultLocale; - locale.formats = locale.formats || {}; + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; - // Hang on to this Unix timestamp because we might mess with it directly below. - var timestamp = d.getTime(); + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + } + }); + return obj; + }; - if (options.utc || typeof options.timezone == 'number') { - d = dateToUTC(d); - } + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + each(keys, function(key) { + if (key in obj) copy[key] = obj[key]; + }); + return copy; + }; - if (typeof options.timezone == 'number') { - d = new Date(d.getTime() + (options.timezone * 60000)); + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + for (var key in obj) { + if (!_.contains(keys, key)) copy[key] = obj[key]; } + return copy; + }; - // Most of the specifiers supported by C's strftime, and some from Ruby. - // Some other syntax extensions from Ruby are supported: %-, %_, and %0 - // to pad with nothing, space, or zero (respectively). - return fmt.replace(/%([-_0]?.)/g, function(_, c) { - var mod, padding; - if (c.length == 2) { - mod = c[0]; - // omit padding - if (mod == '-') { - padding = ''; - } - // pad with space - else if (mod == '_') { - padding = ' '; - } - // pad with zero - else if (mod == '0') { - padding = '0'; - } - else { - // unrecognized, return the format - return _; + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + if (obj[prop] === void 0) obj[prop] = source[prop]; } - c = c[1]; - } - switch (c) { - case 'A': return locale.days[d.getDay()]; - case 'a': return locale.shortDays[d.getDay()]; - case 'B': return locale.months[d.getMonth()]; - case 'b': return locale.shortMonths[d.getMonth()]; - case 'C': return pad(Math.floor(d.getFullYear() / 100), padding); - case 'D': return _strftime(locale.formats.D || '%m/%d/%y', d, locale); - case 'd': return pad(d.getDate(), padding); - case 'e': return d.getDate(); - case 'F': return _strftime(locale.formats.F || '%Y-%m-%d', d, locale); - case 'H': return pad(d.getHours(), padding); - case 'h': return locale.shortMonths[d.getMonth()]; - case 'I': return pad(hours12(d), padding); - case 'j': - var y = new Date(d.getFullYear(), 0, 1); - var day = Math.ceil((d.getTime() - y.getTime()) / (1000 * 60 * 60 * 24)); - return pad(day, 3); - case 'k': return pad(d.getHours(), padding == null ? ' ' : padding); - case 'L': return pad(Math.floor(timestamp % 1000), 3); - case 'l': return pad(hours12(d), padding == null ? ' ' : padding); - case 'M': return pad(d.getMinutes(), padding); - case 'm': return pad(d.getMonth() + 1, padding); - case 'n': return '\n'; - case 'o': return String(d.getDate()) + ordinal(d.getDate()); - case 'P': return d.getHours() < 12 ? locale.am : locale.pm; - case 'p': return d.getHours() < 12 ? locale.AM : locale.PM; - case 'R': return _strftime(locale.formats.R || '%H:%M', d, locale); - case 'r': return _strftime(locale.formats.r || '%I:%M:%S %p', d, locale); - case 'S': return pad(d.getSeconds(), padding); - case 's': return Math.floor(timestamp / 1000); - case 'T': return _strftime(locale.formats.T || '%H:%M:%S', d, locale); - case 't': return '\t'; - case 'U': return pad(weekNumber(d, 'sunday'), padding); - case 'u': - var day = d.getDay(); - return day == 0 ? 7 : day; // 1 - 7, Monday is first day of the week - case 'v': return _strftime(locale.formats.v || '%e-%b-%Y', d, locale); - case 'W': return pad(weekNumber(d, 'monday'), padding); - case 'w': return d.getDay(); // 0 - 6, Sunday is first day of the week - case 'Y': return d.getFullYear(); - case 'y': - var y = String(d.getFullYear()); - return y.slice(y.length - 2); - case 'Z': - if (options.utc) { - return "GMT"; - } - else { - var tz = d.toString().match(/\((\w+)\)/); - return tz && tz[1] || ''; - } - case 'z': - if (options.utc) { - return "+0000"; - } - else { - var off = typeof options.timezone == 'number' ? options.timezone : -d.getTimezoneOffset(); - return (off < 0 ? '-' : '+') + pad(Math.abs(off / 60)) + pad(off % 60); - } - default: return c; } }); - } + return obj; + }; - function dateToUTC(d) { - var msDelta = (d.getTimezoneOffset() || 0) * 60000; - return new Date(d.getTime() + msDelta); - } + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; - var RequiredDateMethods = ['getTime', 'getTimezoneOffset', 'getDay', 'getDate', 'getMonth', 'getFullYear', 'getYear', 'getHours', 'getMinutes', 'getSeconds']; - function quacksLikeDate(x) { - var i = 0 - , n = RequiredDateMethods.length - ; - for (i = 0; i < n; ++i) { - if (typeof x[RequiredDateMethods[i]] != 'function') { - return false; + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) return bStack[length] == b; + } + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && + _.isFunction(bCtor) && (bCtor instanceof bCtor)) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + if (!(result = eq(a[size], b[size], aStack, bStack))) break; + } + } + } else { + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; } } - return true; - } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return result; + }; - // Default padding is '0' and default length is 2, both are optional. - function pad(n, padding, length) { - // pad(n, ) - if (typeof padding === 'number') { - length = padding; - padding = '0'; - } + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, [], []); + }; - // Defaults handle pad(n) and pad(n, ) - if (padding == null) { - padding = '0'; - } - length = length || 2; + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; - var s = String(n); - // padding may be an empty string, don't loop forever if it is - if (padding) { - while (s.length < length) s = padding + s; - } - return s; - } + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; - function hours12(d) { - var hour = d.getHours(); - if (hour == 0) hour = 12; - else if (hour > 12) hour -= 12; - return hour; - } + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; - // Get the ordinal suffix for a number: st, nd, rd, or th - function ordinal(n) { - var i = n % 10 - , ii = n % 100 - ; - if ((ii >= 11 && ii <= 13) || i === 0 || i >= 4) { - return 'th'; - } - switch (i) { - case 1: return 'st'; - case 2: return 'nd'; - case 3: return 'rd'; - } - } + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; - // firstWeekday: 'sunday' or 'monday', default is 'sunday' - // - // Pilfered & ported from Ruby's strftime implementation. - function weekNumber(d, firstWeekday) { - firstWeekday = firstWeekday || 'sunday'; + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. + each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) == '[object ' + name + ']'; + }; + }); - // This works by shifting the weekday back by one day if we - // are treating Monday as the first day of the week. - var wday = d.getDay(); - if (firstWeekday == 'monday') { - if (wday == 0) // Sunday - wday = 6; - else - wday--; - } - var firstDayOfYear = new Date(d.getFullYear(), 0, 1) - , yday = (d - firstDayOfYear) / 86400000 - , weekNum = (yday + 7 - wday) / 7 - ; - return Math.floor(weekNum); + // Define a fallback version of the method in browsers (ahem, IE), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; } -}()); - -},{}],119:[function(_dereq_,module,exports){ -function Agent() { - this._defaults = []; -} - -["use", "on", "once", "set", "query", "type", "accept", "auth", "withCredentials", "sortQuery", "retry", "ok", "redirects", - "timeout", "buffer", "serialize", "parse", "ca", "key", "pfx", "cert"].forEach(function(fn) { - /** Default setting for all requests from this agent */ - Agent.prototype[fn] = function(/*varargs*/) { - this._defaults.push({fn:fn, arguments:arguments}); - return this; + // Optimize `isFunction` if appropriate. + if (typeof (/./) !== 'function') { + _.isFunction = function(obj) { + return typeof obj === 'function'; + }; } -}); -Agent.prototype._setDefaults = function(req) { - this._defaults.forEach(function(def) { - req[def.fn].apply(req, def.arguments); - }); -}; - -module.exports = Agent; - -},{}],120:[function(_dereq_,module,exports){ -/** - * Root reference for iframes. - */ - -var root; -if (typeof window !== 'undefined') { // Browser window - root = window; -} else if (typeof self !== 'undefined') { // Web Worker - root = self; -} else { // Other environments - console.warn("Using browser-only version of superagent in non-browser environment"); - root = this; -} - -var Emitter = _dereq_('component-emitter'); -var RequestBase = _dereq_('./request-base'); -var isObject = _dereq_('./is-object'); -var ResponseBase = _dereq_('./response-base'); -var Agent = _dereq_('./agent-base'); - -/** - * Noop. - */ - -function noop(){}; - -/** - * Expose `request`. - */ - -var request = exports = module.exports = function(method, url) { - // callback - if ('function' == typeof url) { - return new exports.Request('GET', method).end(url); - } + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; - // url first - if (1 == arguments.length) { - return new exports.Request('GET', method); - } + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj != +obj; + }; - return new exports.Request(method, url); -} + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; -exports.Request = Request; + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; -/** - * Determine XHR. - */ + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; -request.getXHR = function () { - if (root.XMLHttpRequest - && (!root.location || 'file:' != root.location.protocol - || !root.ActiveXObject)) { - return new XMLHttpRequest; - } else { - try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} - } - throw Error("Browser-only version of superagent could not find XHR"); -}; + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; -/** - * Removes leading and trailing whitespace, added to support IE. - * - * @param {String} s - * @return {String} - * @api private - */ + // Utility Functions + // ----------------- -var trim = ''.trim - ? function(s) { return s.trim(); } - : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; -/** - * Serialize the given `obj`. - * - * @param {Object} obj - * @return {String} - * @api private - */ + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; -function serialize(obj) { - if (!isObject(obj)) return obj; - var pairs = []; - for (var key in obj) { - pushEncodedKeyValuePair(pairs, key, obj[key]); - } - return pairs.join('&'); -} + _.constant = function(value) { + return function () { + return value; + }; + }; -/** - * Helps 'serialize' with serializing arrays. - * Mutates the pairs array. - * - * @param {Array} pairs - * @param {String} key - * @param {Mixed} val - */ + _.property = function(key) { + return function(obj) { + return obj[key]; + }; + }; -function pushEncodedKeyValuePair(pairs, key, val) { - if (val != null) { - if (Array.isArray(val)) { - val.forEach(function(v) { - pushEncodedKeyValuePair(pairs, key, v); - }); - } else if (isObject(val)) { - for(var subkey in val) { - pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); + // Returns a predicate for checking whether an object has a given set of `key:value` pairs. + _.matches = function(attrs) { + return function(obj) { + if (obj === attrs) return true; //avoid comparing an object to itself. + for (var key in attrs) { + if (attrs[key] !== obj[key]) + return false; } - } else { - pairs.push(encodeURIComponent(key) - + '=' + encodeURIComponent(val)); + return true; } - } else if (val === null) { - pairs.push(encodeURIComponent(key)); - } -} - -/** - * Expose serialization method. - */ + }; -request.serializeObject = serialize; + // Run a function **n** times. + _.times = function(n, iterator, context) { + var accum = Array(Math.max(0, n)); + for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); + return accum; + }; -/** - * Parse the given x-www-form-urlencoded `str`. - * - * @param {String} str - * @return {Object} - * @api private - */ + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; -function parseString(str) { - var obj = {}; - var pairs = str.split('&'); - var pair; - var pos; + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { return new Date().getTime(); }; - for (var i = 0, len = pairs.length; i < len; ++i) { - pair = pairs[i]; - pos = pair.indexOf('='); - if (pos == -1) { - obj[decodeURIComponent(pair)] = ''; - } else { - obj[decodeURIComponent(pair.slice(0, pos))] = - decodeURIComponent(pair.slice(pos + 1)); + // List of HTML entities for escaping. + var entityMap = { + escape: { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' } - } + }; + entityMap.unescape = _.invert(entityMap.escape); - return obj; -} + // Regexes containing the keys and values listed immediately above. + var entityRegexes = { + escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), + unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') + }; -/** - * Expose parser. - */ + // Functions for escaping and unescaping strings to/from HTML interpolation. + _.each(['escape', 'unescape'], function(method) { + _[method] = function(string) { + if (string == null) return ''; + return ('' + string).replace(entityRegexes[method], function(match) { + return entityMap[method][match]; + }); + }; + }); -request.parseString = parseString; + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property) { + if (object == null) return void 0; + var value = object[property]; + return _.isFunction(value) ? value.call(object) : value; + }; -/** - * Default MIME type map. - * - * superagent.types.xml = 'application/xml'; - * - */ + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result.call(this, func.apply(_, args)); + }; + }); + }; -request.types = { - html: 'text/html', - json: 'application/json', - xml: 'text/xml', - urlencoded: 'application/x-www-form-urlencoded', - 'form': 'application/x-www-form-urlencoded', - 'form-data': 'application/x-www-form-urlencoded' -}; + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; -/** - * Default serialization map. - * - * superagent.serialize['application/xml'] = function(obj){ - * return 'generated xml here'; - * }; - * - */ + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; -request.serialize = { - 'application/x-www-form-urlencoded': serialize, - 'application/json': JSON.stringify, -}; + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; -/** - * Default parsers. - * - * superagent.parse['application/xml'] = function(str){ - * return { object parsed from str }; - * }; - * - */ + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; -request.parse = { - 'application/x-www-form-urlencoded': parseString, - 'application/json': JSON.parse, -}; + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; -/** - * Parse the given header `str` into - * an object containing the mapped fields. - * - * @param {String} str - * @return {Object} - * @api private - */ + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(text, data, settings) { + var render; + settings = _.defaults({}, settings, _.templateSettings); -function parseHeader(str) { - var lines = str.split(/\r?\n/); - var fields = {}; - var index; - var line; - var field; - var val; + // Combine delimiters into one regular expression via alternation. + var matcher = new RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); - for (var i = 0, len = lines.length; i < len; ++i) { - line = lines[i]; - index = line.indexOf(':'); - if (index === -1) { // could be empty line, just skip it - continue; + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset) + .replace(escaper, function(match) { return '\\' + escapes[match]; }); + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } + if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + index = offset + match.length; + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + "return __p;\n"; + + try { + render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; } - field = line.slice(0, index).toLowerCase(); - val = trim(line.slice(index + 1)); - fields[field] = val; - } - return fields; -} + if (data) return render(data, _); + var template = function(data) { + return render.call(this, data, _); + }; -/** - * Check if `mime` is json or has +json structured syntax suffix. - * - * @param {String} mime - * @return {Boolean} - * @api private - */ + // Provide the compiled function source as a convenience for precompilation. + template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; -function isJSON(mime) { - // should match /json or +json - // but not /json-seq - return /[\/+]json($|[^-\w])/.test(mime); -} + return template; + }; -/** - * Initialize a new `Response` with the given `xhr`. - * - * - set flags (.ok, .error, etc) - * - parse header - * - * Examples: - * - * Aliasing `superagent` as `request` is nice: - * - * request = superagent; - * - * We can use the promise-like API, or pass callbacks: - * - * request.get('/').end(function(res){}); - * request.get('/', function(res){}); - * - * Sending data can be chained: - * - * request - * .post('/user') - * .send({ name: 'tj' }) - * .end(function(res){}); - * - * Or passed to `.send()`: - * - * request - * .post('/user') - * .send({ name: 'tj' }, function(res){}); - * - * Or passed to `.post()`: - * - * request - * .post('/user', { name: 'tj' }) - * .end(function(res){}); - * - * Or further reduced to a single call for simple cases: - * - * request - * .post('/user', { name: 'tj' }, function(res){}); - * - * @param {XMLHTTPRequest} xhr - * @param {Object} options - * @api private - */ + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; -function Response(req) { - this.req = req; - this.xhr = this.req.xhr; - // responseText is accessible only if responseType is '' or 'text' and on older browsers - this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') - ? this.xhr.responseText - : null; - this.statusText = this.req.xhr.statusText; - var status = this.xhr.status; - // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request - if (status === 1223) { - status = 204; - } - this._setStatusProperties(status); - this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); - // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but - // getResponseHeader still works. so we get content-type even if getting - // other headers fails. - this.header['content-type'] = this.xhr.getResponseHeader('content-type'); - this._setHeaderProperties(this.header); + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. - if (null === this.text && req._responseType) { - this.body = this.xhr.response; - } else { - this.body = this.req.method != 'HEAD' - ? this._parseBody(this.text ? this.text : this.xhr.response) - : null; - } -} + // Helper function to continue chaining intermediate results. + var result = function(obj) { + return this._chain ? _(obj).chain() : obj; + }; -ResponseBase(Response.prototype); + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); -/** - * Parse the given body `str`. - * - * Used for auto-parsing of bodies. Parsers - * are defined on the `superagent.parse` object. - * - * @param {String} str - * @return {Mixed} - * @api private - */ + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; + return result.call(this, obj); + }; + }); -Response.prototype._parseBody = function(str) { - var parse = request.parse[this.type]; - if (this.req._parser) { - return this.req._parser(this, str); - } - if (!parse && isJSON(this.type)) { - parse = request.parse['application/json']; - } - return parse && str && (str.length || str instanceof Object) - ? parse(str) - : null; -}; + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result.call(this, method.apply(this._wrapped, arguments)); + }; + }); -/** - * Return an `Error` representative of this response. - * - * @return {Error} - * @api public - */ + _.extend(_.prototype, { -Response.prototype.toError = function(){ - var req = this.req; - var method = req.method; - var url = req.url; + // Start chaining a wrapped Underscore object. + chain: function() { + this._chain = true; + return this; + }, - var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; - var err = new Error(msg); - err.status = this.status; - err.method = method; - err.url = url; + // Extracts the result from a wrapped and chained object. + value: function() { + return this._wrapped; + } - return err; -}; + }); -/** - * Expose `Response`. - */ + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}).call(this); -request.Response = Response; +},{}],79:[function(_dereq_,module,exports){ +// +// strftime +// github.com/samsonjs/strftime +// @_sjs +// +// Copyright 2010 - 2013 Sami Samhuri +// +// MIT License +// http://sjs.mit-license.org +// -/** - * Initialize a new `Request` with the given `method` and `url`. - * - * @param {String} method - * @param {String} url - * @api public - */ +;(function() { -function Request(method, url) { - var self = this; - this._query = this._query || []; - this.method = method; - this.url = url; - this.header = {}; // preserves header name case - this._header = {}; // coerces header names to lowercase - this.on('end', function(){ - var err = null; - var res = null; + //// Where to export the API + var namespace; - try { - res = new Response(self); - } catch(e) { - err = new Error('Parser is unable to parse the response'); - err.parse = true; - err.original = e; - // issue #675: return the raw response if the response parsing fails - if (self.xhr) { - // ie9 doesn't have 'response' property - err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response; - // issue #876: return the http status code if the response parsing fails - err.status = self.xhr.status ? self.xhr.status : null; - err.statusCode = err.status; // backwards-compat only - } else { - err.rawResponse = null; - err.status = null; - } + // CommonJS / Node module + if (typeof module !== 'undefined') { + namespace = module.exports = strftime; + } - return self.callback(err); - } + // Browsers and other environments + else { + // Get the global object. Works in ES3, ES5, and ES5 strict mode. + namespace = (function(){ return this || (1,eval)('this') }()); + } - self.emit('response', res); + function words(s) { return (s || '').split(' '); } - var new_err; - try { - if (!self._isResponseOK(res)) { - new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); - } - } catch(custom_err) { - new_err = custom_err; // ok() callback can throw - } + var DefaultLocale = + { days: words('Sunday Monday Tuesday Wednesday Thursday Friday Saturday') + , shortDays: words('Sun Mon Tue Wed Thu Fri Sat') + , months: words('January February March April May June July August September October November December') + , shortMonths: words('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec') + , AM: 'AM' + , PM: 'PM' + , am: 'am' + , pm: 'pm' + }; - // #1000 don't catch errors from the callback to avoid double calling it - if (new_err) { - new_err.original = err; - new_err.response = res; - new_err.status = res.status; - self.callback(new_err, res); - } else { - self.callback(null, res); + namespace.strftime = strftime; + function strftime(fmt, d, locale) { + return _strftime(fmt, d, locale); + } + + // locale is optional + namespace.strftimeTZ = strftime.strftimeTZ = strftimeTZ; + function strftimeTZ(fmt, d, locale, timezone) { + if (typeof locale == 'number' && timezone == null) { + timezone = locale; + locale = undefined; } - }); -} + return _strftime(fmt, d, locale, { timezone: timezone }); + } -/** - * Mixin `Emitter` and `RequestBase`. - */ + namespace.strftimeUTC = strftime.strftimeUTC = strftimeUTC; + function strftimeUTC(fmt, d, locale) { + return _strftime(fmt, d, locale, { utc: true }); + } -Emitter(Request.prototype); -RequestBase(Request.prototype); + namespace.localizedStrftime = strftime.localizedStrftime = localizedStrftime; + function localizedStrftime(locale) { + return function(fmt, d, options) { + return strftime(fmt, d, locale, options); + }; + } -/** - * Set Content-Type to `type`, mapping values from `request.types`. - * - * Examples: - * - * superagent.types.xml = 'application/xml'; - * - * request.post('/') - * .type('xml') - * .send(xmlstring) - * .end(callback); - * - * request.post('/') - * .type('application/xml') - * .send(xmlstring) - * .end(callback); - * - * @param {String} type - * @return {Request} for chaining - * @api public - */ + // d, locale, and options are optional, but you can't leave + // holes in the argument list. If you pass options you have to pass + // in all the preceding args as well. + // + // options: + // - locale [object] an object with the same structure as DefaultLocale + // - timezone [number] timezone offset in minutes from GMT + function _strftime(fmt, d, locale, options) { + options = options || {}; -Request.prototype.type = function(type){ - this.set('Content-Type', request.types[type] || type); - return this; -}; + // d and locale are optional so check if d is really the locale + if (d && !quacksLikeDate(d)) { + locale = d; + d = undefined; + } + d = d || new Date(); -/** - * Set Accept to `type`, mapping values from `request.types`. - * - * Examples: - * - * superagent.types.json = 'application/json'; - * - * request.get('/agent') - * .accept('json') - * .end(callback); - * - * request.get('/agent') - * .accept('application/json') - * .end(callback); - * - * @param {String} accept - * @return {Request} for chaining - * @api public - */ + locale = locale || DefaultLocale; + locale.formats = locale.formats || {}; -Request.prototype.accept = function(type){ - this.set('Accept', request.types[type] || type); - return this; -}; + // Hang on to this Unix timestamp because we might mess with it directly below. + var timestamp = d.getTime(); -/** - * Set Authorization field value with `user` and `pass`. - * - * @param {String} user - * @param {String} [pass] optional in case of using 'bearer' as type - * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic') - * @return {Request} for chaining - * @api public - */ + if (options.utc || typeof options.timezone == 'number') { + d = dateToUTC(d); + } -Request.prototype.auth = function(user, pass, options){ - if (1 === arguments.length) pass = ''; - if (typeof pass === 'object' && pass !== null) { // pass is optional and can be replaced with options - options = pass; - pass = ''; + if (typeof options.timezone == 'number') { + d = new Date(d.getTime() + (options.timezone * 60000)); + } + + // Most of the specifiers supported by C's strftime, and some from Ruby. + // Some other syntax extensions from Ruby are supported: %-, %_, and %0 + // to pad with nothing, space, or zero (respectively). + return fmt.replace(/%([-_0]?.)/g, function(_, c) { + var mod, padding; + if (c.length == 2) { + mod = c[0]; + // omit padding + if (mod == '-') { + padding = ''; + } + // pad with space + else if (mod == '_') { + padding = ' '; + } + // pad with zero + else if (mod == '0') { + padding = '0'; + } + else { + // unrecognized, return the format + return _; + } + c = c[1]; + } + switch (c) { + case 'A': return locale.days[d.getDay()]; + case 'a': return locale.shortDays[d.getDay()]; + case 'B': return locale.months[d.getMonth()]; + case 'b': return locale.shortMonths[d.getMonth()]; + case 'C': return pad(Math.floor(d.getFullYear() / 100), padding); + case 'D': return _strftime(locale.formats.D || '%m/%d/%y', d, locale); + case 'd': return pad(d.getDate(), padding); + case 'e': return d.getDate(); + case 'F': return _strftime(locale.formats.F || '%Y-%m-%d', d, locale); + case 'H': return pad(d.getHours(), padding); + case 'h': return locale.shortMonths[d.getMonth()]; + case 'I': return pad(hours12(d), padding); + case 'j': + var y = new Date(d.getFullYear(), 0, 1); + var day = Math.ceil((d.getTime() - y.getTime()) / (1000 * 60 * 60 * 24)); + return pad(day, 3); + case 'k': return pad(d.getHours(), padding == null ? ' ' : padding); + case 'L': return pad(Math.floor(timestamp % 1000), 3); + case 'l': return pad(hours12(d), padding == null ? ' ' : padding); + case 'M': return pad(d.getMinutes(), padding); + case 'm': return pad(d.getMonth() + 1, padding); + case 'n': return '\n'; + case 'o': return String(d.getDate()) + ordinal(d.getDate()); + case 'P': return d.getHours() < 12 ? locale.am : locale.pm; + case 'p': return d.getHours() < 12 ? locale.AM : locale.PM; + case 'R': return _strftime(locale.formats.R || '%H:%M', d, locale); + case 'r': return _strftime(locale.formats.r || '%I:%M:%S %p', d, locale); + case 'S': return pad(d.getSeconds(), padding); + case 's': return Math.floor(timestamp / 1000); + case 'T': return _strftime(locale.formats.T || '%H:%M:%S', d, locale); + case 't': return '\t'; + case 'U': return pad(weekNumber(d, 'sunday'), padding); + case 'u': + var day = d.getDay(); + return day == 0 ? 7 : day; // 1 - 7, Monday is first day of the week + case 'v': return _strftime(locale.formats.v || '%e-%b-%Y', d, locale); + case 'W': return pad(weekNumber(d, 'monday'), padding); + case 'w': return d.getDay(); // 0 - 6, Sunday is first day of the week + case 'Y': return d.getFullYear(); + case 'y': + var y = String(d.getFullYear()); + return y.slice(y.length - 2); + case 'Z': + if (options.utc) { + return "GMT"; + } + else { + var tz = d.toString().match(/\((\w+)\)/); + return tz && tz[1] || ''; + } + case 'z': + if (options.utc) { + return "+0000"; + } + else { + var off = typeof options.timezone == 'number' ? options.timezone : -d.getTimezoneOffset(); + return (off < 0 ? '-' : '+') + pad(Math.abs(off / 60)) + pad(off % 60); + } + default: return c; + } + }); } - if (!options) { - options = { - type: 'function' === typeof btoa ? 'basic' : 'auto', - }; + + function dateToUTC(d) { + var msDelta = (d.getTimezoneOffset() || 0) * 60000; + return new Date(d.getTime() + msDelta); + } + + var RequiredDateMethods = ['getTime', 'getTimezoneOffset', 'getDay', 'getDate', 'getMonth', 'getFullYear', 'getYear', 'getHours', 'getMinutes', 'getSeconds']; + function quacksLikeDate(x) { + var i = 0 + , n = RequiredDateMethods.length + ; + for (i = 0; i < n; ++i) { + if (typeof x[RequiredDateMethods[i]] != 'function') { + return false; + } + } + return true; } - var encoder = function(string) { - if ('function' === typeof btoa) { - return btoa(string); + // Default padding is '0' and default length is 2, both are optional. + function pad(n, padding, length) { + // pad(n, ) + if (typeof padding === 'number') { + length = padding; + padding = '0'; } - throw new Error('Cannot use basic auth, btoa is not a function'); - }; - - return this._auth(user, pass, options, encoder); -}; - -/** - * Add query-string `val`. - * - * Examples: - * - * request.get('/shoes') - * .query('size=10') - * .query({ color: 'blue' }) - * - * @param {Object|String} val - * @return {Request} for chaining - * @api public - */ - -Request.prototype.query = function(val){ - if ('string' != typeof val) val = serialize(val); - if (val) this._query.push(val); - return this; -}; -/** - * Queue the given `file` as an attachment to the specified `field`, - * with optional `options` (or filename). - * - * ``` js - * request.post('/upload') - * .attach('content', new Blob(['hey!'], { type: "text/html"})) - * .end(callback); - * ``` - * - * @param {String} field - * @param {Blob|File} file - * @param {String|Object} options - * @return {Request} for chaining - * @api public - */ + // Defaults handle pad(n) and pad(n, ) + if (padding == null) { + padding = '0'; + } + length = length || 2; -Request.prototype.attach = function(field, file, options){ - if (file) { - if (this._data) { - throw Error("superagent can't mix .send() and .attach()"); + var s = String(n); + // padding may be an empty string, don't loop forever if it is + if (padding) { + while (s.length < length) s = padding + s; } + return s; + } - this._getFormData().append(field, file, options || file.name); + function hours12(d) { + var hour = d.getHours(); + if (hour == 0) hour = 12; + else if (hour > 12) hour -= 12; + return hour; } - return this; -}; -Request.prototype._getFormData = function(){ - if (!this._formData) { - this._formData = new root.FormData(); + // Get the ordinal suffix for a number: st, nd, rd, or th + function ordinal(n) { + var i = n % 10 + , ii = n % 100 + ; + if ((ii >= 11 && ii <= 13) || i === 0 || i >= 4) { + return 'th'; + } + switch (i) { + case 1: return 'st'; + case 2: return 'nd'; + case 3: return 'rd'; + } } - return this._formData; -}; -/** - * Invoke the callback with `err` and `res` - * and handle arity check. - * - * @param {Error} err - * @param {Response} res - * @api private - */ + // firstWeekday: 'sunday' or 'monday', default is 'sunday' + // + // Pilfered & ported from Ruby's strftime implementation. + function weekNumber(d, firstWeekday) { + firstWeekday = firstWeekday || 'sunday'; -Request.prototype.callback = function(err, res){ - if (this._shouldRetry(err, res)) { - return this._retry(); + // This works by shifting the weekday back by one day if we + // are treating Monday as the first day of the week. + var wday = d.getDay(); + if (firstWeekday == 'monday') { + if (wday == 0) // Sunday + wday = 6; + else + wday--; + } + var firstDayOfYear = new Date(d.getFullYear(), 0, 1) + , yday = (d - firstDayOfYear) / 86400000 + , weekNum = (yday + 7 - wday) / 7 + ; + return Math.floor(weekNum); } - var fn = this._callback; - this.clearTimeout(); +}()); - if (err) { - if (this._maxRetries) err.retries = this._retries - 1; - this.emit('error', err); +},{}],80:[function(_dereq_,module,exports){ +function Agent() { + this._defaults = []; +} + +["use", "on", "once", "set", "query", "type", "accept", "auth", "withCredentials", "sortQuery", "retry", "ok", "redirects", + "timeout", "buffer", "serialize", "parse", "ca", "key", "pfx", "cert"].forEach(function(fn) { + /** Default setting for all requests from this agent */ + Agent.prototype[fn] = function(/*varargs*/) { + this._defaults.push({fn:fn, arguments:arguments}); + return this; } +}); - fn(err, res); +Agent.prototype._setDefaults = function(req) { + this._defaults.forEach(function(def) { + req[def.fn].apply(req, def.arguments); + }); }; +module.exports = Agent; + +},{}],81:[function(_dereq_,module,exports){ /** - * Invoke callback with x-domain error. - * - * @api private + * Root reference for iframes. */ -Request.prototype.crossDomainError = function(){ - var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); - err.crossDomain = true; - - err.status = this.status; - err.method = this.method; - err.url = this.url; - - this.callback(err); -}; - -// This only warns, because the request is still likely to work -Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){ - console.warn("This is not supported in browser version of superagent"); - return this; -}; +var root; +if (typeof window !== 'undefined') { // Browser window + root = window; +} else if (typeof self !== 'undefined') { // Web Worker + root = self; +} else { // Other environments + console.warn("Using browser-only version of superagent in non-browser environment"); + root = this; +} -// This throws, because it can't send/receive data as expected -Request.prototype.pipe = Request.prototype.write = function(){ - throw Error("Streaming is not supported in browser version of superagent"); -}; +var Emitter = _dereq_('component-emitter'); +var RequestBase = _dereq_('./request-base'); +var isObject = _dereq_('./is-object'); +var ResponseBase = _dereq_('./response-base'); +var Agent = _dereq_('./agent-base'); /** - * Check if `obj` is a host object, - * we don't want to serialize these :) - * - * @param {Object} obj - * @return {Boolean} - * @api private + * Noop. */ -Request.prototype._isHost = function _isHost(obj) { - // Native objects stringify to [object File], [object Blob], [object FormData], etc. - return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]'; -} + +function noop(){}; /** - * Initiate request, invoking callback `fn(res)` - * with an instanceof `Response`. - * - * @param {Function} fn - * @return {Request} for chaining - * @api public + * Expose `request`. */ -Request.prototype.end = function(fn){ - if (this._endCalled) { - console.warn("Warning: .end() was called twice. This is not supported in superagent"); +var request = exports = module.exports = function(method, url) { + // callback + if ('function' == typeof url) { + return new exports.Request('GET', method).end(url); } - this._endCalled = true; - // store callback - this._callback = fn || noop; + // url first + if (1 == arguments.length) { + return new exports.Request('GET', method); + } - // querystring - this._finalizeQueryString(); + return new exports.Request(method, url); +} - return this._end(); +exports.Request = Request; + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + throw Error("Browser-only version of superagent could not find XHR"); }; -Request.prototype._end = function() { - var self = this; - var xhr = (this.xhr = request.getXHR()); - var data = this._formData || this._data; +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ - this._setTimeouts(); +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; - // state change - xhr.onreadystatechange = function(){ - var readyState = xhr.readyState; - if (readyState >= 2 && self._responseTimeoutTimer) { - clearTimeout(self._responseTimeoutTimer); - } - if (4 != readyState) { - return; - } +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ - // In IE9, reads to any property (e.g. status) off of an aborted XHR will - // result in the error "Could not complete the operation due to error c00c023f" - var status; - try { status = xhr.status } catch(e) { status = 0; } +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + pushEncodedKeyValuePair(pairs, key, obj[key]); + } + return pairs.join('&'); +} - if (!status) { - if (self.timedout || self._aborted) return; - return self.crossDomainError(); - } - self.emit('end'); - }; +/** + * Helps 'serialize' with serializing arrays. + * Mutates the pairs array. + * + * @param {Array} pairs + * @param {String} key + * @param {Mixed} val + */ - // progress - var handleProgress = function(direction, e) { - if (e.total > 0) { - e.percent = e.loaded / e.total * 100; - } - e.direction = direction; - self.emit('progress', e); - }; - if (this.hasListeners('progress')) { - try { - xhr.onprogress = handleProgress.bind(null, 'download'); - if (xhr.upload) { - xhr.upload.onprogress = handleProgress.bind(null, 'upload'); +function pushEncodedKeyValuePair(pairs, key, val) { + if (val != null) { + if (Array.isArray(val)) { + val.forEach(function(v) { + pushEncodedKeyValuePair(pairs, key, v); + }); + } else if (isObject(val)) { + for(var subkey in val) { + pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); } - } catch(e) { - // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. - // Reported here: - // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context - } - } - - // initiate request - try { - if (this.username && this.password) { - xhr.open(this.method, this.url, true, this.username, this.password); } else { - xhr.open(this.method, this.url, true); + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(val)); } - } catch (err) { - // see #1149 - return this.callback(err); + } else if (val === null) { + pairs.push(encodeURIComponent(key)); } +} - // CORS - if (this._withCredentials) xhr.withCredentials = true; +/** + * Expose serialization method. + */ - // body - if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { - // serialize stuff - var contentType = this._header['content-type']; - var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; - if (!serialize && isJSON(contentType)) { - serialize = request.serialize['application/json']; - } - if (serialize) data = serialize(data); - } +request.serializeObject = serialize; - // set header fields - for (var field in this.header) { - if (null == this.header[field]) continue; +/** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ - if (this.header.hasOwnProperty(field)) - xhr.setRequestHeader(field, this.header[field]); - } +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var pair; + var pos; - if (this._responseType) { - xhr.responseType = this._responseType; + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + pos = pair.indexOf('='); + if (pos == -1) { + obj[decodeURIComponent(pair)] = ''; + } else { + obj[decodeURIComponent(pair.slice(0, pos))] = + decodeURIComponent(pair.slice(pos + 1)); + } } - // send stuff - this.emit('request', this); - - // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) - // We need null here if data is undefined - xhr.send(typeof data !== 'undefined' ? data : null); - return this; -}; - -request.agent = function() { - return new Agent(); -}; + return obj; +} -["GET", "POST", "OPTIONS", "PATCH", "PUT", "DELETE"].forEach(function(method) { - Agent.prototype[method.toLowerCase()] = function(url, fn) { - var req = new request.Request(method, url); - this._setDefaults(req); - if (fn) { - req.end(fn); - } - return req; - }; -}); +/** + * Expose parser. + */ -Agent.prototype.del = Agent.prototype['delete']; +request.parseString = parseString; /** - * GET `url` with optional callback `fn(res)`. + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public */ -request.get = function(url, data, fn) { - var req = request('GET', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.query(data); - if (fn) req.end(fn); - return req; +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'text/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' }; /** - * HEAD `url` with optional callback `fn(res)`. + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public */ -request.head = function(url, data, fn) { - var req = request('HEAD', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.query(data); - if (fn) req.end(fn); - return req; +request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify }; /** - * OPTIONS query to `url` with optional callback `fn(res)`. - * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public - */ + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ -request.options = function(url, data, fn) { - var req = request('OPTIONS', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse }; /** - * DELETE `url` with optional `data` and callback `fn(res)`. + * Parse the given header `str` into + * an object containing the mapped fields. * - * @param {String} url - * @param {Mixed} [data] - * @param {Function} [fn] - * @return {Request} - * @api public + * @param {String} str + * @return {Object} + * @api private */ -function del(url, data, fn) { - var req = request('DELETE', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + if (index === -1) { // could be empty line, just skip it + continue; + } + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; } -request['del'] = del; -request['delete'] = del; - /** - * PATCH `url` with optional `data` and callback `fn(res)`. + * Check if `mime` is json or has +json structured syntax suffix. * - * @param {String} url - * @param {Mixed} [data] - * @param {Function} [fn] - * @return {Request} - * @api public + * @param {String} mime + * @return {Boolean} + * @api private */ -request.patch = function(url, data, fn) { - var req = request('PATCH', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; -}; +function isJSON(mime) { + // should match /json or +json + // but not /json-seq + return /[\/+]json($|[^-\w])/.test(mime); +} /** - * POST `url` with optional `data` and callback `fn(res)`. + * Initialize a new `Response` with the given `xhr`. * - * @param {String} url - * @param {Mixed} [data] - * @param {Function} [fn] - * @return {Request} - * @api public + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private */ -request.post = function(url, data, fn) { - var req = request('POST', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; -}; +function Response(req) { + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + var status = this.xhr.status; + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + this._setStatusProperties(status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this._setHeaderProperties(this.header); + + if (null === this.text && req._responseType) { + this.body = this.xhr.response; + } else { + this.body = this.req.method != 'HEAD' + ? this._parseBody(this.text ? this.text : this.xhr.response) + : null; + } +} + +ResponseBase(Response.prototype); /** - * PUT `url` with optional `data` and callback `fn(res)`. + * Parse the given body `str`. * - * @param {String} url - * @param {Mixed|Function} [data] or fn - * @param {Function} [fn] - * @return {Request} - * @api public + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private */ -request.put = function(url, data, fn) { - var req = request('PUT', url); - if ('function' == typeof data) (fn = data), (data = null); - if (data) req.send(data); - if (fn) req.end(fn); - return req; +Response.prototype._parseBody = function(str) { + var parse = request.parse[this.type]; + if (this.req._parser) { + return this.req._parser(this, str); + } + if (!parse && isJSON(this.type)) { + parse = request.parse['application/json']; + } + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; }; -},{"./agent-base":119,"./is-object":121,"./request-base":122,"./response-base":123,"component-emitter":125}],121:[function(_dereq_,module,exports){ -'use strict'; - /** - * Check if `obj` is an object. + * Return an `Error` representative of this response. * - * @param {Object} obj - * @return {Boolean} - * @api private + * @return {Error} + * @api public */ -function isObject(obj) { - return null !== obj && 'object' === typeof obj; -} - -module.exports = isObject; +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; -},{}],122:[function(_dereq_,module,exports){ -'use strict'; + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; -/** - * Module of mixed-in functions shared between node and client code - */ -var isObject = _dereq_('./is-object'); + return err; +}; /** - * Expose `RequestBase`. + * Expose `Response`. */ -module.exports = RequestBase; +request.Response = Response; /** - * Initialize a new `RequestBase`. + * Initialize a new `Request` with the given `method` and `url`. * + * @param {String} method + * @param {String} url * @api public */ -function RequestBase(obj) { - if (obj) return mixin(obj); -} +function Request(method, url) { + var self = this; + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; // preserves header name case + this._header = {}; // coerces header names to lowercase + this.on('end', function(){ + var err = null; + var res = null; -/** - * Mixin the prototype properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + // issue #675: return the raw response if the response parsing fails + if (self.xhr) { + // ie9 doesn't have 'response' property + err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response; + // issue #876: return the http status code if the response parsing fails + err.status = self.xhr.status ? self.xhr.status : null; + err.statusCode = err.status; // backwards-compat only + } else { + err.rawResponse = null; + err.status = null; + } -function mixin(obj) { - for (var key in RequestBase.prototype) { - obj[key] = RequestBase.prototype[key]; - } - return obj; + return self.callback(err); + } + + self.emit('response', res); + + var new_err; + try { + if (!self._isResponseOK(res)) { + new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + } + } catch(custom_err) { + new_err = custom_err; // ok() callback can throw + } + + // #1000 don't catch errors from the callback to avoid double calling it + if (new_err) { + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + self.callback(new_err, res); + } else { + self.callback(null, res); + } + }); } /** - * Clear previous timeout. - * - * @return {Request} for chaining - * @api public + * Mixin `Emitter` and `RequestBase`. */ -RequestBase.prototype.clearTimeout = function _clearTimeout(){ - clearTimeout(this._timer); - clearTimeout(this._responseTimeoutTimer); - delete this._timer; - delete this._responseTimeoutTimer; - return this; -}; +Emitter(Request.prototype); +RequestBase(Request.prototype); /** - * Override default response body parser - * - * This function will be called to convert incoming data into request.body + * Set Content-Type to `type`, mapping values from `request.types`. * - * @param {Function} - * @api public - */ - -RequestBase.prototype.parse = function parse(fn){ - this._parser = fn; - return this; -}; - -/** - * Set format of binary response body. - * In browser valid formats are 'blob' and 'arraybuffer', - * which return Blob and ArrayBuffer, respectively. + * Examples: * - * In Node all values result in Buffer. + * superagent.types.xml = 'application/xml'; * - * Examples: + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); * - * req.get('/') - * .responseType('blob') + * request.post('/') + * .type('application/xml') + * .send(xmlstring) * .end(callback); * - * @param {String} val + * @param {String} type * @return {Request} for chaining * @api public */ -RequestBase.prototype.responseType = function(val){ - this._responseType = val; +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); return this; }; /** - * Override default request body serializer + * Set Accept to `type`, mapping values from `request.types`. * - * This function will be called to convert data set via .send or .attach into payload to send + * Examples: * - * @param {Function} + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining * @api public */ -RequestBase.prototype.serialize = function serialize(fn){ - this._serializer = fn; +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); return this; }; /** - * Set timeouts. - * - * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time. - * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections. - * - * Value of 0 or false means no timeout. + * Set Authorization field value with `user` and `pass`. * - * @param {Number|Object} ms or {response, deadline} + * @param {String} user + * @param {String} [pass] optional in case of using 'bearer' as type + * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic') * @return {Request} for chaining * @api public */ -RequestBase.prototype.timeout = function timeout(options){ - if (!options || 'object' !== typeof options) { - this._timeout = options; - this._responseTimeout = 0; - return this; +Request.prototype.auth = function(user, pass, options){ + if (1 === arguments.length) pass = ''; + if (typeof pass === 'object' && pass !== null) { // pass is optional and can be replaced with options + options = pass; + pass = ''; + } + if (!options) { + options = { + type: 'function' === typeof btoa ? 'basic' : 'auto', + }; } - for(var option in options) { - switch(option) { - case 'deadline': - this._timeout = options.deadline; - break; - case 'response': - this._responseTimeout = options.response; - break; - default: - console.warn("Unknown timeout option", option); + var encoder = function(string) { + if ('function' === typeof btoa) { + return btoa(string); } - } - return this; + throw new Error('Cannot use basic auth, btoa is not a function'); + }; + + return this._auth(user, pass, options, encoder); }; /** - * Set number of retry attempts on error. + * Add query-string `val`. * - * Failed requests will be retried 'count' times if timeout or err.code >= 500. + * Examples: * - * @param {Number} count - * @param {Function} [fn] + * request.get('/shoes') + * .query('size=10') + * .query({ color: 'blue' }) + * + * @param {Object|String} val * @return {Request} for chaining * @api public */ -RequestBase.prototype.retry = function retry(count, fn){ - // Default to 1 if no count passed or true - if (arguments.length === 0 || count === true) count = 1; - if (count <= 0) count = 0; - this._maxRetries = count; - this._retries = 0; - this._retryCallback = fn; +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); return this; }; -var ERROR_CODES = [ - 'ECONNRESET', - 'ETIMEDOUT', - 'EADDRINFO', - 'ESOCKETTIMEDOUT' -]; - /** - * Determine if a request should be retried. - * (Borrowed from segmentio/superagent-retry) + * Queue the given `file` as an attachment to the specified `field`, + * with optional `options` (or filename). * - * @param {Error} err - * @param {Response} [res] - * @returns {Boolean} - */ -RequestBase.prototype._shouldRetry = function(err, res) { - if (!this._maxRetries || this._retries++ >= this._maxRetries) { - return false; - } - if (this._retryCallback) { - try { - var override = this._retryCallback(err, res); - if (override === true) return true; - if (override === false) return false; - // undefined falls back to defaults - } catch(e) { - console.error(e); - } - } - if (res && res.status && res.status >= 500 && res.status != 501) return true; - if (err) { - if (err.code && ~ERROR_CODES.indexOf(err.code)) return true; - // Superagent timeout - if (err.timeout && err.code == 'ECONNABORTED') return true; - if (err.crossDomain) return true; - } - return false; -}; - -/** - * Retry request + * ``` js + * request.post('/upload') + * .attach('content', new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` * + * @param {String} field + * @param {Blob|File} file + * @param {String|Object} options * @return {Request} for chaining - * @api private - */ - -RequestBase.prototype._retry = function() { - - this.clearTimeout(); - - // node - if (this.req) { - this.req = null; - this.req = this.request(); - } - - this._aborted = false; - this.timedout = false; - - return this._end(); -}; - -/** - * Promise support - * - * @param {Function} resolve - * @param {Function} [reject] - * @return {Request} + * @api public */ -RequestBase.prototype.then = function then(resolve, reject) { - if (!this._fullfilledPromise) { - var self = this; - if (this._endCalled) { - console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises"); +Request.prototype.attach = function(field, file, options){ + if (file) { + if (this._data) { + throw Error("superagent can't mix .send() and .attach()"); } - this._fullfilledPromise = new Promise(function(innerResolve, innerReject) { - self.end(function(err, res) { - if (err) innerReject(err); - else innerResolve(res); - }); - }); - } - return this._fullfilledPromise.then(resolve, reject); -}; - -RequestBase.prototype.catch = function(cb) { - return this.then(undefined, cb); -}; - -/** - * Allow for extension - */ - -RequestBase.prototype.use = function use(fn) { - fn(this); - return this; -}; - -RequestBase.prototype.ok = function(cb) { - if ('function' !== typeof cb) throw Error("Callback required"); - this._okCallback = cb; - return this; -}; -RequestBase.prototype._isResponseOK = function(res) { - if (!res) { - return false; - } - - if (this._okCallback) { - return this._okCallback(res); + this._getFormData().append(field, file, options || file.name); } + return this; +}; - return res.status >= 200 && res.status < 300; +Request.prototype._getFormData = function(){ + if (!this._formData) { + this._formData = new root.FormData(); + } + return this._formData; }; /** - * Get request header `field`. - * Case-insensitive. + * Invoke the callback with `err` and `res` + * and handle arity check. * - * @param {String} field - * @return {String} - * @api public + * @param {Error} err + * @param {Response} res + * @api private */ -RequestBase.prototype.get = function(field){ - return this._header[field.toLowerCase()]; +Request.prototype.callback = function(err, res){ + if (this._shouldRetry(err, res)) { + return this._retry(); + } + + var fn = this._callback; + this.clearTimeout(); + + if (err) { + if (this._maxRetries) err.retries = this._retries - 1; + this.emit('error', err); + } + + fn(err, res); }; /** - * Get case-insensitive header `field` value. - * This is a deprecated internal API. Use `.get(field)` instead. - * - * (getHeader is no longer used internally by the superagent code base) + * Invoke callback with x-domain error. * - * @param {String} field - * @return {String} * @api private - * @deprecated */ -RequestBase.prototype.getHeader = RequestBase.prototype.get; +Request.prototype.crossDomainError = function(){ + var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); + err.crossDomain = true; -/** - * Set header `field` to `val`, or multiple fields with one object. - * Case-insensitive. - * - * Examples: - * - * req.get('/') - * .set('Accept', 'application/json') - * .set('X-API-Key', 'foobar') - * .end(callback); - * - * req.get('/') - * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) - * .end(callback); - * - * @param {String|Object} field - * @param {String} val - * @return {Request} for chaining - * @api public - */ + err.status = this.status; + err.method = this.method; + err.url = this.url; -RequestBase.prototype.set = function(field, val){ - if (isObject(field)) { - for (var key in field) { - this.set(key, field[key]); - } - return this; - } - this._header[field.toLowerCase()] = val; - this.header[field] = val; + this.callback(err); +}; + +// This only warns, because the request is still likely to work +Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){ + console.warn("This is not supported in browser version of superagent"); return this; }; +// This throws, because it can't send/receive data as expected +Request.prototype.pipe = Request.prototype.write = function(){ + throw Error("Streaming is not supported in browser version of superagent"); +}; + /** - * Remove header `field`. - * Case-insensitive. - * - * Example: - * - * req.get('/') - * .unset('User-Agent') - * .end(callback); + * Check if `obj` is a host object, + * we don't want to serialize these :) * - * @param {String} field + * @param {Object} obj + * @return {Boolean} + * @api private */ -RequestBase.prototype.unset = function(field){ - delete this._header[field.toLowerCase()]; - delete this.header[field]; - return this; -}; +Request.prototype._isHost = function _isHost(obj) { + // Native objects stringify to [object File], [object Blob], [object FormData], etc. + return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]'; +} /** - * Write the field `name` and `val`, or multiple fields with one object - * for "multipart/form-data" request bodies. - * - * ``` js - * request.post('/upload') - * .field('foo', 'bar') - * .end(callback); - * - * request.post('/upload') - * .field({ foo: 'bar', baz: 'qux' }) - * .end(callback); - * ``` + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. * - * @param {String|Object} name - * @param {String|Blob|File|Buffer|fs.ReadStream} val + * @param {Function} fn * @return {Request} for chaining * @api public */ -RequestBase.prototype.field = function(name, val) { - // name should be either a string or an object. - if (null === name || undefined === name) { - throw new Error('.field(name, val) name can not be empty'); - } - if (this._data) { - console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()"); +Request.prototype.end = function(fn){ + if (this._endCalled) { + console.warn("Warning: .end() was called twice. This is not supported in superagent"); } + this._endCalled = true; - if (isObject(name)) { - for (var key in name) { - this.field(key, name[key]); + // store callback + this._callback = fn || noop; + + // querystring + this._finalizeQueryString(); + + return this._end(); +}; + +Request.prototype._end = function() { + var self = this; + var xhr = (this.xhr = request.getXHR()); + var data = this._formData || this._data; + + this._setTimeouts(); + + // state change + xhr.onreadystatechange = function(){ + var readyState = xhr.readyState; + if (readyState >= 2 && self._responseTimeoutTimer) { + clearTimeout(self._responseTimeoutTimer); + } + if (4 != readyState) { + return; } - return this; - } - if (Array.isArray(val)) { - for (var i in val) { - this.field(name, val[i]); + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (!status) { + if (self.timedout || self._aborted) return; + return self.crossDomainError(); } - return this; - } + self.emit('end'); + }; - // val should be defined now - if (null === val || undefined === val) { - throw new Error('.field(name, val) val can not be empty'); + // progress + var handleProgress = function(direction, e) { + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + e.direction = direction; + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + try { + xhr.onprogress = handleProgress.bind(null, 'download'); + if (xhr.upload) { + xhr.upload.onprogress = handleProgress.bind(null, 'upload'); + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } } - if ('boolean' === typeof val) { - val = '' + val; + + // initiate request + try { + if (this.username && this.password) { + xhr.open(this.method, this.url, true, this.username, this.password); + } else { + xhr.open(this.method, this.url, true); + } + } catch (err) { + // see #1149 + return this.callback(err); } - this._getFormData().append(name, val); - return this; -}; -/** - * Abort the request, and clear potential timeout. - * - * @return {Request} - * @api public - */ -RequestBase.prototype.abort = function(){ - if (this._aborted) { - return this; + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { + // serialize stuff + var contentType = this._header['content-type']; + var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; + if (!serialize && isJSON(contentType)) { + serialize = request.serialize['application/json']; + } + if (serialize) data = serialize(data); } - this._aborted = true; - this.xhr && this.xhr.abort(); // browser - this.req && this.req.abort(); // node - this.clearTimeout(); - this.emit('abort'); - return this; -}; -RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { - switch (options.type) { - case 'basic': - this.set('Authorization', 'Basic ' + base64Encoder(user + ':' + pass)); - break; + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; - case 'auto': - this.username = user; - this.password = pass; - break; + if (this.header.hasOwnProperty(field)) + xhr.setRequestHeader(field, this.header[field]); + } - case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) - this.set('Authorization', 'Bearer ' + user); - break; + if (this._responseType) { + xhr.responseType = this._responseType; } + + // send stuff + this.emit('request', this); + + // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) + // We need null here if data is undefined + xhr.send(typeof data !== 'undefined' ? data : null); return this; }; +request.agent = function() { + return new Agent(); +}; + +["GET", "POST", "OPTIONS", "PATCH", "PUT", "DELETE"].forEach(function(method) { + Agent.prototype[method.toLowerCase()] = function(url, fn) { + var req = new request.Request(method, url); + this._setDefaults(req); + if (fn) { + req.end(fn); + } + return req; + }; +}); + +Agent.prototype.del = Agent.prototype['delete']; + /** - * Enable transmission of cookies with x-domain requests. - * - * Note that for this to work the origin must not be - * using "Access-Control-Allow-Origin" with a wildcard, - * and also must set "Access-Control-Allow-Credentials" - * to "true". + * GET `url` with optional callback `fn(res)`. * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} * @api public */ -RequestBase.prototype.withCredentials = function(on) { - // This is browser-only functionality. Node side is no-op. - if (on == undefined) on = true; - this._withCredentials = on; - return this; +request.get = function(url, data, fn) { + var req = request('GET', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.query(data); + if (fn) req.end(fn); + return req; }; /** - * Set the max redirects to `n`. Does noting in browser XHR implementation. + * HEAD `url` with optional callback `fn(res)`. * - * @param {Number} n - * @return {Request} for chaining + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} * @api public */ -RequestBase.prototype.redirects = function(n){ - this._maxRedirects = n; - return this; +request.head = function(url, data, fn) { + var req = request('HEAD', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.query(data); + if (fn) req.end(fn); + return req; }; /** - * Maximum size of buffered response body, in bytes. Counts uncompressed size. - * Default 200MB. + * OPTIONS query to `url` with optional callback `fn(res)`. * - * @param {Number} n - * @return {Request} for chaining + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public */ -RequestBase.prototype.maxResponseSize = function(n){ - if ('number' !== typeof n) { - throw TypeError("Invalid argument"); - } - this._maxResponseSize = n; - return this; + +request.options = function(url, data, fn) { + var req = request('OPTIONS', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.send(data); + if (fn) req.end(fn); + return req; }; /** - * Convert to a plain javascript object (not JSON string) of scalar properties. - * Note as this method is designed to return a useful non-this value, - * it cannot be chained. + * DELETE `url` with optional `data` and callback `fn(res)`. * - * @return {Object} describing method, url, and data of this request + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} * @api public */ -RequestBase.prototype.toJSON = function() { - return { - method: this.method, - url: this.url, - data: this._data, - headers: this._header, - }; -}; +function del(url, data, fn) { + var req = request('DELETE', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.send(data); + if (fn) req.end(fn); + return req; +} + +request['del'] = del; +request['delete'] = del; /** - * Send `data` as the request body, defaulting the `.type()` to "json" when - * an object is given. - * - * Examples: - * - * // manual json - * request.post('/user') - * .type('json') - * .send('{"name":"tj"}') - * .end(callback) - * - * // auto json - * request.post('/user') - * .send({ name: 'tj' }) - * .end(callback) - * - * // manual x-www-form-urlencoded - * request.post('/user') - * .type('form') - * .send('name=tj') - * .end(callback) - * - * // auto x-www-form-urlencoded - * request.post('/user') - * .type('form') - * .send({ name: 'tj' }) - * .end(callback) - * - * // defaults to x-www-form-urlencoded - * request.post('/user') - * .send('name=tobi') - * .send('species=ferret') - * .end(callback) + * PATCH `url` with optional `data` and callback `fn(res)`. * - * @param {String|Object} data - * @return {Request} for chaining + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} * @api public */ -RequestBase.prototype.send = function(data){ - var isObj = isObject(data); - var type = this._header['content-type']; - - if (this._formData) { - console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()"); - } - - if (isObj && !this._data) { - if (Array.isArray(data)) { - this._data = []; - } else if (!this._isHost(data)) { - this._data = {}; - } - } else if (data && this._data && this._isHost(this._data)) { - throw Error("Can't merge these send calls"); - } - - // merge - if (isObj && isObject(this._data)) { - for (var key in data) { - this._data[key] = data[key]; - } - } else if ('string' == typeof data) { - // default to x-www-form-urlencoded - if (!type) this.type('form'); - type = this._header['content-type']; - if ('application/x-www-form-urlencoded' == type) { - this._data = this._data - ? this._data + '&' + data - : data; - } else { - this._data = (this._data || '') + data; - } - } else { - this._data = data; - } - - if (!isObj || this._isHost(data)) { - return this; - } - - // default to json - if (!type) this.type('json'); - return this; +request.patch = function(url, data, fn) { + var req = request('PATCH', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.send(data); + if (fn) req.end(fn); + return req; }; /** - * Sort `querystring` by the sort function - * - * - * Examples: - * - * // default order - * request.get('/user') - * .query('name=Nick') - * .query('search=Manny') - * .sortQuery() - * .end(callback) - * - * // customized sort function - * request.get('/user') - * .query('name=Nick') - * .query('search=Manny') - * .sortQuery(function(a, b){ - * return a.length - b.length; - * }) - * .end(callback) - * + * POST `url` with optional `data` and callback `fn(res)`. * - * @param {Function} sort - * @return {Request} for chaining + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} * @api public */ -RequestBase.prototype.sortQuery = function(sort) { - // _sort default to true but otherwise can be a function or boolean - this._sort = typeof sort === 'undefined' ? true : sort; - return this; +request.post = function(url, data, fn) { + var req = request('POST', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.send(data); + if (fn) req.end(fn); + return req; }; /** - * Compose querystring to append to req.url + * PUT `url` with optional `data` and callback `fn(res)`. * - * @api private + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public */ -RequestBase.prototype._finalizeQueryString = function(){ - var query = this._query.join('&'); - if (query) { - this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query; - } - this._query.length = 0; // Makes the call idempotent - if (this._sort) { - var index = this.url.indexOf('?'); - if (index >= 0) { - var queryArr = this.url.substring(index + 1).split('&'); - if ('function' === typeof this._sort) { - queryArr.sort(this._sort); - } else { - queryArr.sort(); - } - this.url = this.url.substring(0, index) + '?' + queryArr.join('&'); - } - } +request.put = function(url, data, fn) { + var req = request('PUT', url); + if ('function' == typeof data) (fn = data), (data = null); + if (data) req.send(data); + if (fn) req.end(fn); + return req; }; -// For backwards compat only -RequestBase.prototype._appendQueryString = function() {console.trace("Unsupported");} +},{"./agent-base":80,"./is-object":82,"./request-base":83,"./response-base":84,"component-emitter":2}],82:[function(_dereq_,module,exports){ +'use strict'; /** - * Invoke callback with timeout error. + * Check if `obj` is an object. * + * @param {Object} obj + * @return {Boolean} * @api private */ -RequestBase.prototype._timeoutError = function(reason, timeout, errno){ - if (this._aborted) { - return; - } - var err = new Error(reason + timeout + 'ms exceeded'); - err.timeout = timeout; - err.code = 'ECONNABORTED'; - err.errno = errno; - this.timedout = true; - this.abort(); - this.callback(err); -}; - -RequestBase.prototype._setTimeouts = function() { - var self = this; +function isObject(obj) { + return null !== obj && 'object' === typeof obj; +} - // deadline - if (this._timeout && !this._timer) { - this._timer = setTimeout(function(){ - self._timeoutError('Timeout of ', self._timeout, 'ETIME'); - }, this._timeout); - } - // response timeout - if (this._responseTimeout && !this._responseTimeoutTimer) { - this._responseTimeoutTimer = setTimeout(function(){ - self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT'); - }, this._responseTimeout); - } -}; +module.exports = isObject; -},{"./is-object":121}],123:[function(_dereq_,module,exports){ +},{}],83:[function(_dereq_,module,exports){ 'use strict'; /** - * Module dependencies. + * Module of mixed-in functions shared between node and client code */ - -var utils = _dereq_('./utils'); +var isObject = _dereq_('./is-object'); /** - * Expose `ResponseBase`. + * Expose `RequestBase`. */ -module.exports = ResponseBase; +module.exports = RequestBase; /** - * Initialize a new `ResponseBase`. + * Initialize a new `RequestBase`. * * @api public */ -function ResponseBase(obj) { +function RequestBase(obj) { if (obj) return mixin(obj); } @@ -7149,1691 +7364,1502 @@ function ResponseBase(obj) { */ function mixin(obj) { - for (var key in ResponseBase.prototype) { - obj[key] = ResponseBase.prototype[key]; + for (var key in RequestBase.prototype) { + obj[key] = RequestBase.prototype[key]; } return obj; } /** - * Get case-insensitive `field` value. + * Clear previous timeout. * - * @param {String} field - * @return {String} + * @return {Request} for chaining * @api public */ -ResponseBase.prototype.get = function(field) { - return this.header[field.toLowerCase()]; +RequestBase.prototype.clearTimeout = function _clearTimeout(){ + clearTimeout(this._timer); + clearTimeout(this._responseTimeoutTimer); + delete this._timer; + delete this._responseTimeoutTimer; + return this; }; /** - * Set header related properties: - * - * - `.type` the content type without params + * Override default response body parser * - * A response of "Content-Type: text/plain; charset=utf-8" - * will provide you with a `.type` of "text/plain". + * This function will be called to convert incoming data into request.body * - * @param {Object} header - * @api private + * @param {Function} + * @api public */ -ResponseBase.prototype._setHeaderProperties = function(header){ - // TODO: moar! - // TODO: make this a util +RequestBase.prototype.parse = function parse(fn){ + this._parser = fn; + return this; +}; - // content-type - var ct = header['content-type'] || ''; - this.type = utils.type(ct); +/** + * Set format of binary response body. + * In browser valid formats are 'blob' and 'arraybuffer', + * which return Blob and ArrayBuffer, respectively. + * + * In Node all values result in Buffer. + * + * Examples: + * + * req.get('/') + * .responseType('blob') + * .end(callback); + * + * @param {String} val + * @return {Request} for chaining + * @api public + */ - // params - var params = utils.params(ct); - for (var key in params) this[key] = params[key]; +RequestBase.prototype.responseType = function(val){ + this._responseType = val; + return this; +}; - this.links = {}; +/** + * Override default request body serializer + * + * This function will be called to convert data set via .send or .attach into payload to send + * + * @param {Function} + * @api public + */ - // links - try { - if (header.link) { - this.links = utils.parseLinks(header.link); - } - } catch (err) { - // ignore - } +RequestBase.prototype.serialize = function serialize(fn){ + this._serializer = fn; + return this; }; /** - * Set flags such as `.ok` based on `status`. - * - * For example a 2xx response will give you a `.ok` of __true__ - * whereas 5xx will be __false__ and `.error` will be __true__. The - * `.clientError` and `.serverError` are also available to be more - * specific, and `.statusType` is the class of error ranging from 1..5 - * sometimes useful for mapping respond colors etc. + * Set timeouts. * - * "sugar" properties are also defined for common cases. Currently providing: + * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time. + * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections. * - * - .noContent - * - .badRequest - * - .unauthorized - * - .notAcceptable - * - .notFound + * Value of 0 or false means no timeout. * - * @param {Number} status - * @api private + * @param {Number|Object} ms or {response, deadline} + * @return {Request} for chaining + * @api public */ -ResponseBase.prototype._setStatusProperties = function(status){ - var type = status / 100 | 0; +RequestBase.prototype.timeout = function timeout(options){ + if (!options || 'object' !== typeof options) { + this._timeout = options; + this._responseTimeout = 0; + return this; + } - // status / class - this.status = this.statusCode = status; - this.statusType = type; + for(var option in options) { + switch(option) { + case 'deadline': + this._timeout = options.deadline; + break; + case 'response': + this._responseTimeout = options.response; + break; + default: + console.warn("Unknown timeout option", option); + } + } + return this; +}; - // basics - this.info = 1 == type; - this.ok = 2 == type; - this.redirect = 3 == type; - this.clientError = 4 == type; - this.serverError = 5 == type; - this.error = (4 == type || 5 == type) - ? this.toError() - : false; +/** + * Set number of retry attempts on error. + * + * Failed requests will be retried 'count' times if timeout or err.code >= 500. + * + * @param {Number} count + * @param {Function} [fn] + * @return {Request} for chaining + * @api public + */ - // sugar - this.accepted = 202 == status; - this.noContent = 204 == status; - this.badRequest = 400 == status; - this.unauthorized = 401 == status; - this.notAcceptable = 406 == status; - this.forbidden = 403 == status; - this.notFound = 404 == status; +RequestBase.prototype.retry = function retry(count, fn){ + // Default to 1 if no count passed or true + if (arguments.length === 0 || count === true) count = 1; + if (count <= 0) count = 0; + this._maxRetries = count; + this._retries = 0; + this._retryCallback = fn; + return this; }; -},{"./utils":124}],124:[function(_dereq_,module,exports){ -'use strict'; +var ERROR_CODES = [ + 'ECONNRESET', + 'ETIMEDOUT', + 'EADDRINFO', + 'ESOCKETTIMEDOUT' +]; /** - * Return the mime type for the given `str`. + * Determine if a request should be retried. + * (Borrowed from segmentio/superagent-retry) * - * @param {String} str - * @return {String} - * @api private + * @param {Error} err + * @param {Response} [res] + * @returns {Boolean} */ - -exports.type = function(str){ - return str.split(/ *; */).shift(); +RequestBase.prototype._shouldRetry = function(err, res) { + if (!this._maxRetries || this._retries++ >= this._maxRetries) { + return false; + } + if (this._retryCallback) { + try { + var override = this._retryCallback(err, res); + if (override === true) return true; + if (override === false) return false; + // undefined falls back to defaults + } catch(e) { + console.error(e); + } + } + if (res && res.status && res.status >= 500 && res.status != 501) return true; + if (err) { + if (err.code && ~ERROR_CODES.indexOf(err.code)) return true; + // Superagent timeout + if (err.timeout && err.code == 'ECONNABORTED') return true; + if (err.crossDomain) return true; + } + return false; }; /** - * Return header field parameters. + * Retry request * - * @param {String} str - * @return {Object} + * @return {Request} for chaining * @api private */ -exports.params = function(str){ - return str.split(/ *; */).reduce(function(obj, str){ - var parts = str.split(/ *= */); - var key = parts.shift(); - var val = parts.shift(); +RequestBase.prototype._retry = function() { - if (key && val) obj[key] = val; - return obj; - }, {}); -}; + this.clearTimeout(); -/** - * Parse Link header fields. - * - * @param {String} str - * @return {Object} - * @api private - */ + // node + if (this.req) { + this.req = null; + this.req = this.request(); + } -exports.parseLinks = function(str){ - return str.split(/ *, */).reduce(function(obj, str){ - var parts = str.split(/ *; */); - var url = parts[0].slice(1, -1); - var rel = parts[1].split(/ *= */)[1].slice(1, -1); - obj[rel] = url; - return obj; - }, {}); + this._aborted = false; + this.timedout = false; + + return this._end(); }; /** - * Strip content related fields from `header`. + * Promise support * - * @param {Object} header - * @return {Object} header - * @api private - */ - -exports.cleanHeader = function(header, changesOrigin){ - delete header['content-type']; - delete header['content-length']; - delete header['transfer-encoding']; - delete header['host']; - // secuirty - if (changesOrigin) { - delete header['authorization']; - delete header['cookie']; - } - return header; -}; - -},{}],125:[function(_dereq_,module,exports){ - -/** - * Expose `Emitter`. - */ - -if (typeof module !== 'undefined') { - module.exports = Emitter; -} - -/** - * Initialize a new `Emitter`. - * - * @api public - */ - -function Emitter(obj) { - if (obj) return mixin(obj); -}; - -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; -} - -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks['$' + event] = this._callbacks['$' + event] || []) - .push(fn); - return this; -}; - -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.once = function(event, fn){ - function on() { - this.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; -}; - -/** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks['$' + event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks['$' + event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; -}; - -/** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks['$' + event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; -}; - -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks['$' + event] || []; -}; - -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; + * @param {Function} resolve + * @param {Function} [reject] + * @return {Request} + */ -},{}],126:[function(_dereq_,module,exports){ -// Underscore.js 1.6.0 -// http://underscorejs.org -// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. +RequestBase.prototype.then = function then(resolve, reject) { + if (!this._fullfilledPromise) { + var self = this; + if (this._endCalled) { + console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises"); + } + this._fullfilledPromise = new Promise(function(innerResolve, innerReject) { + self.end(function(err, res) { + if (err) innerReject(err); + else innerResolve(res); + }); + }); + } + return this._fullfilledPromise.then(resolve, reject); +}; -(function() { +RequestBase.prototype['catch'] = function(cb) { + return this.then(undefined, cb); +}; - // Baseline setup - // -------------- +/** + * Allow for extension + */ - // Establish the root object, `window` in the browser, or `exports` on the server. - var root = this; +RequestBase.prototype.use = function use(fn) { + fn(this); + return this; +}; - // Save the previous value of the `_` variable. - var previousUnderscore = root._; +RequestBase.prototype.ok = function(cb) { + if ('function' !== typeof cb) throw Error("Callback required"); + this._okCallback = cb; + return this; +}; - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; +RequestBase.prototype._isResponseOK = function(res) { + if (!res) { + return false; + } - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + if (this._okCallback) { + return this._okCallback(res); + } - // Create quick reference variables for speed access to core prototypes. - var - push = ArrayProto.push, - slice = ArrayProto.slice, - concat = ArrayProto.concat, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; + return res.status >= 200 && res.status < 300; +}; - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; +/** + * Get request header `field`. + * Case-insensitive. + * + * @param {String} field + * @return {String} + * @api public + */ - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; +RequestBase.prototype.get = function(field){ + return this._header[field.toLowerCase()]; +}; - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } +/** + * Get case-insensitive header `field` value. + * This is a deprecated internal API. Use `.get(field)` instead. + * + * (getHeader is no longer used internally by the superagent code base) + * + * @param {String} field + * @return {String} + * @api private + * @deprecated + */ - // Current version. - _.VERSION = '1.6.0'; +RequestBase.prototype.getHeader = RequestBase.prototype.get; - // Collection Functions - // -------------------- +/** + * Set header `field` to `val`, or multiple fields with one object. + * Case-insensitive. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects with the built-in `forEach`, arrays, and raw objects. - // Delegates to **ECMAScript 5**'s native `forEach` if available. - var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return obj; - if (nativeForEach && obj.forEach === nativeForEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, length = obj.length; i < length; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; - } +RequestBase.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); } - return obj; - }; + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; - // Return the results of applying the iterator to each element. - // Delegates to **ECMAScript 5**'s native `map` if available. - _.map = _.collect = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); - each(obj, function(value, index, list) { - results.push(iterator.call(context, value, index, list)); - }); - return results; - }; +/** + * Remove header `field`. + * Case-insensitive. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + */ +RequestBase.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; - var reduceError = 'Reduce of empty array with no initial value'; +/** + * Write the field `name` and `val`, or multiple fields with one object + * for "multipart/form-data" request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * + * request.post('/upload') + * .field({ foo: 'bar', baz: 'qux' }) + * .end(callback); + * ``` + * + * @param {String|Object} name + * @param {String|Blob|File|Buffer|fs.ReadStream} val + * @return {Request} for chaining + * @api public + */ +RequestBase.prototype.field = function(name, val) { + // name should be either a string or an object. + if (null === name || undefined === name) { + throw new Error('.field(name, val) name can not be empty'); + } - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. - _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduce && obj.reduce === nativeReduce) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; + if (this._data) { + console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()"); + } - // The right-associative version of reduce, also known as `foldr`. - // Delegates to **ECMAScript 5**'s native `reduceRight` if available. - _.reduceRight = _.foldr = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + if (isObject(name)) { + for (var key in name) { + this.field(key, name[key]); } - var length = obj.length; - if (length !== +length) { - var keys = _.keys(obj); - length = keys.length; + return this; + } + + if (Array.isArray(val)) { + for (var i in val) { + this.field(name, val[i]); } - each(obj, function(value, index, list) { - index = keys ? keys[--length] : --length; - if (!initial) { - memo = obj[index]; - initial = true; - } else { - memo = iterator.call(context, memo, obj[index], index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; + return this; + } - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, predicate, context) { - var result; - any(obj, function(value, index, list) { - if (predicate.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; + // val should be defined now + if (null === val || undefined === val) { + throw new Error('.field(name, val) val can not be empty'); + } + if ('boolean' === typeof val) { + val = '' + val; + } + this._getFormData().append(name, val); + return this; +}; - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // Aliased as `select`. - _.filter = _.select = function(obj, predicate, context) { - var results = []; - if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); - each(obj, function(value, index, list) { - if (predicate.call(context, value, index, list)) results.push(value); - }); - return results; - }; +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ +RequestBase.prototype.abort = function(){ + if (this._aborted) { + return this; + } + this._aborted = true; + this.xhr && this.xhr.abort(); // browser + this.req && this.req.abort(); // node + this.clearTimeout(); + this.emit('abort'); + return this; +}; - // Return all the elements for which a truth test fails. - _.reject = function(obj, predicate, context) { - return _.filter(obj, function(value, index, list) { - return !predicate.call(context, value, index, list); - }, context); - }; +RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { + switch (options.type) { + case 'basic': + this.set('Authorization', 'Basic ' + base64Encoder(user + ':' + pass)); + break; - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, predicate, context) { - predicate || (predicate = _.identity); - var result = true; - if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context); - each(obj, function(value, index, list) { - if (!(result = result && predicate.call(context, value, index, list))) return breaker; - }); - return !!result; - }; + case 'auto': + this.username = user; + this.password = pass; + break; - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - var any = _.some = _.any = function(obj, predicate, context) { - predicate || (predicate = _.identity); - var result = false; - if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); - each(obj, function(value, index, list) { - if (result || (result = predicate.call(context, value, index, list))) return breaker; - }); - return !!result; - }; + case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) + this.set('Authorization', 'Bearer ' + user); + break; + } + return this; +}; - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; - return any(obj, function(value) { - return value === target; - }); - }; +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); - }); - }; +RequestBase.prototype.withCredentials = function(on) { + // This is browser-only functionality. Node side is no-op. + if (on == undefined) on = true; + this._withCredentials = on; + return this; +}; - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, _.property(key)); - }; +/** + * Set the max redirects to `n`. Does noting in browser XHR implementation. + * + * @param {Number} n + * @return {Request} for chaining + * @api public + */ - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs) { - return _.filter(obj, _.matches(attrs)); - }; +RequestBase.prototype.redirects = function(n){ + this._maxRedirects = n; + return this; +}; - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.find(obj, _.matches(attrs)); +/** + * Maximum size of buffered response body, in bytes. Counts uncompressed size. + * Default 200MB. + * + * @param {Number} n + * @return {Request} for chaining + */ +RequestBase.prototype.maxResponseSize = function(n){ + if ('number' !== typeof n) { + throw TypeError("Invalid argument"); + } + this._maxResponseSize = n; + return this; +}; + +/** + * Convert to a plain javascript object (not JSON string) of scalar properties. + * Note as this method is designed to return a useful non-this value, + * it cannot be chained. + * + * @return {Object} describing method, url, and data of this request + * @api public + */ + +RequestBase.prototype.toJSON = function() { + return { + method: this.method, + url: this.url, + data: this._data, + headers: this._header, }; +}; + +/** + * Send `data` as the request body, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}') + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.send = function(data){ + var isObj = isObject(data); + var type = this._header['content-type']; - // Return the maximum element or (element-based computation). - // Can't optimize arrays of integers longer than 65,535 elements. - // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797) - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.max.apply(Math, obj); + if (this._formData) { + console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()"); + } + + if (isObj && !this._data) { + if (Array.isArray(data)) { + this._data = []; + } else if (!this._isHost(data)) { + this._data = {}; } - var result = -Infinity, lastComputed = -Infinity; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - if (computed > lastComputed) { - result = value; - lastComputed = computed; - } - }); - return result; - }; + } else if (data && this._data && this._isHost(this._data)) { + throw Error("Can't merge these send calls"); + } - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.min.apply(Math, obj); + // merge + if (isObj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; } - var result = Infinity, lastComputed = Infinity; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - if (computed < lastComputed) { - result = value; - lastComputed = computed; - } - }); - return result; - }; + } else if ('string' == typeof data) { + // default to x-www-form-urlencoded + if (!type) this.type('form'); + type = this._header['content-type']; + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } - // Shuffle an array, using the modern version of the - // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). - _.shuffle = function(obj) { - var rand; - var index = 0; - var shuffled = []; - each(obj, function(value) { - rand = _.random(index++); - shuffled[index - 1] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; + if (!isObj || this._isHost(data)) { + return this; + } - // Sample **n** random values from a collection. - // If **n** is not specified, returns a single random element. - // The internal `guard` argument allows it to work with `map`. - _.sample = function(obj, n, guard) { - if (n == null || guard) { - if (obj.length !== +obj.length) obj = _.values(obj); - return obj[_.random(obj.length - 1)]; - } - return _.shuffle(obj).slice(0, Math.max(0, n)); - }; + // default to json + if (!type) this.type('json'); + return this; +}; - // An internal function to generate lookup iterators. - var lookupIterator = function(value) { - if (value == null) return _.identity; - if (_.isFunction(value)) return value; - return _.property(value); - }; +/** + * Sort `querystring` by the sort function + * + * + * Examples: + * + * // default order + * request.get('/user') + * .query('name=Nick') + * .query('search=Manny') + * .sortQuery() + * .end(callback) + * + * // customized sort function + * request.get('/user') + * .query('name=Nick') + * .query('search=Manny') + * .sortQuery(function(a, b){ + * return a.length - b.length; + * }) + * .end(callback) + * + * + * @param {Function} sort + * @return {Request} for chaining + * @api public + */ - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, iterator, context) { - iterator = lookupIterator(iterator); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value: value, - index: index, - criteria: iterator.call(context, value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); - }; +RequestBase.prototype.sortQuery = function(sort) { + // _sort default to true but otherwise can be a function or boolean + this._sort = typeof sort === 'undefined' ? true : sort; + return this; +}; - // An internal function used for aggregate "group by" operations. - var group = function(behavior) { - return function(obj, iterator, context) { - var result = {}; - iterator = lookupIterator(iterator); - each(obj, function(value, index) { - var key = iterator.call(context, value, index, obj); - behavior(result, key, value); - }); - return result; - }; - }; +/** + * Compose querystring to append to req.url + * + * @api private + */ +RequestBase.prototype._finalizeQueryString = function(){ + var query = this._query.join('&'); + if (query) { + this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query; + } + this._query.length = 0; // Makes the call idempotent - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = group(function(result, key, value) { - _.has(result, key) ? result[key].push(value) : result[key] = [value]; - }); + if (this._sort) { + var index = this.url.indexOf('?'); + if (index >= 0) { + var queryArr = this.url.substring(index + 1).split('&'); + if ('function' === typeof this._sort) { + queryArr.sort(this._sort); + } else { + queryArr.sort(); + } + this.url = this.url.substring(0, index) + '?' + queryArr.join('&'); + } + } +}; - // Indexes the object's values by a criterion, similar to `groupBy`, but for - // when you know that your index values will be unique. - _.indexBy = group(function(result, key, value) { - result[key] = value; - }); +// For backwards compat only +RequestBase.prototype._appendQueryString = function() {console.trace("Unsupported");} - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = group(function(result, key) { - _.has(result, key) ? result[key]++ : result[key] = 1; - }); +/** + * Invoke callback with timeout error. + * + * @api private + */ - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iterator, context) { - iterator = lookupIterator(iterator); - var value = iterator.call(context, obj); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >>> 1; - iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; - } - return low; - }; +RequestBase.prototype._timeoutError = function(reason, timeout, errno){ + if (this._aborted) { + return; + } + var err = new Error(reason + timeout + 'ms exceeded'); + err.timeout = timeout; + err.code = 'ECONNABORTED'; + err.errno = errno; + this.timedout = true; + this.abort(); + this.callback(err); +}; - // Safely create a real, live array from anything iterable. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); - return _.values(obj); - }; +RequestBase.prototype._setTimeouts = function() { + var self = this; - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; - }; + // deadline + if (this._timeout && !this._timer) { + this._timer = setTimeout(function(){ + self._timeoutError('Timeout of ', self._timeout, 'ETIME'); + }, this._timeout); + } + // response timeout + if (this._responseTimeout && !this._responseTimeoutTimer) { + this._responseTimeoutTimer = setTimeout(function(){ + self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT'); + }, this._responseTimeout); + } +}; - // Array Functions - // --------------- +},{"./is-object":82}],84:[function(_dereq_,module,exports){ +'use strict'; - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - if ((n == null) || guard) return array[0]; - if (n < 0) return []; - return slice.call(array, 0, n); - }; +/** + * Module dependencies. + */ - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); - }; +var utils = _dereq_('./utils'); - // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if ((n == null) || guard) return array[array.length - 1]; - return slice.call(array, Math.max(array.length - n, 0)); - }; +/** + * Expose `ResponseBase`. + */ - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, (n == null) || guard ? 1 : n); - }; +module.exports = ResponseBase; - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; +/** + * Initialize a new `ResponseBase`. + * + * @api public + */ - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, output) { - if (shallow && _.every(input, _.isArray)) { - return concat.apply(output, input); - } - each(input, function(value) { - if (_.isArray(value) || _.isArguments(value)) { - shallow ? push.apply(output, value) : flatten(value, shallow, output); - } else { - output.push(value); - } - }); - return output; - }; +function ResponseBase(obj) { + if (obj) return mixin(obj); +} - // Flatten out an array, either recursively (by default), or just one level. - _.flatten = function(array, shallow) { - return flatten(array, shallow, []); - }; +/** + * Mixin the prototype properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; +function mixin(obj) { + for (var key in ResponseBase.prototype) { + obj[key] = ResponseBase.prototype[key]; + } + return obj; +} - // Split an array into two arrays: one whose elements all satisfy the given - // predicate, and one whose elements all do not satisfy the predicate. - _.partition = function(array, predicate) { - var pass = [], fail = []; - each(array, function(elem) { - (predicate(elem) ? pass : fail).push(elem); - }); - return [pass, fail]; - }; +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iterator, context) { - if (_.isFunction(isSorted)) { - context = iterator; - iterator = isSorted; - isSorted = false; - } - var initial = iterator ? _.map(array, iterator, context) : array; - var results = []; - var seen = []; - each(initial, function(value, index) { - if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { - seen.push(value); - results.push(array[index]); - } - }); - return results; - }; +ResponseBase.prototype.get = function(field) { + return this.header[field.toLowerCase()]; +}; - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(_.flatten(arguments, true)); - }; +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.contains(other, item); - }); - }); - }; +ResponseBase.prototype._setHeaderProperties = function(header){ + // TODO: moar! + // TODO: make this a util - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); - return _.filter(array, function(value){ return !_.contains(rest, value); }); - }; + // content-type + var ct = header['content-type'] || ''; + this.type = utils.type(ct); - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - var length = _.max(_.pluck(arguments, 'length').concat(0)); - var results = new Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(arguments, '' + i); - } - return results; - }; + // params + var params = utils.params(ct); + for (var key in params) this[key] = params[key]; - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - if (list == null) return {}; - var result = {}; - for (var i = 0, length = list.length; i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; + this.links = {}; - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, length = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted); - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } + // links + try { + if (header.link) { + this.links = utils.parseLinks(header.link); + } + } catch (err) { + // ignore } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); - for (; i < length; i++) if (array[i] === item) return i; - return -1; - }; +}; - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var hasIndex = from != null; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { - return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); - } - var i = (hasIndex ? from : array.length); - while (i--) if (array[i] === item) return i; - return -1; - }; +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +ResponseBase.prototype._setStatusProperties = function(status){ + var type = status / 100 | 0; - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; + // status / class + this.status = this.statusCode = status; + this.statusType = type; - var length = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(length); + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.redirect = 3 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; - while(idx < length) { - range[idx++] = start; - start += step; - } + // sugar + this.created = 201 == status; + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.forbidden = 403 == status; + this.notFound = 404 == status; + this.unprocessableEntity = 422 == status; +}; - return range; - }; +},{"./utils":85}],85:[function(_dereq_,module,exports){ +'use strict'; - // Function (ahem) Functions - // ------------------ +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ - // Reusable constructor function for prototype setting. - var ctor = function(){}; +exports.type = function(str){ + return str.split(/ *; */).shift(); +}; - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - var args, bound; - if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - if (!_.isFunction(func)) throw new TypeError; - args = slice.call(arguments, 2); - return bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - ctor.prototype = func.prototype; - var self = new ctor; - ctor.prototype = null; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (Object(result) === result) return result; - return self; - }; - }; +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. _ acts - // as a placeholder, allowing any combination of arguments to be pre-filled. - _.partial = function(func) { - var boundArgs = slice.call(arguments, 1); - return function() { - var position = 0; - var args = boundArgs.slice(); - for (var i = 0, length = args.length; i < length; i++) { - if (args[i] === _) args[i] = arguments[position++]; - } - while (position < arguments.length) args.push(arguments[position++]); - return func.apply(this, args); - }; - }; +exports.params = function(str){ + return str.split(/ *; */).reduce(function(obj, str){ + var parts = str.split(/ *= */); + var key = parts.shift(); + var val = parts.shift(); - // Bind a number of an object's methods to that object. Remaining arguments - // are the method names to be bound. Useful for ensuring that all callbacks - // defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length === 0) throw new Error('bindAll must be passed function names'); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + if (key && val) obj[key] = val; return obj; - }; + }, {}); +}; - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; +/** + * Parse Link header fields. + * + * @param {String} str + * @return {Object} + * @api private + */ - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; +exports.parseLinks = function(str){ + return str.split(/ *, */).reduce(function(obj, str){ + var parts = str.split(/ *; */); + var url = parts[0].slice(1, -1); + var rel = parts[1].split(/ *= */)[1].slice(1, -1); + obj[rel] = url; + return obj; + }, {}); +}; - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); +/** + * Strip content related fields from `header`. + * + * @param {Object} header + * @return {Object} header + * @api private + */ + +exports.cleanHeader = function(header, changesOrigin){ + delete header['content-type']; + delete header['content-length']; + delete header['transfer-encoding']; + delete header['host']; + // secuirty + if (changesOrigin) { + delete header['authorization']; + delete header['cookie']; + } + return header; +}; + +},{}],86:[function(_dereq_,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],87:[function(_dereq_,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],88:[function(_dereq_,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. Normally, the throttled function will run - // as much as it can, without ever going more than once per `wait` duration; - // but if you'd like to disable the execution on the leading edge, pass - // `{leading: false}`. To disable execution on the trailing edge, ditto. - _.throttle = function(func, wait, options) { - var context, args, result; - var timeout = null; - var previous = 0; - options || (options = {}); - var later = function() { - previous = options.leading === false ? 0 : _.now(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { return function() { - var now = _.now(); - if (!previous && options.leading === false) previous = now; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; + return exports.deprecate(fn, msg).apply(this, arguments); }; - }; + } - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, args, context, timestamp, result; + if (process.noDeprecation === true) { + return fn; + } - var later = function() { - var last = _.now() - timestamp; - if (last < wait) { - timeout = setTimeout(later, wait - last); + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); } else { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - context = args = null; - } + console.error(msg); } - }; + warned = true; + } + return fn.apply(this, arguments); + } - return function() { - context = this; - args = arguments; - timestamp = _.now(); - var callNow = immediate && !timeout; - if (!timeout) { - timeout = setTimeout(later, wait); - } - if (callNow) { - result = func.apply(context, args); - context = args = null; - } + return deprecated; +}; - return result; - }; - }; - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - memo = func.apply(this, arguments); - func = null; - return memo; - }; - }; +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return _.partial(wrapper, func); - }; - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - // Object Functions - // ---------------- +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys.push(key); - return keys; - }; +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; - // Retrieve the values of an object's properties. - _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = new Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - }; - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var pairs = new Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [keys[i], obj[keys[i]]]; - } - return pairs; - }; +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - result[obj[keys[i]]] = keys[i]; - } - return result; - }; - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; +function stylizeNoColor(str, styleType) { + return str; +} - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - } - }); - return obj; - }; - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - each(keys, function(key) { - if (key in obj) copy[key] = obj[key]; - }); - return copy; - }; +function arrayToHash(array) { + var hash = {}; - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - for (var key in obj) { - if (!_.contains(keys, key)) copy[key] = obj[key]; + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); } - return copy; - }; + return ret; + } - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - if (obj[prop] === void 0) obj[prop] = source[prop]; - } - } - }); - return obj; - }; + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a == 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className != toString.call(b)) return false; - switch (className) { - // Strings, numbers, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a == +b; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] == a) return bStack[length] == b; + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && - _.isFunction(bCtor) && (bCtor instanceof bCtor)) - && ('constructor' in a && 'constructor' in b)) { - return false; + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); } - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } + if (isError(value)) { + return formatError(value); } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, [], []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; + } - // Is a given variable an object? - _.isObject = function(obj) { - return obj === Object(obj); - }; + var base = '', array = false, braces = ['{', '}']; - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) == '[object ' + name + ']'; - }; - }); + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; } - // Optimize `isFunction` if appropriate. - if (typeof (/./) !== 'function') { - _.isFunction = function(obj) { - return typeof obj === 'function'; - }; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); } - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj != +obj; - }; + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; - }; + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; + ctx.seen.push(value); - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return hasOwnProperty.call(obj, key); - }; + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } - // Utility Functions - // ----------------- + ctx.seen.pop(); - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; + return reduceToSingleString(output, base, braces); +} - // Keep the identity function around for default iterators. - _.identity = function(value) { - return value; - }; - _.constant = function(value) { - return function () { - return value; - }; - }; +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} - _.property = function(key) { - return function(obj) { - return obj[key]; - }; - }; - // Returns a predicate for checking whether an object has a given set of `key:value` pairs. - _.matches = function(attrs) { - return function(obj) { - if (obj === attrs) return true; //avoid comparing an object to itself. - for (var key in attrs) { - if (attrs[key] !== obj[key]) - return false; - } - return true; - } - }; +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} - // Run a function **n** times. - _.times = function(n, iterator, context) { - var accum = Array(Math.max(0, n)); - for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); - return accum; - }; - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); } - return min + Math.floor(Math.random() * (max - min + 1)); - }; + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} - // A (possibly faster) way to get the current timestamp as an integer. - _.now = Date.now || function() { return new Date().getTime(); }; - // List of HTML entities for escaping. - var entityMap = { - escape: { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); } - }; - entityMap.unescape = _.invert(entityMap.escape); + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } - // Regexes containing the keys and values listed immediately above. - var entityRegexes = { - escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), - unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') - }; + return name + ': ' + str; +} - // Functions for escaping and unescaping strings to/from HTML interpolation. - _.each(['escape', 'unescape'], function(method) { - _[method] = function(string) { - if (string == null) return ''; - return ('' + string).replace(entityRegexes[method], function(match) { - return entityMap[method][match]; - }); - }; - }); - // If the value of the named `property` is a function then invoke it with the - // `object` as context; otherwise, return it. - _.result = function(object, property) { - if (object == null) return void 0; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - each(_.functions(obj), function(name) { - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result.call(this, func.apply(_, args)); - }; - }); - }; + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - var render; - settings = _.defaults({}, settings, _.templateSettings); +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; - // Combine delimiters into one regular expression via alternation. - var matcher = new RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset) - .replace(escaper, function(match) { return '\\' + escapes[match]; }); +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } - if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } - if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - index = offset + match.length; - return match; - }); - source += "';\n"; +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + "return __p;\n"; +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - try { - render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - // Provide the compiled function source as a convenience for precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; - return template; - }; +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. +exports.isBuffer = _dereq_('./support/isBuffer'); - // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; - }; +function objectToString(o) { + return Object.prototype.toString.call(o); +} - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - // Add all mutator Array functions to the wrapper. - each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); - }; - }); +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} - // Add all accessor Array functions to the wrapper. - each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); - }; - }); - _.extend(_.prototype, { +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; - // Start chaining a wrapped Underscore object. - chain: function() { - this._chain = true; - return this; - }, +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} - // Extracts the result from a wrapped and chained object. - value: function() { - return this._wrapped; - } - }); +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; - // AMD registration happens at the end for compatibility with AMD loaders - // that may not enforce next-turn semantics on modules. Even though general - // practice for AMD registration is to be anonymous, underscore registers - // as a named module because, like jQuery, it is a base library that is - // popular enough to be bundled in a third party lib, but not be part of - // an AMD load request. Those cases could generate an error when an - // anonymous define() is called outside of a loader request. - if (typeof define === 'function' && define.amd) { - define('underscore', [], function() { - return _; - }); + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = _dereq_('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; } -}).call(this); + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} -},{}]},{},[1]) +}).call(this,_dereq_("g5I+bs"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":87,"g5I+bs":64,"inherits":86}]},{},[1]) (1) }); \ No newline at end of file diff --git a/package.json b/package.json index 4796911..b9ad993 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "universe-js", - "version": "1.2.6", + "version": "2.0.0", "main": "index.js", "author": { "name": "Joannic Laborde",