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