mirror of
https://github.com/gabemart/hipku.git
synced 2024-10-05 18:30:54 +01:00
1535 lines
23 KiB
JavaScript
1535 lines
23 KiB
JavaScript
/*
|
|
** Hipku version 0.0.1
|
|
** By Gabriel Martin
|
|
** http://gabrielmartin.net
|
|
*/
|
|
;
|
|
var Hipku = (function() {
|
|
/*
|
|
** ##############
|
|
** Public Methods
|
|
** ##############
|
|
*/
|
|
|
|
/*
|
|
** Object holds all public methods and is returned by the module
|
|
*/
|
|
var publicMethods = {};
|
|
|
|
/*
|
|
** Public method to encode IP Addresses as haiku
|
|
*/
|
|
var encode = function(ip) {
|
|
var ipv6, decimalOctetArray, factoredOctetArray, encodedWordArray,
|
|
haikuText;
|
|
|
|
ipv6 = ipIsIpv6(ip);
|
|
decimalOctetArray = splitIp(ip, ipv6);
|
|
factoredOctetArray = factorOctets(decimalOctetArray, ipv6);
|
|
encodedWordArray = encodeWords(factoredOctetArray, ipv6);
|
|
haikuText = writeHaiku(encodedWordArray, ipv6);
|
|
|
|
return haikuText;
|
|
};
|
|
|
|
/*
|
|
** Public method to decode haiku into IP Addresses
|
|
*/
|
|
var decode = function(haiku) {
|
|
var wordArray, ipv6, factorArray, octetArray, ipString;
|
|
|
|
wordArray = splitHaiku(haiku);
|
|
ipv6 = haikuIsIpv6(wordArray);
|
|
factorArray = getFactors(wordArray, ipv6);
|
|
octetArray = getOctets(factorArray, ipv6);
|
|
ipString = getIpString(octetArray, ipv6);
|
|
|
|
return ipString;
|
|
};
|
|
|
|
/*
|
|
** Attach the public methods to the return object
|
|
*/
|
|
publicMethods.encode = encode;
|
|
publicMethods.decode = decode;
|
|
|
|
/*
|
|
** #############################
|
|
** Helper functions for encoding
|
|
** #############################
|
|
*/
|
|
|
|
function ipIsIpv6(ip) {
|
|
if (ip.indexOf(':') != -1) { return true; }
|
|
else if (ip.indexOf('.') != -1) { return false; }
|
|
else {
|
|
throw new Error('Formatting error in IP Address input.' +
|
|
' ' + 'Contains neither ":" or "."');
|
|
}
|
|
}
|
|
|
|
function splitIp(ip, ipv6) {
|
|
var octetArray, separator, v6Base, numOctets, decimalOctetArray;
|
|
|
|
octetArray = [];
|
|
decimalOctetArray = [];
|
|
v6Base = 16;
|
|
|
|
if (ipv6) {
|
|
separator = ':';
|
|
numOctets = 8;
|
|
} else {
|
|
separator = '.';
|
|
numOctets = 4;
|
|
}
|
|
|
|
/*
|
|
** Remove newline and space characters
|
|
*/
|
|
ip = ip.replace(/[\n\ ]/g, '');
|
|
octetArray = ip.split(separator);
|
|
|
|
/*
|
|
** If IPv6 address is in abbreviated format, we need to replace missing octets with 0
|
|
*/
|
|
if (octetArray.length < numOctets) {
|
|
if (ipv6) {
|
|
var numMissingOctets = (numOctets - octetArray.length);
|
|
|
|
octetArray = padOctets(octetArray, numMissingOctets);
|
|
} else {
|
|
throw new Error('Formatting error in IP Address input.' +
|
|
' ' + 'IPv4 address has fewer than 4 octets.');
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Conter IPv6 addresses from hex to decimal
|
|
*/
|
|
if (ipv6) {
|
|
for (var i = 0; i < octetArray.length; i++) {
|
|
decimalOctetArray[i] = parseInt(octetArray[i], v6Base);
|
|
}
|
|
} else {
|
|
decimalOctetArray = octetArray;
|
|
}
|
|
|
|
return decimalOctetArray;
|
|
}
|
|
|
|
/*
|
|
** If IPv6 is abbreviated, pad with appropriate number of 0 octets
|
|
*/
|
|
function padOctets(octetArray, numMissingOctets) {
|
|
var paddedOctet, aLength;
|
|
|
|
paddedOctet = 0;
|
|
aLength = octetArray.length;
|
|
|
|
/*
|
|
** If the first or last octets are blank, zero them
|
|
*/
|
|
if (octetArray[0] === '') {
|
|
octetArray[0] = paddedOctet;
|
|
}
|
|
if (octetArray[aLength - 1] === '') {
|
|
octetArray[aLength - 1] = paddedOctet;
|
|
}
|
|
|
|
/*
|
|
** Check the rest of the array for blank octets and pad as needed
|
|
*/
|
|
for (var i = 0; i < aLength; i++) {
|
|
if (octetArray[i] === '') {
|
|
octetArray[i] = paddedOctet;
|
|
|
|
for (var j = 0; j < numMissingOctets; j++) {
|
|
octetArray.splice(i, 0, paddedOctet);
|
|
}
|
|
}
|
|
}
|
|
|
|
return octetArray;
|
|
}
|
|
|
|
/*
|
|
** Convert each decimal octet into a factor of the divisor (16 or 256)
|
|
** and a remainder
|
|
*/
|
|
function factorOctets(octetArray, ipv6) {
|
|
var divisor, factoredOctetArray;
|
|
|
|
factoredOctetArray = [];
|
|
|
|
if (ipv6) {
|
|
divisor = 256;
|
|
} else {
|
|
divisor = 16;
|
|
}
|
|
|
|
for (var i = 0; i < octetArray.length; i++) {
|
|
var octetValue, factor1, factor2;
|
|
|
|
octetValue = octetArray[i];
|
|
|
|
factor1 = octetArray[i] % divisor;
|
|
octetValue = octetValue - factor1;
|
|
factor2 = octetValue / divisor;
|
|
|
|
factoredOctetArray.push(factor2);
|
|
factoredOctetArray.push(factor1);
|
|
}
|
|
|
|
return factoredOctetArray;
|
|
}
|
|
|
|
function encodeWords(factorArray, ipv6) {
|
|
var key, encodedWordArray;
|
|
|
|
encodedWordArray = [];
|
|
key = getKey(ipv6);
|
|
|
|
for (var i = 0; i < factorArray.length; i++) {
|
|
var dict;
|
|
|
|
dict = key[i];
|
|
encodedWordArray[i] = dict[factorArray[i]];
|
|
}
|
|
|
|
return encodedWordArray;
|
|
}
|
|
|
|
|
|
/*
|
|
** Return an array of dictionaries representing the correct word
|
|
** order for the haiku
|
|
*/
|
|
function getKey(ipv6) {
|
|
var key;
|
|
|
|
if (ipv6) {
|
|
key = [ adjectives,
|
|
nouns,
|
|
adjectives,
|
|
nouns,
|
|
verbs,
|
|
adjectives,
|
|
adjectives,
|
|
adjectives,
|
|
adjectives,
|
|
adjectives,
|
|
nouns,
|
|
adjectives,
|
|
nouns,
|
|
verbs,
|
|
adjectives,
|
|
nouns ];
|
|
} else {
|
|
key = [ animalAdjectives,
|
|
animalColors,
|
|
animalNouns,
|
|
animalVerbs,
|
|
natureAdjectives,
|
|
natureNouns,
|
|
plantNouns,
|
|
plantVerbs ];
|
|
}
|
|
|
|
return key;
|
|
}
|
|
|
|
function writeHaiku(wordArray, ipv6) {
|
|
var octet, schemaResults, schema, nonWords, haiku;
|
|
|
|
octet = 'OCTET'; // String to place in schema to show word slots
|
|
schemaResults = getSchema(ipv6, octet);
|
|
schema = schemaResults[0];
|
|
nonWords = schemaResults[1];
|
|
|
|
/*
|
|
** Replace each instance of 'octet' in the schema with a word from
|
|
** the encoded word array
|
|
*/
|
|
for (var i = 0; i < wordArray.length; i++) {
|
|
for (var j = 0; j < schema.length; j++) {
|
|
if (schema[j] === octet) {
|
|
schema[j] = wordArray[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Capitalize appropriate words
|
|
*/
|
|
schema = capitalizeHaiku(schema, nonWords);
|
|
haiku = schema.join('');
|
|
|
|
return haiku;
|
|
}
|
|
|
|
function getSchema(ipv6, octet) {
|
|
var schema, newLine, period, space, nonWords;
|
|
|
|
schema = [];
|
|
newLine = '\n';
|
|
period = '.';
|
|
space = ' ';
|
|
nonWords = [newLine, period, space];
|
|
|
|
if (ipv6) {
|
|
schema = [octet,
|
|
octet,
|
|
'and',
|
|
octet,
|
|
octet,
|
|
newLine,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
period,
|
|
newLine,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
octet,
|
|
period,
|
|
newLine];
|
|
} else {
|
|
schema = ['The',
|
|
octet,
|
|
octet,
|
|
octet,
|
|
newLine,
|
|
octet,
|
|
'in the',
|
|
octet,
|
|
octet,
|
|
period,
|
|
newLine,
|
|
octet,
|
|
octet,
|
|
period,
|
|
newLine];
|
|
}
|
|
|
|
/*
|
|
** Add spaces before words except the first word
|
|
*/
|
|
for (var i = 1; i < schema.length; i++) {
|
|
var insertSpace = true;
|
|
|
|
/*
|
|
** If the next entry is a nonWord, don't add a space
|
|
*/
|
|
for (var j = 0; j < nonWords.length; j++) {
|
|
if (schema[i] === nonWords[j]) {
|
|
insertSpace = false;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** If the previous entry is a newLine, don't add a space
|
|
*/
|
|
if (schema[i - 1] === newLine) {
|
|
insertSpace = false;
|
|
}
|
|
|
|
if (insertSpace) {
|
|
schema.splice(i, 0, space);
|
|
i = i + 1;
|
|
}
|
|
}
|
|
|
|
return [schema, nonWords];
|
|
}
|
|
|
|
function capitalizeHaiku(haikuArray, nonWords) {
|
|
var period = '.';
|
|
|
|
/*
|
|
** Always capitalize the first word
|
|
*/
|
|
haikuArray[0] = capitalizeWord(haikuArray[0]);
|
|
|
|
for (var i = 1; i < haikuArray.length; i++) {
|
|
|
|
if (haikuArray[i] === period) {
|
|
var isWord;
|
|
|
|
/*
|
|
** If the current entry is a period then the next entry will be
|
|
** a newLine or a space, so check two positions ahead and
|
|
** capitalize that entry, so long as it's a word
|
|
*/
|
|
|
|
isWord = true;
|
|
|
|
if (haikuArray[i + 2] === undefined ||
|
|
haikuArray[i + 2] === null ||
|
|
haikuArray[i + 2] === '') {
|
|
isWord = false;
|
|
}
|
|
|
|
for (var j = 0; j < nonWords.length; j++) {
|
|
if (haikuArray[i + 2] === nonWords[j]) {
|
|
isWord = false;
|
|
}
|
|
}
|
|
|
|
if (isWord) {
|
|
haikuArray[i + 2] = capitalizeWord(haikuArray[i + 2]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return haikuArray;
|
|
}
|
|
|
|
function capitalizeWord(word) {
|
|
word = word.substring(0,1).toUpperCase() +
|
|
word.substring(1, word.length);
|
|
|
|
return word;
|
|
}
|
|
|
|
/*
|
|
** #############################
|
|
** Helper functions for decoding
|
|
** #############################
|
|
*/
|
|
|
|
function splitHaiku(haiku) {
|
|
var wordArray;
|
|
|
|
haiku = haiku.toLowerCase();
|
|
|
|
/*
|
|
** Replace newline characters with spaces
|
|
*/
|
|
haiku = haiku.replace(/\n/g, ' ');
|
|
|
|
/*
|
|
** Remove anything that's not a letter, a space or a dash
|
|
*/
|
|
haiku = haiku.replace(/[^a-z\ -]/g, '');
|
|
wordArray = haiku.split(' ');
|
|
|
|
/*
|
|
** Remove any blank entries
|
|
*/
|
|
for (var i = 0; i < wordArray.length; i++) {
|
|
if (wordArray[i] === '') {
|
|
wordArray.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
return wordArray;
|
|
}
|
|
|
|
function haikuIsIpv6(wordArray) {
|
|
var ipv6, key, dict;
|
|
|
|
key = getKey(false);
|
|
dict = key[0];
|
|
ipv6 = true;
|
|
|
|
/*
|
|
** Compare each word in the haiku against each word in the first
|
|
** dictionary defined in the IPv4 key. If there's a match, the
|
|
** current haiku is IPv4. If not, IPv6.
|
|
*/
|
|
for (var i = 0; i < wordArray.length; i++) {
|
|
var currentWord = wordArray[i];
|
|
|
|
for (var j = 0; j < dict.length; j++) {
|
|
if (currentWord === dict[j]) {
|
|
ipv6 = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ipv6 === false) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ipv6;
|
|
}
|
|
|
|
/*
|
|
** Return an array of factors and remainders for each encoded
|
|
** octet-value
|
|
*/
|
|
function getFactors(wordArray, ipv6) {
|
|
var key, factorArray, wordArrayPosition;
|
|
|
|
key = getKey(ipv6);
|
|
factorArray = [];
|
|
wordArrayPosition = 0;
|
|
|
|
/*
|
|
** Get the first dictionary from the key. Check the first entry in
|
|
** the encoded word array to see if it's in that dictionary. If it
|
|
** is, store the dictionary offset and move onto the next dictionary
|
|
** and the next word in the encoded words array. If there isn't a
|
|
** match, keep the same dictionary but check the next word in the
|
|
** array. Keep going till we have an offset for each dictionary in
|
|
** the key.
|
|
*/
|
|
for (var i = 0; i < key.length; i++) {
|
|
var result, factor, newPosition;
|
|
|
|
result = [];
|
|
result = getFactorFromWord(key[i], key.length,
|
|
wordArray, wordArrayPosition);
|
|
factor = result[0];
|
|
newPosition = result[1];
|
|
wordArrayPosition = newPosition;
|
|
|
|
factorArray.push(factor);
|
|
}
|
|
|
|
return factorArray;
|
|
}
|
|
|
|
function getFactorFromWord(dict, maxLength, words, position) {
|
|
var factor = null;
|
|
|
|
for (var j = 0; j < dict.length; j++) {
|
|
var dictEntryLength, wordToCheck;
|
|
|
|
/*
|
|
** Get the number of words in the dictionary entry
|
|
*/
|
|
dictEntryLength = dict[j].split(' ').length;
|
|
|
|
/*
|
|
** build a string to compare against the dictionary entry
|
|
** by joining the appropriate number of wordArray entries
|
|
*/
|
|
wordToCheck =
|
|
words.slice(position, position + dictEntryLength);
|
|
wordToCheck = wordToCheck.join(' ');
|
|
|
|
if (dict[j] === wordToCheck) {
|
|
factor = j;
|
|
|
|
/*
|
|
** If the dictionary entry word count is greater than one,
|
|
** increment the position counter by the difference to
|
|
** avoid rechecking words we've already checkced
|
|
*/
|
|
position = position + (dictEntryLength - 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
position = position + 1;
|
|
|
|
if (factor === null) {
|
|
if (position >= maxLength) {
|
|
/*
|
|
** We've reached the entry of the haiku and still not matched
|
|
** all necessary dictionaries, so throw an error
|
|
*/
|
|
throw new Error('Decoding error: one or more dictionary words' +
|
|
'missing from input haiku');
|
|
} else {
|
|
/*
|
|
** Couldn't find the current word in the current dictionary,
|
|
** try the next word
|
|
*/
|
|
return getFactorFromWord(dict, maxLength, words, position);
|
|
}
|
|
} else {
|
|
/*
|
|
** Found the word - return the dictionary offset and the new
|
|
** word array position
|
|
*/
|
|
return [factor, position];
|
|
}
|
|
}
|
|
|
|
function getOctets(factorArray, ipv6) {
|
|
var octetArray, multiplier;
|
|
|
|
octetArray = [];
|
|
if (ipv6) {
|
|
multiplier = 256;
|
|
} else {
|
|
multiplier = 16;
|
|
}
|
|
|
|
for (var i = 0; i < factorArray.length; i = i + 2) {
|
|
var factor1, factor2, octet;
|
|
|
|
factor1 = factorArray[i];
|
|
factor2 = factorArray[i + 1];
|
|
octet = (factor1 * multiplier) + factor2;
|
|
|
|
if (ipv6) {
|
|
octet = octet.toString(16);
|
|
}
|
|
|
|
octetArray.push(octet);
|
|
}
|
|
|
|
return octetArray;
|
|
}
|
|
|
|
function getIpString(octetArray, ipv6) {
|
|
var ipString, separator;
|
|
|
|
ipString = '';
|
|
|
|
if (ipv6) {
|
|
separator = ':';
|
|
} else {
|
|
separator = '.';
|
|
}
|
|
|
|
for (var i = 0; i < octetArray.length; i++) {
|
|
if (i > 0) {
|
|
ipString += separator;
|
|
}
|
|
ipString += octetArray[i];
|
|
}
|
|
|
|
return ipString;
|
|
}
|
|
|
|
/*
|
|
** ############
|
|
** Dictionaries
|
|
** ############
|
|
*/
|
|
|
|
var adjectives, nouns, verbs, animalAdjectives, animalColors,
|
|
animalNouns, animalVerbs, natureAdjectives, natureNouns,
|
|
plantNouns, plantVerbs;
|
|
|
|
/*
|
|
** IPv4 dictionaries
|
|
*/
|
|
|
|
animalAdjectives = ["agile",
|
|
"bashful",
|
|
"clever",
|
|
"clumsy",
|
|
"drowsy",
|
|
"fearful",
|
|
"graceful",
|
|
"hungry",
|
|
"lonely",
|
|
"morose",
|
|
"placid",
|
|
"ruthless",
|
|
"silent",
|
|
"thoughtful",
|
|
"vapid",
|
|
"weary"];
|
|
|
|
animalColors = ["beige",
|
|
"black",
|
|
"blue",
|
|
"bright",
|
|
"bronze",
|
|
"brown",
|
|
"dark",
|
|
"drab",
|
|
"green",
|
|
"gold",
|
|
"grey",
|
|
"jade",
|
|
"pale",
|
|
"pink",
|
|
"red",
|
|
"white"];
|
|
|
|
animalNouns = ["ape",
|
|
"bear",
|
|
"crow",
|
|
"dove",
|
|
"frog",
|
|
"goat",
|
|
"hawk",
|
|
"lamb",
|
|
"mouse",
|
|
"newt",
|
|
"owl",
|
|
"pig",
|
|
"rat",
|
|
"snake",
|
|
"toad",
|
|
"wolf"];
|
|
|
|
animalVerbs = ["aches",
|
|
"basks",
|
|
"cries",
|
|
"dives",
|
|
"eats",
|
|
"fights",
|
|
"groans",
|
|
"hunts",
|
|
"jumps",
|
|
"lies",
|
|
"prowls",
|
|
"runs",
|
|
"sleeps",
|
|
"thrives",
|
|
"wakes",
|
|
"yawns"];
|
|
|
|
natureAdjectives = ["ancient",
|
|
"barren",
|
|
"blazing",
|
|
"crowded",
|
|
"distant",
|
|
"empty",
|
|
"foggy",
|
|
"fragrant",
|
|
"frozen",
|
|
"moonlit",
|
|
"peaceful",
|
|
"quiet",
|
|
"rugged",
|
|
"serene",
|
|
"sunlit",
|
|
"wind-swept"];
|
|
|
|
natureNouns = ["canyon",
|
|
"clearing",
|
|
"desert",
|
|
"foothills",
|
|
"forest",
|
|
"grasslands",
|
|
"jungle",
|
|
"meadow",
|
|
"mountains",
|
|
"prairie",
|
|
"river",
|
|
"rockpool",
|
|
"sand-dune",
|
|
"tundra",
|
|
"valley",
|
|
"wetlands"];
|
|
|
|
plantNouns = ["autumn colors",
|
|
"cherry blossoms",
|
|
"chrysanthemums",
|
|
"crabapple blooms",
|
|
"dry palm fronds",
|
|
"fat horse chestnuts",
|
|
"forget-me-nots",
|
|
"jasmine petals",
|
|
"lotus flowers",
|
|
"ripe blackberries",
|
|
"the maple seeds",
|
|
"the pine needles",
|
|
"tiger lillies",
|
|
"water lillies",
|
|
"willow branches",
|
|
"yellowwood leaves"];
|
|
|
|
plantVerbs = ["blow",
|
|
"crunch",
|
|
"dance",
|
|
"drift",
|
|
"drop",
|
|
"fall",
|
|
"grow",
|
|
"pile",
|
|
"rest",
|
|
"roll",
|
|
"show",
|
|
"spin",
|
|
"stir",
|
|
"sway",
|
|
"turn",
|
|
"twist"];
|
|
|
|
/*
|
|
** IPv6 dictionaries
|
|
*/
|
|
|
|
adjectives = ["ace",
|
|
"apt",
|
|
"arched",
|
|
"ash",
|
|
"bad",
|
|
"bare",
|
|
"beige",
|
|
"big",
|
|
"black",
|
|
"bland",
|
|
"bleak",
|
|
"blond",
|
|
"blue",
|
|
"blunt",
|
|
"blush",
|
|
"bold",
|
|
"bone",
|
|
"both",
|
|
"bound",
|
|
"brash",
|
|
"brass",
|
|
"brave",
|
|
"brief",
|
|
"brisk",
|
|
"broad",
|
|
"bronze",
|
|
"brushed",
|
|
"burned",
|
|
"calm",
|
|
"ceil",
|
|
"chaste",
|
|
"cheap",
|
|
"chilled",
|
|
"clean",
|
|
"coarse",
|
|
"cold",
|
|
"cool",
|
|
"corn",
|
|
"crass",
|
|
"crazed",
|
|
"cream",
|
|
"crisp",
|
|
"crude",
|
|
"cruel",
|
|
"cursed",
|
|
"cute",
|
|
"daft",
|
|
"damp",
|
|
"dark",
|
|
"dead",
|
|
"deaf",
|
|
"dear",
|
|
"deep",
|
|
"dense",
|
|
"dim",
|
|
"drab",
|
|
"dry",
|
|
"dull",
|
|
"faint",
|
|
"fair",
|
|
"fake",
|
|
"false",
|
|
"famed",
|
|
"far",
|
|
"fast",
|
|
"fat",
|
|
"fierce",
|
|
"fine",
|
|
"firm",
|
|
"flat",
|
|
"flawed",
|
|
"fond",
|
|
"foul",
|
|
"frail",
|
|
"free",
|
|
"fresh",
|
|
"full",
|
|
"fun",
|
|
"glum",
|
|
"good",
|
|
"grave",
|
|
"gray",
|
|
"great",
|
|
"green",
|
|
"grey",
|
|
"grim",
|
|
"gruff",
|
|
"hard",
|
|
"harsh",
|
|
"high",
|
|
"hoarse",
|
|
"hot",
|
|
"huge",
|
|
"hurt",
|
|
"ill",
|
|
"jade",
|
|
"jet",
|
|
"jinxed",
|
|
"keen",
|
|
"kind",
|
|
"lame",
|
|
"lank",
|
|
"large",
|
|
"last",
|
|
"late",
|
|
"lean",
|
|
"lewd",
|
|
"light",
|
|
"limp",
|
|
"live",
|
|
"loath",
|
|
"lone",
|
|
"long",
|
|
"loose",
|
|
"lost",
|
|
"louche",
|
|
"loud",
|
|
"low",
|
|
"lush",
|
|
"mad",
|
|
"male",
|
|
"masked",
|
|
"mean",
|
|
"meek",
|
|
"mild",
|
|
"mint",
|
|
"moist",
|
|
"mute",
|
|
"near",
|
|
"neat",
|
|
"new",
|
|
"nice",
|
|
"nude",
|
|
"numb",
|
|
"odd",
|
|
"old",
|
|
"pained",
|
|
"pale",
|
|
"peach",
|
|
"pear",
|
|
"peeved",
|
|
"pink",
|
|
"piqued",
|
|
"plain",
|
|
"plum",
|
|
"plump",
|
|
"plush",
|
|
"poor",
|
|
"posed",
|
|
"posh",
|
|
"prim",
|
|
"prime",
|
|
"prompt",
|
|
"prone",
|
|
"proud",
|
|
"prune",
|
|
"puce",
|
|
"pure",
|
|
"quaint",
|
|
"quartz",
|
|
"quick",
|
|
"rare",
|
|
"raw",
|
|
"real",
|
|
"red",
|
|
"rich",
|
|
"ripe",
|
|
"rough",
|
|
"rude",
|
|
"rushed",
|
|
"rust",
|
|
"sad",
|
|
"safe",
|
|
"sage",
|
|
"sane",
|
|
"scortched",
|
|
"shaped",
|
|
"sharp",
|
|
"sheared",
|
|
"short",
|
|
"shrewd",
|
|
"shrill",
|
|
"shrunk",
|
|
"shy",
|
|
"sick",
|
|
"skilled",
|
|
"slain",
|
|
"slick",
|
|
"slight",
|
|
"slim",
|
|
"slow",
|
|
"small",
|
|
"smart",
|
|
"smooth",
|
|
"smug",
|
|
"snide",
|
|
"snug",
|
|
"soft",
|
|
"sore",
|
|
"sought",
|
|
"sour",
|
|
"spare",
|
|
"sparse",
|
|
"spent",
|
|
"spoilt",
|
|
"spry",
|
|
"squat",
|
|
"staid",
|
|
"stale",
|
|
"stary",
|
|
"staunch",
|
|
"steep",
|
|
"stiff",
|
|
"strange",
|
|
"straw",
|
|
"stretched",
|
|
"strict",
|
|
"striped",
|
|
"strong",
|
|
"suave",
|
|
"sure",
|
|
"svelte",
|
|
"swank",
|
|
"sweet",
|
|
"swift",
|
|
"tall",
|
|
"tame",
|
|
"tan",
|
|
"tart",
|
|
"taut",
|
|
"teal",
|
|
"terse",
|
|
"thick",
|
|
"thin",
|
|
"tight",
|
|
"tiny",
|
|
"tired",
|
|
"toothed",
|
|
"torn",
|
|
"tough",
|
|
"trim",
|
|
"trussed",
|
|
"twin",
|
|
"used",
|
|
"vague",
|
|
"vain",
|
|
"vast",
|
|
"veiled",
|
|
"vexed",
|
|
"vile",
|
|
"warm",
|
|
"weak",
|
|
"webbed",
|
|
"wrong",
|
|
"wry",
|
|
"young"];
|
|
|
|
nouns = ["ants",
|
|
"apes",
|
|
"asps",
|
|
"balls",
|
|
"barb",
|
|
"barbs",
|
|
"bass",
|
|
"bats",
|
|
"beads",
|
|
"beaks",
|
|
"bears",
|
|
"bees",
|
|
"bells",
|
|
"belts",
|
|
"birds",
|
|
"blades",
|
|
"blobs",
|
|
"blooms",
|
|
"boars",
|
|
"boats",
|
|
"bolts",
|
|
"books",
|
|
"bowls",
|
|
"boys",
|
|
"bream",
|
|
"brides",
|
|
"broods",
|
|
"brooms",
|
|
"brutes",
|
|
"bucks",
|
|
"bulbs",
|
|
"bulls",
|
|
"busks",
|
|
"cakes",
|
|
"calfs",
|
|
"calves",
|
|
"cats",
|
|
"char",
|
|
"chests",
|
|
"choirs",
|
|
"clams",
|
|
"clans",
|
|
"clouds",
|
|
"clowns",
|
|
"cod",
|
|
"coins",
|
|
"colts",
|
|
"cones",
|
|
"cords",
|
|
"cows",
|
|
"crabs",
|
|
"cranes",
|
|
"crows",
|
|
"cults",
|
|
"czars",
|
|
"darts",
|
|
"dates",
|
|
"deer",
|
|
"dholes",
|
|
"dice",
|
|
"discs",
|
|
"does",
|
|
"dogs",
|
|
"doors",
|
|
"dopes",
|
|
"doves",
|
|
"dreams",
|
|
"drones",
|
|
"ducks",
|
|
"dunes",
|
|
"dwarves",
|
|
"eels",
|
|
"eggs",
|
|
"elk",
|
|
"elks",
|
|
"elms",
|
|
"elves",
|
|
"ewes",
|
|
"eyes",
|
|
"faces",
|
|
"facts",
|
|
"fawns",
|
|
"feet",
|
|
"ferns",
|
|
"fish",
|
|
"fists",
|
|
"flames",
|
|
"fleas",
|
|
"flocks",
|
|
"flutes",
|
|
"foals",
|
|
"foes",
|
|
"fools",
|
|
"fowl",
|
|
"frogs",
|
|
"fruits",
|
|
"gangs",
|
|
"gar",
|
|
"geese",
|
|
"gems",
|
|
"germs",
|
|
"ghosts",
|
|
"gnomes",
|
|
"goats",
|
|
"grapes",
|
|
"grooms",
|
|
"grouse",
|
|
"grubs",
|
|
"guards",
|
|
"gulls",
|
|
"hands",
|
|
"hares",
|
|
"hawks",
|
|
"heads",
|
|
"hearts",
|
|
"hens",
|
|
"herbs",
|
|
"hills",
|
|
"hogs",
|
|
"holes",
|
|
"hordes",
|
|
"ide",
|
|
"jars",
|
|
"jays",
|
|
"kids",
|
|
"kings",
|
|
"kites",
|
|
"lads",
|
|
"lakes",
|
|
"lambs",
|
|
"larks",
|
|
"lice",
|
|
"lights",
|
|
"limbs",
|
|
"looms",
|
|
"loons",
|
|
"mares",
|
|
"masks",
|
|
"mice",
|
|
"mimes",
|
|
"minks",
|
|
"mists",
|
|
"mites",
|
|
"mobs",
|
|
"molds",
|
|
"moles",
|
|
"moons",
|
|
"moths",
|
|
"newts",
|
|
"nymphs",
|
|
"orbs",
|
|
"orcs",
|
|
"owls",
|
|
"pearls",
|
|
"pears",
|
|
"peas",
|
|
"perch",
|
|
"pigs",
|
|
"pikes",
|
|
"pines",
|
|
"plains",
|
|
"plants",
|
|
"plums",
|
|
"pools",
|
|
"prawns",
|
|
"prunes",
|
|
"pugs",
|
|
"punks",
|
|
"quail",
|
|
"quails",
|
|
"queens",
|
|
"quills",
|
|
"rafts",
|
|
"rains",
|
|
"rams",
|
|
"rats",
|
|
"rays",
|
|
"ribs",
|
|
"rocks",
|
|
"rooks",
|
|
"ruffs",
|
|
"runes",
|
|
"sands",
|
|
"seals",
|
|
"seas",
|
|
"seeds",
|
|
"serfs",
|
|
"shards",
|
|
"sharks",
|
|
"sheep",
|
|
"shells",
|
|
"ships",
|
|
"shoals",
|
|
"shrews",
|
|
"shrimp",
|
|
"skate",
|
|
"skies",
|
|
"skunks",
|
|
"sloths",
|
|
"slugs",
|
|
"smew",
|
|
"smiles",
|
|
"snails",
|
|
"snakes",
|
|
"snipes",
|
|
"sole",
|
|
"songs",
|
|
"spades",
|
|
"sprats",
|
|
"sprouts",
|
|
"squabs",
|
|
"squads",
|
|
"squares",
|
|
"squid",
|
|
"stars",
|
|
"stoats",
|
|
"stones",
|
|
"storks",
|
|
"strays",
|
|
"suns",
|
|
"swans",
|
|
"swarms",
|
|
"swells",
|
|
"swifts",
|
|
"tars",
|
|
"teams",
|
|
"teeth",
|
|
"terns",
|
|
"thorns",
|
|
"threads",
|
|
"thrones",
|
|
"ticks",
|
|
"toads",
|
|
"tools",
|
|
"trees",
|
|
"tribes",
|
|
"trolls",
|
|
"trout",
|
|
"tunes",
|
|
"tusks",
|
|
"veins",
|
|
"verbs",
|
|
"vines",
|
|
"voles",
|
|
"wasps",
|
|
"waves",
|
|
"wells",
|
|
"whales",
|
|
"whelks",
|
|
"whiffs",
|
|
"winds",
|
|
"wolves",
|
|
"worms",
|
|
"wraiths",
|
|
"wrens",
|
|
"yaks"];
|
|
|
|
verbs = ["aid",
|
|
"arm",
|
|
"awe",
|
|
"axe",
|
|
"bag",
|
|
"bait",
|
|
"bare",
|
|
"bash",
|
|
"bathe",
|
|
"beat",
|
|
"bid",
|
|
"bilk",
|
|
"blame",
|
|
"bleach",
|
|
"bleed",
|
|
"bless",
|
|
"bluff",
|
|
"blur",
|
|
"boast",
|
|
"boost",
|
|
"boot",
|
|
"bore",
|
|
"botch",
|
|
"breed",
|
|
"brew",
|
|
"bribe",
|
|
"brief",
|
|
"brine",
|
|
"broil",
|
|
"browse",
|
|
"bruise",
|
|
"build",
|
|
"burn",
|
|
"burst",
|
|
"call",
|
|
"calm",
|
|
"carve",
|
|
"chafe",
|
|
"chant",
|
|
"charge",
|
|
"chart",
|
|
"cheat",
|
|
"check",
|
|
"cheer",
|
|
"chill",
|
|
"choke",
|
|
"chomp",
|
|
"choose",
|
|
"churn",
|
|
"cite",
|
|
"clamp",
|
|
"clap",
|
|
"clasp",
|
|
"claw",
|
|
"clean",
|
|
"cleanse",
|
|
"clip",
|
|
"cloack",
|
|
"clone",
|
|
"clutch",
|
|
"coax",
|
|
"crack",
|
|
"crave",
|
|
"crunch",
|
|
"cry",
|
|
"cull",
|
|
"cure",
|
|
"curse",
|
|
"cuss",
|
|
"dare",
|
|
"daze",
|
|
"dent",
|
|
"dig",
|
|
"ding",
|
|
"doubt",
|
|
"dowse",
|
|
"drag",
|
|
"drain",
|
|
"drape",
|
|
"draw",
|
|
"dread",
|
|
"dredge",
|
|
"drill",
|
|
"drink",
|
|
"drip",
|
|
"drive",
|
|
"drop",
|
|
"drown",
|
|
"dry",
|
|
"dump",
|
|
"eat",
|
|
"etch",
|
|
"face",
|
|
"fail",
|
|
"fault",
|
|
"fear",
|
|
"feed",
|
|
"feel",
|
|
"fetch",
|
|
"fight",
|
|
"find",
|
|
"fix",
|
|
"flap",
|
|
"flay",
|
|
"flee",
|
|
"fling",
|
|
"flip",
|
|
"float",
|
|
"foil",
|
|
"forge",
|
|
"free",
|
|
"freeze",
|
|
"frisk",
|
|
"gain",
|
|
"glimpse",
|
|
"gnaw",
|
|
"goad",
|
|
"gouge",
|
|
"grab",
|
|
"grasp",
|
|
"graze",
|
|
"grieve",
|
|
"grip",
|
|
"groom",
|
|
"guard",
|
|
"guards",
|
|
"guide",
|
|
"gulp",
|
|
"gush",
|
|
"halt",
|
|
"harm",
|
|
"hate",
|
|
"haul",
|
|
"haunt",
|
|
"have",
|
|
"heal",
|
|
"hear",
|
|
"help",
|
|
"herd",
|
|
"hex",
|
|
"hire",
|
|
"hit",
|
|
"hoist",
|
|
"hound",
|
|
"hug",
|
|
"hurl",
|
|
"irk",
|
|
"jab",
|
|
"jeer",
|
|
"join",
|
|
"jolt",
|
|
"keep",
|
|
"kick",
|
|
"kill",
|
|
"kiss",
|
|
"lash",
|
|
"leash",
|
|
"leave",
|
|
"lift",
|
|
"like",
|
|
"love",
|
|
"lugg",
|
|
"lure",
|
|
"maim",
|
|
"make",
|
|
"mask",
|
|
"meet",
|
|
"melt",
|
|
"mend",
|
|
"miss",
|
|
"mould",
|
|
"move",
|
|
"nab",
|
|
"name",
|
|
"need",
|
|
"oust",
|
|
"paint",
|
|
"paw",
|
|
"pay",
|
|
"peck",
|
|
"peeve",
|
|
"pelt",
|
|
"please",
|
|
"pluck",
|
|
"poach",
|
|
"poll",
|
|
"praise",
|
|
"prick",
|
|
"print",
|
|
"probe",
|
|
"prod",
|
|
"prompt",
|
|
"punch",
|
|
"quash",
|
|
"quell",
|
|
"quote",
|
|
"raid",
|
|
"raise",
|
|
"raze",
|
|
"ride",
|
|
"roast",
|
|
"rouse",
|
|
"rule",
|
|
"scald",
|
|
"scalp",
|
|
"scar",
|
|
"scathe",
|
|
"score",
|
|
"scorn",
|
|
"scour",
|
|
"scuff",
|
|
"sear",
|
|
"see",
|
|
"seek",
|
|
"seize",
|
|
"send",
|
|
"sense",
|
|
"serve",
|
|
"shake",
|
|
"shear",
|
|
"shift",
|
|
"shoot",
|
|
"shun",
|
|
"slap",
|
|
"slay",
|
|
"slice",
|
|
"smack",
|
|
"smash",
|
|
"smell",
|
|
"smite",
|
|
"snare",
|
|
"snatch",
|
|
"sniff",
|
|
"snub",
|
|
"soak",
|
|
"spare",
|
|
"splash",
|
|
"split",
|
|
"spook",
|
|
"spray",
|
|
"squash",
|
|
"squeeze",
|
|
"stab",
|
|
"stain",
|
|
"starve",
|
|
"steal",
|
|
"steer",
|
|
"sting",
|
|
"strike",
|
|
"stun",
|
|
"tag",
|
|
"tame",
|
|
"taste",
|
|
"taunt",
|
|
"teach",
|
|
"tend"];
|
|
|
|
return publicMethods;
|
|
|
|
})();
|