Created
October 22, 2013 12:47
-
-
Save aluedeke/7100091 to your computer and use it in GitHub Desktop.
Using randomly generated emails
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Chance.js 0.4.3 | |
// http://chancejs.com | |
// (c) 2013 Victor Quinn | |
// Chance may be freely distributed or modified under the MIT license. | |
var window = {}; | |
(function () { | |
// Constructor | |
var MAX_INT = 9007199254740992; | |
var MIN_INT = -MAX_INT; | |
var NUMBERS = '0123456789'; | |
var CHARS_LOWER = 'abcdefghijklmnopqrstuvwxyz'; | |
var CHARS_UPPER = CHARS_LOWER.toUpperCase(); | |
var HEX_POOL = NUMBERS + "abcdef"; | |
var Chance = function (seed) { | |
if (seed !== undefined) { | |
// If we were passed a generator rather than a seed, use it. | |
if (typeof seed === 'function') { | |
this.random = seed; | |
} else { | |
this.seed = seed; | |
} | |
} | |
// If no generator function was provided, use our MT | |
if (typeof this.random === 'undefined') { | |
this.mt = this.mersenne_twister(seed); | |
this.random = function () { | |
return this.mt.random(this.seed); | |
}; | |
} | |
}; | |
// -- Basics -- | |
Chance.prototype.bool = function (options) { | |
// likelihood of success (true) | |
options = initOptions(options, {likelihood : 50}); | |
testRange( | |
options.likelihood < 0 || options.likelihood > 100, | |
"Chance: Likelihood accepts values from 0 to 100." | |
); | |
return this.random() * 100 < options.likelihood; | |
}; | |
// NOTE the max and min are INCLUDED in the range. So: | |
// | |
// chance.natural({min: 1, max: 3}); | |
// | |
// would return either 1, 2, or 3. | |
Chance.prototype.natural = function (options) { | |
// 9007199254740992 (2^53) is the max integer number in JavaScript | |
// See: http://vq.io/132sa2j | |
options = initOptions(options, {min: 0, max: MAX_INT}); | |
testRange(options.min > options.max, "Chance: Min cannot be greater than Max."); | |
return Math.floor(this.random() * (options.max - options.min + 1) + options.min); | |
}; | |
Chance.prototype.integer = function (options) { | |
var num, range; | |
options = initOptions(options, {min : MIN_INT, max : MAX_INT}); | |
// Greatest of absolute value of either max or min so we know we're | |
// including the entire search domain. | |
range = Math.max(Math.abs(options.min), Math.abs(options.max)); | |
// Probably a better way to do this... | |
do { | |
num = this.natural({max: range}); | |
num = this.bool() ? num : num * -1; | |
} while (num < options.min || num > options.max); | |
return num; | |
}; | |
Chance.prototype.normal = function (options) { | |
options = initOptions(options, {mean : 0, dev : 1}); | |
// The Marsaglia Polar method | |
var s, u, v, norm, | |
mean = options.mean, | |
dev = options.dev; | |
do { | |
// U and V are from the uniform distribution on (-1, 1) | |
u = this.random() * 2 - 1; | |
v = this.random() * 2 - 1; | |
s = u * u + v * v; | |
} while (s >= 1); | |
// Compute the standard normal variate | |
norm = u * Math.sqrt(-2 * Math.log(s) / s); | |
// Shape and scale | |
return dev * norm + mean; | |
}; | |
// Note, wanted to use "float" or "double" but those are both JS reserved words. | |
// Note, fixed means N OR LESS digits after the decimal. This because | |
// It could be 14.9000 but in JavaScript, when this is cast as a number, | |
// the trailing zeroes are dropped. Left to the consumer if trailing zeroes are | |
// needed | |
Chance.prototype.floating = function (options) { | |
var num, range; | |
options = initOptions(options, {fixed : 4}); | |
var fixed = Math.pow(10, options.fixed); | |
testRange( | |
options.fixed && options.precision, | |
"Chance: Cannot specify both fixed and precision." | |
); | |
var max = MAX_INT / fixed; | |
var min = -max; | |
testRange( | |
options.min && options.fixed && options.min < min, | |
"Chance: Min specified is out of range with fixed. Min should be, at least, " + min | |
); | |
testRange( | |
options.max && options.fixed && options.max > max, | |
"Chance: Max specified is out of range with fixed. Max should be, at most, " + max | |
); | |
options = initOptions(options, {min : min, max : max}); | |
// Todo - Make this work! | |
// options.precision = (typeof options.precision !== "undefined") ? options.precision : false; | |
num = this.integer({min: options.min * fixed, max: options.max * fixed}); | |
var num_fixed = (num / fixed).toFixed(options.fixed); | |
return parseFloat(num_fixed); | |
}; | |
Chance.prototype.character = function (options) { | |
options = initOptions(options); | |
var symbols = "!@#$%^&*()[]", | |
letters, pool; | |
testRange( | |
options.alpha && options.symbols, | |
"Chance: Cannot specify both alpha and symbols." | |
); | |
if (options.casing === 'lower') { | |
letters = CHARS_LOWER; | |
} else if (options.casing === 'upper') { | |
letters = CHARS_UPPER; | |
} else { | |
letters = CHARS_LOWER + CHARS_UPPER; | |
} | |
if (options.pool) { | |
pool = options.pool; | |
} else if (options.alpha) { | |
pool = letters; | |
} else if (options.symbols) { | |
pool = symbols; | |
} else { | |
pool = letters + NUMBERS + symbols; | |
} | |
return pool.charAt(this.natural({max: (pool.length - 1)})); | |
}; | |
Chance.prototype.string = function (options) { | |
options = initOptions(options); | |
var length = options.length || this.natural({min: 5, max: 20}), | |
text = '', | |
pool = options.pool; | |
for (var i = 0; i < length; i++) { | |
text += this.character({pool: pool}); | |
} | |
return text; | |
}; | |
// -- End Basics -- | |
// -- Helpers -- | |
Chance.prototype.capitalize = function (word) { | |
return word.charAt(0).toUpperCase() + word.substr(1); | |
}; | |
Chance.prototype.pick = function (arr, count) { | |
if (!count || count === 1) { | |
return arr[this.natural({max: arr.length - 1})]; | |
} else { | |
return this.shuffle(arr).slice(0, count); | |
} | |
}; | |
Chance.prototype.shuffle = function (arr) { | |
var old_array = arr.slice(0), | |
new_array = [], | |
j = 0, | |
length = Number(old_array.length); | |
for (var i = 0; i < length; i++) { | |
// Pick a random index from the array | |
j = this.natural({max: old_array.length - 1}); | |
// Add it to the new array | |
new_array[i] = old_array[j]; | |
// Remove that element from the original array | |
old_array.splice(j, 1); | |
} | |
return new_array; | |
}; | |
// -- End Helpers -- | |
// -- Text -- | |
Chance.prototype.paragraph = function (options) { | |
options = initOptions(options); | |
var sentences = options.sentences || this.natural({min: 3, max: 7}), | |
sentence_array = []; | |
for (var i = 0; i < sentences; i++) { | |
sentence_array.push(this.sentence()); | |
} | |
return sentence_array.join(' '); | |
}; | |
// Could get smarter about this than generating random words and | |
// chaining them together. Such as: http://vq.io/1a5ceOh | |
Chance.prototype.sentence = function (options) { | |
options = initOptions(options); | |
var words = options.words || this.natural({min: 12, max: 18}), | |
text, word_array = []; | |
for (var i = 0; i < words; i++) { | |
word_array.push(this.word()); | |
} | |
text = word_array.join(' '); | |
// Capitalize first letter of sentence, add period at end | |
text = this.capitalize(text) + '.'; | |
return text; | |
}; | |
Chance.prototype.syllable = function (options) { | |
options = initOptions(options); | |
var length = options.length || this.natural({min: 2, max: 3}), | |
consanants = 'bcdfghjklmnprstvwz', // consonants except hard to speak ones | |
vowels = 'aeiou', // vowels | |
all = consanants + vowels, // all | |
text = '', | |
chr; | |
// I'm sure there's a more elegant way to do this, but this works | |
// decently well. | |
for (var i = 0; i < length; i++) { | |
if (i === 0) { | |
// First character can be anything | |
chr = this.character({pool: all}); | |
} else if (consanants.indexOf(chr) === -1) { | |
// Last charcter was a vowel, now we want a consanant | |
chr = this.character({pool: consanants}); | |
} else { | |
// Last charcter was a consanant, now we want a vowel | |
chr = this.character({pool: vowels}); | |
} | |
text += chr; | |
} | |
return text; | |
}; | |
Chance.prototype.word = function (options) { | |
options = initOptions(options); | |
testRange( | |
options.syllables && options.length, | |
"Chance: Cannot specify both syllables AND length." | |
); | |
var syllables = options.syllables || this.natural({min: 1, max: 3}), | |
text = ''; | |
if (options.length) { | |
// Either bound word by length | |
do { | |
text += this.syllable(); | |
} while (text.length < options.length); | |
text = text.substring(0, options.length); | |
} else { | |
// Or by number of syllables | |
for (var i = 0; i < syllables; i++) { | |
text += this.syllable(); | |
} | |
} | |
return text; | |
}; | |
// -- End Text -- | |
// -- Name -- | |
// Perhaps make this more intelligent at some point | |
Chance.prototype.first = function () { | |
return this.capitalize(this.word()); | |
}; | |
Chance.prototype.last = function () { | |
return this.capitalize(this.word()); | |
}; | |
Chance.prototype.name = function (options) { | |
options = initOptions(options); | |
var first = this.first(), | |
last = this.last(), | |
name; | |
if (options.middle) { | |
name = first + ' ' + this.capitalize(this.word()) + ' ' + last; | |
} else if (options.middle_initial) { | |
name = first + ' ' + this.character({alpha: true, casing: 'upper'}) + '. ' + last; | |
} else { | |
name = first + ' ' + last; | |
} | |
if (options.prefix) { | |
name = this.prefix() + ' ' + name; | |
} | |
return name; | |
}; | |
Chance.prototype.name_prefixes = function () { | |
return [ | |
{name: 'Doctor', abbreviation: 'Dr.'}, | |
{name: 'Miss', abbreviation: 'Miss'}, | |
{name: 'Misses', abbreviation: 'Mrs.'}, | |
{name: 'Mister', abbreviation: 'Mr.'} | |
]; | |
}; | |
// Alias for name_prefix | |
Chance.prototype.prefix = function (options) { | |
return this.name_prefix(options); | |
}; | |
Chance.prototype.name_prefix = function (options) { | |
options = initOptions(options); | |
return options.full ? | |
this.pick(this.name_prefixes()).name : | |
this.pick(this.name_prefixes()).abbreviation; | |
}; | |
// -- End Name -- | |
// -- Web -- | |
Chance.prototype.color = function (options) { | |
function gray(value, delimiter) { | |
return [value, value, value].join(delimiter || ''); | |
} | |
options = initOptions(options, {format: this.pick(['hex', 'shorthex', 'rgb']), grayscale: false}); | |
var isGrayscale = options.grayscale; | |
if (options.format === 'hex') { | |
return '#' + (isGrayscale ? gray(this.hash({length: 2})) : this.hash({length: 6})); | |
} | |
if (options.format === 'shorthex') { | |
return '#' + (isGrayscale ? gray(this.hash({length: 1})) : this.hash({length: 3})); | |
} | |
if (options.format === 'rgb') { | |
if (isGrayscale) { | |
return 'rgb(' + gray(this.natural({max: 255}), ',') + ')'; | |
} else { | |
return 'rgb(' + this.natural({max: 255}) + ',' + this.natural({max: 255}) + ',' + this.natural({max: 255}) + ')'; | |
} | |
} | |
throw new Error('Invalid format provided. Please provide one of "hex", "shorthex", or "rgb"'); | |
}; | |
Chance.prototype.domain = function (options) { | |
options = initOptions(options); | |
return this.word() + '.' + (options.tld || this.tld()); | |
}; | |
Chance.prototype.email = function (options) { | |
options = initOptions(options); | |
return this.word() + '@' + (options.domain || this.domain()); | |
}; | |
Chance.prototype.fbid = function () { | |
return '10000' + this.natural({max: 100000000000}).toString(); | |
}; | |
Chance.prototype.ip = function () { | |
// Todo: This could return some reserved IPs. See http://vq.io/137dgYy | |
// this should probably be updated to account for that rare as it may be | |
return this.natural({max: 255}) + '.' + | |
this.natural({max: 255}) + '.' + | |
this.natural({max: 255}) + '.' + | |
this.natural({max: 255}); | |
}; | |
Chance.prototype.ipv6 = function () { | |
var ip_addr = ""; | |
for (var i = 0; i < 8; i++) { | |
ip_addr += this.hash({length: 4}) + ':'; | |
} | |
return ip_addr.substr(0, ip_addr.length - 1); | |
}; | |
Chance.prototype.tlds = function () { | |
return ['com', 'org', 'edu', 'gov', 'co.uk', 'net', 'io']; | |
}; | |
Chance.prototype.tld = function () { | |
return this.pick(this.tlds()); | |
}; | |
Chance.prototype.twitter = function () { | |
return '@' + this.word(); | |
}; | |
// -- End Web -- | |
// -- Address -- | |
Chance.prototype.address = function (options) { | |
options = initOptions(options); | |
return this.natural({min: 5, max: 2000}) + ' ' + this.street(options); | |
}; | |
Chance.prototype.areacode = function (options) { | |
options = initOptions(options, {parens : true}); | |
// Don't want area codes to start with 1, or have a 9 as the second digit | |
var areacode = this.natural({min: 2, max: 9}).toString() + this.natural({min: 0, max: 8}).toString() + this.natural({min: 0, max: 9}).toString(); | |
return options.parens ? '(' + areacode + ')' : areacode; | |
}; | |
Chance.prototype.city = function () { | |
return this.capitalize(this.word({syllables: 3})); | |
}; | |
Chance.prototype.coordinates = function (options) { | |
options = initOptions(options); | |
return this.latitude(options) + ', ' + this.longitude(options); | |
}; | |
Chance.prototype.latitude = function (options) { | |
options = initOptions(options, {fixed : 5}); | |
return this.floating({min: -90, max: 90, fixed: options.fixed}); | |
}; | |
Chance.prototype.longitude = function (options) { | |
options = initOptions(options, {fixed : 5}); | |
return this.floating({min: 0, max: 180, fixed: options.fixed}); | |
}; | |
Chance.prototype.phone = function (options) { | |
options = initOptions(options, {formatted : true}); | |
if (!options.formatted) { | |
options.parens = false; | |
} | |
var areacode = this.areacode(options).toString(); | |
var exchange = this.natural({min: 2, max: 9}).toString() + this.natural({min: 0, max: 9}).toString() + this.natural({min: 0, max: 9}).toString(); | |
var subscriber = this.natural({min: 1000, max: 9999}).toString(); // this could be random [0-9]{4} | |
return options.formatted ? areacode + ' ' + exchange + '-' + subscriber : areacode + exchange + subscriber; | |
}; | |
Chance.prototype.postal = function () { | |
// Postal District | |
var pd = this.character({pool: "XVTSRPNKLMHJGECBA"}); | |
// Forward Sortation Area (FSA) | |
var fsa = pd + this.natural({max: 9}) + this.character({alpha: true, casing: "upper"}); | |
// Local Delivery Unut (LDU) | |
var ldu = this.natural({max: 9}) + this.character({alpha: true, casing: "upper"}) + this.natural({max: 9}); | |
return fsa + " " + ldu; | |
}; | |
Chance.prototype.provinces = function () { | |
return [ | |
{name: 'Alberta', abbreviation: 'AB'}, | |
{name: 'British Columbia', abbreviation: 'BC'}, | |
{name: 'Manitoba', abbreviation: 'MB'}, | |
{name: 'New Brunswick', abbreviation: 'NB'}, | |
{name: 'Newfoundland and Labrador', abbreviation: 'NL'}, | |
{name: 'Nova Scotia', abbreviation: 'NS'}, | |
{name: 'Ontario', abbreviation: 'ON'}, | |
{name: 'Prince Edward Island', abbreviation: 'PE'}, | |
{name: 'Quebec', abbreviation: 'QC'}, | |
{name: 'Saskatchewan', abbreviation: 'SK'}, | |
// The case could be made that the following are not actually provinces | |
// since they are technically considered "territories" however they all | |
// look the same on an envelope! | |
{name: 'Northwest Territories', abbreviation: 'NT'}, | |
{name: 'Nunavut', abbreviation: 'NU'}, | |
{name: 'Yukon', abbreviation: 'YT'} | |
]; | |
}; | |
Chance.prototype.province = function (options) { | |
return (options && options.full) ? | |
this.pick(this.provinces()).name : | |
this.pick(this.provinces()).abbreviation; | |
}; | |
Chance.prototype.radio = function (options) { | |
// Initial Letter (Typically Designated by Side of Mississippi River) | |
options = initOptions(options, {side : "?"}); | |
var fl = ""; | |
switch (options.side.toLowerCase()) { | |
case "east": | |
case "e": | |
fl = "W"; | |
break; | |
case "west": | |
case "w": | |
fl = "K"; | |
break; | |
default: | |
fl = this.character({pool: "KW"}); | |
break; | |
} | |
return fl + this.character({alpha: true, casing: "upper"}) + this.character({alpha: true, casing: "upper"}) + this.character({alpha: true, casing: "upper"}); | |
}; | |
Chance.prototype.state = function (options) { | |
return (options && options.full) ? | |
this.pick(this.states()).name : | |
this.pick(this.states()).abbreviation; | |
}; | |
Chance.prototype.states = function () { | |
return [ | |
{name: 'Alabama', abbreviation: 'AL'}, | |
{name: 'Alaska', abbreviation: 'AK'}, | |
{name: 'American Samoa', abbreviation: 'AS'}, | |
{name: 'Arizona', abbreviation: 'AZ'}, | |
{name: 'Arkansas', abbreviation: 'AR'}, | |
{name: 'Armed Forces Europe', abbreviation: 'AE'}, | |
{name: 'Armed Forces Pacific', abbreviation: 'AP'}, | |
{name: 'Armed Forces the Americas', abbreviation: 'AA'}, | |
{name: 'California', abbreviation: 'CA'}, | |
{name: 'Colorado', abbreviation: 'CO'}, | |
{name: 'Connecticut', abbreviation: 'CT'}, | |
{name: 'Delaware', abbreviation: 'DE'}, | |
{name: 'District of Columbia', abbreviation: 'DC'}, | |
{name: 'Federated States of Micronesia', abbreviation: 'FM'}, | |
{name: 'Florida', abbreviation: 'FL'}, | |
{name: 'Georgia', abbreviation: 'GA'}, | |
{name: 'Guam', abbreviation: 'GU'}, | |
{name: 'Hawaii', abbreviation: 'HI'}, | |
{name: 'Idaho', abbreviation: 'ID'}, | |
{name: 'Illinois', abbreviation: 'IL'}, | |
{name: 'Indiana', abbreviation: 'IN'}, | |
{name: 'Iowa', abbreviation: 'IA'}, | |
{name: 'Kansas', abbreviation: 'KS'}, | |
{name: 'Kentucky', abbreviation: 'KY'}, | |
{name: 'Louisiana', abbreviation: 'LA'}, | |
{name: 'Maine', abbreviation: 'ME'}, | |
{name: 'Marshall Islands', abbreviation: 'MH'}, | |
{name: 'Maryland', abbreviation: 'MD'}, | |
{name: 'Massachusetts', abbreviation: 'MA'}, | |
{name: 'Michigan', abbreviation: 'MI'}, | |
{name: 'Minnesota', abbreviation: 'MN'}, | |
{name: 'Mississippi', abbreviation: 'MS'}, | |
{name: 'Missouri', abbreviation: 'MO'}, | |
{name: 'Montana', abbreviation: 'MT'}, | |
{name: 'Nebraska', abbreviation: 'NE'}, | |
{name: 'Nevada', abbreviation: 'NV'}, | |
{name: 'New Hampshire', abbreviation: 'NH'}, | |
{name: 'New Jersey', abbreviation: 'NJ'}, | |
{name: 'New Mexico', abbreviation: 'NM'}, | |
{name: 'New York', abbreviation: 'NY'}, | |
{name: 'North Carolina', abbreviation: 'NC'}, | |
{name: 'North Dakota', abbreviation: 'ND'}, | |
{name: 'Northern Mariana Islands', abbreviation: 'MP'}, | |
{name: 'Ohio', abbreviation: 'OH'}, | |
{name: 'Oklahoma', abbreviation: 'OK'}, | |
{name: 'Oregon', abbreviation: 'OR'}, | |
{name: 'Pennsylvania', abbreviation: 'PA'}, | |
{name: 'Puerto Rico', abbreviation: 'PR'}, | |
{name: 'Rhode Island', abbreviation: 'RI'}, | |
{name: 'South Carolina', abbreviation: 'SC'}, | |
{name: 'South Dakota', abbreviation: 'SD'}, | |
{name: 'Tennessee', abbreviation: 'TN'}, | |
{name: 'Texas', abbreviation: 'TX'}, | |
{name: 'Utah', abbreviation: 'UT'}, | |
{name: 'Vermont', abbreviation: 'VT'}, | |
{name: 'Virgin Islands, U.S.', abbreviation: 'VI'}, | |
{name: 'Virginia', abbreviation: 'VA'}, | |
{name: 'Washington', abbreviation: 'WA'}, | |
{name: 'West Virginia', abbreviation: 'WV'}, | |
{name: 'Wisconsin', abbreviation: 'WI'}, | |
{name: 'Wyoming', abbreviation: 'WY'} | |
]; | |
}; | |
Chance.prototype.street = function (options) { | |
options = initOptions(options); | |
var street = this.word({syllables: 2}); | |
street = this.capitalize(street); | |
street += ' '; | |
street += options.short_suffix ? | |
this.street_suffix().abbreviation : | |
this.street_suffix().name; | |
return street; | |
}; | |
Chance.prototype.street_suffix = function () { | |
return this.pick(this.street_suffixes()); | |
}; | |
Chance.prototype.street_suffixes = function () { | |
// These are the most common suffixes. | |
return [ | |
{name: 'Avenue', abbreviation: 'Ave'}, | |
{name: 'Boulevard', abbreviation: 'Blvd'}, | |
{name: 'Center', abbreviation: 'Ctr'}, | |
{name: 'Circle', abbreviation: 'Cir'}, | |
{name: 'Court', abbreviation: 'Ct'}, | |
{name: 'Drive', abbreviation: 'Dr'}, | |
{name: 'Extension', abbreviation: 'Ext'}, | |
{name: 'Glen', abbreviation: 'Gln'}, | |
{name: 'Grove', abbreviation: 'Grv'}, | |
{name: 'Heights', abbreviation: 'Hts'}, | |
{name: 'Highway', abbreviation: 'Hwy'}, | |
{name: 'Junction', abbreviation: 'Jct'}, | |
{name: 'Key', abbreviation: 'Key'}, | |
{name: 'Lane', abbreviation: 'Ln'}, | |
{name: 'Loop', abbreviation: 'Loop'}, | |
{name: 'Manor', abbreviation: 'Mnr'}, | |
{name: 'Mill', abbreviation: 'Mill'}, | |
{name: 'Park', abbreviation: 'Park'}, | |
{name: 'Parkway', abbreviation: 'Pkwy'}, | |
{name: 'Pass', abbreviation: 'Pass'}, | |
{name: 'Path', abbreviation: 'Path'}, | |
{name: 'Pike', abbreviation: 'Pike'}, | |
{name: 'Place', abbreviation: 'Pl'}, | |
{name: 'Plaza', abbreviation: 'Plz'}, | |
{name: 'Point', abbreviation: 'Pt'}, | |
{name: 'Ridge', abbreviation: 'Rdg'}, | |
{name: 'River', abbreviation: 'Riv'}, | |
{name: 'Road', abbreviation: 'Rd'}, | |
{name: 'Square', abbreviation: 'Sq'}, | |
{name: 'Street', abbreviation: 'St'}, | |
{name: 'Terrace', abbreviation: 'Ter'}, | |
{name: 'Trail', abbreviation: 'Trl'}, | |
{name: 'Turnpike', abbreviation: 'Tpke'}, | |
{name: 'View', abbreviation: 'Vw'}, | |
{name: 'Way', abbreviation: 'Way'} | |
]; | |
}; | |
// Note: only returning US zip codes, internationalization will be a whole | |
// other beast to tackle at some point. | |
Chance.prototype.zip = function (options) { | |
var zip = ""; | |
for (var i = 0; i < 5; i++) { | |
zip += this.natural({max: 9}).toString(); | |
} | |
if (options && options.plusfour === true) { | |
zip += '-'; | |
for (i = 0; i < 4; i++) { | |
zip += this.natural({max: 9}).toString(); | |
} | |
} | |
return zip; | |
}; | |
// -- End Address -- | |
// -- Time | |
Chance.prototype.ampm = function () { | |
return this.bool() ? 'am' : 'pm'; | |
}; | |
Chance.prototype.hour = function (options) { | |
options = initOptions(options); | |
var max = options.twentyfour ? 24 : 12; | |
return this.natural({min: 1, max: max}); | |
}; | |
Chance.prototype.minute = function () { | |
return this.natural({max: 59}); | |
}; | |
Chance.prototype.month = function (options) { | |
options = initOptions(options); | |
var month = this.pick(this.months()); | |
return options.raw ? month : month.name; | |
}; | |
Chance.prototype.months = function () { | |
return [ | |
{name: 'January', short_name: 'Jan', numeric: '01'}, | |
{name: 'February', short_name: 'Feb', numeric: '02'}, | |
{name: 'March', short_name: 'Mar', numeric: '03'}, | |
{name: 'April', short_name: 'Apr', numeric: '04'}, | |
{name: 'May', short_name: 'May', numeric: '05'}, | |
{name: 'June', short_name: 'Jun', numeric: '06'}, | |
{name: 'July', short_name: 'Jul', numeric: '07'}, | |
{name: 'August', short_name: 'Aug', numeric: '08'}, | |
{name: 'September', short_name: 'Sep', numeric: '09'}, | |
{name: 'October', short_name: 'Oct', numeric: '10'}, | |
{name: 'November', short_name: 'Nov', numeric: '11'}, | |
{name: 'December', short_name: 'Dec', numeric: '12'} | |
]; | |
}; | |
Chance.prototype.second = function () { | |
return this.natural({max: 59}); | |
}; | |
Chance.prototype.timestamp = function () { | |
return this.natural({min: 1, max: parseInt(new Date().getTime() / 1000, 10)}); | |
}; | |
Chance.prototype.year = function (options) { | |
// Default to current year as min if none specified | |
options = initOptions(options, {min: new Date().getFullYear()}); | |
// Default to one century after current year as max if none specified | |
options.max = (typeof options.max !== "undefined") ? options.max : options.min + 100; | |
return this.natural(options).toString(); | |
}; | |
// -- End Time | |
// -- Finance -- | |
Chance.prototype.cc = function (options) { | |
options = initOptions(options); | |
var type, number, to_generate, type_name; | |
type = (options.type) ? | |
this.cc_type({ name: options.type, raw: true }) : | |
this.cc_type({ raw: true }); | |
number = type.prefix.split(""); | |
to_generate = type.length - type.prefix.length - 1; | |
// Generates n - 1 digits | |
for (var i = 0; i < to_generate; i++) { | |
number.push(this.integer({min: 0, max: 9})); | |
} | |
// Generates the last digit according to Luhn algorithm | |
number.push(this.luhn_calculate(number.join(""))); | |
return number.join(""); | |
}; | |
Chance.prototype.cc_types = function () { | |
// http://en.wikipedia.org/wiki/Bank_card_number#Issuer_identification_number_.28IIN.29 | |
return [ | |
{name: "American Express", short_name: 'amex', prefix: '34', length: 15}, | |
{name: "Bankcard", short_name: 'bankcard', prefix: '5610', length: 16}, | |
{name: "China UnionPay", short_name: 'chinaunion', prefix: '62', length: 16}, | |
{name: "Diners Club Carte Blanche", short_name: 'dccarte', prefix: '300', length: 14}, | |
{name: "Diners Club enRoute", short_name: 'dcenroute', prefix: '2014', length: 15}, | |
{name: "Diners Club International", short_name: 'dcintl', prefix: '36', length: 14}, | |
{name: "Diners Club United States & Canada", short_name: 'dcusc', prefix: '54', length: 16}, | |
{name: "Discover Card", short_name: 'discover', prefix: '6011', length: 16}, | |
{name: "InstaPayment", short_name: 'instapay', prefix: '637', length: 16}, | |
{name: "JCB", short_name: 'jcb', prefix: '3528', length: 16}, | |
{name: "Laser", short_name: 'laser', prefix: '6304', length: 16}, | |
{name: "Maestro", short_name: 'maestro', prefix: '5018', length: 16}, | |
{name: "Mastercard", short_name: 'mc', prefix: '51', length: 16}, | |
{name: "Solo", short_name: 'solo', prefix: '6334', length: 16}, | |
{name: "Switch", short_name: 'switch', prefix: '4903', length: 16}, | |
{name: "Visa", short_name: 'visa', prefix: '4', length: 16}, | |
{name: "Visa Electron", short_name: 'electron', prefix: '4026', length: 16} | |
]; | |
}; | |
Chance.prototype.cc_type = function (options) { | |
options = initOptions(options); | |
var types = this.cc_types(), | |
type = null; | |
if (options.name) { | |
for (var i = 0; i < types.length; i++) { | |
// Accept either name or short_name to specify card type | |
if (types[i].name === options.name || types[i].short_name === options.name) { | |
type = types[i]; | |
break; | |
} | |
} | |
if (type === null) { | |
throw new Error("Credit card type '" + options.name + "'' is not suppoted"); | |
} | |
} else { | |
type = this.pick(types); | |
} | |
return options.raw ? type : type.name; | |
}; | |
Chance.prototype.dollar = function (options) { | |
// By default, a somewhat more sane max for dollar than all available numbers | |
options = initOptions(options, {max : 10000, min : 0}); | |
var dollar = this.floating({min: options.min, max: options.max, fixed: 2}).toString(), | |
cents = dollar.split('.')[1]; | |
if (cents === undefined) { | |
dollar += '.00'; | |
} else if (cents.length < 2) { | |
dollar = dollar + '0'; | |
} | |
return '$' + dollar; | |
}; | |
Chance.prototype.exp = function (options) { | |
options = initOptions(options); | |
var exp = {}; | |
exp.year = this.exp_year(); | |
// If the year is this year, need to ensure month is greater than the | |
// current month or this expiration will not be valid | |
if (exp.year === (new Date().getFullYear())) { | |
exp.month = this.exp_month({future: true}); | |
} else { | |
exp.month = this.exp_month(); | |
} | |
return options.raw ? exp : exp.month + '/' + exp.year; | |
}; | |
Chance.prototype.exp_month = function (options) { | |
options = initOptions(options); | |
var month, month_int; | |
if (options.future) { | |
do { | |
month = this.month({raw: true}).numeric; | |
month_int = parseInt(month, 10); | |
} while (month_int < new Date().getMonth()); | |
} else { | |
month = this.month({raw: true}).numeric; | |
} | |
return month; | |
}; | |
Chance.prototype.exp_year = function () { | |
return this.year({max: new Date().getFullYear() + 10}); | |
}; | |
// -- End Finance | |
// -- Miscellaneous -- | |
// Dice - For all the board game geeks out there, myself included ;) | |
Chance.prototype.d4 = function () { return this.natural({min: 1, max: 4}); }; | |
Chance.prototype.d6 = function () { return this.natural({min: 1, max: 6}); }; | |
Chance.prototype.d8 = function () { return this.natural({min: 1, max: 8}); }; | |
Chance.prototype.d10 = function () { return this.natural({min: 1, max: 10}); }; | |
Chance.prototype.d12 = function () { return this.natural({min: 1, max: 12}); }; | |
Chance.prototype.d20 = function () { return this.natural({min: 1, max: 20}); }; | |
Chance.prototype.d30 = function () { return this.natural({min: 1, max: 30}); }; | |
Chance.prototype.d100 = function () { return this.natural({min: 1, max: 100}); }; | |
Chance.prototype.rpg = function (thrown, options) { | |
options = initOptions(options); | |
if (thrown === null) { | |
throw new Error("A type of die roll must be included"); | |
} else { | |
var bits = thrown.toLowerCase().split("d"), | |
rolls = []; | |
if (bits.length !== 2 || !parseInt(bits[0], 10) || !parseInt(bits[1], 10)) { | |
throw new Error("Invalid format provided. Please provide #d# where the first # is the number of dice to roll, the second # is the max of each die"); | |
} | |
for (var i = bits[0]; i > 0; i--) { | |
rolls[i - 1] = this.natural({min: 1, max: bits[1]}); | |
} | |
return (typeof options.sum !== 'undefined' && options.sum) ? rolls.reduce(function (p, c) { return p + c; }) : rolls; | |
} | |
}; | |
// Guid | |
Chance.prototype.guid = function () { | |
return this.hash({casing: 'upper', length: 8}) + '-' + | |
this.hash({casing: 'upper', length: 4}) + '-' + | |
this.hash({casing: 'upper', length: 4}) + '-' + | |
this.hash({casing: 'upper', length: 4}) + '-' + | |
this.hash({casing: 'upper', length: 12}); | |
}; | |
// Hash | |
Chance.prototype.hash = function (options) { | |
options = initOptions(options, {length : 40, casing: 'lower'}); | |
var pool = options.casing === 'upper' ? HEX_POOL.toUpperCase() : HEX_POOL; | |
return this.string({pool: pool, length: options.length}); | |
}; | |
Chance.prototype.mersenne_twister = function (seed) { | |
return new MersenneTwister(seed); | |
}; | |
Chance.prototype.luhn_check = function (num) { | |
var str = num.toString(); | |
var checkDigit = +str.substring(str.length - 1); | |
return checkDigit === this.luhn_calculate(+str.substring(0, str.length - 1)); | |
}; | |
Chance.prototype.luhn_calculate = function (num) { | |
var digits = num.toString().split("").reverse(); | |
var sum = 0; | |
for (var i = 0, l = digits.length; l > i; ++i) { | |
var digit = +digits[i]; | |
if (i % 2 === 0) { | |
digit *= 2; | |
if (digit > 9) { | |
digit -= 9; | |
} | |
} | |
sum += digit; | |
} | |
return (sum * 9) % 10; | |
}; | |
// -- End Miscellaneous -- | |
Chance.prototype.VERSION = "0.4.3"; | |
// Mersenne Twister from https://gist.github.com/banksean/300494 | |
var MersenneTwister = function (seed) { | |
if (seed === undefined) { | |
seed = new Date().getTime(); | |
} | |
/* Period parameters */ | |
this.N = 624; | |
this.M = 397; | |
this.MATRIX_A = 0x9908b0df; /* constant vector a */ | |
this.UPPER_MASK = 0x80000000; /* most significant w-r bits */ | |
this.LOWER_MASK = 0x7fffffff; /* least significant r bits */ | |
this.mt = new Array(this.N); /* the array for the state vector */ | |
this.mti = this.N + 1; /* mti==N + 1 means mt[N] is not initialized */ | |
this.init_genrand(seed); | |
}; | |
/* initializes mt[N] with a seed */ | |
MersenneTwister.prototype.init_genrand = function (s) { | |
this.mt[0] = s >>> 0; | |
for (this.mti = 1; this.mti < this.N; this.mti++) { | |
s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30); | |
this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) + this.mti; | |
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ | |
/* In the previous versions, MSBs of the seed affect */ | |
/* only MSBs of the array mt[]. */ | |
/* 2002/01/09 modified by Makoto Matsumoto */ | |
this.mt[this.mti] >>>= 0; | |
/* for >32 bit machines */ | |
} | |
}; | |
/* initialize by an array with array-length */ | |
/* init_key is the array for initializing keys */ | |
/* key_length is its length */ | |
/* slight change for C++, 2004/2/26 */ | |
MersenneTwister.prototype.init_by_array = function (init_key, key_length) { | |
var i = 1, j = 0, k, s; | |
this.init_genrand(19650218); | |
k = (this.N > key_length ? this.N : key_length); | |
for (; k; k--) { | |
s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); | |
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) + init_key[j] + j; /* non linear */ | |
this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ | |
i++; | |
j++; | |
if (i >= this.N) { this.mt[0] = this.mt[this.N - 1]; i = 1; } | |
if (j >= key_length) { j = 0; } | |
} | |
for (k = this.N - 1; k; k--) { | |
s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); | |
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) - i; /* non linear */ | |
this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ | |
i++; | |
if (i >= this.N) { this.mt[0] = this.mt[this.N - 1]; i = 1; } | |
} | |
this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ | |
}; | |
/* generates a random number on [0,0xffffffff]-interval */ | |
MersenneTwister.prototype.genrand_int32 = function () { | |
var y; | |
var mag01 = new Array(0x0, this.MATRIX_A); | |
/* mag01[x] = x * MATRIX_A for x=0,1 */ | |
if (this.mti >= this.N) { /* generate N words at one time */ | |
var kk; | |
if (this.mti === this.N + 1) { /* if init_genrand() has not been called, */ | |
this.init_genrand(5489); /* a default initial seed is used */ | |
} | |
for (kk = 0; kk < this.N - this.M; kk++) { | |
y = (this.mt[kk]&this.UPPER_MASK)|(this.mt[kk + 1]&this.LOWER_MASK); | |
this.mt[kk] = this.mt[kk + this.M] ^ (y >>> 1) ^ mag01[y & 0x1]; | |
} | |
for (;kk < this.N - 1; kk++) { | |
y = (this.mt[kk]&this.UPPER_MASK)|(this.mt[kk + 1]&this.LOWER_MASK); | |
this.mt[kk] = this.mt[kk + (this.M - this.N)] ^ (y >>> 1) ^ mag01[y & 0x1]; | |
} | |
y = (this.mt[this.N - 1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK); | |
this.mt[this.N - 1] = this.mt[this.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1]; | |
this.mti = 0; | |
} | |
y = this.mt[this.mti++]; | |
/* Tempering */ | |
y ^= (y >>> 11); | |
y ^= (y << 7) & 0x9d2c5680; | |
y ^= (y << 15) & 0xefc60000; | |
y ^= (y >>> 18); | |
return y >>> 0; | |
}; | |
/* generates a random number on [0,0x7fffffff]-interval */ | |
MersenneTwister.prototype.genrand_int31 = function () { | |
return (this.genrand_int32() >>> 1); | |
}; | |
/* generates a random number on [0,1]-real-interval */ | |
MersenneTwister.prototype.genrand_real1 = function () { | |
return this.genrand_int32() * (1.0 / 4294967295.0); | |
/* divided by 2^32-1 */ | |
}; | |
/* generates a random number on [0,1)-real-interval */ | |
MersenneTwister.prototype.random = function () { | |
return this.genrand_int32() * (1.0 / 4294967296.0); | |
/* divided by 2^32 */ | |
}; | |
/* generates a random number on (0,1)-real-interval */ | |
MersenneTwister.prototype.genrand_real3 = function () { | |
return (this.genrand_int32() + 0.5) * (1.0 / 4294967296.0); | |
/* divided by 2^32 */ | |
}; | |
/* generates a random number on [0,1) with 53-bit resolution*/ | |
MersenneTwister.prototype.genrand_res53 = function () { | |
var a = this.genrand_int32()>>>5, b = this.genrand_int32()>>>6; | |
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); | |
}; | |
// CommonJS module | |
if (typeof exports !== 'undefined') { | |
if (typeof module !== 'undefined' && module.exports) { | |
exports = module.exports = Chance; | |
} | |
exports.Chance = Chance; | |
} | |
// Register as a named AMD module | |
if (typeof define === 'function' && define.amd) { | |
define('Chance', [], function () { | |
return Chance; | |
}); | |
} | |
// If there is a window object, that at least has a document property, | |
// instantiate and define chance on the window | |
window.Chance = Chance; | |
window.chance = new Chance(); | |
function initOptions(options, defaults) { | |
options || (options = {}); | |
if (!defaults) { | |
return options; | |
} | |
for (var i in defaults) { | |
if (typeof options[i] === 'undefined') { | |
options[i] = defaults[i]; | |
} | |
} | |
return options; | |
} | |
function testRange(test, errorMessage) { | |
if (test) { | |
throw new RangeError(errorMessage); | |
} | |
} | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
importScript(24) // chance.js | |
var randomMail = window.chance.email({domain: 'example.com'}); | |
launchDefaultApp() | |
click(image(62).before().box(366, 46, 104, 56).offset(84, 34), image(62)) | |
click(image(63).before().box(23, 588, 433, 79).offset(354, 33), image(63)) | |
type('Andreas', image(64)) | |
click(image(65).before().box(4, 276, 472, 69).offset(304, 31), image(65)) | |
type(randomMail, image(66)) | |
click(image(67).before().box(4, 382, 472, 69).offset(173, 38), image(67)) | |
type('abcd1234', image(68)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment