first commit

This commit is contained in:
2025-10-26 23:10:15 +08:00
commit 8f0345b7be
14961 changed files with 2356381 additions and 0 deletions

16
node_modules/indefinite/lib/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
const STARTS_WITH_VOWEL = /^[aeiouAEIOU]/;
/**
* Array#indexOf is faster IF the word starts with "a" (for example),
* but negligibly faster when you have to .toLowerCase() the word, and
* slower if the word happens to start with (e.g.) "u."
*/
exports.startsWithVowel = word => STARTS_WITH_VOWEL.test(word);
exports.capitalize = (article, opts) => {
if (opts.capitalize) {
article = `${article.charAt(0).toUpperCase()}${article.slice(1)}`;
}
return article;
};

34
node_modules/indefinite/lib/indefinite.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
const { capitalize } = require('./helpers');
const irregulars = require('./irregular-words');
const rules = require('./rules');
const indefinite = (word, opts = {}) => {
let article;
/**
* I'd really prefer to use for of here, but babel converts that
* to something using Symbol.iterator, which PhantomJS chokes on.
*/
rules.some((rule) => {
if (rule.check(word, opts)) {
article = rule.run(word, opts);
return true;
}
});
return handleOptions(article, opts, word);
};
const handleOptions = (article, opts, word) => {
article = capitalize(article, opts);
if (opts.articleOnly) {
return article;
}
return `${article} ${word}`;
};
indefinite.irregularWords = irregulars.list;
module.exports = indefinite;

83
node_modules/indefinite/lib/irregular-words.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
exports.check = (word, ending) => {
if (ending) {
// If the word ends in the ending, remove it.
let regex = new RegExp(`${ending}$`);
word = word.replace(regex, '');
if (word.length <= 1) {
return false;
}
}
return exports.list.indexOf(word) > -1;
};
/**
* Here follows a List of words that take irregular articles because their
* first letter is either a consonant pronounced like a vowel (hour) or a
* vowel proncounced like a consonant (ukelele). Note that this is not only
* nouns because adjectives and adverbs that start with these letters could
* also follow an article when they identify a later noun, as in "a useless
* tool."
*
* This is not an attempt at a complete list, but rather a collection of
* words used in at least moderate frequency. A list of ALL irregular words
* would be too exhaustive to compile without some sort of tool.
* http://www.thefreedictionary.com/words-that-start-with-eu says there are
* over 1800 words starting with "eu" alone.
*
* At least for now, this list omits proper names, as they aren't USUALLY
* used in such a way as to require an _indefinite_ article. I can't think,
* for example, of a case where you'd want to say "a Eustace."
*/
exports.list = [
// Nouns: eu like y
'eunuch', 'eucalyptus', 'eugenics', 'eulogy', 'euphemism', 'euphony', 'euphoria', 'eureka',
// Adjectives: eu like y
'euro', 'european', 'euphemistic', 'euphonic', 'euphoric',
// Adverbs: eu like y
'euphemistically', 'euphonically', 'euphorically',
// Nouns: silent h
'heir', 'heiress', 'herb', 'homage', 'honesty', 'honor', 'honour', 'honoree', 'hour',
// Adjectives: silent h
'honest', 'honorous', 'honorific', 'honorable', 'honourable',
// Adverbs: silent h
'honestly', 'hourly',
// Nouns: o like w
'one', 'ouija',
// Adjectives: o like w
'once',
// Adverbs: o like w
// Nouns: u like y
'ubiquity', 'udometer', 'ufo', 'uke', 'ukelele', 'ululate', 'unicorn', 'unicycle', 'uniform',
'unify', 'union', 'unison', 'unit', 'unity', 'universe', 'university', 'upas', 'ural', 'uranium',
'urea', 'ureter', 'urethra', 'urine', 'urologist', 'urology', 'urus', 'usage', 'use', 'user', 'usual', 'usurp',
'usurper', 'usury', 'utensil', 'uterus', 'utility', 'utopia', 'utricle', 'uvarovite', 'uvea', 'uvula', 'utah',
'utahn',
// Adjectives: u like y
'ubiquitous', 'ugandan', 'ukrainian', 'unanimous', 'unicameral', 'unified', 'unique', 'unisex',
'universal', 'urinal', 'urological', 'useful', 'useless', 'usurious', 'utilitarian',
'utopic',
// Adverbs: u like y
'ubiquitously', 'unanimously', 'unicamerally', 'uniquely', 'universally', 'urologically', 'usefully', 'uselessly', 'usuriously',
// Nouns: y like i
'yttria', 'yggdrasil', 'ylem', 'yperite', 'ytterbia', 'ytterbium', 'yttrium',
// Adjectives: y like i
'ytterbous', 'ytterbic', 'yttric',
// Single letters
'f', 'h', 'l', 'm', 'n', 'r', 's', 'u', 'x'
];

5
node_modules/indefinite/lib/rules.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
module.exports = [
require('./rules/numbers'),
require('./rules/acronyms'),
require('./rules/other')
];

35
node_modules/indefinite/lib/rules/acronyms.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
const { startsWithVowel } = require('../helpers');
const ACRONYM = /^[A-Z]+$/;
const IRREGULAR_ACRONYM = /^[UFHLMNRSX]/;
const isIrregularAcronym = word => IRREGULAR_ACRONYM.test(word.charAt(0));
/**
* Both = a && b
* Neither = !a && !b
* In the case of Booleans, this means
* either both true or both false, so
* we can just compare the equality of
* a and b.
*/
const bothOrNeither = (a, b) => a === b;
/**
* If the entirety of the first word is capital letters
* and case insensitivity is off, it's an acronym.
*/
exports.check = (word, { caseInsensitive }) => caseInsensitive ? false : ACRONYM.test(word.split(' ')[0]);
exports.run = (word) => {
let isIrregular = isIrregularAcronym(word);
let initialVowel = startsWithVowel(word);
/*
* If it starts with U: "a"
* If it starts with any other vowel: "an"
* If it starts with F, H, L, M, N, R, S, or X: "an"
* If it starts with any other consonant: "a"
*/
let article = bothOrNeither(initialVowel, isIrregular) ? 'a' : 'an';
return article;
};

29
node_modules/indefinite/lib/rules/numbers.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
const NUMBERS = /^([0-9,]+)/;
const EIGHT_ELEVEN_EIGHTEEN = /^(11|8|18)/;
const ELEVEN_EIGHTEEN = /^(11|18)/;
exports.check = (word) => NUMBERS.test(word);
exports.run = (word, opts) => {
let number = word.toString().match(NUMBERS)[1].replace(/,/g, '');
let article = 'a';
if (EIGHT_ELEVEN_EIGHTEEN.test(number)) {
const startsWith11Or18 = ELEVEN_EIGHTEEN.test(number);
// If the number starts with 11 or 18 and is of length 4,
// the pronunciation is ambiguous so check opts.numbers to see
// how to render it. Otherwise, if it starts with 11 or 18
// and has 2, 5, 8, 11, etc. digits, use 'an.' Finally, if it
// starts with an 8, use 'an.' For everything else, use 'a.'
if (startsWith11Or18 && number.length === 4) {
article = opts.numbers === 'colloquial' ? 'an' : 'a';
} else if (startsWith11Or18 && (number.length - 2) % 3 === 0) {
article = 'an';
} else {
article = number.startsWith('8') ? 'an' : 'a';
}
}
return article;
};

33
node_modules/indefinite/lib/rules/other.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
const { startsWithVowel } = require('../helpers');
const irregulars = require('../irregular-words');
const EXTRAS = /[\s'-]/;
const getFirst = word => word.split(EXTRAS)[0].toLowerCase();
const xor = (a, b) => (a || b) && !(a && b);
/**
* Try some variations on the word to determine whether it's irregular.
* Specifically, try trimming s, then es, then ed because those are common
* forms of plurals and past tense verbs (which can be used like adjectives).
*/
const checkForIrregulars = part => [ null, 's', 'es', 'ed' ].reduce((memo, ending) => memo || irregulars.check(part, ending), false);
exports.check = () => true;
exports.run = (word, opts) => {
// Only check the first word. Also, if it's hyphenated, only
// check the first part. Finally, if it's possessive, ignore
// the possessive part.
let first = getFirst(word);
let isIrregular = checkForIrregulars(first);
/**
* If it starts with a vowel and isn't irregular: "an"
* If it starts with a vowel and IS irregular: "a"
* If it starts with a consonant and isn't irregular: "a"
* If it starts with a consonant and IS irregular: "an"
*/
let article = xor(startsWithVowel(word), isIrregular) ? 'an' : 'a';
return article;
};