{"version":3,"sources":["approve.js"],"names":["root","factory","define","amd","approve","exports","module","this","Result","approved","errors","each","callback","isFunc","constructor","call","apply","i","length","Card","scheme","valid","Score","strength","points","isMinimum","hasLower","hasUpper","hasNumber","hasSpecial","isBonus","percent","VERSION","tests","required","validate","value","message","expects","email","regex","test","url","alphaNumeric","numeric","alpha","decimal","currency","ip","ipv4","ipv4Cidr","ipv6","ipv6Cidr","min","pars","max","range","equal","format","Object","prototype","toString","time","date","truthy","falsy","_format","text","col","Array","slice","arguments","replace","m","n","trim","_start","rules","result","title","hasOwnProperty","rule","constraint","params","_test","args","_getArgs","ret","concat","_formatMessages","prop","push","_formatMessage","_eachExpected","fn","isArray","expectsLength","config","_getFormat","addTest","obj","name","e","cc","schemes","_getScheme","ca","card","sum","mul","charAt","minimum","minimumBonus","strengths","0","1","2","3","4","5","6","_getScore","match","Math","ceil","_getStrength","bonus","messages"],"mappings":"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","file":"approve.min.js","sourcesContent":["/**\n * approve.js v1.1.1\n * A simple validation library that doesn't interfere.\n * Author: Charl Gottschalk\n * @license: MIT\n */\n\n/** @namespace approve */\n;(function(root, factory) { // eslint-disable-line no-extra-semi\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(function() {\n // Also create a global in case some scripts\n // that are loaded still are looking for\n // a global even when an AMD loader is in use.\n return (root.approve = factory());\n });\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like enviroments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is self)\n root.approve = factory();\n }\n}(this, function(root) {\n /**\n * The result object returned by the approve.value()
method.\n * @memberOf approve\n * @ignore\n */\n function Result() {\n this.approved = true;\n this.errors = [];\n // Provides easy access to the loop for the errors.\n this.each = function(callback) {\n var isFunc = callback && callback.constructor && callback.call && callback.apply,\n i = this.errors.length;\n while (i--) {\n if (isFunc) {\n callback(this.errors[i]);\n }\n }\n };\n }\n\n /** @constructor */\n var approve = {};\n\n /**\n * ApproveJs version\n * @memberOf approve\n * @ignore\n */\n approve.VERSION = '1.1.1';\n\n /**\n * Default tests.
\n * Each test has at least three members.
\n * validate()
- the method which is called when testing a value.
\n * message
- the property that holds the default error message.
\n * expects
- the property that is either false if the test expects no parameters, or an array of strings representing the names of the expected parameters.
\n * Each test either returns a boolean or an object.\n * @memberOf approve\n * @namespace approve.tests\n */\n approve.tests = {\n /**\n * Checks if a value is present.\n * @example\n * approve.value('some value', {required: true});\n * @function required\n * @memberOf approve.tests\n * @inner\n */\n required: {\n validate: function(value) {\n return !!value;\n },\n message: '{title} is required',\n expects: false\n },\n /**\n * Checks if a value is a valid email address.\n * @example\n * approve.value('some value', {email: true});\n * @function email\n * @memberOf approve.tests\n * @inner\n */\n email: {\n regex: /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i, // eslint-disable-line no-control-regex\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} must be a valid email address',\n expects: false\n },\n /**\n * Checks if a value is a valid web address.\n * @example\n * approve.value('some value', {url: true});\n * @function url\n * @memberOf approve.tests\n * @inner\n */\n url: {\n regex: /^(?:(?:https?|ftp):\\/\\/)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/\\S*)?$/i,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} must be a valid web address',\n expects: false\n },\n /**\n * Checks if a value contains both letters and numbers.\n * @example\n * approve.value('some value', {alphaNumeric: true});\n * @function alphaNumeric\n * @memberOf approve.tests\n * @inner\n */\n alphaNumeric: {\n regex: /^[A-Za-z0-9]+$/i,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} may only contain [A-Za-z] and [0-9]',\n expects: false\n },\n /**\n * Checks if a value contains only numbers.\n * @example\n * approve.value('some value', {numeric: true});\n * @function numeric\n * @memberOf approve.tests\n * @inner\n */\n numeric: {\n regex: /^[0-9]+$/,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} may only contain [0-9]',\n expects: false\n },\n /**\n * Checks if a value contains only letters.\n * @example\n * approve.value('some value', {alpha: true});\n * @function alpha\n * @memberOf approve.tests\n * @inner\n */\n alpha: {\n regex: /^[A-Za-z]+$/,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} may only contain [A-Za-z]',\n expects: false\n },\n /**\n * Checks if a value is a valid decimal.\n * @example\n * approve.value('some value', {decimal: true});\n * @function decimal\n * @memberOf approve.tests\n * @inner\n */\n decimal: {\n regex: /^\\s*(\\+|-)?((\\d+(\\.\\d+)?)|(\\.\\d+))\\s*$/,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} must be a valid decimal',\n expects: false\n },\n /**\n * Similar to 'decimal', but for currency values.\n * @example\n * approve.value('some value', {currency: true});\n * @function currency\n * @memberOf approve.tests\n * @inner\n */\n currency: {\n regex: /^\\s*(\\+|-)?((\\d+(\\.\\d\\d)?)|(\\.\\d\\d))\\s*$/,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} must be a valid currency value',\n expects: false\n },\n /**\n * Checks if a value is a valid ipv4 or ipv6 address.\n * @example\n * approve.value('some value', {ip: true});\n * @function ip\n * @memberOf approve.tests\n * @inner\n */\n ip: {\n regex: {\n ipv4: /^(?:(?:\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}(?:\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])$/,\n ipv4Cidr: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$/,\n ipv6: /^((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|$))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})$/i,\n ipv6Cidr: /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$/\n },\n validate: function(value) {\n return this.regex.ipv4.test(value) || this.regex.ipv6.test(value) || this.regex.ipv4Cidr.test(value) || this.regex.ipv6Cidr.test(value);\n },\n message: '{title} must be a valid IP address',\n expects: false\n },\n /**\n * Checks if a value is a minimum of n characters.\n * @param {Integer} min - The minimum allowed length.\n * @example\n * approve.value('some value', {min: 5});\n * @function min\n * @memberOf approve.tests\n * @inner\n */\n min: {\n validate: function(value, pars) {\n return typeof value === 'string' && value.length >= pars.min;\n },\n message: '{title} must be a minimum of {min} characters',\n expects: ['min']\n },\n /**\n * Checks if a value is a maximum of n characters.\n * @param {Integer} max - The maximum allowed length.\n * @example\n * approve.value('some value', {max: 20});\n * @function max\n * @memberOf approve.tests\n * @inner\n */\n max: {\n validate: function(value, pars) {\n return typeof value === 'string' && value.length <= pars.max;\n },\n message: '{title} must be a maximum of {max} characters',\n expects: ['max']\n },\n /**\n * Checks if a string's length or number is between a minimum and maximum.\n * @param {Integer} min - The minimum allowed length.\n * @param {Integer} max - The maximum allowed length.\n * @example\n * var rule = {\n * range: {\n * min: 5,\n * max: 20\n * }\n * };\n * approve.value('some value', rule);\n * @function range\n * @memberOf approve.tests\n * @inner\n */\n range: {\n validate: function(value, pars) {\n if (typeof value === 'string')\n {\n return value.length >= pars.min && value.length <= pars.max;\n } else if (typeof value === 'number') {\n return value >= pars.min && value <= pars.max;\n }\n return false;\n },\n message: '{title} must be a minimum of {min} and a maximum of {max} characters',\n expects: ['min', 'max']\n },\n /**\n * Checks if a value is the same as the value of another.\n * This test gets the value from a DOM <input/> element.\n * @param {String} field - The id of the DOM <input/> element to test against.\n * @example\n * var rule = {\n * equal: 'password'\n * };\n * approve.value('some value', rule);\n * @function equal\n * @memberOf approve.tests\n * @inner\n */\n equal: {\n validate: function(value, pars) {\n return '' + value === '' + pars.value;\n },\n message: '{title} must be equal to {field}',\n expects: ['value', 'field']\n },\n /**\n * Checks if a value passes a given regular expression.\n * @param {RegExp} regex - The regular expression to test against. MDN\n * @example\n * var rule = {\n * format: /^[A-Za-z0-9]+$/i\n * };\n * approve.value('some value', rule);\n * @function format\n * @memberOf approve.tests\n * @inner\n */\n format: {\n validate: function(value, pars) {\n if (Object.prototype.toString.call(pars.regex) === '[object RegExp]') {\n return pars.regex.test(value);\n }\n throw 'approve.value(): [format] - regex is not a valid regular expression.';\n },\n message: '{title} did not pass the [{regex}] test',\n expects: ['regex']\n },\n /**\n * Checks if a value is a valid time string.\n * @example\n * approve.value('12:25:30', {timeString: true});\n * @function time\n * @memberOf approve.tests\n * @inner\n */\n time: {\n regex: /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} is not a valid time',\n expects: false\n },\n /**\n * Checks if a value is a valid date (YYYY[-/]MM[-/]DD).\n * @example\n * approve.value('2016-10-01', {dateString: true});\n * @function date\n * @memberOf approve.tests\n * @inner\n */\n date: {\n regex: /^(?:\\2)(?:[0-9]{2})?[0-9]{2}([\\/-])(1[0-2]|0?[1-9])([\\/-])(3[01]|[12][0-9]|0?[1-9])$/,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} is not a valid date',\n expects: false\n },\n /**\n * Checks if a value is truthy ('yes', 'true', 'ok[ay]', '1').\n * @example\n * approve.value('yes', {truthy: true});\n * @function truthy\n * @memberOf approve.tests\n * @inner\n */\n truthy: {\n regex: /^(?:1|t(?:rue)?|y(?:es)?|ok(?:ay)?)$/i,\n validate: function(value) {\n return this.regex.test(value);\n },\n message: '{title} is not valid',\n expects: false\n },\n /**\n * Checks if a value is falsy ('No', 'false', '0').\n * @example\n * approve.value('No', {falsy: true});\n * @function falsy\n * @memberOf approve.tests\n * @inner\n */\n falsy: {\n regex: /^(?:1|t(?:rue)?|y(?:es)?|ok(?:ay)?)$/i,\n validate: function(value) {\n return !this.regex.test(value);\n },\n message: '{title} is not valid',\n expects: false\n }\n };\n /**\n * A helper function for formatting strings:\n * @example\n * this._format('i can speak {language} since i was {age}', {language:'javascript',age:10});\n * @example\n * this._format('i can speak {0} since i was {1}', 'javascript',10});\n * @return {String} The formatted string.\n * @memberOf approve\n * @ignore\n */\n approve._format = function(text, col) {\n col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 1);\n return text.replace(/\\{\\{|\\}\\}|\\{(\\w+)\\}/g, function (m, n) {\n if (m === \"{{\") { return \"{\"; }\n if (m === \"}}\") { return \"}\"; }\n return col[n];\n }).trim();\n };\n\n /**\n * The start of the validation process:\n * @example\n * var result = this._start(value, rules);\n * @param {Object} value - The value to test.\n * @param {Object} rules - The object containing the test constraints.\n * @return {Object} The result of the test.\n * @memberOf approve\n * @ignore\n */\n approve._start = function(value, rules) {\n // Instantiate a result object.\n var result = new Result(),\n // This is used to format the message with the value title.\n title = '';\n // Check if the rule has a title property?\n if (rules.hasOwnProperty('title')) {\n title = rules.title;\n }\n // Loop through given rules.\n for (var rule in rules) {\n if (rules.hasOwnProperty(rule) && rule !== 'title') {\n var constraint = rules[rule];\n // Check if rule exists in tests.\n if (this.tests.hasOwnProperty(rule)) {\n // Set a pointer to the current test.\n var params = {\n constraint: constraint,\n rule: rule,\n title: title,\n test: this.tests[rule],\n value: value\n };\n this._test(params, result);\n } else {\n throw 'approve.value(): ' + rule + ' test not defined.';\n }\n }\n }\n\n return result;\n };\n\n /**\n * Performs the actual testing of the value and returns the result including any errors.\n * @example\n * var result = this._test(params);\n * @param {Object} params - The parameters required for testing.\n * @param {Object} result - The result object\n * @memberOf approve\n * @ignore\n */\n approve._test = function(params, result) {\n // Create an args object for required parameters.\n var args = this._getArgs(params),\n // Test the value.\n ret = params.test.validate(params.value, args);\n // Check if the returned value is an object.\n if(typeof ret === 'object')\n {\n // An object was returned.\n // Check if the test was successful.\n result.approved = !ret.valid ? false : result.approved;\n // Add the error messages returned by the resluting object.\n if (ret.hasOwnProperty('errors')) {\n result.errors = result.errors.concat(this._formatMessages(ret.errors, params));\n }\n // Merge any properties from the resulting object with the main result to be returned.\n for (var prop in ret) {\n if (ret.hasOwnProperty(prop) && !result.hasOwnProperty(prop)) {\n result[prop] = ret[prop];\n }\n }\n } else if (typeof ret !== 'boolean') {\n // We don't process if it's not a boolean or object.\n throw 'approve.value(): ' + params.rule + ' returned an invalid value';\n } else {\n result.approved = !ret ? false : result.approved;\n }\n if (!result.approved) {\n result.errors.push(this._formatMessage(params));\n }\n };\n\n /**\n * Helper method to loop over expected test parameters.\n * @example\n * this._eachExpected(params, function(expected) {\n * // Do something with expected.\n * });\n * @param {Object} params - The parameters required for testing.\n * @param {Function} fn - The callback function called during loop.\n * @return {Void}\n * @memberOf approve\n * @ignore\n */\n approve._eachExpected = function(params, fn) {\n if (Array.isArray(params.test.expects)) {\n var expectsLength = params.test.expects.length,\n i = expectsLength;\n // This test expects paramaters.\n // Loop through the test's expected parameters and call the given function.\n while (i--) {\n fn(params.test.expects[i], expectsLength);\n }\n }\n };\n\n /**\n * Returns an object containing the arguments for a test's expected parameters.\n * @example\n * var pars = this._getArgs(params);\n * @param {Object} params - The parameters required for testing.\n * @return {Object} The object containing the arguments.\n * @memberOf approve\n * @ignore\n */\n approve._getArgs = function(params) {\n var pars = {};\n // Does the test for this rule expect any paramaters?\n this._eachExpected(params, function(expects, expectsLength) {\n // Check if the rule object has the required parameter.\n if (params.constraint.hasOwnProperty(expects)) {\n // Add the expected parameter value to the pars object.\n pars[expects] = params.constraint[expects];\n } else if (expectsLength <= 1 && /^[A-Za-z0-9]+$/i.test(params.constraint)) {\n // Set the parameter to the rule's value.\n pars[expects] = params.constraint;\n } else {\n throw 'approve.value(): ' + params.rule + ' expects the ' + expects + ' parameter.';\n }\n });\n\n // Does the rule have config?\n if (params.constraint.hasOwnProperty('config')) {\n // Add the config to the pars object.\n pars.config = params.constraint.config;\n }\n // Return the parameters object\n return pars;\n };\n\n /**\n * Returns an object containing placholder values to correctly format an error message.\n * @example\n * var format = this._getFormat(params);\n * @param {Object} params - The parameters required for testing.\n * @return {Object} The object used to format an error message.\n * @memberOf approve\n * @ignore\n */\n approve._getFormat = function(params) {\n var format = {};\n // Does the test for the rule expect parameters?\n this._eachExpected(params, function(expects) {\n // Check if the rule object has the required parameter.\n if (params.constraint.hasOwnProperty(expects)) {\n // Add the expected parameter's format to the parameter value.\n format[expects] = params.constraint[expects];\n }\n // Expected parameter not present, is the constraint formattable?\n if (/^[A-Za-z0-9]+$/i.test(params.constraint)) {\n format[expects] = params.constraint;\n }\n });\n format.title = params.title;\n // Return the formatted message.\n return format;\n };\n\n /**\n * Returns an array of formatted error messages returned by tests that return objects instead of booleans.\n * @example\n * var errors = this._formatMessages(['array', 'of', 'errors'], params);\n * @param {Array} errors - The array of unformatted errors returned by the test's result.\n * @param {Object} params - The parameters required for testing.\n * @return {Array} The formatted errors\n * @memberOf approve\n * @ignore\n */\n approve._formatMessages = function(errors, params) {\n var format = this._getFormat(params),\n i = errors.length;\n while (i--) {\n errors[i] = this._format(errors[i], format);\n }\n return errors;\n };\n\n /**\n * Returns the correctly formatted message representing the current test's failure.\n * @example\n * this._message(rule, rules, title);\n * @param {Object} params - The parameters required for testing.\n * @return {String} The correctly formatted error message\n * @memberOf approve\n * @ignore\n */\n approve._formatMessage = function(params) {\n var format = this._getFormat(params);\n var message;\n\n // Does the provided rule have a custom message?\n if (params.constraint.hasOwnProperty('message')) {\n // The rule has a custom message, return it.\n message = params.constraint.message;\n return this._format(message, format);\n }\n else {\n // The rule does not have a custom message.\n // Get the default message from the tests.\n message = params.test.message;\n return this._format(message, format);\n }\n };\n\n /**\n * Executes the tests based on given rules to validate a given value.
\n * Returns an object with at least two properties:
\n * approved
: Boolean - true
if test succeeded, otherwise false
.
\n * errors
: Array of String - holds a list of formatted errors.\n * @example\n * var result = approve.value('some value', {test: constraints});\n * if (result.approved) {\n * // Value is approved - do something\n * } else {\n * // Do something with the errors\n * result.each(function(error) {\n * console.log(error);\n * });\n * }\n * @param {Object} value - The value to test against the rules.\n * @param {Object} rules - The constraints for the value being tested.\n * @return {Object} The object containing the result of the tests performed.\n * @memberOf approve\n */\n approve.value = function(value, rules) {\n\n // If rules is not an object, we cannot continue.\n if (typeof rules !== 'object') {\n throw 'approve.value(value, rules): rules is not a valid object.';\n }\n // Return the result object.\n return this._start(value, rules);\n };\n\n /**\n * Used to add custom tests.\n * @example\n * var test = {\n * expects: false,\n * message: '{title} did not pass the test.',\n * validate: function(value) {\n * return this.strength(value);\n * },\n * };\n * approve.addTest(test, 'test_name');\n * @param {Object} obj - The test object to add.\n * @param {String} name - The name of the test.\n * @return void\n * @memberOf approve\n */\n approve.addTest = function(obj, name) {\n // If obj is not a valid object, we cannot continue.\n if (typeof obj !== 'object') {\n throw 'approve.addTest(obj, name): obj is not a valid object.';\n }\n try {\n // Check if the test name already exists.\n if (!this.tests.hasOwnProperty(name)) {\n // The name does not exist, add it to the tests.\n this.tests[name] = obj;\n }\n } catch (e) {\n throw 'approve.addTest(): ' + e.message;\n }\n };\n /**\n * The result object containing the outcome of the credit card test.\n */\n function Card() {\n this.scheme = '';\n this.valid = false;\n }\n /** \n * Checks if a value is a valid credit card.\n * @example\n * var rule = {\n * cc: true\n * };\n * approve.value('5105105105105100', rule);\n * @return {Object} An object with various properties relating to the value's score.\n * @function cc\n * @memberOf approve.tests\n * @inner\n */\n var cc = {\n /**\n * The default error message.\n */\n message: '{title} is not a valid credit card number',\n schemes: [\n {\n regex: /^(5610|560221|560222|560223|560224|560225)/,\n scheme: 'Australian Bank Card'\n },\n {\n regex: /^(2014|2149)/,\n scheme: 'Diner\\'s Club'\n },\n {\n regex: /^36/,\n scheme: 'Diner\\'s Club International'\n },\n {\n regex: /^(30[0-5]|36|38|54|55|2014|2149)/,\n scheme: 'Diner\\'s Club / Carte Blanche'\n },\n {\n regex: /^35(2[89]|[3-8][0-9])/,\n scheme: 'Japanese Credit Bureau'\n },\n {\n regex: /^(5018|5020|5038|6304|6759|676[1-3])/,\n scheme: 'Maestro'\n },\n {\n regex: /^5[1-5]/,\n scheme: 'Mastercard'\n },\n {\n regex: /^(6304|670[69]|6771)/,\n scheme: 'Laser'\n },\n {\n regex: /^(6334|6767)/,\n scheme: 'Solo (Paymentech)'\n },\n {\n regex: /^(6011|622|64|65)/,\n scheme: 'Discover'\n },\n {\n regex: /^3[47]/,\n scheme: 'American Express'\n },\n {\n regex: /^(4026|417500|4508|4844|491(3|7))/,\n scheme: 'Visa Electron'\n },\n {\n regex: /^(4)/,\n scheme: 'Visa'\n }\n ],\n /**\n * Returns the name of the credit card scheme.\n * @param {Object} value - The credit card number to test.\n * @return {Object} The result of the test.\n */\n _getScheme: function(value) {\n value = (''+ value).replace(/\\D/g, '');\n\n var i = this.schemes.length;\n while (i--) {\n if (this.schemes[i].regex.test(value)) {\n return this.schemes[i].scheme;\n }\n }\n\n return undefined;\n },\n /**\n * The method that is called by ApproveJs to perform the test.\n * @param {Object} value - The value to test.\n * @return {Object} The result object of the test.\n */\n validate: function(value) {\n value = (''+ value).replace(/\\D/g, '');\n\n var card = new Card(), \n i = value.length,\n sum = 0,\n mul = 1,\n ca;\n\n // Not enough numbers. Shortest currently is 12. \n if (i < 12) {\n return false;\n }\n\n while (i--) {\n ca = value.charAt(i) * mul;\n sum += ca - (ca > 9) * 9;\n mul ^= 3;\n }\n\n card.valid = (sum % 10 === 0) && (sum > 0);\n card.scheme = this._getScheme(value);\n\n return card;\n }\n };\n approve.tests.cc = cc;\n\n /**\n * The result object containing the outcome of the strength test.\n * @param {string} strength - The initial strength.\n */\n function Score(strength) {\n this.strength = strength;\n this.points = 0;\n this.isMinimum = false;\n this.hasLower = false;\n this.hasUpper = false;\n this.hasNumber = false;\n this.hasSpecial = false;\n this.isBonus = false;\n this.percent = 0;\n this.valid = false;\n this.errors = [];\n }\n /** \n * Checks if a value is a strong password string.\n * @example\n * var rule = {\n * strength: {\n * min: 8,\n * bonus: 10\n * }\n * };\n * approve.value('some value', rule);\n * @return {Object} An object with various properties relating to the value's score.\n * @function strength\n * @memberOf approve.tests\n * @inner\n */\n var strength = {\n /**\n * The minimum length a password must be.\n */\n minimum: 8,\n /**\n * The minimum length a password must be for a bonus point.\n */\n minimumBonus: 10,\n /**\n * The text representing the strength of a password.\n */\n strengths: {\n 0: 'Very Weak',\n 1: 'Weak',\n 2: 'Better',\n 3: 'Almost',\n 4: 'Acceptable',\n 5: 'Strong',\n 6: 'Very Strong'\n },\n /**\n * The default error message.\n */\n message: '{title} did not pass the strength test.',\n /**\n * Expects the 'min' and 'bonus' parameters.\n */\n expects: ['min', 'bonus'],\n /**\n * Default error messages\n * @type {Object}\n */\n errors: {\n isMinimum: '{title} must be at least {min} characters',\n hasLower: '{title} must have at least 1 lower case character',\n hasUpper: '{title} must have at least 1 upper case character',\n hasNumber: '{title} must have at least 1 number',\n hasSpecial: '{title} must have at least 1 special character'\n },\n /**\n * Returns an object containing the score of a value.\n * @param {String} text - The text to score.\n * @return {Object} The score of the text.\n */\n _getScore: function(text) {\n // Create the object that represents the score of the text\n var result = new Score(this.strengths[0]);\n // If text is longer than minimum give 1 point.\n // If text is longer than minimumBonus give another 1 point.\n if (text.length > this.minimumBonus) {\n result.points += 2;\n result.isBonus = true;\n result.isMinimum = true;\n } else if (text.length > this.minimum){\n result.points++;\n result.isMinimum = true;\n } else {\n result.points = 1;\n result.isMinimum = false;\n }\n // If text has lowercase characters give 1 point.\n result.hasLower = text.match(/[a-z]/);\n if(result.isMinimum) {\n result.points++;\n }\n // If text has uppercase characters give 1 point.\n result.hasUpper = text.match(/[A-Z]/);\n if(result.isMinimum) {\n result.points++;\n }\n // If text has at least one number give 1 point.\n result.hasNumber = text.match(/\\d+/);\n if(result.isMinimum) {\n result.points++;\n }\n // If text has at least one special caracther give 1 point.\n result.hasSpecial = text.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/);\n if(result.isMinimum) {\n result.points++;\n }\n // Set the percentage value.\n result.percent = Math.ceil((result.points / 6) * 100);\n // Return the score object.\n return result;\n },\n /**\n * Returns an object containing the score and validation of a value.\n * @param {String} text - The text to score.\n * @return {Object} The score and validation of the text.\n */\n _getStrength: function (text) {\n var result = this._getScore(text);\n result.strength = this.strengths[result.points];\n if (!result.isMinimum) {\n result.errors.push(this.errors.isMinimum);\n }\n if (!result.hasLower) {\n result.errors.push(this.errors.hasLower);\n }\n if (!result.hasUpper) {\n result.errors.push(this.errors.hasUpper);\n }\n if (!result.hasSpecial) {\n result.errors.push(this.errors.hasSpecial);\n }\n if (!result.hasNumber) {\n result.errors.push(this.errors.hasNumber);\n }\n if (result.points > 4) {\n result.valid = true;\n } \n return result;\n },\n /**\n * The method that is called by ApproveJs to perform the test.\n * @param {String} value - The value to test.\n * @return {Object} The result object of the test.\n */\n validate: function(value, pars) {\n this.minimum = pars.min || this.minimum;\n this.minimumBonus = pars.bonus || this.minimumBonus;\n if (pars.hasOwnProperty('config') && pars.config.hasOwnProperty('messages')) {\n for (var message in pars.config.messages) {\n if (pars.config.messages.hasOwnProperty(message)) {\n this.errors[message] = pars.config.messages[message];\n }\n }\n }\n return this._getStrength(value);\n }\n };\n approve.tests.strength = strength;\n\n /*\n * Return the main ApproveJs object.\n */\n return approve;\n}));"],"sourceRoot":"/source/"}