import { buildRankedDictionary } from './utils/helper.mjs'; import l33tTable from './data/l33tTable.mjs'; import translationKeys from './data/translationKeys.mjs'; import TrieNode from './matcher/dictionary/variants/matching/unmunger/TrieNode.mjs'; import l33tTableToTrieNode from './matcher/dictionary/variants/matching/unmunger/l33tTableToTrieNode.mjs'; import { timeEstimationValuesDefaults, checkTimeEstimationValues } from './TimeEstimates.mjs'; class Options { constructor(options = {}, customMatchers = {}) { this.matchers = {}; this.l33tTable = l33tTable; this.trieNodeRoot = l33tTableToTrieNode(l33tTable, new TrieNode()); this.dictionary = { userInputs: [] }; this.rankedDictionaries = {}; this.rankedDictionariesMaxWordSize = {}; this.translations = translationKeys; this.graphs = {}; this.useLevenshteinDistance = false; this.levenshteinThreshold = 2; this.l33tMaxSubstitutions = 100; this.maxLength = 256; this.wordSequenceNames = ['cardinalNumbers', 'ordinalNumbers', 'daysOfWeek', 'months', 'seasons', 'timePeriods', 'rainbowColors', 'directions', 'intermediateDirections', 'sizeProgression', 'militaryAlphabet', 'planets', 'zodiacSigns', 'chineseZodiac']; this.timeEstimationValues = { scoring: { ...timeEstimationValuesDefaults.scoring }, attackTime: { ...timeEstimationValuesDefaults.attackTime } }; this.setOptions(options); Object.entries(customMatchers).forEach(([name, matcher]) => { this.addMatcher(name, matcher); }); } isWordSequence(key) { return this.wordSequenceNames.some(name => key === name || key.startsWith(`${name}-`)); } // eslint-disable-next-line max-statements,complexity setOptions(options = {}) { if (options.l33tTable) { this.l33tTable = options.l33tTable; this.trieNodeRoot = l33tTableToTrieNode(options.l33tTable, new TrieNode()); } if (options.dictionary) { this.dictionary = options.dictionary; this.setRankedDictionaries(); } if (options.translations) { this.setTranslations(options.translations); } if (options.graphs) { this.graphs = options.graphs; } if (options.useLevenshteinDistance !== undefined) { this.useLevenshteinDistance = options.useLevenshteinDistance; } if (options.levenshteinThreshold !== undefined) { this.levenshteinThreshold = options.levenshteinThreshold; } if (options.l33tMaxSubstitutions !== undefined) { this.l33tMaxSubstitutions = options.l33tMaxSubstitutions; } if (options.maxLength !== undefined) { this.maxLength = options.maxLength; } if (options.timeEstimationValues !== undefined) { checkTimeEstimationValues(options.timeEstimationValues); this.timeEstimationValues = { scoring: { ...options.timeEstimationValues.scoring }, attackTime: { ...options.timeEstimationValues.attackTime } }; } } setTranslations(translations) { if (this.checkCustomTranslations(translations)) { this.translations = translations; } else { throw new Error('Invalid translations object fallback to keys'); } } checkCustomTranslations(translations) { let valid = true; Object.keys(translationKeys).forEach(type => { if (type in translations) { const translationType = type; Object.keys(translationKeys[translationType]).forEach(key => { if (!(key in translations[translationType])) { valid = false; } const translation = translations[translationType][key]; if (typeof translation !== 'string' && typeof translation !== 'function') { valid = false; } }); } else { valid = false; } }); return valid; } setRankedDictionaries() { const rankedDictionaries = {}; const rankedDictionariesMaxWorkSize = {}; Object.keys(this.dictionary).forEach(name => { rankedDictionaries[name] = buildRankedDictionary(this.dictionary[name]); rankedDictionariesMaxWorkSize[name] = this.getRankedDictionariesMaxWordSize(this.dictionary[name]); }); this.rankedDictionaries = rankedDictionaries; this.rankedDictionariesMaxWordSize = rankedDictionariesMaxWorkSize; } getRankedDictionariesMaxWordSize(list) { const data = list.map(el => { if (typeof el !== 'string') { return el.toString().length; } return el.length; }); // do not use Math.max(...data) because it can result in max stack size error because every entry will be used as an argument if (data.length === 0) { return 0; } return data.reduce((a, b) => Math.max(a, b), -Infinity); } buildSanitizedRankedDictionary(list) { const sanitizedInputs = []; list.forEach(input => { const inputType = typeof input; if (inputType === 'string' || inputType === 'number' || inputType === 'boolean') { sanitizedInputs.push(input.toString().toLowerCase()); } }); return buildRankedDictionary(sanitizedInputs); } getUserInputsOptions(dictionary) { let rankedDictionary = {}; let rankedDictionaryMaxWordSize = 0; if (dictionary) { rankedDictionary = this.buildSanitizedRankedDictionary(dictionary); rankedDictionaryMaxWordSize = this.getRankedDictionariesMaxWordSize(dictionary); } return { rankedDictionary, rankedDictionaryMaxWordSize }; } addMatcher(name, matcher) { if (this.matchers[name]) { console.info(`Matcher ${name} already exists`); } else { this.matchers[name] = matcher; } } } export { Options as default }; //# sourceMappingURL=Options.mjs.map