| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 | 
							- /* global define */
 
- (function (root, pluralize) {
 
-   /* istanbul ignore else */
 
-   if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
 
-     // Node.
 
-     module.exports = pluralize();
 
-   } else if (typeof define === 'function' && define.amd) {
 
-     // AMD, registers as an anonymous module.
 
-     define(function () {
 
-       return pluralize();
 
-     });
 
-   } else {
 
-     // Browser global.
 
-     root.pluralize = pluralize();
 
-   }
 
- })(this, function () {
 
-   // Rule storage - pluralize and singularize need to be run sequentially,
 
-   // while other rules can be optimized using an object for instant lookups.
 
-   var pluralRules = [];
 
-   var singularRules = [];
 
-   var uncountables = {};
 
-   var irregularPlurals = {};
 
-   var irregularSingles = {};
 
-   /**
 
-    * Sanitize a pluralization rule to a usable regular expression.
 
-    *
 
-    * @param  {(RegExp|string)} rule
 
-    * @return {RegExp}
 
-    */
 
-   function sanitizeRule (rule) {
 
-     if (typeof rule === 'string') {
 
-       return new RegExp('^' + rule + '$', 'i');
 
-     }
 
-     return rule;
 
-   }
 
-   /**
 
-    * Pass in a word token to produce a function that can replicate the case on
 
-    * another word.
 
-    *
 
-    * @param  {string}   word
 
-    * @param  {string}   token
 
-    * @return {Function}
 
-    */
 
-   function restoreCase (word, token) {
 
-     // Tokens are an exact match.
 
-     if (word === token) return token;
 
-     // Upper cased words. E.g. "HELLO".
 
-     if (word === word.toUpperCase()) return token.toUpperCase();
 
-     // Title cased words. E.g. "Title".
 
-     if (word[0] === word[0].toUpperCase()) {
 
-       return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
 
-     }
 
-     // Lower cased words. E.g. "test".
 
-     return token.toLowerCase();
 
-   }
 
-   /**
 
-    * Interpolate a regexp string.
 
-    *
 
-    * @param  {string} str
 
-    * @param  {Array}  args
 
-    * @return {string}
 
-    */
 
-   function interpolate (str, args) {
 
-     return str.replace(/\$(\d{1,2})/g, function (match, index) {
 
-       return args[index] || '';
 
-     });
 
-   }
 
-   /**
 
-    * Replace a word using a rule.
 
-    *
 
-    * @param  {string} word
 
-    * @param  {Array}  rule
 
-    * @return {string}
 
-    */
 
-   function replace (word, rule) {
 
-     return word.replace(rule[0], function (match, index) {
 
-       var result = interpolate(rule[1], arguments);
 
-       if (match === '') {
 
-         return restoreCase(word[index - 1], result);
 
-       }
 
-       return restoreCase(match, result);
 
-     });
 
-   }
 
-   /**
 
-    * Sanitize a word by passing in the word and sanitization rules.
 
-    *
 
-    * @param  {string}   token
 
-    * @param  {string}   word
 
-    * @param  {Array}    rules
 
-    * @return {string}
 
-    */
 
-   function sanitizeWord (token, word, rules) {
 
-     // Empty string or doesn't need fixing.
 
-     if (!token.length || uncountables.hasOwnProperty(token)) {
 
-       return word;
 
-     }
 
-     var len = rules.length;
 
-     // Iterate over the sanitization rules and use the first one to match.
 
-     while (len--) {
 
-       var rule = rules[len];
 
-       if (rule[0].test(word)) return replace(word, rule);
 
-     }
 
-     return word;
 
-   }
 
-   /**
 
-    * Replace a word with the updated word.
 
-    *
 
-    * @param  {Object}   replaceMap
 
-    * @param  {Object}   keepMap
 
-    * @param  {Array}    rules
 
-    * @return {Function}
 
-    */
 
-   function replaceWord (replaceMap, keepMap, rules) {
 
-     return function (word) {
 
-       // Get the correct token and case restoration functions.
 
-       var token = word.toLowerCase();
 
-       // Check against the keep object map.
 
-       if (keepMap.hasOwnProperty(token)) {
 
-         return restoreCase(word, token);
 
-       }
 
-       // Check against the replacement map for a direct word replacement.
 
-       if (replaceMap.hasOwnProperty(token)) {
 
-         return restoreCase(word, replaceMap[token]);
 
-       }
 
-       // Run all the rules against the word.
 
-       return sanitizeWord(token, word, rules);
 
-     };
 
-   }
 
-   /**
 
-    * Check if a word is part of the map.
 
-    */
 
-   function checkWord (replaceMap, keepMap, rules, bool) {
 
-     return function (word) {
 
-       var token = word.toLowerCase();
 
-       if (keepMap.hasOwnProperty(token)) return true;
 
-       if (replaceMap.hasOwnProperty(token)) return false;
 
-       return sanitizeWord(token, token, rules) === token;
 
-     };
 
-   }
 
-   /**
 
-    * Pluralize or singularize a word based on the passed in count.
 
-    *
 
-    * @param  {string}  word
 
-    * @param  {number}  count
 
-    * @param  {boolean} inclusive
 
-    * @return {string}
 
-    */
 
-   function pluralize (word, count, inclusive) {
 
-     var pluralized = count === 1
 
-       ? pluralize.singular(word) : pluralize.plural(word);
 
-     return (inclusive ? count + ' ' : '') + pluralized;
 
-   }
 
-   /**
 
-    * Pluralize a word.
 
-    *
 
-    * @type {Function}
 
-    */
 
-   pluralize.plural = replaceWord(
 
-     irregularSingles, irregularPlurals, pluralRules
 
-   );
 
-   /**
 
-    * Check if a word is plural.
 
-    *
 
-    * @type {Function}
 
-    */
 
-   pluralize.isPlural = checkWord(
 
-     irregularSingles, irregularPlurals, pluralRules
 
-   );
 
-   /**
 
-    * Singularize a word.
 
-    *
 
-    * @type {Function}
 
-    */
 
-   pluralize.singular = replaceWord(
 
-     irregularPlurals, irregularSingles, singularRules
 
-   );
 
-   /**
 
-    * Check if a word is singular.
 
-    *
 
-    * @type {Function}
 
-    */
 
-   pluralize.isSingular = checkWord(
 
-     irregularPlurals, irregularSingles, singularRules
 
-   );
 
-   /**
 
-    * Add a pluralization rule to the collection.
 
-    *
 
-    * @param {(string|RegExp)} rule
 
-    * @param {string}          replacement
 
-    */
 
-   pluralize.addPluralRule = function (rule, replacement) {
 
-     pluralRules.push([sanitizeRule(rule), replacement]);
 
-   };
 
-   /**
 
-    * Add a singularization rule to the collection.
 
-    *
 
-    * @param {(string|RegExp)} rule
 
-    * @param {string}          replacement
 
-    */
 
-   pluralize.addSingularRule = function (rule, replacement) {
 
-     singularRules.push([sanitizeRule(rule), replacement]);
 
-   };
 
-   /**
 
-    * Add an uncountable word rule.
 
-    *
 
-    * @param {(string|RegExp)} word
 
-    */
 
-   pluralize.addUncountableRule = function (word) {
 
-     if (typeof word === 'string') {
 
-       uncountables[word.toLowerCase()] = true;
 
-       return;
 
-     }
 
-     // Set singular and plural references for the word.
 
-     pluralize.addPluralRule(word, '$0');
 
-     pluralize.addSingularRule(word, '$0');
 
-   };
 
-   /**
 
-    * Add an irregular word definition.
 
-    *
 
-    * @param {string} single
 
-    * @param {string} plural
 
-    */
 
-   pluralize.addIrregularRule = function (single, plural) {
 
-     plural = plural.toLowerCase();
 
-     single = single.toLowerCase();
 
-     irregularSingles[single] = plural;
 
-     irregularPlurals[plural] = single;
 
-   };
 
-   /**
 
-    * Irregular rules.
 
-    */
 
-   [
 
-     // Pronouns.
 
-     ['I', 'we'],
 
-     ['me', 'us'],
 
-     ['he', 'they'],
 
-     ['she', 'they'],
 
-     ['them', 'them'],
 
-     ['myself', 'ourselves'],
 
-     ['yourself', 'yourselves'],
 
-     ['itself', 'themselves'],
 
-     ['herself', 'themselves'],
 
-     ['himself', 'themselves'],
 
-     ['themself', 'themselves'],
 
-     ['is', 'are'],
 
-     ['was', 'were'],
 
-     ['has', 'have'],
 
-     ['this', 'these'],
 
-     ['that', 'those'],
 
-     // Words ending in with a consonant and `o`.
 
-     ['echo', 'echoes'],
 
-     ['dingo', 'dingoes'],
 
-     ['volcano', 'volcanoes'],
 
-     ['tornado', 'tornadoes'],
 
-     ['torpedo', 'torpedoes'],
 
-     // Ends with `us`.
 
-     ['genus', 'genera'],
 
-     ['viscus', 'viscera'],
 
-     // Ends with `ma`.
 
-     ['stigma', 'stigmata'],
 
-     ['stoma', 'stomata'],
 
-     ['dogma', 'dogmata'],
 
-     ['lemma', 'lemmata'],
 
-     ['schema', 'schemata'],
 
-     ['anathema', 'anathemata'],
 
-     // Other irregular rules.
 
-     ['ox', 'oxen'],
 
-     ['axe', 'axes'],
 
-     ['die', 'dice'],
 
-     ['yes', 'yeses'],
 
-     ['foot', 'feet'],
 
-     ['eave', 'eaves'],
 
-     ['goose', 'geese'],
 
-     ['tooth', 'teeth'],
 
-     ['quiz', 'quizzes'],
 
-     ['human', 'humans'],
 
-     ['proof', 'proofs'],
 
-     ['carve', 'carves'],
 
-     ['valve', 'valves'],
 
-     ['looey', 'looies'],
 
-     ['thief', 'thieves'],
 
-     ['groove', 'grooves'],
 
-     ['pickaxe', 'pickaxes'],
 
-     ['whiskey', 'whiskies']
 
-   ].forEach(function (rule) {
 
-     return pluralize.addIrregularRule(rule[0], rule[1]);
 
-   });
 
-   /**
 
-    * Pluralization rules.
 
-    */
 
-   [
 
-     [/s?$/i, 's'],
 
-     [/[^\u0000-\u007F]$/i, '$0'],
 
-     [/([^aeiou]ese)$/i, '$1'],
 
-     [/(ax|test)is$/i, '$1es'],
 
-     [/(alias|[^aou]us|tlas|gas|ris)$/i, '$1es'],
 
-     [/(e[mn]u)s?$/i, '$1s'],
 
-     [/([^l]ias|[aeiou]las|[emjzr]as|[iu]am)$/i, '$1'],
 
-     [/(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'],
 
-     [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'],
 
-     [/(seraph|cherub)(?:im)?$/i, '$1im'],
 
-     [/(her|at|gr)o$/i, '$1oes'],
 
-     [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'],
 
-     [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'],
 
-     [/sis$/i, 'ses'],
 
-     [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'],
 
-     [/([^aeiouy]|qu)y$/i, '$1ies'],
 
-     [/([^ch][ieo][ln])ey$/i, '$1ies'],
 
-     [/(x|ch|ss|sh|zz)$/i, '$1es'],
 
-     [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'],
 
-     [/(m|l)(?:ice|ouse)$/i, '$1ice'],
 
-     [/(pe)(?:rson|ople)$/i, '$1ople'],
 
-     [/(child)(?:ren)?$/i, '$1ren'],
 
-     [/eaux$/i, '$0'],
 
-     [/m[ae]n$/i, 'men'],
 
-     ['thou', 'you']
 
-   ].forEach(function (rule) {
 
-     return pluralize.addPluralRule(rule[0], rule[1]);
 
-   });
 
-   /**
 
-    * Singularization rules.
 
-    */
 
-   [
 
-     [/s$/i, ''],
 
-     [/(ss)$/i, '$1'],
 
-     [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'],
 
-     [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'],
 
-     [/ies$/i, 'y'],
 
-     [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'],
 
-     [/\b(mon|smil)ies$/i, '$1ey'],
 
-     [/(m|l)ice$/i, '$1ouse'],
 
-     [/(seraph|cherub)im$/i, '$1'],
 
-     [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|tlas|gas|(?:her|at|gr)o|ris)(?:es)?$/i, '$1'],
 
-     [/(analy|ba|diagno|parenthe|progno|synop|the|empha|cri)(?:sis|ses)$/i, '$1sis'],
 
-     [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'],
 
-     [/(test)(?:is|es)$/i, '$1is'],
 
-     [/(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'],
 
-     [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'],
 
-     [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'],
 
-     [/(alumn|alg|vertebr)ae$/i, '$1a'],
 
-     [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'],
 
-     [/(matr|append)ices$/i, '$1ix'],
 
-     [/(pe)(rson|ople)$/i, '$1rson'],
 
-     [/(child)ren$/i, '$1'],
 
-     [/(eau)x?$/i, '$1'],
 
-     [/men$/i, 'man']
 
-   ].forEach(function (rule) {
 
-     return pluralize.addSingularRule(rule[0], rule[1]);
 
-   });
 
-   /**
 
-    * Uncountable rules.
 
-    */
 
-   [
 
-     // Singular words with no plurals.
 
-     'adulthood',
 
-     'advice',
 
-     'agenda',
 
-     'aid',
 
-     'alcohol',
 
-     'ammo',
 
-     'anime',
 
-     'athletics',
 
-     'audio',
 
-     'bison',
 
-     'blood',
 
-     'bream',
 
-     'buffalo',
 
-     'butter',
 
-     'carp',
 
-     'cash',
 
-     'chassis',
 
-     'chess',
 
-     'clothing',
 
-     'cod',
 
-     'commerce',
 
-     'cooperation',
 
-     'corps',
 
-     'debris',
 
-     'diabetes',
 
-     'digestion',
 
-     'elk',
 
-     'energy',
 
-     'equipment',
 
-     'excretion',
 
-     'expertise',
 
-     'flounder',
 
-     'fun',
 
-     'gallows',
 
-     'garbage',
 
-     'graffiti',
 
-     'headquarters',
 
-     'health',
 
-     'herpes',
 
-     'highjinks',
 
-     'homework',
 
-     'housework',
 
-     'information',
 
-     'jeans',
 
-     'justice',
 
-     'kudos',
 
-     'labour',
 
-     'literature',
 
-     'machinery',
 
-     'mackerel',
 
-     'mail',
 
-     'media',
 
-     'mews',
 
-     'moose',
 
-     'music',
 
-     'manga',
 
-     'news',
 
-     'pike',
 
-     'plankton',
 
-     'pliers',
 
-     'pollution',
 
-     'premises',
 
-     'rain',
 
-     'research',
 
-     'rice',
 
-     'salmon',
 
-     'scissors',
 
-     'series',
 
-     'sewage',
 
-     'shambles',
 
-     'shrimp',
 
-     'species',
 
-     'staff',
 
-     'swine',
 
-     'tennis',
 
-     'traffic',
 
-     'transporation',
 
-     'trout',
 
-     'tuna',
 
-     'wealth',
 
-     'welfare',
 
-     'whiting',
 
-     'wildebeest',
 
-     'wildlife',
 
-     'you',
 
-     // Regexes.
 
-     /[^aeiou]ese$/i, // "chinese", "japanese"
 
-     /deer$/i, // "deer", "reindeer"
 
-     /fish$/i, // "fish", "blowfish", "angelfish"
 
-     /measles$/i,
 
-     /o[iu]s$/i, // "carnivorous"
 
-     /pox$/i, // "chickpox", "smallpox"
 
-     /sheep$/i
 
-   ].forEach(pluralize.addUncountableRule);
 
-   return pluralize;
 
- });
 
 
  |