diff --git a/.gitignore b/.gitignore
index f6cb919..91d2503 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
node_modules/
.DS_STORE
-dist
npm-debug.log
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..3005f36
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,9 @@
+test/
+gulpfile.js
+.travis.yml
+.gitignore
+.eslintrc
+.eslintignore
+.nvmrc
+bower.json
+.npmignore
diff --git a/README.md b/README.md
index 45ce152..1bda6a3 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,14 @@ A typical use case in a credit card form is to notify the user if the data they
Credit Card Validator will also provide a determined card type (using [credit-card-type](https://github.com/braintree/credit-card-type)). This is useful for scenarios in which you wish to render an accompanying payment method icon (Visa, MasterCard, etc.). Additionally, by having access to the current card type, you can better manage the state of your credit card form as a whole. For example, if you detect a user is entering (or has entered) an American Express card number, you can update the `maxlength` attribute of your `CVV` input element from 3 to 4 and even update the corresponding `label` from 'CVV' to 'CID'.
+## Download
+
+You can install `card-validator` through `npm`. The npm module also includes the built, UMD bundle and its minified variant under `dist/`
+
+```
+npm install card-validator
+```
+
## Example
```javascript
diff --git a/dist/card-validator.js b/dist/card-validator.js
new file mode 100644
index 0000000..5075687
--- /dev/null
+++ b/dist/card-validator.js
@@ -0,0 +1,2350 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)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.cardValidator=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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.7.0
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var baseClone = require('lodash._baseclone'),
+ bindCallback = require('lodash._bindcallback');
+
+/**
+ * Creates a deep clone of `value`. If `customizer` is provided it is invoked
+ * to produce the cloned values. If `customizer` returns `undefined` cloning
+ * is handled by the method instead. The `customizer` is bound to `thisArg`
+ * and invoked with two argument; (value [, index|key, object]).
+ *
+ * **Note:** This method is loosely based on the structured clone algorithm.
+ * The enumerable properties of `arguments` objects and objects created by
+ * constructors other than `Object` are cloned to plain `Object` objects. An
+ * empty object is returned for uncloneable values such as functions, DOM nodes,
+ * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to deep clone.
+ * @param {Function} [customizer] The function to customize cloning values.
+ * @param {*} [thisArg] The `this` binding of `customizer`.
+ * @returns {*} Returns the deep cloned value.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney' },
+ * { 'user': 'fred' }
+ * ];
+ *
+ * var deep = _.cloneDeep(users);
+ * deep[0] === users[0];
+ * // => false
+ *
+ * // using a customizer callback
+ * var el = _.cloneDeep(document.body, function(value) {
+ * return _.isElement(value) ? value.cloneNode(true) : undefined;
+ * });
+ *
+ * body === document.body
+ * // => false
+ * body.nodeName
+ * // => BODY
+ * body.childNodes.length;
+ * // => 20
+ */
+function cloneDeep(value, customizer, thisArg) {
+ customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1);
+ return baseClone(value, true, customizer);
+}
+
+module.exports = cloneDeep;
+
+},{"lodash._baseclone":4,"lodash._bindcallback":14}],4:[function(require,module,exports){
+(function (global){
+/**
+ * lodash 3.1.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var arrayCopy = require('lodash._arraycopy'),
+ arrayEach = require('lodash._arrayeach'),
+ baseAssign = require('lodash._baseassign'),
+ baseFor = require('lodash._basefor'),
+ isArray = require('lodash.isarray'),
+ isNative = require('lodash.isnative'),
+ keys = require('lodash.keys');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+ arrayTag = '[object Array]',
+ boolTag = '[object Boolean]',
+ dateTag = '[object Date]',
+ errorTag = '[object Error]',
+ funcTag = '[object Function]',
+ mapTag = '[object Map]',
+ numberTag = '[object Number]',
+ objectTag = '[object Object]',
+ regexpTag = '[object RegExp]',
+ setTag = '[object Set]',
+ stringTag = '[object String]',
+ weakMapTag = '[object WeakMap]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+ float32Tag = '[object Float32Array]',
+ float64Tag = '[object Float64Array]',
+ int8Tag = '[object Int8Array]',
+ int16Tag = '[object Int16Array]',
+ int32Tag = '[object Int32Array]',
+ uint8Tag = '[object Uint8Array]',
+ uint8ClampedTag = '[object Uint8ClampedArray]',
+ uint16Tag = '[object Uint16Array]',
+ uint32Tag = '[object Uint32Array]';
+
+/** Used to match `RegExp` flags from their coerced string values. */
+var reFlags = /\w*$/;
+
+/** Used to identify `toStringTag` values supported by `_.clone`. */
+var cloneableTags = {};
+cloneableTags[argsTag] = cloneableTags[arrayTag] =
+cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
+cloneableTags[dateTag] = cloneableTags[float32Tag] =
+cloneableTags[float64Tag] = cloneableTags[int8Tag] =
+cloneableTags[int16Tag] = cloneableTags[int32Tag] =
+cloneableTags[numberTag] = cloneableTags[objectTag] =
+cloneableTags[regexpTag] = cloneableTags[stringTag] =
+cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+cloneableTags[errorTag] = cloneableTags[funcTag] =
+cloneableTags[mapTag] = cloneableTags[setTag] =
+cloneableTags[weakMapTag] = false;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Native method references. */
+var ArrayBuffer = isNative(ArrayBuffer = global.ArrayBuffer) && ArrayBuffer,
+ bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice,
+ floor = Math.floor,
+ Uint8Array = isNative(Uint8Array = global.Uint8Array) && Uint8Array;
+
+/** Used to clone array buffers. */
+var Float64Array = (function() {
+ // Safari 5 errors when using an array buffer to initialize a typed array
+ // where the array buffer's `byteLength` is not a multiple of the typed
+ // array's `BYTES_PER_ELEMENT`.
+ try {
+ var func = isNative(func = global.Float64Array) && func,
+ result = new func(new ArrayBuffer(10), 0, 1) && func;
+ } catch(e) {}
+ return result;
+}());
+
+/** Used as the size, in bytes, of each `Float64Array` element. */
+var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
+
+/**
+ * The base implementation of `_.clone` without support for argument juggling
+ * and `this` binding `customizer` functions.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @param {Function} [customizer] The function to customize cloning values.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The object `value` belongs to.
+ * @param {Array} [stackA=[]] Tracks traversed source objects.
+ * @param {Array} [stackB=[]] Associates clones with source counterparts.
+ * @returns {*} Returns the cloned value.
+ */
+function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
+ var result;
+ if (customizer) {
+ result = object ? customizer(value, key, object) : customizer(value);
+ }
+ if (result !== undefined) {
+ return result;
+ }
+ if (!isObject(value)) {
+ return value;
+ }
+ var isArr = isArray(value);
+ if (isArr) {
+ result = initCloneArray(value);
+ if (!isDeep) {
+ return arrayCopy(value, result);
+ }
+ } else {
+ var tag = objToString.call(value),
+ isFunc = tag == funcTag;
+
+ if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+ result = initCloneObject(isFunc ? {} : value);
+ if (!isDeep) {
+ return baseAssign(result, value);
+ }
+ } else {
+ return cloneableTags[tag]
+ ? initCloneByTag(value, tag, isDeep)
+ : (object ? value : {});
+ }
+ }
+ // Check for circular references and return corresponding clone.
+ stackA || (stackA = []);
+ stackB || (stackB = []);
+
+ var length = stackA.length;
+ while (length--) {
+ if (stackA[length] == value) {
+ return stackB[length];
+ }
+ }
+ // Add the source value to the stack of traversed objects and associate it with its clone.
+ stackA.push(value);
+ stackB.push(result);
+
+ // Recursively populate clone (susceptible to call stack limits).
+ (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
+ result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
+ });
+ return result;
+}
+
+/**
+ * The base implementation of `_.forOwn` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForOwn(object, iteratee) {
+ return baseFor(object, iteratee, keys);
+}
+
+/**
+ * Creates a clone of the given array buffer.
+ *
+ * @private
+ * @param {ArrayBuffer} buffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+function bufferClone(buffer) {
+ return bufferSlice.call(buffer, 0);
+}
+if (!bufferSlice) {
+ // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`.
+ bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) {
+ var byteLength = buffer.byteLength,
+ floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0,
+ offset = floatLength * FLOAT64_BYTES_PER_ELEMENT,
+ result = new ArrayBuffer(byteLength);
+
+ if (floatLength) {
+ var view = new Float64Array(result, 0, floatLength);
+ view.set(new Float64Array(buffer, 0, floatLength));
+ }
+ if (byteLength != offset) {
+ view = new Uint8Array(result, offset);
+ view.set(new Uint8Array(buffer, offset));
+ }
+ return result;
+ };
+}
+
+/**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */
+function initCloneArray(array) {
+ var length = array.length,
+ result = new array.constructor(length);
+
+ // Add array properties assigned by `RegExp#exec`.
+ if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+ result.index = array.index;
+ result.input = array.input;
+ }
+ return result;
+}
+
+/**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneObject(object) {
+ var Ctor = object.constructor;
+ if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
+ Ctor = Object;
+ }
+ return new Ctor;
+}
+
+/**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneByTag(object, tag, isDeep) {
+ var Ctor = object.constructor;
+ switch (tag) {
+ case arrayBufferTag:
+ return bufferClone(object);
+
+ case boolTag:
+ case dateTag:
+ return new Ctor(+object);
+
+ case float32Tag: case float64Tag:
+ case int8Tag: case int16Tag: case int32Tag:
+ case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
+ var buffer = object.buffer;
+ return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
+
+ case numberTag:
+ case stringTag:
+ return new Ctor(object);
+
+ case regexpTag:
+ var result = new Ctor(object.source, reFlags.exec(object));
+ result.lastIndex = object.lastIndex;
+ }
+ return result;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return type == 'function' || (!!value && type == 'object');
+}
+
+/**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var getter = _.constant(object);
+ *
+ * getter() === object;
+ * // => true
+ */
+function constant(value) {
+ return function() {
+ return value;
+ };
+}
+
+module.exports = baseClone;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"lodash._arraycopy":5,"lodash._arrayeach":6,"lodash._baseassign":7,"lodash._basefor":9,"lodash.isarray":10,"lodash.isnative":11,"lodash.keys":12}],5:[function(require,module,exports){
+/**
+ * lodash 3.0.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.7.0
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+function arrayCopy(source, array) {
+ var index = -1,
+ length = source.length;
+
+ array || (array = Array(length));
+ while (++index < length) {
+ array[index] = source[index];
+ }
+ return array;
+}
+
+module.exports = arrayCopy;
+
+},{}],6:[function(require,module,exports){
+/**
+ * lodash 3.0.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.7.0
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * A specialized version of `_.forEach` for arrays without support for callback
+ * shorthands or `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+function arrayEach(array, iteratee) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break;
+ }
+ }
+ return array;
+}
+
+module.exports = arrayEach;
+
+},{}],7:[function(require,module,exports){
+/**
+ * lodash 3.1.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var baseCopy = require('lodash._basecopy'),
+ isNative = require('lodash.isnative'),
+ keys = require('lodash.keys');
+
+/** Native method references. */
+var getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols;
+
+/**
+ * The base implementation of `_.assign` without support for argument juggling,
+ * multiple sources, and `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+var baseAssign = function(object, source) {
+ return source == null
+ ? object
+ : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object));
+};
+
+/**
+ * Creates an array of the own symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) {
+ return getOwnPropertySymbols(toObject(object));
+};
+
+/**
+ * Converts `value` to an object if it is not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Object} Returns the object.
+ */
+function toObject(value) {
+ return isObject(value) ? value : Object(value);
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return type == 'function' || (!!value && type == 'object');
+}
+
+/**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var getter = _.constant(object);
+ *
+ * getter() === object;
+ * // => true
+ */
+function constant(value) {
+ return function() {
+ return value;
+ };
+}
+
+module.exports = baseAssign;
+
+},{"lodash._basecopy":8,"lodash.isnative":11,"lodash.keys":12}],8:[function(require,module,exports){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+function baseCopy(source, props, object) {
+ object || (object = {});
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index];
+ object[key] = source[key];
+ }
+ return object;
+}
+
+module.exports = baseCopy;
+
+},{}],9:[function(require,module,exports){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.2
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iterator functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+var baseFor = createBaseFor();
+
+/**
+ * Creates a base function for `_.forIn` or `_.forInRight`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var iterable = toObject(object),
+ props = keysFunc(object),
+ length = props.length,
+ index = fromRight ? length : -1;
+
+ while ((fromRight ? index-- : ++index < length)) {
+ var key = props[index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ };
+}
+
+/**
+ * Converts `value` to an object if it is not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Object} Returns the object.
+ */
+function toObject(value) {
+ return isObject(value) ? value : Object(value);
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return type == 'function' || (!!value && type == 'object');
+}
+
+module.exports = baseFor;
+
+},{}],10:[function(require,module,exports){
+/**
+ * lodash 3.0.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var arrayTag = '[object Array]',
+ funcTag = '[object Function]';
+
+/**
+ * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special).
+ * In addition to special characters the forward slash is escaped to allow for
+ * easier `eval` use and `Function` compilation.
+ */
+var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
+ reHasRegExpChars = RegExp(reRegExpChars.source);
+
+/** Used to detect host constructors (Safari > 5). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/**
+ * Converts `value` to a string if it is not one. An empty string is returned
+ * for `null` or `undefined` values.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */
+function baseToString(value) {
+ if (typeof value == 'string') {
+ return value;
+ }
+ return value == null ? '' : (value + '');
+}
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var fnToString = Function.prototype.toString;
+
+/**
+ * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+ escapeRegExp(objToString)
+ .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray;
+
+/**
+ * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(function() { return arguments; }());
+ * // => false
+ */
+var isArray = nativeIsArray || function(value) {
+ return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+};
+
+/**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+function isNative(value) {
+ if (value == null) {
+ return false;
+ }
+ if (objToString.call(value) == funcTag) {
+ return reIsNative.test(fnToString.call(value));
+ }
+ return isObjectLike(value) && reIsHostCtor.test(value);
+}
+
+/**
+ * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
+ * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escapeRegExp('[lodash](https://lodash.com/)');
+ * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
+ */
+function escapeRegExp(string) {
+ string = baseToString(string);
+ return (string && reHasRegExpChars.test(string))
+ ? string.replace(reRegExpChars, '\\$&')
+ : string;
+}
+
+module.exports = isArray;
+
+},{}],11:[function(require,module,exports){
+/**
+ * lodash 3.0.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var funcTag = '[object Function]';
+
+/**
+ * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special).
+ * In addition to special characters the forward slash is escaped to allow for
+ * easier `eval` use and `Function` compilation.
+ */
+var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
+ reHasRegExpChars = RegExp(reRegExpChars.source);
+
+/** Used to detect host constructors (Safari > 5). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/**
+ * Converts `value` to a string if it is not one. An empty string is returned
+ * for `null` or `undefined` values.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */
+function baseToString(value) {
+ if (typeof value == 'string') {
+ return value;
+ }
+ return value == null ? '' : (value + '');
+}
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var fnToString = Function.prototype.toString;
+
+/**
+ * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+ escapeRegExp(objToString)
+ .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+function isNative(value) {
+ if (value == null) {
+ return false;
+ }
+ if (objToString.call(value) == funcTag) {
+ return reIsNative.test(fnToString.call(value));
+ }
+ return isObjectLike(value) && reIsHostCtor.test(value);
+}
+
+/**
+ * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
+ * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escapeRegExp('[lodash](https://lodash.com/)');
+ * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
+ */
+function escapeRegExp(string) {
+ string = baseToString(string);
+ return (string && reHasRegExpChars.test(string))
+ ? string.replace(reRegExpChars, '\\$&')
+ : string;
+}
+
+module.exports = isNative;
+
+},{}],12:[function(require,module,exports){
+/**
+ * lodash 3.0.7 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var isArguments = require('lodash.isarguments'),
+ isArray = require('lodash.isarray'),
+ isNative = require('lodash.isnative');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Native method references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys;
+
+/**
+ * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
+
+/**
+ * An object environment feature flags.
+ *
+ * @static
+ * @memberOf _
+ * @type Object
+ */
+var support = {};
+
+(function(x) {
+ var Ctor = function() { this.x = x; },
+ args = arguments,
+ object = { '0': x, 'length': x },
+ props = [];
+
+ Ctor.prototype = { 'valueOf': x, 'y': x };
+ for (var key in new Ctor) { props.push(key); }
+
+ /**
+ * Detect if `arguments` object indexes are non-enumerable.
+ *
+ * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object
+ * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat
+ * `arguments` object indexes as non-enumerable and fail `hasOwnProperty`
+ * checks for indexes that exceed the number of function parameters and
+ * whose associated argument values are `0`.
+ *
+ * @memberOf _.support
+ * @type boolean
+ */
+ try {
+ support.nonEnumArgs = !propertyIsEnumerable.call(args, 1);
+ } catch(e) {
+ support.nonEnumArgs = true;
+ }
+}(1, 0));
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+}
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+ return value != null && isLength(getLength(value));
+}
+
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+ value = +value;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * A fallback implementation of `Object.keys` which creates an array of the
+ * own enumerable property names of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function shimKeys(object) {
+ var props = keysIn(object),
+ propsLength = props.length,
+ length = propsLength && object.length;
+
+ var allowIndexes = length && isLength(length) &&
+ (isArray(object) || (support.nonEnumArgs && isArguments(object)));
+
+ var index = -1,
+ result = [];
+
+ while (++index < propsLength) {
+ var key = props[index];
+ if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
+ result.push(key);
+ }
+ }
+ return result;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return type == 'function' || (!!value && type == 'object');
+}
+
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+var keys = !nativeKeys ? shimKeys : function(object) {
+ var Ctor = object != null && object.constructor;
+ if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
+ (typeof object != 'function' && isArrayLike(object))) {
+ return shimKeys(object);
+ }
+ return isObject(object) ? nativeKeys(object) : [];
+};
+
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+ if (object == null) {
+ return [];
+ }
+ if (!isObject(object)) {
+ object = Object(object);
+ }
+ var length = object.length;
+ length = (length && isLength(length) &&
+ (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0;
+
+ var Ctor = object.constructor,
+ index = -1,
+ isProto = typeof Ctor == 'function' && Ctor.prototype === object,
+ result = Array(length),
+ skipIndexes = length > 0;
+
+ while (++index < length) {
+ result[index] = (index + '');
+ }
+ for (var key in object) {
+ if (!(skipIndexes && isIndex(key, length)) &&
+ !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+ result.push(key);
+ }
+ }
+ return result;
+}
+
+module.exports = keys;
+
+},{"lodash.isarguments":13,"lodash.isarray":10,"lodash.isnative":11}],13:[function(require,module,exports){
+/**
+ * lodash 3.0.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]';
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+}
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+ return value != null && isLength(getLength(value));
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * Checks if `value` is classified as an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+function isArguments(value) {
+ return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag;
+}
+
+module.exports = isArguments;
+
+},{}],14:[function(require,module,exports){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * A specialized version of `baseCallback` which only supports `this` binding
+ * and specifying the number of arguments to provide to `func`.
+ *
+ * @private
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {number} [argCount] The number of arguments to provide to `func`.
+ * @returns {Function} Returns the callback.
+ */
+function bindCallback(func, thisArg, argCount) {
+ if (typeof func != 'function') {
+ return identity;
+ }
+ if (thisArg === undefined) {
+ return func;
+ }
+ switch (argCount) {
+ case 1: return function(value) {
+ return func.call(thisArg, value);
+ };
+ 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);
+ };
+ case 5: return function(value, other, key, object, source) {
+ return func.call(thisArg, value, other, key, object, source);
+ };
+ }
+ return function() {
+ return func.apply(thisArg, arguments);
+ };
+}
+
+/**
+ * This method returns the first argument provided to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+function identity(value) {
+ return value;
+}
+
+module.exports = bindCallback;
+
+},{}],15:[function(require,module,exports){
+/**
+ * lodash 3.1.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var baseAssign = require('lodash._baseassign'),
+ createAssigner = require('lodash._createassigner'),
+ isNative = require('lodash.isnative'),
+ keys = require('lodash.keys');
+
+/** Used for native method references. */
+var arrayProto = Array.prototype;
+
+/** Native method references. */
+var getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols,
+ push = arrayProto.push;
+
+/**
+ * A specialized version of `_.assign` for customizing assigned values without
+ * support for argument juggling, multiple sources, and `this` binding `customizer`
+ * functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {Function} customizer The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ */
+function assignWith(object, source, customizer) {
+ var props = keys(source);
+ push.apply(props, getSymbols(source));
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index],
+ value = object[key],
+ result = customizer(value, source[key], key, object, source);
+
+ if ((result === result ? (result !== value) : (value === value)) ||
+ (value === undefined && !(key in object))) {
+ object[key] = result;
+ }
+ }
+ return object;
+}
+
+/**
+ * Creates an array of the own symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) {
+ return getOwnPropertySymbols(toObject(object));
+};
+
+/**
+ * Converts `value` to an object if it is not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Object} Returns the object.
+ */
+function toObject(value) {
+ return isObject(value) ? value : Object(value);
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return type == 'function' || (!!value && type == 'object');
+}
+
+/**
+ * Assigns own enumerable properties of source object(s) to the destination
+ * object. Subsequent sources overwrite property assignments of previous sources.
+ * If `customizer` is provided it is invoked to produce the assigned values.
+ * The `customizer` is bound to `thisArg` and invoked with five arguments:
+ * (objectValue, sourceValue, key, object, source).
+ *
+ * **Note:** This method mutates `object` and is based on
+ * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign).
+ *
+ *
+ * @static
+ * @memberOf _
+ * @alias extend
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {*} [thisArg] The `this` binding of `customizer`.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
+ * // => { 'user': 'fred', 'age': 40 }
+ *
+ * // using a customizer callback
+ * var defaults = _.partialRight(_.assign, function(value, other) {
+ * return _.isUndefined(value) ? other : value;
+ * });
+ *
+ * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+ * // => { 'user': 'barney', 'age': 36 }
+ */
+var assign = createAssigner(function(object, source, customizer) {
+ return customizer
+ ? assignWith(object, source, customizer)
+ : baseAssign(object, source);
+});
+
+/**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var getter = _.constant(object);
+ *
+ * getter() === object;
+ * // => true
+ */
+function constant(value) {
+ return function() {
+ return value;
+ };
+}
+
+module.exports = assign;
+
+},{"lodash._baseassign":16,"lodash._createassigner":18,"lodash.isnative":22,"lodash.keys":23}],16:[function(require,module,exports){
+module.exports=require(7)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._baseclone/node_modules/lodash._baseassign/index.js":7,"lodash._basecopy":17,"lodash.isnative":22,"lodash.keys":23}],17:[function(require,module,exports){
+module.exports=require(8)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._baseclone/node_modules/lodash._baseassign/node_modules/lodash._basecopy/index.js":8}],18:[function(require,module,exports){
+/**
+ * lodash 3.1.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var bindCallback = require('lodash._bindcallback'),
+ isIterateeCall = require('lodash._isiterateecall'),
+ restParam = require('lodash.restparam');
+
+/**
+ * Creates a function that assigns properties of source object(s) to a given
+ * destination object.
+ *
+ * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @returns {Function} Returns the new assigner function.
+ */
+function createAssigner(assigner) {
+ return restParam(function(object, sources) {
+ var index = -1,
+ length = object == null ? 0 : sources.length,
+ customizer = length > 2 && sources[length - 2],
+ guard = length > 2 && sources[2],
+ thisArg = length > 1 && sources[length - 1];
+
+ if (typeof customizer == 'function') {
+ customizer = bindCallback(customizer, thisArg, 5);
+ length -= 2;
+ } else {
+ customizer = typeof thisArg == 'function' ? thisArg : null;
+ length -= (customizer ? 1 : 0);
+ }
+ if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+ customizer = length < 3 ? null : customizer;
+ length = 1;
+ }
+ while (++index < length) {
+ var source = sources[index];
+ if (source) {
+ assigner(object, source, customizer);
+ }
+ }
+ return object;
+ });
+}
+
+module.exports = createAssigner;
+
+},{"lodash._bindcallback":19,"lodash._isiterateecall":20,"lodash.restparam":21}],19:[function(require,module,exports){
+module.exports=require(14)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._bindcallback/index.js":14}],20:[function(require,module,exports){
+/**
+ * lodash 3.0.7 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+}
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+ return value != null && isLength(getLength(value));
+}
+
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+ value = +value;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+}
+
+/**
+ * Checks if the provided arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
+ */
+function isIterateeCall(value, index, object) {
+ if (!isObject(object)) {
+ return false;
+ }
+ var type = typeof index;
+ if (type == 'number'
+ ? (isArrayLike(object) && isIndex(index, object.length))
+ : (type == 'string' && index in object)) {
+ var other = object[index];
+ return value === value ? (value === other) : (other !== other);
+ }
+ return false;
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return type == 'function' || (!!value && type == 'object');
+}
+
+module.exports = isIterateeCall;
+
+},{}],21:[function(require,module,exports){
+/**
+ * lodash 3.6.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.restParam(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+function restParam(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+ return function() {
+ var args = arguments,
+ index = -1,
+ length = nativeMax(args.length - start, 0),
+ rest = Array(length);
+
+ while (++index < length) {
+ rest[index] = args[start + index];
+ }
+ switch (start) {
+ case 0: return func.call(this, rest);
+ case 1: return func.call(this, args[0], rest);
+ case 2: return func.call(this, args[0], args[1], rest);
+ }
+ var otherArgs = Array(start + 1);
+ index = -1;
+ while (++index < start) {
+ otherArgs[index] = args[index];
+ }
+ otherArgs[start] = rest;
+ return func.apply(this, otherArgs);
+ };
+}
+
+module.exports = restParam;
+
+},{}],22:[function(require,module,exports){
+module.exports=require(11)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._baseclone/node_modules/lodash.isnative/index.js":11}],23:[function(require,module,exports){
+module.exports=require(12)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._baseclone/node_modules/lodash.keys/index.js":12,"lodash.isarguments":24,"lodash.isarray":25,"lodash.isnative":22}],24:[function(require,module,exports){
+module.exports=require(13)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._baseclone/node_modules/lodash.keys/node_modules/lodash.isarguments/index.js":13}],25:[function(require,module,exports){
+module.exports=require(10)
+},{"/Users/mrak/Developer/Braintree/card-validator/node_modules/credit-card-type/node_modules/lodash.clonedeep/node_modules/lodash._baseclone/node_modules/lodash.isarray/index.js":10}],26:[function(require,module,exports){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.2
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var numberTag = '[object Number]';
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a `Number` primitive or object.
+ *
+ * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
+ * as numbers, use the `_.isFinite` method.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isNumber(8.4);
+ * // => true
+ *
+ * _.isNumber(NaN);
+ * // => true
+ *
+ * _.isNumber('8.4');
+ * // => false
+ */
+function isNumber(value) {
+ return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
+}
+
+module.exports = isNumber;
+
+},{}],27:[function(require,module,exports){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.2
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var stringTag = '[object String]';
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+function isString(value) {
+ return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+}
+
+module.exports = isString;
+
+},{}],28:[function(require,module,exports){
+var isString = require('lodash.isstring');
+var extend = require('lodash.assign');
+var luhn10 = require('./luhn-10');
+var getCardType = require('credit-card-type');
+var isNumber = require('lodash.isnumber');
+
+function verification(card, isPotentiallyValid, isValid) {
+ return extend({}, {card: card, isPotentiallyValid: isPotentiallyValid, isValid: isValid});
+}
+
+function isEmptyObject(object) {
+ var key;
+
+ for (key in object) {
+ if (object.hasOwnProperty(key)) { return false; }
+ }
+
+ return true;
+}
+
+function cardNumber(value) {
+ var cardType, valid;
+
+ if (isNumber(value)) {
+ value = String(value);
+ }
+
+ if (!isString(value)) { return verification(null, false, false); }
+
+ if (value === '') { return verification(null, true, false); }
+
+ value = value.replace(/\-|\s/g, '');
+
+ if (!/^\d*$/.test(value)) { return verification(null, false, false); }
+
+ // TODO: Just letting these go here as validPartials
+ // The optimal solution would be to have a separate
+ // set of regexes for partial validations
+
+ // Discover cannot be determined until we have 4 digits
+ if (value.length <= 3 && value[0] === '6') {
+ return verification(null, true, false);
+ }
+
+ // Non-discover cards
+ if (value.length <= 1 && /^(5|4|3)/.test(value)) { return verification(null, true, false); }
+
+ cardType = getCardType(value);
+ if (isEmptyObject(cardType)) { return verification(null, false, false); }
+
+ // Recognized as card but not long enough yet: validPartial
+ if (value.length < cardType.length) {
+ return verification(cardType, true, false);
+ }
+
+ if (value.length > cardType.length) {
+ return verification(cardType, false, false);
+ }
+
+ valid = luhn10(value);
+ return verification(cardType, valid, valid);
+}
+
+module.exports = cardNumber;
+
+},{"./luhn-10":33,"credit-card-type":2,"lodash.assign":15,"lodash.isnumber":26,"lodash.isstring":27}],29:[function(require,module,exports){
+var isString = require('lodash.isstring');
+var DEFAULT_LENGTH = 3;
+
+function verification(isValid, isPotentiallyValid) {
+ return {isValid: isValid, isPotentiallyValid: isPotentiallyValid};
+}
+
+function cvv(value, maxLength) {
+ maxLength = maxLength || DEFAULT_LENGTH;
+
+ if (!isString(value)) { return verification(false, false); }
+ if (!/^\d*$/.test(value)) { return verification(false, false); }
+ if (value.length === maxLength) { return verification(true, true); }
+ if (value.length < maxLength) { return verification(false, true); }
+ if (value.length > maxLength) { return verification(false, false); }
+
+ return verification(true, true);
+}
+
+module.exports = cvv;
+
+},{"lodash.isstring":27}],30:[function(require,module,exports){
+var parseDate = require('./parse-date');
+var expirationMonth = require('./expiration-month');
+var expirationYear = require('./expiration-year');
+var isString = require('lodash.isstring');
+
+function verification(isValid, isPotentiallyValid, month, year) {
+ return {
+ isValid: isValid,
+ isPotentiallyValid: isPotentiallyValid,
+ month: month,
+ year: year
+ };
+}
+
+function expirationDate(value) {
+ var date, monthValid, yearValid;
+
+ if (!isString(value)) {
+ return verification(false, false, null, null);
+ }
+
+ value = value.replace(/^(\d\d) (\d\d(\d\d)?)$/, '$1/$2');
+ date = parseDate(value);
+ monthValid = expirationMonth(date.month);
+ yearValid = expirationYear(date.year);
+
+ if (monthValid.isValid && yearValid.isValid) {
+ return verification(true, true, date.month, date.year);
+ }
+
+ if (monthValid.isPotentiallyValid && yearValid.isPotentiallyValid) {
+ return verification(false, true, null, null);
+ }
+
+ return verification(false, false, null, null);
+}
+
+module.exports = expirationDate;
+
+},{"./expiration-month":31,"./expiration-year":32,"./parse-date":34,"lodash.isstring":27}],31:[function(require,module,exports){
+var isString = require('lodash.isstring');
+
+function verification(isValid, isPotentiallyValid) {
+ return {isValid: isValid, isPotentiallyValid: isPotentiallyValid};
+}
+
+function expirationMonth(value) {
+ var month, result;
+
+ if (!isString(value)) {
+ return verification(false, false);
+ }
+ if ((value.replace(/\s/g, '') === '') || (value === '0')) {
+ return verification(false, true);
+ }
+ if (!/^\d*$/.test(value)) {
+ return verification(false, false);
+ }
+
+ month = parseInt(value, 10);
+
+ if (isNaN(value)) {
+ return verification(false, false);
+ }
+
+ result = month > 0 && month < 13;
+
+ return verification(result, result);
+}
+
+module.exports = expirationMonth;
+
+},{"lodash.isstring":27}],32:[function(require,module,exports){
+var isString = require('lodash.isstring');
+var maxYear = 19;
+
+function verification(isValid, isPotentiallyValid) {
+ return {isValid: isValid, isPotentiallyValid: isPotentiallyValid};
+}
+
+function expirationYear(value) {
+ var currentFirstTwo, currentYear, firstTwo, len, twoDigitYear, valid;
+
+ if (!isString(value)) {
+ return verification(false, false);
+ }
+ if (value.replace(/\s/g, '') === '') {
+ return verification(false, true);
+ }
+ if (!/^\d*$/.test(value)) {
+ return verification(false, false);
+ }
+
+ len = value.length;
+
+ if (len < 2) {
+ return verification(false, true);
+ }
+
+ currentYear = new Date().getFullYear();
+
+ if (len === 3) {
+ // 20x === 20x
+ firstTwo = value.slice(0, 2);
+ currentFirstTwo = String(currentYear).slice(0, 2);
+ return verification(false, firstTwo === currentFirstTwo);
+ }
+
+ if (len > 4) {
+ return verification(false, false);
+ }
+
+ value = parseInt(value, 10);
+ twoDigitYear = Number(String(currentYear).substr(2, 2));
+
+ if (len === 2) {
+ valid = value >= twoDigitYear && value <= twoDigitYear + maxYear;
+ } else if (len === 4) {
+ valid = value >= currentYear && value <= currentYear + maxYear;
+ }
+
+ return verification(valid, valid);
+}
+
+module.exports = expirationYear;
+
+},{"lodash.isstring":27}],33:[function(require,module,exports){
+/*eslint-disable*/
+module.exports = function luhn10(a,b,c,d,e) {
+ for(d = +a[b = a.length-1], e=0; b--;)
+ c = +a[b], d += ++e % 2 ? 2 * c % 10 + (c > 4) : c;
+ return !(d%10)
+};
+
+},{}],34:[function(require,module,exports){
+function parseDate(value) {
+ var month, len;
+
+ if (value.match('/')) {
+ value = value.split(/\s*\/\s*/g);
+
+ return {
+ month: value[0],
+ year: value.slice(1).join()
+ };
+ }
+
+ len = value[0] === '0' || value.length > 5 || value.length === 4 || value.length === 3 ? 2 : 1;
+ month = value.substr(0, len);
+
+ return {
+ month: month,
+ year: value.substr(month.length, 4)
+ };
+}
+
+module.exports = parseDate;
+
+},{}],35:[function(require,module,exports){
+var isString = require('lodash.isstring');
+
+function verification(isValid, isPotentiallyValid) {
+ return {isValid: isValid, isPotentiallyValid: isPotentiallyValid};
+}
+
+function postalCode(value) {
+ if (!isString(value)) {
+ return verification(false, false);
+ } else if (value.length < 4) {
+ return verification(false, true);
+ }
+
+ return verification(true, true);
+}
+
+module.exports = postalCode;
+
+},{"lodash.isstring":27}]},{},[1])(1)
+});
\ No newline at end of file
diff --git a/dist/card-validator.min.js b/dist/card-validator.min.js
new file mode 100644
index 0000000..efe3438
--- /dev/null
+++ b/dist/card-validator.min.js
@@ -0,0 +1 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.cardValidator=e()}}(function(){return function e(n,t,r){function o(s,i){if(!t[s]){if(!n[s]){var u="function"==typeof require&&require;if(!i&&u)return u(s,!0);if(a)return a(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=t[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return o(t?t:e)},l,l.exports,e,n,t,r)}return t[s].exports}for(var a="function"==typeof require&&require,s=0;s-1&&e%1==0&&v>=e}function s(e){return null==e?!1:y.call(e)==c?g.test(h.call(e)):o(e)&&f.test(e)}function i(e){return e=r(e),e&&d.test(e)?e.replace(l,"\\$&"):e}var u="[object Array]",c="[object Function]",l=/[.*+?^${}()|[\]\/\\]/g,d=RegExp(l.source),f=/^\[object .+?Constructor\]$/,p=Object.prototype,h=Function.prototype.toString,y=p.toString,g=RegExp("^"+i(y).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),b=s(b=Array.isArray)&&b,v=Math.pow(2,53)-1,m=b||function(e){return o(e)&&a(e.length)&&y.call(e)==u};n.exports=m},{}],11:[function(e,n,t){function r(e){return"string"==typeof e?e:null==e?"":e+""}function o(e){return!!e&&"object"==typeof e}function a(e){return null==e?!1:p.call(e)==i?h.test(f.call(e)):o(e)&&l.test(e)}function s(e){return e=r(e),e&&c.test(e)?e.replace(u,"\\$&"):e}var i="[object Function]",u=/[.*+?^${}()|[\]\/\\]/g,c=RegExp(u.source),l=/^\[object .+?Constructor\]$/,d=Object.prototype,f=Function.prototype.toString,p=d.toString,h=RegExp("^"+s(p).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");n.exports=a},{}],12:[function(e,n,t){function r(e){return function(n){return null==n?void 0:n[e]}}function o(e){return null!=e&&s(m(e))}function a(e,n){return e=+e,n=null==n?b:n,e>-1&&e%1==0&&n>e}function s(e){return"number"==typeof e&&e>-1&&e%1==0&&b>=e}function i(e){for(var n=c(e),t=n.length,r=t&&e.length,o=r&&s(r)&&(d(e)||v.nonEnumArgs&&l(e)),i=-1,u=[];++i0;++r-1&&e%1==0&&d>=e}function i(e){return r(e)&&a(e)&&l.call(e)==u}var u="[object Arguments]",c=Object.prototype,l=c.toString,d=Math.pow(2,53)-1,f=o("length");n.exports=i},{}],14:[function(e,n,t){function r(e,n,t){if("function"!=typeof e)return o;if(void 0===n)return e;switch(t){case 1:return function(t){return e.call(n,t)};case 3:return function(t,r,o){return e.call(n,t,r,o)};case 4:return function(t,r,o,a){return e.call(n,t,r,o,a)};case 5:return function(t,r,o,a,s){return e.call(n,t,r,o,a,s)}}return function(){return e.apply(n,arguments)}}function o(e){return e}n.exports=r},{}],15:[function(e,n,t){function r(e,n,t){var r=l(n);p.apply(r,h(n));for(var o=-1,a=r.length;++o2&&t[s-2],u=s>2&&t[2],c=s>1&&t[s-1];for("function"==typeof i?(i=o(i,c,5),s-=2):(i="function"==typeof c?c:null,s-=i?1:0),u&&a(t[0],t[1],u)&&(i=3>s?null:i,s=1);++r-1&&e%1==0&&n>e}function s(e,n,t){if(!u(t))return!1;var r=typeof n;if("number"==r?o(t)&&a(n,t.length):"string"==r&&n in t){var s=t[n];return e===e?e===s:s!==s}return!1}function i(e){return"number"==typeof e&&e>-1&&e%1==0&&c>=e}function u(e){var n=typeof e;return"function"==n||!!e&&"object"==n}var c=Math.pow(2,53)-1,l=r("length");n.exports=s},{}],21:[function(e,n,t){function r(e,n){if("function"!=typeof e)throw new TypeError(o);return n=a(void 0===n?e.length-1:+n||0,0),function(){for(var t=arguments,r=-1,o=a(t.length-n,0),s=Array(o);++rn.length?r(n,!1,!1):(t=u(e),r(n,t,t))):r(null,!1,!1)):r(null,!1,!1)}var s=e("lodash.isstring"),i=e("lodash.assign"),u=e("./luhn-10"),c=e("credit-card-type"),l=e("lodash.isnumber");n.exports=a},{"./luhn-10":33,"credit-card-type":2,"lodash.assign":15,"lodash.isnumber":26,"lodash.isstring":27}],29:[function(e,n,t){function r(e,n){return{isValid:e,isPotentiallyValid:n}}function o(e,n){return n=n||s,a(e)&&/^\d*$/.test(e)?e.length===n?r(!0,!0):e.lengthn?r(!1,!1):r(!0,!0):r(!1,!1)}var a=e("lodash.isstring"),s=3;n.exports=o},{"lodash.isstring":27}],30:[function(e,n,t){function r(e,n,t,r){return{isValid:e,isPotentiallyValid:n,month:t,year:r}}function o(e){var n,t,o;return u(e)?(e=e.replace(/^(\d\d) (\d\d(\d\d)?)$/,"$1/$2"),n=a(e),t=s(n.month),o=i(n.year),t.isValid&&o.isValid?r(!0,!0,n.month,n.year):t.isPotentiallyValid&&o.isPotentiallyValid?r(!1,!0,null,null):r(!1,!1,null,null)):r(!1,!1,null,null)}var a=e("./parse-date"),s=e("./expiration-month"),i=e("./expiration-year"),u=e("lodash.isstring");n.exports=o},{"./expiration-month":31,"./expiration-year":32,"./parse-date":34,"lodash.isstring":27}],31:[function(e,n,t){function r(e,n){return{isValid:e,isPotentiallyValid:n}}function o(e){var n,t;return a(e)?""===e.replace(/\s/g,"")||"0"===e?r(!1,!0):/^\d*$/.test(e)?(n=parseInt(e,10),isNaN(e)?r(!1,!1):(t=n>0&&13>n,r(t,t))):r(!1,!1):r(!1,!1)}var a=e("lodash.isstring");n.exports=o},{"lodash.isstring":27}],32:[function(e,n,t){function r(e,n){return{isValid:e,isPotentiallyValid:n}}function o(e){var n,t,o,i,u,c;return a(e)?""===e.replace(/\s/g,"")?r(!1,!0):/^\d*$/.test(e)?(i=e.length,2>i?r(!1,!0):(t=(new Date).getFullYear(),3===i?(o=e.slice(0,2),n=String(t).slice(0,2),r(!1,o===n)):i>4?r(!1,!1):(e=parseInt(e,10),u=Number(String(t).substr(2,2)),2===i?c=e>=u&&u+s>=e:4===i&&(c=e>=t&&t+s>=e),r(c,c)))):r(!1,!1):r(!1,!1)}var a=e("lodash.isstring"),s=19;n.exports=o},{"lodash.isstring":27}],33:[function(e,n,t){n.exports=function(e,n,t,r,o){for(r=+e[n=e.length-1],o=0;n--;)t=+e[n],r+=++o%2?2*t%10+(t>4):t;return!(r%10)}},{}],34:[function(e,n,t){function r(e){var n,t;return e.match("/")?(e=e.split(/\s*\/\s*/g),{month:e[0],year:e.slice(1).join()}):(t="0"===e[0]||e.length>5||4===e.length||3===e.length?2:1,n=e.substr(0,t),{month:n,year:e.substr(n.length,4)})}n.exports=r},{}],35:[function(e,n,t){function r(e,n){return{isValid:e,isPotentiallyValid:n}}function o(e){return a(e)?e.length<4?r(!1,!0):r(!0,!0):r(!1,!1)}var a=e("lodash.isstring");n.exports=o},{"lodash.isstring":27}]},{},[1])(1)});
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index fcc4321..a853689 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -17,38 +17,34 @@ var config = {
js: {
all: './src/**/*.js',
main: './index.js',
- watch: './public/js/**/*.js',
- output: 'app.built.js',
- min: 'app.built.min.js'
+ output: 'card-validator.js',
+ min: 'card-validator.min.js'
}
},
- dist: { js: 'dist/js' }
+ dist: 'dist'
};
gulp.task('lint', function () {
- gulp.src([config.src.js.main])
+ gulp.src([config.src.js.all])
.pipe(eslint())
.pipe(eslint.format());
});
gulp.task('js', ['lint'], function () {
- return browserify(config.src.js.main)
+ return browserify({standalone: 'cardValidator'})
+ .add(config.src.js.main)
.bundle()
.pipe(source(config.src.js.output))
.pipe(streamify(size()))
- .pipe(gulp.dest(config.dist.js))
+ .pipe(gulp.dest(config.dist))
.pipe(streamify(uglify()))
.pipe(streamify(size()))
.pipe(rename(config.src.js.min))
- .pipe(gulp.dest(config.dist.js));
-});
-
-gulp.task('watch', ['js'], function () {
- gulp.watch(config.src.js.watch, ['js']);
+ .pipe(gulp.dest(config.dist));
});
gulp.task('clean', function (done) {
- del([ config.dist.js ], done);
+ del([ config.dist ], done);
});
gulp.task('build', ['clean', 'js']);
diff --git a/src/card-number.js b/src/card-number.js
index 7b5f98a..396c727 100644
--- a/src/card-number.js
+++ b/src/card-number.js
@@ -19,7 +19,7 @@ function isEmptyObject(object) {
}
function cardNumber(value) {
- var cardType, valid, i;
+ var cardType, valid, i, maxLength;
if (isNumber(value)) {
value = String(value);
diff --git a/src/luhn-10.js b/src/luhn-10.js
index d331b79..274bb5d 100644
--- a/src/luhn-10.js
+++ b/src/luhn-10.js
@@ -1,3 +1,4 @@
+/*eslint-disable*/
module.exports = function luhn10(a,b,c,d,e) {
for(d = +a[b = a.length-1], e=0; b--;)
c = +a[b], d += ++e % 2 ? 2 * c % 10 + (c > 4) : c;
diff --git a/src/parse-date.js b/src/parse-date.js
index 009334e..6e05909 100644
--- a/src/parse-date.js
+++ b/src/parse-date.js
@@ -8,15 +8,15 @@ function parseDate(value) {
month: value[0],
year: value.slice(1).join()
};
- } else {
- len = value[0] === '0' || value.length > 5 || value.length === 4 || value.length === 3 ? 2 : 1;
- month = value.substr(0, len);
-
- return {
- month: month,
- year: value.substr(month.length, 4)
- };
}
+
+ len = value[0] === '0' || value.length > 5 || value.length === 4 || value.length === 3 ? 2 : 1;
+ month = value.substr(0, len);
+
+ return {
+ month: month,
+ year: value.substr(month.length, 4)
+ };
}
module.exports = parseDate;