yomitan-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +485 -0
- package/dist/anki-connect-BQyCGW3O.cjs +513 -0
- package/dist/anki-connect-BQyCGW3O.cjs.map +1 -0
- package/dist/anki-connect-CPPuhyiQ.js +6 -0
- package/dist/anki-connect-DbrQHphS.js +495 -0
- package/dist/anki-connect-DbrQHphS.js.map +1 -0
- package/dist/anki-connect-DcheJrp-.cjs +6 -0
- package/dist/anki.cjs +1758 -0
- package/dist/anki.cjs.map +1 -0
- package/dist/anki.d.cts +751 -0
- package/dist/anki.d.cts.map +1 -0
- package/dist/anki.d.ts +751 -0
- package/dist/anki.d.ts.map +1 -0
- package/dist/anki.js +1751 -0
- package/dist/anki.js.map +1 -0
- package/dist/audio-D9DvYyB7.d.cts +48 -0
- package/dist/audio-D9DvYyB7.d.cts.map +1 -0
- package/dist/audio-DQulUkDM.d.ts +48 -0
- package/dist/audio-DQulUkDM.d.ts.map +1 -0
- package/dist/audio-url-generator-BXvQaqUi.cjs +4 -0
- package/dist/audio-url-generator-Dy2hb2Mm.cjs +414 -0
- package/dist/audio-url-generator-Dy2hb2Mm.cjs.map +1 -0
- package/dist/audio-url-generator-Qi0rfzHz.js +4 -0
- package/dist/audio-url-generator-pFQAB5Nb.js +390 -0
- package/dist/audio-url-generator-pFQAB5Nb.js.map +1 -0
- package/dist/audio.cjs +7 -0
- package/dist/audio.d.cts +86 -0
- package/dist/audio.d.cts.map +1 -0
- package/dist/audio.d.ts +86 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +4 -0
- package/dist/batch-processor-BR-gB3H3.js +84 -0
- package/dist/batch-processor-BR-gB3H3.js.map +1 -0
- package/dist/batch-processor-CSF1acTw.cjs +3 -0
- package/dist/batch-processor-DFqM_L-_.cjs +91 -0
- package/dist/batch-processor-DFqM_L-_.cjs.map +1 -0
- package/dist/batch-processor-Quo9jUyf.js +3 -0
- package/dist/chunk-BCwAaXi7.cjs +31 -0
- package/dist/cjk-util-Dp0ZU0sh.cjs +167 -0
- package/dist/cjk-util-Dp0ZU0sh.cjs.map +1 -0
- package/dist/cjk-util-DubXBGDG.js +94 -0
- package/dist/cjk-util-DubXBGDG.js.map +1 -0
- package/dist/core-BUpclilG.d.cts +102 -0
- package/dist/core-BUpclilG.d.cts.map +1 -0
- package/dist/core-DFUj5GtA.d.ts +102 -0
- package/dist/core-DFUj5GtA.d.ts.map +1 -0
- package/dist/database.cjs +7 -0
- package/dist/database.d.cts +4 -0
- package/dist/database.d.ts +4 -0
- package/dist/database.js +5 -0
- package/dist/dictionary-D7l-qFt1.d.cts +316 -0
- package/dist/dictionary-D7l-qFt1.d.cts.map +1 -0
- package/dist/dictionary-_vzfBLWi.d.ts +316 -0
- package/dist/dictionary-_vzfBLWi.d.ts.map +1 -0
- package/dist/dictionary-data-util-CHnRdYZ9.cjs +378 -0
- package/dist/dictionary-data-util-CHnRdYZ9.cjs.map +1 -0
- package/dist/dictionary-data-util-CfOLfEDE.js +323 -0
- package/dist/dictionary-data-util-CfOLfEDE.js.map +1 -0
- package/dist/dictionary-database-BDC2f9zc.d.ts +58 -0
- package/dist/dictionary-database-BDC2f9zc.d.ts.map +1 -0
- package/dist/dictionary-database-CU4TsvCC.js +393 -0
- package/dist/dictionary-database-CU4TsvCC.js.map +1 -0
- package/dist/dictionary-database-DsOi04Sg.d.cts +58 -0
- package/dist/dictionary-database-DsOi04Sg.d.cts.map +1 -0
- package/dist/dictionary-database-lvFvftnO.cjs +412 -0
- package/dist/dictionary-database-lvFvftnO.cjs.map +1 -0
- package/dist/dictionary-importer-BkQQSBhm.d.ts +237 -0
- package/dist/dictionary-importer-BkQQSBhm.d.ts.map +1 -0
- package/dist/dictionary-importer-Cen1z6co.js +1821 -0
- package/dist/dictionary-importer-Cen1z6co.js.map +1 -0
- package/dist/dictionary-importer-DYmmWmcX.cjs +8 -0
- package/dist/dictionary-importer-Da3AuTZw.d.cts +237 -0
- package/dist/dictionary-importer-Da3AuTZw.d.cts.map +1 -0
- package/dist/dictionary-importer-Dhn75iZ4.cjs +1834 -0
- package/dist/dictionary-importer-Dhn75iZ4.cjs.map +1 -0
- package/dist/dictionary-importer-xWkel0h-.js +8 -0
- package/dist/dictionary-update-checker-BNE4pGTx.js +4 -0
- package/dist/dictionary-update-checker-Byjvifd2.cjs +75 -0
- package/dist/dictionary-update-checker-Byjvifd2.cjs.map +1 -0
- package/dist/dictionary-update-checker-YdpalZ41.cjs +4 -0
- package/dist/dictionary-update-checker-kKukiovj.js +69 -0
- package/dist/dictionary-update-checker-kKukiovj.js.map +1 -0
- package/dist/display-generator-BGVWiI0t.js +746 -0
- package/dist/display-generator-BGVWiI0t.js.map +1 -0
- package/dist/display-generator-BMQmG5Ov.cjs +9 -0
- package/dist/display-generator-BxZ7mBjP.js +9 -0
- package/dist/display-generator-DyP-HNzP.cjs +758 -0
- package/dist/display-generator-DyP-HNzP.cjs.map +1 -0
- package/dist/errors-BSezaJwm.cjs +35 -0
- package/dist/errors-BSezaJwm.cjs.map +1 -0
- package/dist/errors-DuuDSO5N.js +22 -0
- package/dist/errors-DuuDSO5N.js.map +1 -0
- package/dist/frequency-ranking-BXjfhhUQ.js +3 -0
- package/dist/frequency-ranking-Cx1kkIrw.cjs +3 -0
- package/dist/frequency-ranking-DEJMTMdg.js +159 -0
- package/dist/frequency-ranking-DEJMTMdg.js.map +1 -0
- package/dist/frequency-ranking-DVYxTXN-.cjs +166 -0
- package/dist/frequency-ranking-DVYxTXN-.cjs.map +1 -0
- package/dist/furigana-5HK97CY8.js +4 -0
- package/dist/furigana-9bBI9-qe.d.ts +47 -0
- package/dist/furigana-9bBI9-qe.d.ts.map +1 -0
- package/dist/furigana-B3-0y231.js +471 -0
- package/dist/furigana-B3-0y231.js.map +1 -0
- package/dist/furigana-CjOhzvZt.d.cts +47 -0
- package/dist/furigana-CjOhzvZt.d.cts.map +1 -0
- package/dist/furigana-DpZLcues.cjs +609 -0
- package/dist/furigana-DpZLcues.cjs.map +1 -0
- package/dist/furigana-h3v2ub4-.cjs +4 -0
- package/dist/import.cjs +12 -0
- package/dist/import.d.cts +107 -0
- package/dist/import.d.cts.map +1 -0
- package/dist/import.d.ts +107 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +9 -0
- package/dist/index.cjs +275 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +211 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +211 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +238 -0
- package/dist/index.js.map +1 -0
- package/dist/json-DGd-cunA.js +17 -0
- package/dist/json-DGd-cunA.js.map +1 -0
- package/dist/json-DKWp-B7Y.cjs +30 -0
- package/dist/json-DKWp-B7Y.cjs.map +1 -0
- package/dist/language-KN_u-nTR.d.ts +104 -0
- package/dist/language-KN_u-nTR.d.ts.map +1 -0
- package/dist/language-xAbQxgXc.d.cts +104 -0
- package/dist/language-xAbQxgXc.d.cts.map +1 -0
- package/dist/language.cjs +15626 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +959 -0
- package/dist/language.d.cts.map +1 -0
- package/dist/language.d.ts +959 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +15522 -0
- package/dist/language.js.map +1 -0
- package/dist/log-D8KtR3aP.cjs +67 -0
- package/dist/log-D8KtR3aP.cjs.map +1 -0
- package/dist/log-hgSll-dS.js +60 -0
- package/dist/log-hgSll-dS.js.map +1 -0
- package/dist/lookup.cjs +13 -0
- package/dist/lookup.d.cts +161 -0
- package/dist/lookup.d.cts.map +1 -0
- package/dist/lookup.d.ts +161 -0
- package/dist/lookup.d.ts.map +1 -0
- package/dist/lookup.js +10 -0
- package/dist/media-loader-BABA_E4W.js +3 -0
- package/dist/media-loader-Ce9cuANS.cjs +21 -0
- package/dist/media-loader-Ce9cuANS.cjs.map +1 -0
- package/dist/media-loader-qRti-Q6h.js +14 -0
- package/dist/media-loader-qRti-Q6h.js.map +1 -0
- package/dist/media-loader-xlUGaJrx.cjs +3 -0
- package/dist/multi-language-transformer-AlxOM6b3.js +637 -0
- package/dist/multi-language-transformer-AlxOM6b3.js.map +1 -0
- package/dist/multi-language-transformer-MdbQBBOt.cjs +685 -0
- package/dist/multi-language-transformer-MdbQBBOt.cjs.map +1 -0
- package/dist/multi-language-transformer-SEhcJXEB.d.ts +63 -0
- package/dist/multi-language-transformer-SEhcJXEB.d.ts.map +1 -0
- package/dist/multi-language-transformer-Ul9mbRce.d.cts +63 -0
- package/dist/multi-language-transformer-Ul9mbRce.d.cts.map +1 -0
- package/dist/pronunciation-generator-BtBc4q_V.js +397 -0
- package/dist/pronunciation-generator-BtBc4q_V.js.map +1 -0
- package/dist/pronunciation-generator-CBYdXYou.js +4 -0
- package/dist/pronunciation-generator-CFbZlf5J.cjs +445 -0
- package/dist/pronunciation-generator-CFbZlf5J.cjs.map +1 -0
- package/dist/pronunciation-generator-DOz9hEuk.cjs +4 -0
- package/dist/render.cjs +2796 -0
- package/dist/render.cjs.map +1 -0
- package/dist/render.d.cts +424 -0
- package/dist/render.d.cts.map +1 -0
- package/dist/render.d.ts +424 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +2777 -0
- package/dist/render.js.map +1 -0
- package/dist/sentence-parser-BPAJNzqW.js +126 -0
- package/dist/sentence-parser-BPAJNzqW.js.map +1 -0
- package/dist/sentence-parser-BVIOI64h.cjs +132 -0
- package/dist/sentence-parser-BVIOI64h.cjs.map +1 -0
- package/dist/sentence-parser-BoHO3cHn.js +5 -0
- package/dist/sentence-parser-DQVLSW0z.cjs +5 -0
- package/dist/structured-content-generator-BtOApkTW.cjs +4 -0
- package/dist/structured-content-generator-Bx62RYa8.js +4 -0
- package/dist/structured-content-generator-CLnybumI.js +276 -0
- package/dist/structured-content-generator-CLnybumI.js.map +1 -0
- package/dist/structured-content-generator-DrwkB0-k.cjs +282 -0
- package/dist/structured-content-generator-DrwkB0-k.cjs.map +1 -0
- package/dist/text-utilities-B7PIythe.js +8 -0
- package/dist/text-utilities-B7PIythe.js.map +1 -0
- package/dist/text-utilities-Del2Ivkg.cjs +15 -0
- package/dist/text-utilities-Del2Ivkg.cjs.map +1 -0
- package/dist/translator-CRPlPzqi.cjs +1545 -0
- package/dist/translator-CRPlPzqi.cjs.map +1 -0
- package/dist/translator-CWgG5drA.js +1539 -0
- package/dist/translator-CWgG5drA.js.map +1 -0
- package/dist/translator-CaGtJvnQ.cjs +6 -0
- package/dist/translator-Cc6OGxrW.d.ts +180 -0
- package/dist/translator-Cc6OGxrW.d.ts.map +1 -0
- package/dist/translator-CcA-s-W4.d.cts +180 -0
- package/dist/translator-CcA-s-W4.d.cts.map +1 -0
- package/dist/translator-CuJOTK6l.js +6 -0
- package/dist/utilities-C-lbZaJE.cjs +52 -0
- package/dist/utilities-C-lbZaJE.cjs.map +1 -0
- package/dist/utilities-bi3EF-q5.js +33 -0
- package/dist/utilities-bi3EF-q5.js.map +1 -0
- package/package.json +102 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translator-CWgG5drA.js","names":["text: string","pattern: RegExp","replacement: string","match: RegExpExecArray","g0: string","g1: string | undefined","g2: string | undefined","HIRAGANA_RANGE: CodepointRange","KATAKANA_RANGE: CodepointRange","JAPANESE_RANGES: CodepointRange[]","BOPOMOFO_RANGE: CodepointRange","BOPOMOFO_EXTENDED_RANGE: CodepointRange","IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION_RANGE: CodepointRange","SMALL_FORM_RANGE: CodepointRange","VERTICAL_FORM_RANGE: CodepointRange","CHINESE_RANGES: CodepointRange[]","HANGUL_JAMO_RANGE: CodepointRange","HANGUL_COMPATIBILITY_JAMO_RANGE: CodepointRange","HANGUL_SYLLABLES_RANGE: CodepointRange","HANGUL_JAMO_EXTENDED_A_RANGE: CodepointRange","HANGUL_JAMO_EXTENDED_B_RANGE: CodepointRange","HANGUL_JAMO_HALF_WIDTH_RANGE: CodepointRange","KOREAN_RANGES: CodepointRange[]","codePoint: number","tags: Dictionary.Tag[]","dictionary: string","tagNames: string[]","results: TagExpansionTarget[]","newTags: Dictionary.Tag[]","tagGroups: TagGroup[]","newTagGroup: TagGroup","tagGroup: TagGroup","newTagNames: string[]","database: DictionaryDB","mode: FindTermsMode","text: string","options: Translation.FindTermsOptions","sortDictionaryMap: Translation.TermEnabledDictionaryMap","options: Translation.FindKanjiOptions","dictionaryEntries: Dictionary.KanjiDictionaryEntry[]","termReadingList: { term: string; reading: string | null }[]","dictionaries: string[]","results: {\n term: string;\n reading: string | null;\n dictionary: string;\n hasReading: boolean;\n frequency: number;\n displayValue: string | null;\n displayValueParsed: boolean;\n }[]","tagAggregator: TranslatorTagAggregator","primaryReading: string","deinflections: DatabaseDeinflection[]","enabledDictionaryMap: Translation.TermEnabledDictionaryMap","dictionaryEntries: TermDictionaryEntry[]","id: number","existingEntry: TermDictionaryEntry","textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[]","inflectionRuleChainCandidates: InflectionRuleChainCandidate[]","array1: string[]","array2: string[]","language: string","enabledDictionaryMap: Map<string, Translation.FindTermDictionary>","matchType: Dictionary.TermSourceMatchType","dictionaryDeinflections: DatabaseDeinflection[]","databaseEntries: DictionaryDatabase.TermEntry[]","uniqueDeinflectionArrays: DatabaseDeinflection[][]","sourceCache: TextCache","inflectionRuleChainCandidate: InflectionRuleChainCandidate","textProcessors: Language.TextProcessorWithId<unknown>[]","textReplacements: (Translation.FindTermsTextReplacement[] | null)[]","textCache: TextCache","variantsMap: VariantAndTextProcessorRuleChainCandidatesMap","newVariantsMap: VariantAndTextProcessorRuleChainCandidatesMap","id: string","setting: unknown","process: Language.TextProcessorFunction","searchResolution: string","currentString: string","replacements: Translation.FindTermsTextReplacement[]","originalText: string","transformedText: string","deinflectedText: string","conditions: number","sequenceList: SequenceQuery[]","groupedDictionaryEntries: DictionaryEntryGroup[]","newDictionaryEntries: TermDictionaryEntry[]","ungroupedDictionaryEntriesMap: Map<number, TermDictionaryEntry>","secondarySearchDictionaryMap: Translation.TermEnabledDictionaryMap","termList: DictionaryDatabase.TermExactRequest[]","targetList: { groups: DictionaryEntryGroup[] }[]","dictionaryEntries: Iterable<TermDictionaryEntry>","dictionaryEntry: TermDictionaryEntry","createGroupingKey: (entry: TermDictionaryEntry) => string","excludeDictionaryDefinitions: Set<string>","definitions: Dictionary.TermDefinition[]","indexRemap: Map<number, number>","array: (Dictionary.TermPronunciation | Dictionary.TermFrequency)[]","array: { dictionary: string }[]","array: Dictionary.Tag[]","array: { tags: Dictionary.Tag[] }[]","tagExpansionTargets: TagExpansionTarget[]","tagTargets: TagExpansionTarget[]","allItems: TagTargetItem[]","nonCachedItems: TagTargetItem[]","v1: Dictionary.Tag","v2: Dictionary.Tag","category: string","results: string[]","lastDictionary: string | null","headwordMapKeys: string[]","headwordReadingMaps: Map<\n string,\n {\n headwordIndex: number;\n pronunciations: Dictionary.TermPronunciation[];\n frequencies: Dictionary.TermFrequency[];\n }[]\n >[]","pitches: Dictionary.PitchAccent[]","tags2: Dictionary.Tag[]","phoneticTranscriptions: Dictionary.PhoneticTranscription[]","enabledDictionaryMap: Translation.KanjiEnabledDictionaryMap","kanjiList: string[]","stats: { [key: string]: string | number }","items: { query: string; dictionary: string }[]","groupedStats: Dictionary.KanjiStatGroups","stats: Dictionary.KanjiStat[]","value: string","frequency: DictionaryData.GenericFrequencyData","displayValue: string | null","name: string","enabledDictionaryMap: Translation.TermEnabledDictionaryMap | Translation.KanjiEnabledDictionaryMap","array: unknown[]","value: number | number[] | undefined","value: string | number","databaseInfo: DictionaryDatabase.Tag","index: number","dictionaryIndex: number","dictionaryAlias: string","character: string","frequency: number","displayValueParsed: boolean","onyomi: string[]","kunyomi: string[]","stats: Dictionary.KanjiStatGroups","definitions: string[]","databaseTag: DictionaryDatabase.Tag | null","category: string | undefined","notes: string | undefined","order: number | undefined","score: number | undefined","matchSource: Dictionary.TermSourceMatchSource","isPrimary: boolean","term: string","reading: string","sources: Dictionary.TermSource[]","wordClasses: string[]","headwordIndices: number[]","score: number","sequences: number[]","entries: DictionaryData.TermGlossaryContent[]","headwordIndex: number","pronunciations: Dictionary.Pronunciation[]","hasReading: boolean","inflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[]","sourceTermExactMatchCount: number","matchPrimaryReading: boolean","maxOriginalTextLength: number","headwords: Dictionary.TermHeadword[]","databaseEntry: DictionaryDatabase.TermEntry","headwordTagGroups: Dictionary.Tag[]","definitionTagGroups: Dictionary.Tag[]","expandedInflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[]","checkDuplicateDefinitions: boolean","definitionEntries: { index: number; dictionaryEntry: TermDictionaryEntry; headwordIndexMap: number[] }[]","definitionsMap: Map<string, Dictionary.TermDefinition> | null","inflections: Dictionary.InflectionRuleChainCandidate[] | null","textProcesses: TextProcessorRuleChainCandidate[] | null","headwordsArray: Dictionary.TermHeadword[]","headwordDictionaryIndices: Map<number, number>","list: T[]","newItems: T[]","newSources: Dictionary.TermSource[]","headwordsMap: Map<string, Dictionary.TermHeadword>","headwordIndexMap: number[]","newDefinitions: Dictionary.TermDefinition[]","headwordIndicesNew: number[]","definitionsMap: Map<string, Dictionary.TermDefinition>","databaseEntries: (DictionaryDatabase.TermEntry | DictionaryDatabase.KanjiEntry)[]","v1: { index: number }","v2: { index: number }","v1: Dictionary.KanjiDictionaryEntry","v2: Dictionary.KanjiDictionaryEntry","v1: TermDictionaryEntry","v2: TermDictionaryEntry","v1: Dictionary.TermDefinition","v2: Dictionary.TermDefinition","dataList: (Dictionary.TermFrequency | Dictionary.TermPronunciation)[]","v1: Dictionary.TermFrequency | Dictionary.TermPronunciation","v2: Dictionary.TermFrequency | Dictionary.TermPronunciation","v1: Dictionary.KanjiFrequency","v2: Dictionary.KanjiFrequency","ascending: boolean","result: TermDictionaryEntry[]","set: Set<T>","values: T[]"],"sources":["../src/util/regex-util.ts","../src/lookup/translator.ts"],"sourcesContent":["const matchReplacementPattern = /\\$(?:\\$|&|`|'|(\\d\\d?)|<([^>]*)>)/g;\n\n/**\n * Applies string.replace using a regular expression and replacement string as arguments.\n */\nexport function applyTextReplacement(text: string, pattern: RegExp, replacement: string): string {\n const isGlobal = pattern.global;\n if (isGlobal) {\n pattern.lastIndex = 0;\n }\n for (let loop = true; loop; loop = isGlobal) {\n const match = pattern.exec(text);\n if (match === null) {\n break;\n }\n\n const matchText = match[0];\n const index = match.index;\n const actualReplacement = applyMatchReplacement(replacement, match);\n const actualReplacementLength = actualReplacement.length;\n const delta = actualReplacementLength - (matchText.length > 0 ? matchText.length : -1);\n\n text = `${text.substring(0, index)}${actualReplacement}${text.substring(index + matchText.length)}`;\n pattern.lastIndex += delta;\n }\n return text;\n}\n\n/**\n * Applies the replacement string for a given regular expression match.\n */\nexport function applyMatchReplacement(replacement: string, match: RegExpExecArray): string {\n const pattern = matchReplacementPattern;\n pattern.lastIndex = 0;\n const replacer = (g0: string, g1: string | undefined, g2: string | undefined): string => {\n if (typeof g1 !== 'undefined') {\n const matchIndex = Number.parseInt(g1, 10);\n if (matchIndex >= 1 && matchIndex <= match.length) {\n return match[matchIndex];\n }\n } else if (typeof g2 !== 'undefined') {\n const { groups } = match;\n if (typeof groups === 'object' && groups !== null && Object.prototype.hasOwnProperty.call(groups, g2)) {\n return groups[g2];\n }\n } else {\n let { index } = match;\n if (typeof index !== 'number') {\n index = 0;\n }\n switch (g0) {\n case '$':\n return '$';\n case '&':\n return match[0];\n case '`':\n return replacement.substring(0, index);\n case \"'\":\n return replacement.substring(index + g0.length);\n }\n }\n return g0;\n };\n return replacement.replace(pattern, replacer);\n}\n","/*\n * Copyright (C) 2023-2025 Yomitan Authors\n * Copyright (C) 2016-2022 Yomichan Authors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\nimport type { DictionaryDB } from '../database/dictionary-database';\nimport {\n CJK_IDEOGRAPH_RANGES,\n CJK_PUNCTUATION_RANGE,\n FULLWIDTH_CHARACTER_RANGES,\n isCodePointInRanges,\n} from '../language/cjk-util';\nimport type { CodepointRange } from '../language/cjk-util';\nimport { LanguageTransformer } from '../language/language-transformer';\nimport type { TransformedText } from '../language/language-transformer';\nimport { getAllLanguageReadingNormalizers, getAllLanguageTextProcessors } from '../language/languages';\nimport { MultiLanguageTransformer } from '../language/multi-language-transformer';\nimport type * as Dictionary from '../types/dictionary';\nimport type * as DictionaryData from '../types/dictionary-data';\nimport type * as DictionaryDatabase from '../types/dictionary-database';\nimport type * as Language from '../types/language';\nimport type * as Translation from '../types/translation';\nimport { applyTextReplacement } from '../util/regex-util';\n\n// --- Internal types ---\n\ntype DictionaryTagCache = Map<string, Map<string, DictionaryDatabase.Tag | null>>;\n\ntype TextProcessorMap = Map<\n string,\n {\n textPreprocessors: Language.TextProcessorWithId<unknown>[];\n textPostprocessors: Language.TextProcessorWithId<unknown>[];\n }\n>;\n\ntype ReadingNormalizerMap = Map<string, Language.ReadingNormalizer>;\n\ntype TextProcessorRuleChainCandidate = string[];\n\ntype InflectionRuleChainCandidate = {\n source: Dictionary.InflectionSource;\n inflectionRules: string[];\n};\n\ntype TermDictionaryEntry = Dictionary.TermDictionaryEntry;\n\ntype DatabaseDeinflection = {\n originalText: string;\n transformedText: string;\n deinflectedText: string;\n conditions: number;\n textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[];\n inflectionRuleChainCandidates: InflectionRuleChainCandidate[];\n databaseEntries: DictionaryDatabase.TermEntry[];\n};\n\ntype DictionaryEntryGroup = {\n ids: Set<number>;\n dictionaryEntries: TermDictionaryEntry[];\n};\n\ntype SequenceQuery = {\n query: number;\n dictionary: string;\n};\n\ntype TagGroup = {\n dictionary: string;\n tagNames: string[];\n};\n\ntype TagExpansionTarget = {\n tags: Dictionary.Tag[];\n tagGroups: TagGroup[];\n};\n\ntype TagTargetItem = {\n query: string;\n dictionary: string;\n tagName: string;\n cache: Map<string, DictionaryDatabase.Tag | null> | null;\n databaseTag: DictionaryDatabase.Tag | null;\n targets: Dictionary.Tag[][];\n};\n\ntype TextCache = Map<string, Map<string, Map<unknown, string>>>;\n\ntype VariantAndTextProcessorRuleChainCandidatesMap = Map<string, TextProcessorRuleChainCandidate[]>;\n\nexport type FindTermsMode = 'group' | 'term' | 'merge' | 'simple';\n\n// --- CJK Range definitions for JCK filtering ---\n\nconst HIRAGANA_RANGE: CodepointRange = [0x3040, 0x309f];\nconst KATAKANA_RANGE: CodepointRange = [0x30a0, 0x30ff];\n\nconst JAPANESE_RANGES: CodepointRange[] = [\n HIRAGANA_RANGE,\n KATAKANA_RANGE,\n ...CJK_IDEOGRAPH_RANGES,\n [0xff66, 0xff9f], // Halfwidth katakana\n [0x30fb, 0x30fc], // Katakana punctuation\n [0xff61, 0xff65], // Kana punctuation\n CJK_PUNCTUATION_RANGE,\n ...FULLWIDTH_CHARACTER_RANGES,\n];\n\nconst BOPOMOFO_RANGE: CodepointRange = [0x3100, 0x312f];\nconst BOPOMOFO_EXTENDED_RANGE: CodepointRange = [0x31a0, 0x31bf];\nconst IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION_RANGE: CodepointRange = [0x16fe0, 0x16fff];\nconst SMALL_FORM_RANGE: CodepointRange = [0xfe50, 0xfe6f];\nconst VERTICAL_FORM_RANGE: CodepointRange = [0xfe10, 0xfe1f];\n\nconst CHINESE_RANGES: CodepointRange[] = [\n ...CJK_IDEOGRAPH_RANGES,\n CJK_PUNCTUATION_RANGE,\n ...FULLWIDTH_CHARACTER_RANGES,\n BOPOMOFO_RANGE,\n BOPOMOFO_EXTENDED_RANGE,\n IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION_RANGE,\n SMALL_FORM_RANGE,\n VERTICAL_FORM_RANGE,\n];\n\nconst HANGUL_JAMO_RANGE: CodepointRange = [0x1100, 0x11ff];\nconst HANGUL_COMPATIBILITY_JAMO_RANGE: CodepointRange = [0x3130, 0x318f];\nconst HANGUL_SYLLABLES_RANGE: CodepointRange = [0xac00, 0xd7af];\nconst HANGUL_JAMO_EXTENDED_A_RANGE: CodepointRange = [0xa960, 0xa97f];\nconst HANGUL_JAMO_EXTENDED_B_RANGE: CodepointRange = [0xd7b0, 0xd7ff];\nconst HANGUL_JAMO_HALF_WIDTH_RANGE: CodepointRange = [0xffa0, 0xffdc];\n\nconst KOREAN_RANGES: CodepointRange[] = [\n ...CJK_IDEOGRAPH_RANGES,\n CJK_PUNCTUATION_RANGE,\n ...FULLWIDTH_CHARACTER_RANGES,\n HANGUL_JAMO_RANGE,\n HANGUL_COMPATIBILITY_JAMO_RANGE,\n HANGUL_SYLLABLES_RANGE,\n HANGUL_JAMO_EXTENDED_A_RANGE,\n HANGUL_JAMO_EXTENDED_B_RANGE,\n HANGUL_JAMO_HALF_WIDTH_RANGE,\n];\n\nfunction isCodePointJapanese(codePoint: number): boolean {\n return isCodePointInRanges(codePoint, JAPANESE_RANGES);\n}\n\nfunction isCodePointChinese(codePoint: number): boolean {\n return isCodePointInRanges(codePoint, CHINESE_RANGES);\n}\n\nfunction isCodePointKorean(codePoint: number): boolean {\n return isCodePointInRanges(codePoint, KOREAN_RANGES);\n}\n\n// --- TranslatorTagAggregator ---\n\nclass TranslatorTagAggregator {\n private _tagExpansionTargetMap: Map<Dictionary.Tag[], TagGroup[]>;\n\n constructor() {\n this._tagExpansionTargetMap = new Map();\n }\n\n addTags(tags: Dictionary.Tag[], dictionary: string, tagNames: string[]): void {\n if (tagNames.length === 0) {\n return;\n }\n const tagGroups = this._getOrCreateTagGroups(tags);\n const tagGroup = this._getOrCreateTagGroup(tagGroups, dictionary);\n this._addUniqueTags(tagGroup, tagNames);\n }\n\n getTagExpansionTargets(): TagExpansionTarget[] {\n const results: TagExpansionTarget[] = [];\n for (const [tags, tagGroups] of this._tagExpansionTargetMap) {\n results.push({ tags, tagGroups });\n }\n return results;\n }\n\n mergeTags(tags: Dictionary.Tag[], newTags: Dictionary.Tag[]): void {\n const newTagGroups = this._tagExpansionTargetMap.get(newTags);\n if (typeof newTagGroups === 'undefined') {\n return;\n }\n const tagGroups = this._getOrCreateTagGroups(tags);\n for (const { dictionary, tagNames } of newTagGroups) {\n const tagGroup = this._getOrCreateTagGroup(tagGroups, dictionary);\n this._addUniqueTags(tagGroup, tagNames);\n }\n }\n\n private _getOrCreateTagGroups(tags: Dictionary.Tag[]): TagGroup[] {\n let tagGroups = this._tagExpansionTargetMap.get(tags);\n if (typeof tagGroups === 'undefined') {\n tagGroups = [];\n this._tagExpansionTargetMap.set(tags, tagGroups);\n }\n return tagGroups;\n }\n\n private _getOrCreateTagGroup(tagGroups: TagGroup[], dictionary: string): TagGroup {\n for (const tagGroup of tagGroups) {\n if (tagGroup.dictionary === dictionary) {\n return tagGroup;\n }\n }\n const newTagGroup: TagGroup = { dictionary, tagNames: [] };\n tagGroups.push(newTagGroup);\n return newTagGroup;\n }\n\n private _addUniqueTags(tagGroup: TagGroup, newTagNames: string[]): void {\n const { tagNames } = tagGroup;\n for (const tagName of newTagNames) {\n if (tagNames.includes(tagName)) {\n continue;\n }\n tagNames.push(tagName);\n }\n }\n}\n\n// --- Translator ---\n\n/**\n * Class which finds term and kanji dictionary entries for text.\n */\nexport class Translator {\n private _database: DictionaryDB;\n private _multiLanguageTransformer: MultiLanguageTransformer;\n private _tagCache: DictionaryTagCache;\n private _stringComparer: Intl.Collator;\n private _numberRegex: RegExp;\n private _textProcessors: TextProcessorMap;\n private _readingNormalizers: ReadingNormalizerMap;\n\n constructor(database: DictionaryDB) {\n this._database = database;\n this._multiLanguageTransformer = new MultiLanguageTransformer();\n this._tagCache = new Map();\n this._stringComparer = new Intl.Collator('en-US'); // Invariant locale\n this._numberRegex = /[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?/;\n this._textProcessors = new Map();\n this._readingNormalizers = new Map();\n }\n\n /**\n * Initializes the instance for use. The public API should not be used until this function has been called.\n */\n prepare(): void {\n this._multiLanguageTransformer.prepare();\n for (const { iso, textPreprocessors = [], textPostprocessors = [] } of getAllLanguageTextProcessors()) {\n this._textProcessors.set(iso, { textPreprocessors, textPostprocessors });\n }\n for (const { iso, readingNormalizer } of getAllLanguageReadingNormalizers()) {\n this._readingNormalizers.set(iso, readingNormalizer);\n }\n }\n\n /**\n * Clears the database tag cache. This should be executed if the database is changed.\n */\n clearDatabaseCaches(): void {\n this._tagCache.clear();\n }\n\n /**\n * Finds term definitions for the given text.\n */\n async findTerms(\n mode: FindTermsMode,\n text: string,\n options: Translation.FindTermsOptions,\n ): Promise<{ dictionaryEntries: TermDictionaryEntry[]; originalTextLength: number }> {\n const {\n enabledDictionaryMap,\n excludeDictionaryDefinitions,\n sortFrequencyDictionary,\n sortFrequencyDictionaryOrder,\n language,\n primaryReading,\n } = options;\n const tagAggregator = new TranslatorTagAggregator();\n let { dictionaryEntries, originalTextLength } = await this._findTermsInternal(\n text,\n options,\n tagAggregator,\n primaryReading,\n );\n\n switch (mode) {\n case 'group':\n dictionaryEntries = this._groupDictionaryEntriesByHeadword(\n language,\n dictionaryEntries,\n tagAggregator,\n primaryReading,\n );\n break;\n case 'term':\n dictionaryEntries = this._groupDictionaryEntriesByTerm(\n language,\n dictionaryEntries,\n tagAggregator,\n primaryReading,\n );\n break;\n case 'merge':\n dictionaryEntries = await this._getRelatedDictionaryEntries(dictionaryEntries, options, tagAggregator);\n break;\n }\n\n if (excludeDictionaryDefinitions !== null) {\n this._removeExcludedDefinitions(dictionaryEntries, excludeDictionaryDefinitions);\n }\n\n if (mode !== 'simple') {\n await this._addTermMeta(dictionaryEntries, enabledDictionaryMap, tagAggregator);\n await this._expandTagGroupsAndGroup(tagAggregator.getTagExpansionTargets());\n } else {\n if (sortFrequencyDictionary !== null) {\n const sortDictionaryMap: Translation.TermEnabledDictionaryMap = new Map();\n const value = enabledDictionaryMap.get(sortFrequencyDictionary);\n if (typeof value !== 'undefined') {\n sortDictionaryMap.set(sortFrequencyDictionary, value);\n }\n await this._addTermMeta(dictionaryEntries, sortDictionaryMap, tagAggregator);\n }\n }\n\n if (sortFrequencyDictionary !== null) {\n this._updateSortFrequencies(\n dictionaryEntries,\n sortFrequencyDictionary,\n sortFrequencyDictionaryOrder === 'ascending',\n );\n }\n if (dictionaryEntries.length > 1) {\n this._sortTermDictionaryEntries(dictionaryEntries);\n }\n for (const { definitions, frequencies, pronunciations } of dictionaryEntries) {\n this._flagRedundantDefinitionTags(definitions);\n if (definitions.length > 1) {\n this._sortTermDictionaryEntryDefinitions(definitions);\n }\n if (frequencies.length > 1) {\n this._sortTermDictionaryEntrySimpleData(frequencies);\n }\n if (pronunciations.length > 1) {\n this._sortTermDictionaryEntrySimpleData(pronunciations);\n }\n }\n const withUserFacingInflections = this._addUserFacingInflections(language, dictionaryEntries);\n\n return { dictionaryEntries: withUserFacingInflections, originalTextLength };\n }\n\n /**\n * Finds kanji definitions for the given text.\n */\n async findKanji(text: string, options: Translation.FindKanjiOptions): Promise<Dictionary.KanjiDictionaryEntry[]> {\n if (options.removeNonJapaneseCharacters) {\n text = this._getJapaneseChineseKoreanOnlyText(text);\n }\n const { enabledDictionaryMap } = options;\n const kanjiUnique = new Set<string>();\n for (const c of text) {\n kanjiUnique.add(c);\n }\n\n const databaseEntries = await this._database.findKanjiBulk([...kanjiUnique], enabledDictionaryMap);\n if (databaseEntries.length === 0) {\n return [];\n }\n\n this._sortDatabaseEntriesByIndex(databaseEntries);\n\n const dictionaryEntries: Dictionary.KanjiDictionaryEntry[] = [];\n const tagAggregator = new TranslatorTagAggregator();\n for (const { character, onyomi, kunyomi, tags, definitions, stats, dictionary } of databaseEntries) {\n const expandedStats = await this._expandKanjiStats(stats, dictionary);\n const dictionaryAlias = this._getDictionaryAlias(dictionary, enabledDictionaryMap);\n const dictionaryEntry = this._createKanjiDictionaryEntry(\n character,\n dictionary,\n dictionaryAlias,\n onyomi,\n kunyomi,\n expandedStats,\n definitions,\n enabledDictionaryMap,\n );\n dictionaryEntries.push(dictionaryEntry);\n tagAggregator.addTags(dictionaryEntry.tags, dictionary, tags);\n }\n\n if (dictionaryEntries.length > 1) {\n this._sortKanjiDictionaryEntries(dictionaryEntries);\n }\n\n await this._addKanjiMeta(dictionaryEntries, enabledDictionaryMap);\n await this._expandTagGroupsAndGroup(tagAggregator.getTagExpansionTargets());\n\n this._sortKanjiDictionaryEntryData(dictionaryEntries);\n\n return dictionaryEntries;\n }\n\n /**\n * Gets a list of frequency information for a given list of term-reading pairs\n * and a list of dictionaries.\n */\n async getTermFrequencies(\n termReadingList: { term: string; reading: string | null }[],\n dictionaries: string[],\n ): Promise<\n {\n term: string;\n reading: string | null;\n dictionary: string;\n hasReading: boolean;\n frequency: number;\n displayValue: string | null;\n displayValueParsed: boolean;\n }[]\n > {\n const dictionarySet = new Set<string>();\n for (const dictionary of dictionaries) {\n dictionarySet.add(dictionary);\n }\n\n const termList = termReadingList.map(({ term }) => term);\n const metas = await this._database.findTermMetaBulk(termList, dictionarySet);\n\n const results: {\n term: string;\n reading: string | null;\n dictionary: string;\n hasReading: boolean;\n frequency: number;\n displayValue: string | null;\n displayValueParsed: boolean;\n }[] = [];\n for (const { mode, data, dictionary, index } of metas) {\n if (mode !== 'freq') {\n continue;\n }\n let { term, reading } = termReadingList[index];\n const hasReading =\n data !== null &&\n typeof data === 'object' &&\n typeof (data as DictionaryData.TermMetaFrequencyDataWithReading).reading === 'string';\n if (hasReading && (data as DictionaryData.TermMetaFrequencyDataWithReading).reading !== reading) {\n if (reading !== null) {\n continue;\n }\n reading = (data as DictionaryData.TermMetaFrequencyDataWithReading).reading;\n }\n const frequency = hasReading\n ? (data as DictionaryData.TermMetaFrequencyDataWithReading).frequency\n : (data as DictionaryData.GenericFrequencyData);\n const { frequency: frequencyValue, displayValue, displayValueParsed } = this._getFrequencyInfo(frequency);\n results.push({\n term,\n reading,\n dictionary,\n hasReading,\n frequency: frequencyValue,\n displayValue,\n displayValueParsed,\n });\n }\n return results;\n }\n\n // Find terms internal implementation\n\n private async _findTermsInternal(\n text: string,\n options: Translation.FindTermsOptions,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): Promise<{ dictionaryEntries: TermDictionaryEntry[]; originalTextLength: number }> {\n const { removeNonJapaneseCharacters, enabledDictionaryMap } = options;\n if (removeNonJapaneseCharacters && ['ja', 'zh', 'yue', 'ko'].includes(options.language)) {\n text = this._getJapaneseChineseKoreanOnlyText(text);\n }\n if (text.length === 0) {\n return { dictionaryEntries: [], originalTextLength: 0 };\n }\n\n const deinflections = await this._getDeinflections(text, options);\n\n return this._getDictionaryEntries(deinflections, enabledDictionaryMap, tagAggregator, primaryReading);\n }\n\n private _getDictionaryEntries(\n deinflections: DatabaseDeinflection[],\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): { dictionaryEntries: TermDictionaryEntry[]; originalTextLength: number } {\n let originalTextLength = 0;\n const dictionaryEntries: TermDictionaryEntry[] = [];\n const ids = new Set<number>();\n for (const {\n databaseEntries,\n originalText,\n transformedText,\n deinflectedText,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates,\n } of deinflections) {\n if (databaseEntries.length === 0) {\n continue;\n }\n originalTextLength = Math.max(originalTextLength, originalText.length);\n for (const databaseEntry of databaseEntries) {\n const { id } = databaseEntry;\n if (ids.has(id)) {\n const existingEntryInfo = this._findExistingEntry(dictionaryEntries, id);\n if (!existingEntryInfo) {\n continue;\n }\n const { existingEntry, existingIndex } = existingEntryInfo;\n\n const existingTransformedLength = existingEntry.headwords[0].sources[0].transformedText.length;\n if (transformedText.length < existingTransformedLength) {\n continue;\n }\n if (transformedText.length > existingTransformedLength) {\n dictionaryEntries.splice(\n existingIndex,\n 1,\n this._createTermDictionaryEntryFromDatabaseEntry(\n databaseEntry,\n originalText,\n transformedText,\n deinflectedText,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates,\n true,\n enabledDictionaryMap,\n tagAggregator,\n primaryReading,\n ),\n );\n } else {\n this._mergeInflectionRuleChains(existingEntry, inflectionRuleChainCandidates);\n this._mergeTextProcessorRuleChains(existingEntry, textProcessorRuleChainCandidates);\n }\n } else {\n const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(\n databaseEntry,\n originalText,\n transformedText,\n deinflectedText,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates,\n true,\n enabledDictionaryMap,\n tagAggregator,\n primaryReading,\n );\n dictionaryEntries.push(dictionaryEntry);\n ids.add(id);\n }\n }\n }\n return { dictionaryEntries, originalTextLength };\n }\n\n private _findExistingEntry(\n dictionaryEntries: TermDictionaryEntry[],\n id: number,\n ): { existingEntry: TermDictionaryEntry; existingIndex: number } | null {\n for (const [index, entry] of dictionaryEntries.entries()) {\n if (entry.definitions.some((definition) => definition.id === id)) {\n return { existingEntry: entry, existingIndex: index };\n }\n }\n return null;\n }\n\n private _mergeTextProcessorRuleChains(\n existingEntry: TermDictionaryEntry,\n textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[],\n ): void {\n const existingChains = existingEntry.textProcessorRuleChainCandidates;\n\n for (const textProcessorRules of textProcessorRuleChainCandidates) {\n const duplicate = existingChains.find((existingChain) => {\n return this._areArraysEqualIgnoreOrder(existingChain, textProcessorRules);\n });\n if (!duplicate) {\n existingEntry.textProcessorRuleChainCandidates.push(textProcessorRules);\n }\n }\n }\n\n private _mergeInflectionRuleChains(\n existingEntry: TermDictionaryEntry,\n inflectionRuleChainCandidates: InflectionRuleChainCandidate[],\n ): void {\n const existingChains = existingEntry.inflectionRuleChainCandidates;\n\n for (const { source, inflectionRules } of inflectionRuleChainCandidates) {\n const duplicate = existingChains.find((existingChain) => {\n return this._areArraysEqualIgnoreOrder(\n existingChain.inflectionRules.map((r) => r.name),\n inflectionRules,\n );\n });\n if (!duplicate) {\n existingEntry.inflectionRuleChainCandidates.push({\n source,\n inflectionRules: inflectionRules.map((rule) => ({ name: rule })),\n });\n } else if (duplicate.source !== source) {\n duplicate.source = 'both';\n }\n }\n }\n\n private _areArraysEqualIgnoreOrder(array1: string[], array2: string[]): boolean {\n if (array1.length !== array2.length) {\n return false;\n }\n\n const frequencyCounter = new Map<string, number>();\n\n for (const element of array1) {\n frequencyCounter.set(element, (frequencyCounter.get(element) || 0) + 1);\n }\n\n for (const element of array2) {\n const frequency = frequencyCounter.get(element);\n if (!frequency) {\n return false;\n }\n frequencyCounter.set(element, frequency - 1);\n }\n\n return true;\n }\n\n // Deinflections\n\n private async _getDeinflections(\n text: string,\n options: Translation.FindTermsOptions,\n ): Promise<DatabaseDeinflection[]> {\n let deinflections = options.deinflect\n ? this._getAlgorithmDeinflections(text, options)\n : [this._createDeinflection(text, text, text, 0, [], [])];\n if (deinflections.length === 0) {\n return [];\n }\n\n const { matchType, language, enabledDictionaryMap } = options;\n\n await this._addEntriesToDeinflections(language, deinflections, enabledDictionaryMap, matchType);\n\n const dictionaryDeinflections = await this._getDictionaryDeinflections(\n language,\n deinflections,\n enabledDictionaryMap,\n matchType,\n );\n deinflections.push(...dictionaryDeinflections);\n\n for (const deinflection of deinflections) {\n for (const entry of deinflection.databaseEntries) {\n entry.definitions = entry.definitions.filter((definition) => !Array.isArray(definition));\n }\n deinflection.databaseEntries = deinflection.databaseEntries.filter((entry) => entry.definitions.length);\n }\n deinflections = deinflections.filter((deinflection) => deinflection.databaseEntries.length);\n\n return deinflections;\n }\n\n private async _getDictionaryDeinflections(\n language: string,\n deinflections: DatabaseDeinflection[],\n enabledDictionaryMap: Map<string, Translation.FindTermDictionary>,\n matchType: Dictionary.TermSourceMatchType,\n ): Promise<DatabaseDeinflection[]> {\n const dictionaryDeinflections: DatabaseDeinflection[] = [];\n for (const deinflection of deinflections) {\n const {\n originalText,\n transformedText,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates: algorithmChains,\n databaseEntries,\n } = deinflection;\n for (const entry of databaseEntries) {\n const { dictionary, definitions } = entry;\n const entryDictionary = enabledDictionaryMap.get(dictionary);\n const useDeinflections = entryDictionary?.useDeinflections ?? true;\n if (!useDeinflections) {\n continue;\n }\n for (const definition of definitions) {\n if (Array.isArray(definition)) {\n const [formOf, inflectionRules] = definition as [string, string[]];\n if (!formOf) {\n continue;\n }\n\n const inflectionRuleChainCandidates = algorithmChains.map(\n ({ inflectionRules: algInflections }) => {\n return {\n source: (algInflections.length === 0\n ? 'dictionary'\n : 'both') as Dictionary.InflectionSource,\n inflectionRules: [...algInflections, ...inflectionRules],\n };\n },\n );\n\n const dictionaryDeinflection = this._createDeinflection(\n originalText,\n transformedText,\n formOf,\n 0,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates,\n );\n dictionaryDeinflections.push(dictionaryDeinflection);\n }\n }\n }\n }\n\n await this._addEntriesToDeinflections(language, dictionaryDeinflections, enabledDictionaryMap, matchType);\n\n return dictionaryDeinflections;\n }\n\n private async _addEntriesToDeinflections(\n language: string,\n deinflections: DatabaseDeinflection[],\n enabledDictionaryMap: Map<string, Translation.FindTermDictionary>,\n matchType: Dictionary.TermSourceMatchType,\n ): Promise<void> {\n const uniqueDeinflectionsMap = this._groupDeinflectionsByTerm(deinflections);\n const uniqueDeinflectionArrays = [...uniqueDeinflectionsMap.values()];\n const uniqueDeinflectionTerms = [...uniqueDeinflectionsMap.keys()];\n\n const databaseEntries = await this._database.findTermsBulk(\n uniqueDeinflectionTerms,\n enabledDictionaryMap,\n matchType,\n );\n this._matchEntriesToDeinflections(language, databaseEntries, uniqueDeinflectionArrays, enabledDictionaryMap);\n }\n\n private _groupDeinflectionsByTerm(deinflections: DatabaseDeinflection[]): Map<string, DatabaseDeinflection[]> {\n const result = new Map<string, DatabaseDeinflection[]>();\n for (const deinflection of deinflections) {\n const { deinflectedText } = deinflection;\n let deinflectionArray = result.get(deinflectedText);\n if (typeof deinflectionArray === 'undefined') {\n deinflectionArray = [];\n result.set(deinflectedText, deinflectionArray);\n }\n deinflectionArray.push(deinflection);\n }\n return result;\n }\n\n private _matchEntriesToDeinflections(\n language: string,\n databaseEntries: DictionaryDatabase.TermEntry[],\n uniqueDeinflectionArrays: DatabaseDeinflection[][],\n enabledDictionaryMap: Map<string, Translation.FindTermDictionary>,\n ): void {\n for (const databaseEntry of databaseEntries) {\n const entryDictionary = enabledDictionaryMap.get(databaseEntry.dictionary);\n if (typeof entryDictionary === 'undefined') {\n continue;\n }\n const { partsOfSpeechFilter } = entryDictionary;\n\n const definitionConditions = this._multiLanguageTransformer.getConditionFlagsFromPartsOfSpeech(\n language,\n databaseEntry.rules,\n );\n for (const deinflection of uniqueDeinflectionArrays[databaseEntry.index]) {\n if (\n !partsOfSpeechFilter ||\n LanguageTransformer.conditionsMatch(deinflection.conditions, definitionConditions)\n ) {\n deinflection.databaseEntries.push(databaseEntry);\n }\n }\n }\n }\n\n // Deinflections and text processing\n\n private _getAlgorithmDeinflections(text: string, options: Translation.FindTermsOptions): DatabaseDeinflection[] {\n const { language } = options;\n const processorsForLanguage = this._textProcessors.get(language);\n if (typeof processorsForLanguage === 'undefined') {\n throw new Error(`Unsupported language: ${language}`);\n }\n const { textPreprocessors, textPostprocessors } = processorsForLanguage;\n\n const deinflections: DatabaseDeinflection[] = [];\n const sourceCache: TextCache = new Map();\n\n for (\n let rawSource = text;\n rawSource.length > 0;\n rawSource = this._getNextSubstring(options.searchResolution, rawSource)\n ) {\n const preprocessedTextVariants = this._getTextVariants(\n rawSource,\n textPreprocessors,\n this._getTextReplacementsVariants(options),\n sourceCache,\n );\n\n for (const [source, preprocessorRuleChainCandidates] of preprocessedTextVariants) {\n for (const deinflection of this._multiLanguageTransformer.transform(language, source)) {\n const { trace, conditions } = deinflection;\n const postprocessedTextVariants = this._getTextVariants(\n deinflection.text,\n textPostprocessors,\n [null],\n sourceCache,\n );\n for (const [transformedText, postprocessorRuleChainCandidates] of postprocessedTextVariants) {\n const inflectionRuleChainCandidate: InflectionRuleChainCandidate = {\n source: 'algorithm',\n inflectionRules: trace.map((frame) => frame.transform),\n };\n\n // Every combination of preprocessor rule candidates and postprocessor rule candidates\n const textProcessorRuleChainCandidates = preprocessorRuleChainCandidates.flatMap(\n (preprocessorRuleChainCandidate) =>\n postprocessorRuleChainCandidates.map((postprocessorRuleChainCandidate) => [\n ...preprocessorRuleChainCandidate,\n ...postprocessorRuleChainCandidate,\n ]),\n );\n deinflections.push(\n this._createDeinflection(\n rawSource,\n source,\n transformedText,\n conditions,\n textProcessorRuleChainCandidates,\n [inflectionRuleChainCandidate],\n ),\n );\n }\n }\n }\n }\n return deinflections;\n }\n\n private _getTextVariants(\n text: string,\n textProcessors: Language.TextProcessorWithId<unknown>[],\n textReplacements: (Translation.FindTermsTextReplacement[] | null)[],\n textCache: TextCache,\n ): VariantAndTextProcessorRuleChainCandidatesMap {\n let variantsMap: VariantAndTextProcessorRuleChainCandidatesMap = new Map([[text, [[]]]]);\n\n for (const [id, textReplacement] of textReplacements.entries()) {\n if (textReplacement === null) {\n continue;\n }\n variantsMap.set(this._applyTextReplacements(text, textReplacement), [[`Text Replacement ${id}`]]);\n }\n for (const {\n id,\n textProcessor: { process, options },\n } of textProcessors) {\n const newVariantsMap: VariantAndTextProcessorRuleChainCandidatesMap = new Map();\n for (const [variant, currentPreprocessorRuleChainCandidates] of variantsMap) {\n for (const option of options) {\n const processed = this._getProcessedText(textCache, variant, id, option, process);\n const existingCandidates = newVariantsMap.get(processed);\n\n // Ignore if applying the textProcessor doesn't change the source\n if (processed === variant) {\n if (typeof existingCandidates === 'undefined') {\n newVariantsMap.set(processed, currentPreprocessorRuleChainCandidates);\n } else {\n newVariantsMap.set(processed, existingCandidates);\n }\n } else if (typeof existingCandidates === 'undefined') {\n newVariantsMap.set(\n processed,\n currentPreprocessorRuleChainCandidates.map((candidate) => [...candidate, id]),\n );\n } else {\n newVariantsMap.set(processed, [\n ...existingCandidates,\n ...currentPreprocessorRuleChainCandidates.map((candidate) => [...candidate, id]),\n ]);\n }\n }\n }\n variantsMap = newVariantsMap;\n }\n return variantsMap;\n }\n\n private _getProcessedText(\n textCache: TextCache,\n text: string,\n id: string,\n setting: unknown,\n process: Language.TextProcessorFunction,\n ): string {\n let level1 = textCache.get(text);\n if (!level1) {\n level1 = new Map();\n textCache.set(text, level1);\n }\n\n let level2 = level1.get(id);\n if (!level2) {\n level2 = new Map();\n level1.set(id, level2);\n }\n\n if (!level2.has(setting)) {\n text = process(text, setting);\n level2.set(setting, text);\n } else {\n text = level2.get(setting) || '';\n }\n return text;\n }\n\n private _getNextSubstring(searchResolution: string, currentString: string): string {\n const nextSubstringLength =\n searchResolution === 'word'\n ? currentString.search(/[^\\p{Letter}][\\p{Letter}\\p{Number}]*$/u)\n : currentString.length - 1;\n return currentString.substring(0, nextSubstringLength);\n }\n\n private _applyTextReplacements(text: string, replacements: Translation.FindTermsTextReplacement[]): string {\n for (const { pattern, replacement } of replacements) {\n text = applyTextReplacement(text, pattern, replacement);\n }\n return text;\n }\n\n private _getJapaneseChineseKoreanOnlyText(text: string): string {\n let length = 0;\n for (const c of text) {\n const codePoint = c.codePointAt(0) as number;\n if (!isCodePointJapanese(codePoint) && !isCodePointChinese(codePoint) && !isCodePointKorean(codePoint)) {\n return text.substring(0, length);\n }\n length += c.length;\n }\n return text;\n }\n\n private _getTextReplacementsVariants(\n options: Translation.FindTermsOptions,\n ): (Translation.FindTermsTextReplacement[] | null)[] {\n return options.textReplacements;\n }\n\n private _createDeinflection(\n originalText: string,\n transformedText: string,\n deinflectedText: string,\n conditions: number,\n textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[],\n inflectionRuleChainCandidates: InflectionRuleChainCandidate[],\n ): DatabaseDeinflection {\n return {\n originalText,\n transformedText,\n deinflectedText,\n conditions,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates,\n databaseEntries: [],\n };\n }\n\n // Term dictionary entry grouping\n\n private async _getRelatedDictionaryEntries(\n dictionaryEntries: TermDictionaryEntry[],\n options: Translation.FindTermsOptions,\n tagAggregator: TranslatorTagAggregator,\n ): Promise<TermDictionaryEntry[]> {\n const { mainDictionary, enabledDictionaryMap, language, primaryReading } = options;\n const sequenceList: SequenceQuery[] = [];\n const groupedDictionaryEntries: DictionaryEntryGroup[] = [];\n const groupedDictionaryEntriesMap = new Map<number, DictionaryEntryGroup>();\n const ungroupedDictionaryEntriesMap = new Map<number, TermDictionaryEntry>();\n for (const dictionaryEntry of dictionaryEntries) {\n const {\n definitions: [\n {\n id,\n dictionary,\n sequences: [sequence],\n },\n ],\n } = dictionaryEntry;\n if (mainDictionary === dictionary && sequence >= 0) {\n let group = groupedDictionaryEntriesMap.get(sequence);\n if (typeof group === 'undefined') {\n group = {\n ids: new Set(),\n dictionaryEntries: [],\n };\n sequenceList.push({ query: sequence, dictionary });\n groupedDictionaryEntries.push(group);\n groupedDictionaryEntriesMap.set(sequence, group);\n }\n group.dictionaryEntries.push(dictionaryEntry);\n group.ids.add(id);\n } else {\n ungroupedDictionaryEntriesMap.set(id, dictionaryEntry);\n }\n }\n\n if (sequenceList.length > 0) {\n const secondarySearchDictionaryMap = this._getSecondarySearchDictionaryMap(enabledDictionaryMap);\n await this._addRelatedDictionaryEntries(\n groupedDictionaryEntries,\n ungroupedDictionaryEntriesMap,\n sequenceList,\n enabledDictionaryMap,\n tagAggregator,\n primaryReading,\n );\n for (const group of groupedDictionaryEntries) {\n this._sortTermDictionaryEntriesById(group.dictionaryEntries);\n }\n if (ungroupedDictionaryEntriesMap.size > 0 || secondarySearchDictionaryMap.size > 0) {\n await this._addSecondaryRelatedDictionaryEntries(\n language,\n groupedDictionaryEntries,\n ungroupedDictionaryEntriesMap,\n enabledDictionaryMap,\n secondarySearchDictionaryMap,\n tagAggregator,\n primaryReading,\n );\n }\n }\n\n const newDictionaryEntries: TermDictionaryEntry[] = [];\n for (const group of groupedDictionaryEntries) {\n newDictionaryEntries.push(\n this._createGroupedDictionaryEntry(\n language,\n group.dictionaryEntries,\n true,\n tagAggregator,\n primaryReading,\n ),\n );\n }\n newDictionaryEntries.push(\n ...this._groupDictionaryEntriesByHeadword(\n language,\n ungroupedDictionaryEntriesMap.values(),\n tagAggregator,\n primaryReading,\n ),\n );\n return newDictionaryEntries;\n }\n\n private async _addRelatedDictionaryEntries(\n groupedDictionaryEntries: DictionaryEntryGroup[],\n ungroupedDictionaryEntriesMap: Map<number, TermDictionaryEntry>,\n sequenceList: SequenceQuery[],\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): Promise<void> {\n const databaseEntries = await this._database.findTermsBySequenceBulk(sequenceList);\n for (const databaseEntry of databaseEntries) {\n const { dictionaryEntries: groupEntries, ids } = groupedDictionaryEntries[databaseEntry.index];\n const { id } = databaseEntry;\n if (ids.has(id)) {\n continue;\n }\n\n const { term } = databaseEntry;\n const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(\n databaseEntry,\n term,\n term,\n term,\n [],\n [],\n false,\n enabledDictionaryMap,\n tagAggregator,\n primaryReading,\n );\n groupEntries.push(dictionaryEntry);\n ids.add(id);\n ungroupedDictionaryEntriesMap.delete(id);\n }\n }\n\n private async _addSecondaryRelatedDictionaryEntries(\n language: string,\n groupedDictionaryEntries: DictionaryEntryGroup[],\n ungroupedDictionaryEntriesMap: Map<number, TermDictionaryEntry>,\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap,\n secondarySearchDictionaryMap: Translation.TermEnabledDictionaryMap,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): Promise<void> {\n // Prepare grouping info\n const termList: DictionaryDatabase.TermExactRequest[] = [];\n const targetList: { groups: DictionaryEntryGroup[] }[] = [];\n const targetMap = new Map<string, { groups: DictionaryEntryGroup[] }>();\n\n const readingNormalizer = this._readingNormalizers.get(language);\n\n for (const group of groupedDictionaryEntries) {\n const { dictionaryEntries: groupEntries } = group;\n for (const dictionaryEntry of groupEntries) {\n const { term, reading } = dictionaryEntry.headwords[0];\n const normalizedReading =\n typeof readingNormalizer === 'undefined' ? reading : readingNormalizer(reading);\n const key = this._createMapKey([term, normalizedReading]);\n let target = targetMap.get(key);\n if (typeof target === 'undefined') {\n target = {\n groups: [],\n };\n targetMap.set(key, target);\n termList.push({ term, reading });\n targetList.push(target);\n }\n target.groups.push(group);\n }\n }\n\n // Group unsequenced dictionary entries with sequenced entries that have a matching [term, reading].\n for (const [id, dictionaryEntry] of ungroupedDictionaryEntriesMap.entries()) {\n const { term, reading } = dictionaryEntry.headwords[0];\n const normalizedReading = typeof readingNormalizer === 'undefined' ? reading : readingNormalizer(reading);\n const key = this._createMapKey([term, normalizedReading]);\n const target = targetMap.get(key);\n if (typeof target === 'undefined') {\n continue;\n }\n\n for (const { ids, dictionaryEntries: groupEntries } of target.groups) {\n if (ids.has(id)) {\n continue;\n }\n groupEntries.push(dictionaryEntry);\n ids.add(id);\n }\n ungroupedDictionaryEntriesMap.delete(id);\n }\n\n // Search database for additional secondary terms\n if (termList.length === 0 || secondarySearchDictionaryMap.size === 0) {\n return;\n }\n\n const databaseEntries = await this._database.findTermsExactBulk(termList, secondarySearchDictionaryMap);\n this._sortDatabaseEntriesByIndex(databaseEntries);\n\n for (const databaseEntry of databaseEntries) {\n const { index, id } = databaseEntry;\n const sourceText = termList[index].term;\n const target = targetList[index];\n for (const { ids, dictionaryEntries: groupEntries } of target.groups) {\n if (ids.has(id)) {\n continue;\n }\n\n const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(\n databaseEntry,\n sourceText,\n sourceText,\n sourceText,\n [],\n [],\n false,\n enabledDictionaryMap,\n tagAggregator,\n primaryReading,\n );\n groupEntries.push(dictionaryEntry);\n ids.add(id);\n ungroupedDictionaryEntriesMap.delete(id);\n }\n }\n }\n\n private _groupDictionaryEntriesByHeadword(\n language: string,\n dictionaryEntries: Iterable<TermDictionaryEntry>,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): TermDictionaryEntry[] {\n const readingNormalizer = this._readingNormalizers.get(language);\n const createGroupingKey = (dictionaryEntry: TermDictionaryEntry): string => {\n const {\n inflectionRuleChainCandidates,\n headwords: [{ term, reading }],\n } = dictionaryEntry;\n const normalizedReading = typeof readingNormalizer === 'undefined' ? reading : readingNormalizer(reading);\n return this._createMapKey([term, normalizedReading, ...inflectionRuleChainCandidates]);\n };\n return this._groupDictionaryEntries(\n language,\n dictionaryEntries,\n tagAggregator,\n primaryReading,\n createGroupingKey,\n );\n }\n\n private _groupDictionaryEntriesByTerm(\n language: string,\n dictionaryEntries: Iterable<TermDictionaryEntry>,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): TermDictionaryEntry[] {\n const createGroupingKey = (dictionaryEntry: TermDictionaryEntry): string => {\n const {\n inflectionRuleChainCandidates,\n headwords: [{ term }],\n } = dictionaryEntry;\n return this._createMapKey([term, ...inflectionRuleChainCandidates]);\n };\n return this._groupDictionaryEntries(\n language,\n dictionaryEntries,\n tagAggregator,\n primaryReading,\n createGroupingKey,\n );\n }\n\n private _groupDictionaryEntries(\n language: string,\n dictionaryEntries: Iterable<TermDictionaryEntry>,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n createGroupingKey: (entry: TermDictionaryEntry) => string,\n ): TermDictionaryEntry[] {\n const groups = new Map<string, TermDictionaryEntry[]>();\n for (const dictionaryEntry of dictionaryEntries) {\n const key = createGroupingKey(dictionaryEntry);\n let groupDictionaryEntries = groups.get(key);\n if (typeof groupDictionaryEntries === 'undefined') {\n groupDictionaryEntries = [];\n groups.set(key, groupDictionaryEntries);\n }\n groupDictionaryEntries.push(dictionaryEntry);\n }\n\n const newDictionaryEntries: TermDictionaryEntry[] = [];\n for (const groupDictionaryEntries of groups.values()) {\n newDictionaryEntries.push(\n this._createGroupedDictionaryEntry(\n language,\n groupDictionaryEntries,\n false,\n tagAggregator,\n primaryReading,\n ),\n );\n }\n return newDictionaryEntries;\n }\n\n // Removing data\n\n private _removeExcludedDefinitions(\n dictionaryEntries: TermDictionaryEntry[],\n excludeDictionaryDefinitions: Set<string>,\n ): void {\n for (let i = dictionaryEntries.length - 1; i >= 0; --i) {\n const dictionaryEntry = dictionaryEntries[i];\n const { definitions, pronunciations, frequencies, headwords } = dictionaryEntry;\n const definitionsChanged = this._removeArrayItemsWithDictionary(definitions, excludeDictionaryDefinitions);\n this._removeArrayItemsWithDictionary(pronunciations, excludeDictionaryDefinitions);\n this._removeArrayItemsWithDictionary(frequencies, excludeDictionaryDefinitions);\n this._removeTagGroupsWithDictionary(definitions, excludeDictionaryDefinitions);\n this._removeTagGroupsWithDictionary(headwords, excludeDictionaryDefinitions);\n\n if (!definitionsChanged) {\n continue;\n }\n\n if (definitions.length === 0) {\n dictionaryEntries.splice(i, 1);\n } else {\n this._removeUnusedHeadwords(dictionaryEntry);\n }\n }\n }\n\n private _removeUnusedHeadwords(dictionaryEntry: TermDictionaryEntry): void {\n const { definitions, pronunciations, frequencies, headwords } = dictionaryEntry;\n const removeHeadwordIndices = new Set<number>();\n for (let i = 0, ii = headwords.length; i < ii; ++i) {\n removeHeadwordIndices.add(i);\n }\n for (const { headwordIndices } of definitions) {\n for (const headwordIndex of headwordIndices) {\n removeHeadwordIndices.delete(headwordIndex);\n }\n }\n\n if (removeHeadwordIndices.size === 0) {\n return;\n }\n\n const indexRemap = new Map<number, number>();\n let oldIndex = 0;\n for (let i = 0, ii = headwords.length; i < ii; ++i) {\n if (removeHeadwordIndices.has(oldIndex)) {\n headwords.splice(i, 1);\n --i;\n --ii;\n } else {\n indexRemap.set(oldIndex, indexRemap.size);\n }\n ++oldIndex;\n }\n\n this._updateDefinitionHeadwordIndices(definitions, indexRemap);\n this._updateArrayItemsHeadwordIndex(pronunciations, indexRemap);\n this._updateArrayItemsHeadwordIndex(frequencies, indexRemap);\n }\n\n private _updateDefinitionHeadwordIndices(\n definitions: Dictionary.TermDefinition[],\n indexRemap: Map<number, number>,\n ): void {\n for (const { headwordIndices } of definitions) {\n for (let i = headwordIndices.length - 1; i >= 0; --i) {\n const newHeadwordIndex = indexRemap.get(headwordIndices[i]);\n if (typeof newHeadwordIndex === 'undefined') {\n headwordIndices.splice(i, 1);\n } else {\n headwordIndices[i] = newHeadwordIndex;\n }\n }\n }\n }\n\n private _updateArrayItemsHeadwordIndex(\n array: (Dictionary.TermPronunciation | Dictionary.TermFrequency)[],\n indexRemap: Map<number, number>,\n ): void {\n for (let i = array.length - 1; i >= 0; --i) {\n const item = array[i];\n const { headwordIndex } = item;\n const newHeadwordIndex = indexRemap.get(headwordIndex);\n if (typeof newHeadwordIndex === 'undefined') {\n array.splice(i, 1);\n } else {\n item.headwordIndex = newHeadwordIndex;\n }\n }\n }\n\n private _removeArrayItemsWithDictionary(\n array: { dictionary: string }[],\n excludeDictionaryDefinitions: Set<string>,\n ): boolean {\n let changed = false;\n for (let j = array.length - 1; j >= 0; --j) {\n const { dictionary } = array[j];\n if (!excludeDictionaryDefinitions.has(dictionary)) {\n continue;\n }\n array.splice(j, 1);\n changed = true;\n }\n return changed;\n }\n\n private _removeArrayItemsWithDictionary2(\n array: Dictionary.Tag[],\n excludeDictionaryDefinitions: Set<string>,\n ): boolean {\n let changed = false;\n for (let j = array.length - 1; j >= 0; --j) {\n const { dictionaries } = array[j];\n if (this._hasAny(excludeDictionaryDefinitions, dictionaries)) {\n continue;\n }\n array.splice(j, 1);\n changed = true;\n }\n return changed;\n }\n\n private _removeTagGroupsWithDictionary(\n array: { tags: Dictionary.Tag[] }[],\n excludeDictionaryDefinitions: Set<string>,\n ): void {\n for (const { tags } of array) {\n this._removeArrayItemsWithDictionary2(tags, excludeDictionaryDefinitions);\n }\n }\n\n // Tags\n\n private async _expandTagGroupsAndGroup(tagExpansionTargets: TagExpansionTarget[]): Promise<void> {\n await this._expandTagGroups(tagExpansionTargets);\n this._groupTags(tagExpansionTargets);\n }\n\n private async _expandTagGroups(tagTargets: TagExpansionTarget[]): Promise<void> {\n const allItems: TagTargetItem[] = [];\n const targetMap = new Map<string, Map<string, TagTargetItem>>();\n for (const { tagGroups, tags } of tagTargets) {\n for (const { dictionary, tagNames } of tagGroups) {\n let dictionaryItems = targetMap.get(dictionary);\n if (typeof dictionaryItems === 'undefined') {\n dictionaryItems = new Map();\n targetMap.set(dictionary, dictionaryItems);\n }\n for (const tagName of tagNames) {\n let item = dictionaryItems.get(tagName);\n if (typeof item === 'undefined') {\n const query = this._getNameBase(tagName);\n item = { query, dictionary, tagName, cache: null, databaseTag: null, targets: [] };\n dictionaryItems.set(tagName, item);\n allItems.push(item);\n }\n item.targets.push(tags);\n }\n }\n }\n\n const nonCachedItems: TagTargetItem[] = [];\n const tagCache = this._tagCache;\n for (const [dictionary, dictionaryItems] of targetMap.entries()) {\n let cache = tagCache.get(dictionary);\n if (typeof cache === 'undefined') {\n cache = new Map();\n tagCache.set(dictionary, cache);\n }\n for (const item of dictionaryItems.values()) {\n const databaseTag = cache.get(item.query);\n if (typeof databaseTag !== 'undefined') {\n item.databaseTag = databaseTag;\n } else {\n item.cache = cache;\n nonCachedItems.push(item);\n }\n }\n }\n\n const nonCachedItemCount = nonCachedItems.length;\n if (nonCachedItemCount > 0) {\n const databaseTags = await this._database.findTagMetaBulk(nonCachedItems);\n for (let i = 0; i < nonCachedItemCount; ++i) {\n const item = nonCachedItems[i];\n const databaseTag = databaseTags[i];\n const databaseTag2 = typeof databaseTag !== 'undefined' ? databaseTag : null;\n item.databaseTag = databaseTag2;\n if (item.cache !== null) {\n item.cache.set(item.query, databaseTag2);\n }\n }\n }\n\n for (const { dictionary, tagName, databaseTag, targets } of allItems) {\n for (const tags of targets) {\n tags.push(this._createTag(databaseTag, tagName, dictionary));\n }\n }\n }\n\n private _groupTags(tagTargets: TagExpansionTarget[]): void {\n const stringComparer = this._stringComparer;\n const compare = (v1: Dictionary.Tag, v2: Dictionary.Tag): number => {\n const i = v1.order - v2.order;\n return i !== 0 ? i : stringComparer.compare(v1.name, v2.name);\n };\n\n for (const { tags } of tagTargets) {\n if (tags.length <= 1) {\n continue;\n }\n this._mergeSimilarTags(tags);\n tags.sort(compare);\n }\n }\n\n private _mergeSimilarTags(tags: Dictionary.Tag[]): void {\n let tagCount = tags.length;\n for (let i = 0; i < tagCount; ++i) {\n const tag1 = tags[i];\n const { category, name } = tag1;\n for (let j = i + 1; j < tagCount; ++j) {\n const tag2 = tags[j];\n if (tag2.name !== name || tag2.category !== category) {\n continue;\n }\n // Merge tag\n tag1.order = Math.min(tag1.order, tag2.order);\n tag1.score = Math.max(tag1.score, tag2.score);\n tag1.dictionaries.push(...tag2.dictionaries);\n this._addUniqueSimple(tag1.content, tag2.content);\n tags.splice(j, 1);\n --tagCount;\n --j;\n }\n }\n }\n\n private _getTagNamesWithCategory(tags: Dictionary.Tag[], category: string): string[] {\n const results: string[] = [];\n for (const tag of tags) {\n if (tag.category !== category) {\n continue;\n }\n results.push(tag.name);\n }\n results.sort();\n return results;\n }\n\n private _flagRedundantDefinitionTags(definitions: Dictionary.TermDefinition[]): void {\n if (definitions.length === 0) {\n return;\n }\n\n let lastDictionary: string | null = null;\n let lastPartOfSpeech = '';\n const removeCategoriesSet = new Set<string>();\n\n for (const { dictionary, tags } of definitions) {\n const partOfSpeech = this._createMapKey(this._getTagNamesWithCategory(tags, 'partOfSpeech'));\n\n if (lastDictionary !== dictionary) {\n lastDictionary = dictionary;\n lastPartOfSpeech = '';\n }\n\n if (lastPartOfSpeech === partOfSpeech) {\n removeCategoriesSet.add('partOfSpeech');\n } else {\n lastPartOfSpeech = partOfSpeech;\n }\n\n if (removeCategoriesSet.size > 0) {\n for (const tag of tags) {\n if (removeCategoriesSet.has(tag.category)) {\n tag.redundant = true;\n }\n }\n removeCategoriesSet.clear();\n }\n }\n }\n\n // Metadata\n\n private async _addTermMeta(\n dictionaryEntries: TermDictionaryEntry[],\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap,\n tagAggregator: TranslatorTagAggregator,\n ): Promise<void> {\n const headwordMap = new Map<\n string,\n Map<\n string,\n {\n headwordIndex: number;\n pronunciations: Dictionary.TermPronunciation[];\n frequencies: Dictionary.TermFrequency[];\n }[]\n >\n >();\n const headwordMapKeys: string[] = [];\n const headwordReadingMaps: Map<\n string,\n {\n headwordIndex: number;\n pronunciations: Dictionary.TermPronunciation[];\n frequencies: Dictionary.TermFrequency[];\n }[]\n >[] = [];\n\n for (const { headwords, pronunciations, frequencies } of dictionaryEntries) {\n for (let i = 0, ii = headwords.length; i < ii; ++i) {\n const { term, reading } = headwords[i];\n let readingMap = headwordMap.get(term);\n if (typeof readingMap === 'undefined') {\n readingMap = new Map();\n headwordMap.set(term, readingMap);\n headwordMapKeys.push(term);\n headwordReadingMaps.push(readingMap);\n }\n let targets = readingMap.get(reading);\n if (typeof targets === 'undefined') {\n targets = [];\n readingMap.set(reading, targets);\n }\n targets.push({ headwordIndex: i, pronunciations, frequencies });\n }\n }\n\n const metas = await this._database.findTermMetaBulk(headwordMapKeys, enabledDictionaryMap);\n for (const { mode, data, dictionary, index } of metas) {\n const { index: dictionaryIndex } = this._getDictionaryOrder(dictionary, enabledDictionaryMap);\n const dictionaryAlias = this._getDictionaryAlias(dictionary, enabledDictionaryMap);\n const map2 = headwordReadingMaps[index];\n for (const [reading, targets] of map2.entries()) {\n switch (mode) {\n case 'freq':\n {\n const hasReading =\n data !== null &&\n typeof data === 'object' &&\n typeof (data as DictionaryData.TermMetaFrequencyDataWithReading).reading === 'string';\n if (\n hasReading &&\n (data as DictionaryData.TermMetaFrequencyDataWithReading).reading !== reading\n ) {\n continue;\n }\n const frequency = hasReading\n ? (data as DictionaryData.TermMetaFrequencyDataWithReading).frequency\n : (data as DictionaryData.GenericFrequencyData);\n for (const { frequencies, headwordIndex } of targets) {\n const {\n frequency: frequencyValue,\n displayValue,\n displayValueParsed,\n } = this._getFrequencyInfo(frequency);\n frequencies.push(\n this._createTermFrequency(\n frequencies.length,\n headwordIndex,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n hasReading,\n frequencyValue,\n displayValue,\n displayValueParsed,\n ),\n );\n }\n }\n break;\n case 'pitch':\n {\n if ((data as DictionaryData.TermMetaPitchData).reading !== reading) {\n continue;\n }\n const pitches: Dictionary.PitchAccent[] = [];\n for (const { position, tags, nasal, devoice } of (data as DictionaryData.TermMetaPitchData)\n .pitches) {\n const tags2: Dictionary.Tag[] = [];\n if (Array.isArray(tags)) {\n tagAggregator.addTags(tags2, dictionary, tags);\n }\n const nasalPositions = this._toNumberArray(nasal);\n const devoicePositions = this._toNumberArray(devoice);\n pitches.push({\n type: 'pitch-accent',\n positions: position,\n nasalPositions,\n devoicePositions,\n tags: tags2,\n });\n }\n for (const { pronunciations, headwordIndex } of targets) {\n pronunciations.push(\n this._createTermPronunciation(\n pronunciations.length,\n headwordIndex,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n pitches,\n ),\n );\n }\n }\n break;\n case 'ipa': {\n if ((data as DictionaryData.TermMetaPhoneticData).reading !== reading) {\n continue;\n }\n const phoneticTranscriptions: Dictionary.PhoneticTranscription[] = [];\n for (const { ipa, tags } of (data as DictionaryData.TermMetaPhoneticData).transcriptions) {\n const tags2: Dictionary.Tag[] = [];\n if (Array.isArray(tags)) {\n tagAggregator.addTags(tags2, dictionary, tags);\n }\n phoneticTranscriptions.push({\n type: 'phonetic-transcription',\n ipa,\n tags: tags2,\n });\n }\n for (const { pronunciations, headwordIndex } of targets) {\n pronunciations.push(\n this._createTermPronunciation(\n pronunciations.length,\n headwordIndex,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n phoneticTranscriptions,\n ),\n );\n }\n }\n }\n }\n }\n }\n\n private async _addKanjiMeta(\n dictionaryEntries: Dictionary.KanjiDictionaryEntry[],\n enabledDictionaryMap: Translation.KanjiEnabledDictionaryMap,\n ): Promise<void> {\n const kanjiList: string[] = [];\n for (const { character } of dictionaryEntries) {\n kanjiList.push(character);\n }\n\n const metas = await this._database.findKanjiMetaBulk(kanjiList, enabledDictionaryMap);\n for (const { character, mode, data, dictionary, index } of metas) {\n const { index: dictionaryIndex } = this._getDictionaryOrder(dictionary, enabledDictionaryMap);\n const dictionaryAlias = this._getDictionaryAlias(dictionary, enabledDictionaryMap);\n switch (mode) {\n case 'freq':\n {\n const { frequencies } = dictionaryEntries[index];\n const { frequency, displayValue, displayValueParsed } = this._getFrequencyInfo(data);\n frequencies.push(\n this._createKanjiFrequency(\n frequencies.length,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n character,\n frequency,\n displayValue,\n displayValueParsed,\n ),\n );\n }\n break;\n }\n }\n }\n\n private async _expandKanjiStats(\n stats: { [key: string]: string | number },\n dictionary: string,\n ): Promise<Dictionary.KanjiStatGroups> {\n const statsEntries = Object.entries(stats);\n const items: { query: string; dictionary: string }[] = [];\n for (const [name] of statsEntries) {\n const query = this._getNameBase(name);\n items.push({ query, dictionary });\n }\n\n const databaseInfos = await this._database.findTagMetaBulk(items);\n\n const statsGroups = new Map<string, Dictionary.KanjiStat[]>();\n for (let i = 0, ii = statsEntries.length; i < ii; ++i) {\n const databaseInfo = databaseInfos[i];\n if (typeof databaseInfo === 'undefined') {\n continue;\n }\n\n const [name, value] = statsEntries[i];\n const { category } = databaseInfo;\n let group = statsGroups.get(category);\n if (typeof group === 'undefined') {\n group = [];\n statsGroups.set(category, group);\n }\n\n group.push(this._createKanjiStat(name, value, databaseInfo, dictionary));\n }\n\n const groupedStats: Dictionary.KanjiStatGroups = {};\n for (const [category, group] of statsGroups.entries()) {\n this._sortKanjiStats(group);\n groupedStats[category] = group;\n }\n return groupedStats;\n }\n\n private _sortKanjiStats(stats: Dictionary.KanjiStat[]): void {\n if (stats.length <= 1) {\n return;\n }\n const stringComparer = this._stringComparer;\n stats.sort((v1, v2) => {\n const i = v1.order - v2.order;\n return i !== 0 ? i : stringComparer.compare(v1.content, v2.content);\n });\n }\n\n private _convertStringToNumber(value: string): number {\n const match = this._numberRegex.exec(value);\n if (match === null) {\n return 0;\n }\n const result = Number.parseFloat(match[0]);\n return Number.isFinite(result) ? result : 0;\n }\n\n private _getFrequencyInfo(frequency: DictionaryData.GenericFrequencyData): {\n frequency: number;\n displayValue: string | null;\n displayValueParsed: boolean;\n } {\n let frequencyValue = 0;\n let displayValue: string | null = null;\n let displayValueParsed = false;\n if (typeof frequency === 'object' && frequency !== null) {\n const { value: frequencyValue2, displayValue: displayValue2 } = frequency;\n if (typeof frequencyValue2 === 'number') {\n frequencyValue = frequencyValue2;\n }\n if (typeof displayValue2 === 'string') {\n displayValue = displayValue2;\n }\n } else {\n switch (typeof frequency) {\n case 'number':\n frequencyValue = frequency;\n break;\n case 'string':\n displayValue = frequency;\n displayValueParsed = true;\n frequencyValue = this._convertStringToNumber(frequency);\n break;\n }\n }\n return { frequency: frequencyValue, displayValue, displayValueParsed };\n }\n\n // Helpers\n\n private _getNameBase(name: string): string {\n const pos = name.indexOf(':');\n return pos >= 0 ? name.substring(0, pos) : name;\n }\n\n private _getSecondarySearchDictionaryMap(\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap,\n ): Translation.TermEnabledDictionaryMap {\n const secondarySearchDictionaryMap: Translation.TermEnabledDictionaryMap = new Map();\n for (const [dictionary, details] of enabledDictionaryMap.entries()) {\n if (!details.allowSecondarySearches) {\n continue;\n }\n secondarySearchDictionaryMap.set(dictionary, details);\n }\n return secondarySearchDictionaryMap;\n }\n\n private _getDictionaryOrder(\n dictionary: string,\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap | Translation.KanjiEnabledDictionaryMap,\n ): { index: number } {\n const info = enabledDictionaryMap.get(dictionary);\n const { index } = typeof info !== 'undefined' ? info : { index: enabledDictionaryMap.size };\n return { index };\n }\n\n private _getDictionaryAlias(\n dictionary: string,\n enabledDictionaryMap: Translation.TermEnabledDictionaryMap | Translation.KanjiEnabledDictionaryMap,\n ): string {\n const info = enabledDictionaryMap.get(dictionary);\n return (info as { alias?: string })?.alias || dictionary;\n }\n\n private _createMapKey(array: unknown[]): string {\n return JSON.stringify(array);\n }\n\n private _toNumberArray(value: number | number[] | undefined): number[] {\n return Array.isArray(value) ? value : typeof value === 'number' ? [value] : [];\n }\n\n // Kanji data\n\n private _createKanjiStat(\n name: string,\n value: string | number,\n databaseInfo: DictionaryDatabase.Tag,\n dictionary: string,\n ): Dictionary.KanjiStat {\n const { category, notes, order, score } = databaseInfo;\n return {\n name,\n category: typeof category === 'string' && category.length > 0 ? category : 'default',\n content: typeof notes === 'string' ? notes : '',\n order: typeof order === 'number' ? order : 0,\n score: typeof score === 'number' ? score : 0,\n dictionary,\n value,\n };\n }\n\n private _createKanjiFrequency(\n index: number,\n dictionary: string,\n dictionaryIndex: number,\n dictionaryAlias: string,\n character: string,\n frequency: number,\n displayValue: string | null,\n displayValueParsed: boolean,\n ): Dictionary.KanjiFrequency {\n return {\n index,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n character,\n frequency,\n displayValue,\n displayValueParsed,\n };\n }\n\n private _createKanjiDictionaryEntry(\n character: string,\n dictionary: string,\n dictionaryAlias: string,\n onyomi: string[],\n kunyomi: string[],\n stats: Dictionary.KanjiStatGroups,\n definitions: string[],\n enabledDictionaryMap: Translation.KanjiEnabledDictionaryMap,\n ): Dictionary.KanjiDictionaryEntry {\n const { index: dictionaryIndex } = this._getDictionaryOrder(dictionary, enabledDictionaryMap);\n return {\n type: 'kanji',\n character,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n onyomi,\n kunyomi,\n tags: [],\n stats,\n definitions,\n frequencies: [],\n };\n }\n\n // Term data\n\n private _createTag(databaseTag: DictionaryDatabase.Tag | null, name: string, dictionary: string): Dictionary.Tag {\n let category: string | undefined;\n let notes: string | undefined;\n let order: number | undefined;\n let score: number | undefined;\n if (typeof databaseTag === 'object' && databaseTag !== null) {\n ({ category, notes, order, score } = databaseTag);\n }\n return {\n name,\n category: typeof category === 'string' && category.length > 0 ? category : 'default',\n order: typeof order === 'number' ? order : 0,\n score: typeof score === 'number' ? score : 0,\n content: typeof notes === 'string' && notes.length > 0 ? [notes] : [],\n dictionaries: [dictionary],\n redundant: false,\n };\n }\n\n private _createSource(\n originalText: string,\n transformedText: string,\n deinflectedText: string,\n matchType: Dictionary.TermSourceMatchType,\n matchSource: Dictionary.TermSourceMatchSource,\n isPrimary: boolean,\n ): Dictionary.TermSource {\n return { originalText, transformedText, deinflectedText, matchType, matchSource, isPrimary };\n }\n\n private _createTermHeadword(\n index: number,\n term: string,\n reading: string,\n sources: Dictionary.TermSource[],\n tags: Dictionary.Tag[],\n wordClasses: string[],\n ): Dictionary.TermHeadword {\n return { index, term, reading, sources, tags, wordClasses };\n }\n\n private _createTermDefinition(\n index: number,\n headwordIndices: number[],\n dictionary: string,\n dictionaryIndex: number,\n dictionaryAlias: string,\n id: number,\n score: number,\n sequences: number[],\n isPrimary: boolean,\n tags: Dictionary.Tag[],\n entries: DictionaryData.TermGlossaryContent[],\n ): Dictionary.TermDefinition {\n return {\n index,\n headwordIndices,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n id,\n score,\n frequencyOrder: 0,\n sequences,\n isPrimary,\n tags,\n entries,\n };\n }\n\n private _createTermPronunciation(\n index: number,\n headwordIndex: number,\n dictionary: string,\n dictionaryIndex: number,\n dictionaryAlias: string,\n pronunciations: Dictionary.Pronunciation[],\n ): Dictionary.TermPronunciation {\n return { index, headwordIndex, dictionary, dictionaryIndex, dictionaryAlias, pronunciations };\n }\n\n private _createTermFrequency(\n index: number,\n headwordIndex: number,\n dictionary: string,\n dictionaryIndex: number,\n dictionaryAlias: string,\n hasReading: boolean,\n frequency: number,\n displayValue: string | null,\n displayValueParsed: boolean,\n ): Dictionary.TermFrequency {\n return {\n index,\n headwordIndex,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n hasReading,\n frequency,\n displayValue,\n displayValueParsed,\n };\n }\n\n private _createTermDictionaryEntry(\n isPrimary: boolean,\n textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[],\n inflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[],\n score: number,\n dictionaryIndex: number,\n dictionaryAlias: string,\n sourceTermExactMatchCount: number,\n matchPrimaryReading: boolean,\n maxOriginalTextLength: number,\n headwords: Dictionary.TermHeadword[],\n definitions: Dictionary.TermDefinition[],\n ): TermDictionaryEntry {\n return {\n type: 'term',\n isPrimary,\n textProcessorRuleChainCandidates,\n inflectionRuleChainCandidates,\n score,\n frequencyOrder: 0,\n dictionaryIndex,\n dictionaryAlias,\n sourceTermExactMatchCount,\n matchPrimaryReading,\n maxOriginalTextLength,\n headwords,\n definitions,\n pronunciations: [],\n frequencies: [],\n };\n }\n\n private _createTermDictionaryEntryFromDatabaseEntry(\n databaseEntry: DictionaryDatabase.TermEntry,\n originalText: string,\n transformedText: string,\n deinflectedText: string,\n textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[],\n inflectionRuleChainCandidates: InflectionRuleChainCandidate[],\n isPrimary: boolean,\n enabledDictionaryMap: Map<string, Translation.FindTermDictionary>,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): TermDictionaryEntry {\n const {\n matchType,\n matchSource,\n term,\n reading: rawReading,\n definitionTags,\n termTags,\n definitions,\n score,\n dictionary,\n id,\n sequence: rawSequence,\n rules,\n } = databaseEntry;\n // Cast is safe because getDeinflections filters out deinflection definitions\n const contentDefinitions = definitions as DictionaryData.TermGlossaryContent[];\n const reading = rawReading.length > 0 ? rawReading : term;\n const matchPrimaryReading = primaryReading.length > 0 && reading === primaryReading;\n const { index: dictionaryIndex } = this._getDictionaryOrder(dictionary, enabledDictionaryMap);\n const dictionaryAlias = this._getDictionaryAlias(dictionary, enabledDictionaryMap);\n const sourceTermExactMatchCount = isPrimary && deinflectedText === term ? 1 : 0;\n const source = this._createSource(\n originalText,\n transformedText,\n deinflectedText,\n matchType,\n matchSource,\n isPrimary,\n );\n const maxOriginalTextLength = originalText.length;\n const hasSequence = rawSequence >= 0;\n const sequence = hasSequence ? rawSequence : -1;\n\n const headwordTagGroups: Dictionary.Tag[] = [];\n const definitionTagGroups: Dictionary.Tag[] = [];\n tagAggregator.addTags(headwordTagGroups, dictionary, termTags);\n tagAggregator.addTags(definitionTagGroups, dictionary, definitionTags);\n\n const expandedInflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[] =\n inflectionRuleChainCandidates.map(({ source: src, inflectionRules }) => ({\n source: src,\n inflectionRules: inflectionRules.map((rule) => ({ name: rule })),\n }));\n\n return this._createTermDictionaryEntry(\n isPrimary,\n textProcessorRuleChainCandidates,\n expandedInflectionRuleChainCandidates,\n score,\n dictionaryIndex,\n dictionaryAlias,\n sourceTermExactMatchCount,\n matchPrimaryReading,\n maxOriginalTextLength,\n [this._createTermHeadword(0, term, reading, [source], headwordTagGroups, rules)],\n [\n this._createTermDefinition(\n 0,\n [0],\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n id,\n score,\n [sequence],\n isPrimary,\n definitionTagGroups,\n contentDefinitions,\n ),\n ],\n );\n }\n\n private _createGroupedDictionaryEntry(\n language: string,\n dictionaryEntries: TermDictionaryEntry[],\n checkDuplicateDefinitions: boolean,\n tagAggregator: TranslatorTagAggregator,\n primaryReading: string,\n ): TermDictionaryEntry {\n // Headwords are generated before sorting, so that the order of dictionaryEntries can be maintained\n const definitionEntries: { index: number; dictionaryEntry: TermDictionaryEntry; headwordIndexMap: number[] }[] =\n [];\n const headwords = new Map<string, Dictionary.TermHeadword>();\n const headwordDictionaryIndices = new Map<number, number>();\n for (const dictionaryEntry of dictionaryEntries) {\n const headwordIndexMap = this._addTermHeadwords(\n language,\n headwords,\n dictionaryEntry.headwords,\n tagAggregator,\n );\n // Track minimum dictionary index for each headword\n for (const headwordIndex of headwordIndexMap) {\n const existing = headwordDictionaryIndices.get(headwordIndex);\n if (typeof existing === 'undefined' || dictionaryEntry.dictionaryIndex < existing) {\n headwordDictionaryIndices.set(headwordIndex, dictionaryEntry.dictionaryIndex);\n }\n }\n definitionEntries.push({ index: definitionEntries.length, dictionaryEntry, headwordIndexMap });\n }\n\n // Sort\n if (definitionEntries.length <= 1) {\n checkDuplicateDefinitions = false;\n }\n\n // Merge dictionary entry data\n let score = Number.MIN_SAFE_INTEGER;\n let dictionaryIndex = Number.MAX_SAFE_INTEGER;\n const dictionaryAlias = '';\n let maxOriginalTextLength = 0;\n let isPrimary = false;\n const definitions: Dictionary.TermDefinition[] = [];\n const definitionsMap: Map<string, Dictionary.TermDefinition> | null = checkDuplicateDefinitions\n ? new Map()\n : null;\n\n let inflections: Dictionary.InflectionRuleChainCandidate[] | null = null;\n let textProcesses: TextProcessorRuleChainCandidate[] | null = null;\n\n for (const { dictionaryEntry, headwordIndexMap } of definitionEntries) {\n score = Math.max(score, dictionaryEntry.score);\n dictionaryIndex = Math.min(dictionaryIndex, dictionaryEntry.dictionaryIndex);\n\n if (dictionaryEntry.isPrimary) {\n isPrimary = true;\n maxOriginalTextLength = Math.max(maxOriginalTextLength, dictionaryEntry.maxOriginalTextLength);\n\n const dictionaryEntryInflections = dictionaryEntry.inflectionRuleChainCandidates;\n const dictionaryEntryTextProcesses = dictionaryEntry.textProcessorRuleChainCandidates;\n\n if (inflections === null || dictionaryEntryInflections.length < inflections.length) {\n inflections = dictionaryEntryInflections;\n }\n if (textProcesses === null || dictionaryEntryTextProcesses.length < textProcesses.length) {\n textProcesses = dictionaryEntryTextProcesses;\n }\n }\n\n if (definitionsMap !== null) {\n this._addTermDefinitions(\n definitions,\n definitionsMap,\n dictionaryEntry.definitions,\n headwordIndexMap,\n tagAggregator,\n );\n } else {\n this._addTermDefinitionsFast(definitions, dictionaryEntry.definitions, headwordIndexMap);\n }\n }\n\n const headwordsArray = [...headwords.values()];\n\n this._sortHeadwords(headwordsArray, headwordDictionaryIndices, definitions);\n\n const { sourceTermExactMatchCount, matchPrimaryReading } = this._getHeadwordMatchCounts(\n headwordsArray,\n primaryReading,\n );\n\n return this._createTermDictionaryEntry(\n isPrimary,\n textProcesses !== null ? textProcesses : [],\n inflections !== null ? inflections : [],\n score,\n dictionaryIndex,\n dictionaryAlias,\n sourceTermExactMatchCount,\n matchPrimaryReading,\n maxOriginalTextLength,\n headwordsArray,\n definitions,\n );\n }\n\n private _sortHeadwords(\n headwordsArray: Dictionary.TermHeadword[],\n headwordDictionaryIndices: Map<number, number>,\n definitions: Dictionary.TermDefinition[],\n ): void {\n // Sort headwords: primary sources first, then by dictionary index\n headwordsArray.sort((a, b) => {\n const aHasPrimary = a.sources.some((s) => s.isPrimary);\n const bHasPrimary = b.sources.some((s) => s.isPrimary);\n if (aHasPrimary !== bHasPrimary) {\n return aHasPrimary ? -1 : 1;\n }\n const aDictIndex = headwordDictionaryIndices.get(a.index) ?? Number.MAX_SAFE_INTEGER;\n const bDictIndex = headwordDictionaryIndices.get(b.index) ?? Number.MAX_SAFE_INTEGER;\n return aDictIndex - bDictIndex;\n });\n\n // Update headword indices after sorting\n const headwordIndexMap = new Map<number, number>();\n for (let i = 0; i < headwordsArray.length; i++) {\n headwordIndexMap.set(headwordsArray[i].index, i);\n headwordsArray[i].index = i;\n }\n\n // Remap definition headword indices\n for (const definition of definitions) {\n for (let i = 0; i < definition.headwordIndices.length; i++) {\n const oldIndex = definition.headwordIndices[i];\n const newIndex = headwordIndexMap.get(oldIndex);\n if (typeof newIndex === 'number') {\n definition.headwordIndices[i] = newIndex;\n }\n }\n }\n }\n\n private _getHeadwordMatchCounts(\n headwordsArray: Dictionary.TermHeadword[],\n primaryReading: string,\n ): { sourceTermExactMatchCount: number; matchPrimaryReading: boolean } {\n let sourceTermExactMatchCount = 0;\n let matchPrimaryReading = false;\n for (const { sources, reading } of headwordsArray) {\n if (primaryReading.length > 0 && reading === primaryReading) {\n matchPrimaryReading = true;\n }\n for (const source of sources) {\n if (source.isPrimary && source.matchSource === 'term') {\n ++sourceTermExactMatchCount;\n break;\n }\n }\n }\n return { sourceTermExactMatchCount, matchPrimaryReading };\n }\n\n // Data collection addition functions\n\n private _addUniqueSimple<T>(list: T[], newItems: T[]): void {\n for (const item of newItems) {\n if (!list.includes(item)) {\n list.push(item);\n }\n }\n }\n\n private _addUniqueSources(sources: Dictionary.TermSource[], newSources: Dictionary.TermSource[]): void {\n if (newSources.length === 0) {\n return;\n }\n if (sources.length === 0) {\n sources.push(...newSources);\n return;\n }\n for (const newSource of newSources) {\n const { originalText, transformedText, deinflectedText, matchType, matchSource, isPrimary } = newSource;\n let has = false;\n for (const source of sources) {\n if (\n source.deinflectedText === deinflectedText &&\n source.transformedText === transformedText &&\n source.originalText === originalText &&\n source.matchType === matchType &&\n source.matchSource === matchSource\n ) {\n if (isPrimary) {\n source.isPrimary = true;\n }\n has = true;\n break;\n }\n }\n if (!has) {\n sources.push(newSource);\n }\n }\n }\n\n private _addTermHeadwords(\n language: string,\n headwordsMap: Map<string, Dictionary.TermHeadword>,\n headwords: Dictionary.TermHeadword[],\n tagAggregator: TranslatorTagAggregator,\n ): number[] {\n const headwordIndexMap: number[] = [];\n for (const { term, reading, sources, tags, wordClasses } of headwords) {\n const readingNormalizer = this._readingNormalizers.get(language);\n const normalizedReading = typeof readingNormalizer === 'undefined' ? reading : readingNormalizer(reading);\n const key = this._createMapKey([term, normalizedReading]);\n let headword = headwordsMap.get(key);\n if (typeof headword === 'undefined') {\n headword = this._createTermHeadword(headwordsMap.size, term, reading, [], [], []);\n headwordsMap.set(key, headword);\n }\n this._addUniqueSources(headword.sources, sources);\n this._addUniqueSimple(headword.wordClasses, wordClasses);\n tagAggregator.mergeTags(headword.tags, tags);\n headwordIndexMap.push(headword.index);\n }\n return headwordIndexMap;\n }\n\n private _addUniqueTermHeadwordIndex(headwordIndices: number[], headwordIndex: number): void {\n let end = headwordIndices.length;\n if (end === 0) {\n headwordIndices.push(headwordIndex);\n return;\n }\n\n let start = 0;\n while (start < end) {\n const mid = Math.floor((start + end) / 2);\n const value = headwordIndices[mid];\n if (headwordIndex === value) {\n return;\n }\n if (headwordIndex > value) {\n start = mid + 1;\n } else {\n end = mid;\n }\n }\n\n if (headwordIndex === headwordIndices[start]) {\n return;\n }\n headwordIndices.splice(start, 0, headwordIndex);\n }\n\n private _addTermDefinitionsFast(\n definitions: Dictionary.TermDefinition[],\n newDefinitions: Dictionary.TermDefinition[],\n headwordIndexMap: number[],\n ): void {\n for (const {\n headwordIndices,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n sequences,\n id,\n score,\n isPrimary,\n tags,\n entries,\n } of newDefinitions) {\n const headwordIndicesNew: number[] = [];\n for (const headwordIndex of headwordIndices) {\n headwordIndicesNew.push(headwordIndexMap[headwordIndex]);\n }\n definitions.push(\n this._createTermDefinition(\n definitions.length,\n headwordIndicesNew,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n id,\n score,\n sequences,\n isPrimary,\n tags,\n entries,\n ),\n );\n }\n }\n\n private _addTermDefinitions(\n definitions: Dictionary.TermDefinition[],\n definitionsMap: Map<string, Dictionary.TermDefinition>,\n newDefinitions: Dictionary.TermDefinition[],\n headwordIndexMap: number[],\n tagAggregator: TranslatorTagAggregator,\n ): void {\n for (const {\n headwordIndices,\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n sequences,\n id,\n score,\n isPrimary,\n tags,\n entries,\n } of newDefinitions) {\n const key = this._createMapKey([dictionary, ...entries]);\n let definition = definitionsMap.get(key);\n if (typeof definition === 'undefined') {\n definition = this._createTermDefinition(\n definitions.length,\n [],\n dictionary,\n dictionaryIndex,\n dictionaryAlias,\n id,\n score,\n [...sequences],\n isPrimary,\n [],\n [...entries],\n );\n definitions.push(definition);\n definitionsMap.set(key, definition);\n } else {\n if (isPrimary) {\n definition.isPrimary = true;\n }\n this._addUniqueSimple(definition.sequences, sequences);\n }\n\n const newHeadwordIndices = definition.headwordIndices;\n for (const headwordIndex of headwordIndices) {\n this._addUniqueTermHeadwordIndex(newHeadwordIndices, headwordIndexMap[headwordIndex]);\n }\n tagAggregator.mergeTags(definition.tags, tags);\n }\n }\n\n // Sorting functions\n\n private _sortDatabaseEntriesByIndex(\n databaseEntries: (DictionaryDatabase.TermEntry | DictionaryDatabase.KanjiEntry)[],\n ): void {\n if (databaseEntries.length <= 1) {\n return;\n }\n const compareFunction = (v1: { index: number }, v2: { index: number }): number => v1.index - v2.index;\n databaseEntries.sort(compareFunction);\n }\n\n private _sortKanjiDictionaryEntries(dictionaryEntries: Dictionary.KanjiDictionaryEntry[]): void {\n const compareFunction = (v1: Dictionary.KanjiDictionaryEntry, v2: Dictionary.KanjiDictionaryEntry): number => {\n // Sort by dictionary order\n return v1.dictionaryIndex - v2.dictionaryIndex;\n };\n dictionaryEntries.sort(compareFunction);\n }\n\n private _sortTermDictionaryEntries(dictionaryEntries: TermDictionaryEntry[]): void {\n const stringComparer = this._stringComparer;\n const compareFunction = (v1: TermDictionaryEntry, v2: TermDictionaryEntry): number => {\n // Sort by reading match\n let i = (v2.matchPrimaryReading ? 1 : 0) - (v1.matchPrimaryReading ? 1 : 0);\n if (i !== 0) {\n return i;\n }\n\n // Sort by length of source term\n i = v2.maxOriginalTextLength - v1.maxOriginalTextLength;\n if (i !== 0) {\n return i;\n }\n\n // Sort by length of the shortest text processing chain\n i =\n this._getShortestTextProcessingChainLength(v1.textProcessorRuleChainCandidates) -\n this._getShortestTextProcessingChainLength(v2.textProcessorRuleChainCandidates);\n if (i !== 0) {\n return i;\n }\n\n // Sort by length of the shortest inflection chain\n i =\n this._getShortestInflectionChainLength(v1.inflectionRuleChainCandidates) -\n this._getShortestInflectionChainLength(v2.inflectionRuleChainCandidates);\n if (i !== 0) {\n return i;\n }\n\n // Sort by how many terms exactly match the source\n i = v2.sourceTermExactMatchCount - v1.sourceTermExactMatchCount;\n if (i !== 0) {\n return i;\n }\n\n // Sort by frequency order\n i = v1.frequencyOrder - v2.frequencyOrder;\n if (i !== 0) {\n return i;\n }\n\n // Sort by dictionary order\n i = v1.dictionaryIndex - v2.dictionaryIndex;\n if (i !== 0) {\n return i;\n }\n\n // Sort by term score\n i = v2.score - v1.score;\n if (i !== 0) {\n return i;\n }\n\n // Sort by headword term text\n const headwords1 = v1.headwords;\n const headwords2 = v2.headwords;\n for (let j = 0, jj = Math.min(headwords1.length, headwords2.length); j < jj; ++j) {\n const term1 = headwords1[j].term;\n const term2 = headwords2[j].term;\n\n i = term2.length - term1.length;\n if (i !== 0) {\n return i;\n }\n\n i = stringComparer.compare(term1, term2);\n if (i !== 0) {\n return i;\n }\n }\n\n // Sort by definition count\n i = v2.definitions.length - v1.definitions.length;\n return i;\n };\n dictionaryEntries.sort(compareFunction);\n }\n\n private _sortTermDictionaryEntryDefinitions(definitions: Dictionary.TermDefinition[]): void {\n const compareFunction = (v1: Dictionary.TermDefinition, v2: Dictionary.TermDefinition): number => {\n // Sort by frequency order\n let i = v1.frequencyOrder - v2.frequencyOrder;\n if (i !== 0) {\n return i;\n }\n\n // Sort by dictionary order\n i = v1.dictionaryIndex - v2.dictionaryIndex;\n if (i !== 0) {\n return i;\n }\n\n // Sort by term score\n i = v2.score - v1.score;\n if (i !== 0) {\n return i;\n }\n\n // Sort by definition headword index\n const headwordIndices1 = v1.headwordIndices;\n const headwordIndices2 = v2.headwordIndices;\n const jj = headwordIndices1.length;\n i = headwordIndices2.length - jj;\n if (i !== 0) {\n return i;\n }\n for (let j = 0; j < jj; ++j) {\n i = headwordIndices1[j] - headwordIndices2[j];\n if (i !== 0) {\n return i;\n }\n }\n\n // Sort by original order\n i = v1.index - v2.index;\n return i;\n };\n definitions.sort(compareFunction);\n }\n\n private _sortTermDictionaryEntriesById(dictionaryEntries: TermDictionaryEntry[]): void {\n if (dictionaryEntries.length <= 1) {\n return;\n }\n dictionaryEntries.sort((a, b) => a.definitions[0].id - b.definitions[0].id);\n }\n\n private _sortTermDictionaryEntrySimpleData(\n dataList: (Dictionary.TermFrequency | Dictionary.TermPronunciation)[],\n ): void {\n const compare = (\n v1: Dictionary.TermFrequency | Dictionary.TermPronunciation,\n v2: Dictionary.TermFrequency | Dictionary.TermPronunciation,\n ): number => {\n // Sort by headword order\n let i = v1.headwordIndex - v2.headwordIndex;\n if (i !== 0) {\n return i;\n }\n\n // Sort by dictionary order\n i = v1.dictionaryIndex - v2.dictionaryIndex;\n if (i !== 0) {\n return i;\n }\n\n // Default order\n i = v1.index - v2.index;\n return i;\n };\n dataList.sort(compare);\n }\n\n private _sortKanjiDictionaryEntryData(dictionaryEntries: Dictionary.KanjiDictionaryEntry[]): void {\n const compare = (v1: Dictionary.KanjiFrequency, v2: Dictionary.KanjiFrequency): number => {\n // Sort by dictionary order\n let i = v1.dictionaryIndex - v2.dictionaryIndex;\n if (i !== 0) {\n return i;\n }\n\n // Default order\n i = v1.index - v2.index;\n return i;\n };\n\n for (const { frequencies } of dictionaryEntries) {\n frequencies.sort(compare);\n }\n }\n\n private _updateSortFrequencies(\n dictionaryEntries: TermDictionaryEntry[],\n dictionary: string,\n ascending: boolean,\n ): void {\n const frequencyMap = new Map<number, number>();\n for (const dictionaryEntry of dictionaryEntries) {\n const { definitions, frequencies } = dictionaryEntry;\n let frequencyMin = Number.MAX_SAFE_INTEGER;\n let frequencyMax = Number.MIN_SAFE_INTEGER;\n for (const item of frequencies) {\n if (item.dictionary !== dictionary) {\n continue;\n }\n const { headwordIndex, frequency } = item;\n if (typeof frequency !== 'number') {\n continue;\n }\n frequencyMap.set(headwordIndex, frequency);\n frequencyMin = Math.min(frequencyMin, frequency);\n frequencyMax = Math.max(frequencyMax, frequency);\n }\n dictionaryEntry.frequencyOrder =\n frequencyMin <= frequencyMax\n ? ascending\n ? frequencyMin\n : -frequencyMax\n : ascending\n ? Number.MAX_SAFE_INTEGER\n : 0;\n for (const definition of definitions) {\n frequencyMin = Number.MAX_SAFE_INTEGER;\n frequencyMax = Number.MIN_SAFE_INTEGER;\n const { headwordIndices } = definition;\n for (const headwordIndex of headwordIndices) {\n const frequency = frequencyMap.get(headwordIndex);\n if (typeof frequency !== 'number') {\n continue;\n }\n frequencyMin = Math.min(frequencyMin, frequency);\n frequencyMax = Math.max(frequencyMax, frequency);\n }\n definition.frequencyOrder =\n frequencyMin <= frequencyMax\n ? ascending\n ? frequencyMin\n : -frequencyMax\n : ascending\n ? Number.MAX_SAFE_INTEGER\n : 0;\n }\n frequencyMap.clear();\n }\n }\n\n private _getShortestTextProcessingChainLength(\n textProcessorRuleChainCandidates: TextProcessorRuleChainCandidate[],\n ): number {\n if (textProcessorRuleChainCandidates.length === 0) {\n return 0;\n }\n let length = Number.MAX_SAFE_INTEGER;\n for (const candidate of textProcessorRuleChainCandidates) {\n length = Math.min(length, candidate.length);\n }\n return length;\n }\n\n private _getShortestInflectionChainLength(\n inflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[],\n ): number {\n if (inflectionRuleChainCandidates.length === 0) {\n return 0;\n }\n let length = Number.MAX_SAFE_INTEGER;\n for (const { inflectionRules } of inflectionRuleChainCandidates) {\n length = Math.min(length, inflectionRules.length);\n }\n return length;\n }\n\n private _addUserFacingInflections(\n language: string,\n dictionaryEntries: TermDictionaryEntry[],\n ): TermDictionaryEntry[] {\n const result: TermDictionaryEntry[] = [];\n for (const dictionaryEntry of dictionaryEntries) {\n const { inflectionRuleChainCandidates } = dictionaryEntry;\n const expandedChains = inflectionRuleChainCandidates.map(({ source, inflectionRules }) => ({\n source,\n inflectionRules: this._multiLanguageTransformer.getUserFacingInflectionRules(\n language,\n inflectionRules.map((r) => r.name),\n ),\n }));\n result.push({ ...dictionaryEntry, inflectionRuleChainCandidates: expandedChains });\n }\n return result;\n }\n\n // Miscellaneous\n\n private _hasAny<T>(set: Set<T>, values: T[]): boolean {\n for (const value of values) {\n if (set.has(value)) {\n return true;\n }\n }\n return false;\n }\n}\n"],"mappings":"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AW;GAC3E,cAAc,UAAU,WAAW,QAAQ;GAC3C,cAAc,UAAU,WAAW,QAAQ;GAC3C,gBAAgB,UAAU,YAAY,MAAM,SAAS,IAAI,CAAC,KAAM,IAAG,CAAE;GACrE,cAAc,CAAC,UAAW;GAC1B,WAAW;EACd;CACJ;CAED,AAAQ,cACJhE,cACAC,iBACAC,iBACAnB,WACAkF,aACAC,WACqB;AACrB,SAAO;GAAE;GAAc;GAAiB;GAAiB;GAAW;GAAa;EAAW;CAC/F;CAED,AAAQ,oBACJhB,OACAiB,MACAC,SACAC,SACAtH,MACAuH,aACuB;AACvB,SAAO;GAAE;GAAO;GAAM;GAAS;GAAS;GAAM;EAAa;CAC9D;CAED,AAAQ,sBACJpB,OACAqB,iBACAvH,YACAmG,iBACAC,iBACA7E,IACAiG,OACAC,WACAP,WACAnH,MACA2H,SACyB;AACzB,SAAO;GACH;GACA;GACA;GACA;GACA;GACA;GACA;GACA,gBAAgB;GAChB;GACA;GACA;GACA;EACH;CACJ;CAED,AAAQ,yBACJxB,OACAyB,eACA3H,YACAmG,iBACAC,iBACAwB,gBAC4B;AAC5B,SAAO;GAAE;GAAO;GAAe;GAAY;GAAiB;GAAiB;EAAgB;CAChG;CAED,AAAQ,qBACJ1B,OACAyB,eACA3H,YACAmG,iBACAC,iBACAyB,YACAvB,WACAX,cACAY,oBACwB;AACxB,SAAO;GACH;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACH;CACJ;CAED,AAAQ,2BACJW,WACAzF,kCACAqG,+BACAN,OACArB,iBACAC,iBACA2B,2BACAC,qBACAC,uBACAC,WACAnE,aACmB;AACnB,SAAO;GACH,MAAM;GACN;GACA;GACA;GACA;GACA,gBAAgB;GAChB;GACA;GACA;GACA;GACA;GACA;GACA;GACA,gBAAgB,CAAE;GAClB,aAAa,CAAE;EAClB;CACJ;CAED,AAAQ,4CACJoE,eACAnF,cACAC,iBACAC,iBACAzB,kCACAC,+BACAwF,WACApF,sBACAZ,eACAC,gBACmB;EACnB,MAAM,EACF,WACA,aACA,MACA,SAAS,YACT,gBACA,UACA,aACA,OACA,YA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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { KanjiDictionaryEntry, TermDictionaryEntry, TermSourceMatchType } from "./dictionary-_vzfBLWi.js";
|
|
2
|
+
import { DictionaryDB$1 as DictionaryDB } from "./dictionary-database-BDC2f9zc.js";
|
|
3
|
+
|
|
4
|
+
//#region src/types/translation.d.ts
|
|
5
|
+
type SearchResolution = 'letter' | 'word';
|
|
6
|
+
type FindKanjiOptions = {
|
|
7
|
+
enabledDictionaryMap: KanjiEnabledDictionaryMap;
|
|
8
|
+
removeNonJapaneseCharacters: boolean;
|
|
9
|
+
};
|
|
10
|
+
type FindKanjiDictionary = {
|
|
11
|
+
index: number;
|
|
12
|
+
alias: string;
|
|
13
|
+
};
|
|
14
|
+
type FindTermsOptions = {
|
|
15
|
+
matchType: FindTermsMatchType;
|
|
16
|
+
deinflect: boolean;
|
|
17
|
+
primaryReading: string;
|
|
18
|
+
mainDictionary: string;
|
|
19
|
+
sortFrequencyDictionary: string | null;
|
|
20
|
+
sortFrequencyDictionaryOrder: FindTermsSortOrder;
|
|
21
|
+
removeNonJapaneseCharacters: boolean;
|
|
22
|
+
textReplacements: FindTermsTextReplacements;
|
|
23
|
+
enabledDictionaryMap: TermEnabledDictionaryMap;
|
|
24
|
+
excludeDictionaryDefinitions: Set<string> | null;
|
|
25
|
+
searchResolution: SearchResolution;
|
|
26
|
+
language: string;
|
|
27
|
+
};
|
|
28
|
+
type FindTermsMatchType = TermSourceMatchType;
|
|
29
|
+
type FindTermsSortOrder = 'ascending' | 'descending';
|
|
30
|
+
type FindTermsTextReplacement = {
|
|
31
|
+
pattern: RegExp;
|
|
32
|
+
replacement: string;
|
|
33
|
+
};
|
|
34
|
+
type FindTermsTextReplacements = (FindTermsTextReplacement[] | null)[];
|
|
35
|
+
type FindTermDictionary = {
|
|
36
|
+
index: number;
|
|
37
|
+
alias: string;
|
|
38
|
+
allowSecondarySearches: boolean;
|
|
39
|
+
partsOfSpeechFilter: boolean;
|
|
40
|
+
useDeinflections: boolean;
|
|
41
|
+
};
|
|
42
|
+
type TermEnabledDictionaryMap = Map<string, FindTermDictionary>;
|
|
43
|
+
type KanjiEnabledDictionaryMap = Map<string, FindKanjiDictionary>; //#endregion
|
|
44
|
+
//#region src/lookup/translator.d.ts
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=translation.d.ts.map
|
|
47
|
+
type TermDictionaryEntry$1 = TermDictionaryEntry;
|
|
48
|
+
type FindTermsMode = 'group' | 'term' | 'merge' | 'simple';
|
|
49
|
+
/**
|
|
50
|
+
* Class which finds term and kanji dictionary entries for text.
|
|
51
|
+
*/
|
|
52
|
+
declare class Translator {
|
|
53
|
+
private _database;
|
|
54
|
+
private _multiLanguageTransformer;
|
|
55
|
+
private _tagCache;
|
|
56
|
+
private _stringComparer;
|
|
57
|
+
private _numberRegex;
|
|
58
|
+
private _textProcessors;
|
|
59
|
+
private _readingNormalizers;
|
|
60
|
+
constructor(database: DictionaryDB);
|
|
61
|
+
/**
|
|
62
|
+
* Initializes the instance for use. The public API should not be used until this function has been called.
|
|
63
|
+
*/
|
|
64
|
+
prepare(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Clears the database tag cache. This should be executed if the database is changed.
|
|
67
|
+
*/
|
|
68
|
+
clearDatabaseCaches(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Finds term definitions for the given text.
|
|
71
|
+
*/
|
|
72
|
+
findTerms(mode: FindTermsMode, text: string, options: FindTermsOptions): Promise<{
|
|
73
|
+
dictionaryEntries: TermDictionaryEntry$1[];
|
|
74
|
+
originalTextLength: number;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Finds kanji definitions for the given text.
|
|
78
|
+
*/
|
|
79
|
+
findKanji(text: string, options: FindKanjiOptions): Promise<KanjiDictionaryEntry[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Gets a list of frequency information for a given list of term-reading pairs
|
|
82
|
+
* and a list of dictionaries.
|
|
83
|
+
*/
|
|
84
|
+
getTermFrequencies(termReadingList: {
|
|
85
|
+
term: string;
|
|
86
|
+
reading: string | null;
|
|
87
|
+
}[], dictionaries: string[]): Promise<{
|
|
88
|
+
term: string;
|
|
89
|
+
reading: string | null;
|
|
90
|
+
dictionary: string;
|
|
91
|
+
hasReading: boolean;
|
|
92
|
+
frequency: number;
|
|
93
|
+
displayValue: string | null;
|
|
94
|
+
displayValueParsed: boolean;
|
|
95
|
+
}[]>;
|
|
96
|
+
private _findTermsInternal;
|
|
97
|
+
private _getDictionaryEntries;
|
|
98
|
+
private _findExistingEntry;
|
|
99
|
+
private _mergeTextProcessorRuleChains;
|
|
100
|
+
private _mergeInflectionRuleChains;
|
|
101
|
+
private _areArraysEqualIgnoreOrder;
|
|
102
|
+
private _getDeinflections;
|
|
103
|
+
private _getDictionaryDeinflections;
|
|
104
|
+
private _addEntriesToDeinflections;
|
|
105
|
+
private _groupDeinflectionsByTerm;
|
|
106
|
+
private _matchEntriesToDeinflections;
|
|
107
|
+
private _getAlgorithmDeinflections;
|
|
108
|
+
private _getTextVariants;
|
|
109
|
+
private _getProcessedText;
|
|
110
|
+
private _getNextSubstring;
|
|
111
|
+
private _applyTextReplacements;
|
|
112
|
+
private _getJapaneseChineseKoreanOnlyText;
|
|
113
|
+
private _getTextReplacementsVariants;
|
|
114
|
+
private _createDeinflection;
|
|
115
|
+
private _getRelatedDictionaryEntries;
|
|
116
|
+
private _addRelatedDictionaryEntries;
|
|
117
|
+
private _addSecondaryRelatedDictionaryEntries;
|
|
118
|
+
private _groupDictionaryEntriesByHeadword;
|
|
119
|
+
private _groupDictionaryEntriesByTerm;
|
|
120
|
+
private _groupDictionaryEntries;
|
|
121
|
+
private _removeExcludedDefinitions;
|
|
122
|
+
private _removeUnusedHeadwords;
|
|
123
|
+
private _updateDefinitionHeadwordIndices;
|
|
124
|
+
private _updateArrayItemsHeadwordIndex;
|
|
125
|
+
private _removeArrayItemsWithDictionary;
|
|
126
|
+
private _removeArrayItemsWithDictionary2;
|
|
127
|
+
private _removeTagGroupsWithDictionary;
|
|
128
|
+
private _expandTagGroupsAndGroup;
|
|
129
|
+
private _expandTagGroups;
|
|
130
|
+
private _groupTags;
|
|
131
|
+
private _mergeSimilarTags;
|
|
132
|
+
private _getTagNamesWithCategory;
|
|
133
|
+
private _flagRedundantDefinitionTags;
|
|
134
|
+
private _addTermMeta;
|
|
135
|
+
private _addKanjiMeta;
|
|
136
|
+
private _expandKanjiStats;
|
|
137
|
+
private _sortKanjiStats;
|
|
138
|
+
private _convertStringToNumber;
|
|
139
|
+
private _getFrequencyInfo;
|
|
140
|
+
private _getNameBase;
|
|
141
|
+
private _getSecondarySearchDictionaryMap;
|
|
142
|
+
private _getDictionaryOrder;
|
|
143
|
+
private _getDictionaryAlias;
|
|
144
|
+
private _createMapKey;
|
|
145
|
+
private _toNumberArray;
|
|
146
|
+
private _createKanjiStat;
|
|
147
|
+
private _createKanjiFrequency;
|
|
148
|
+
private _createKanjiDictionaryEntry;
|
|
149
|
+
private _createTag;
|
|
150
|
+
private _createSource;
|
|
151
|
+
private _createTermHeadword;
|
|
152
|
+
private _createTermDefinition;
|
|
153
|
+
private _createTermPronunciation;
|
|
154
|
+
private _createTermFrequency;
|
|
155
|
+
private _createTermDictionaryEntry;
|
|
156
|
+
private _createTermDictionaryEntryFromDatabaseEntry;
|
|
157
|
+
private _createGroupedDictionaryEntry;
|
|
158
|
+
private _sortHeadwords;
|
|
159
|
+
private _getHeadwordMatchCounts;
|
|
160
|
+
private _addUniqueSimple;
|
|
161
|
+
private _addUniqueSources;
|
|
162
|
+
private _addTermHeadwords;
|
|
163
|
+
private _addUniqueTermHeadwordIndex;
|
|
164
|
+
private _addTermDefinitionsFast;
|
|
165
|
+
private _addTermDefinitions;
|
|
166
|
+
private _sortDatabaseEntriesByIndex;
|
|
167
|
+
private _sortKanjiDictionaryEntries;
|
|
168
|
+
private _sortTermDictionaryEntries;
|
|
169
|
+
private _sortTermDictionaryEntryDefinitions;
|
|
170
|
+
private _sortTermDictionaryEntriesById;
|
|
171
|
+
private _sortTermDictionaryEntrySimpleData;
|
|
172
|
+
private _sortKanjiDictionaryEntryData;
|
|
173
|
+
private _updateSortFrequencies;
|
|
174
|
+
private _getShortestTextProcessingChainLength;
|
|
175
|
+
private _getShortestInflectionChainLength;
|
|
176
|
+
private _addUserFacingInflections;
|
|
177
|
+
private _hasAny;
|
|
178
|
+
} //#endregion
|
|
179
|
+
export { FindKanjiDictionary, FindKanjiOptions, FindTermDictionary, FindTermsMatchType, FindTermsMode, FindTermsOptions, FindTermsSortOrder, FindTermsTextReplacement, FindTermsTextReplacements, KanjiEnabledDictionaryMap, SearchResolution, TermEnabledDictionaryMap, Translator as Translator$1 };
|
|
180
|
+
//# sourceMappingURL=translator-Cc6OGxrW.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translator-Cc6OGxrW.d.ts","names":[],"sources":["../src/types/translation.ts","../src/lookup/translator.ts"],"sourcesContent":null,"mappings":";;;;KAEY,gBAAA;KAEA,gBAAA;wBACc;EAHd,2BAAgB,EAAA,OAAA;AAE5B,CAAA;AAKY,KAAA,mBAAA,GAAmB;EAKnB,KAAA,EAAA,MAAA;EAAgB,KAAA,EAAA,MAAA;CAAA;AAMM,KANtB,gBAAA,GAMsB;EAAkB,SAE9B,EAPP,kBAOO;EAAyB,SACrB,EAAA,OAAA;EAAwB,cAChB,EAAA,MAAA;EAAG,cACf,EAAA,MAAA;EAAgB,uBAAA,EAAA,MAAA,GAAA,IAAA;EAI1B,4BAAkB,EATI,kBASJ;EAElB,2BAAkB,EAAA,OAAA;EAElB,gBAAA,EAXU,yBAYT;EAID,oBAAA,EAfc,wBAee;EAE7B,4BAAkB,EAhBI,GAgBJ,CAAA,MAAA,CAAA,GAAA,IAAA;EAQlB,gBAAA,EAvBU,gBAuBc;EAAA,QAAA,EAAA,MAAA;CAAA;AAAG,KAnB3B,kBAAA,GAAkB,mBAmBS;AAAG,KAjB9B,kBAAA,GAiB8B,WAAA,GAAA,YAAA;AAE9B,KAjBA,wBAAA,GAiByB;EAAA,OAAA,EAhBxB,MAgBwB;EAAA,WAAe,EAAA,MAAA;CAAmB;AAA5B,KAZ/B,yBAAA,GAY+B,CAZF,wBAYE,EAAA,GAAA,IAAA,CAAA,EAAA;KAV/B,kBAAA;;;ECkBP,sBAAA,EAAmB,OAAA;EA6CZ,mBAAa,EAAA,OAAA;;;KDvDb,wBAAA,GAA2B,YAAY;ACmMtC,KDjMD,yBAAA,GAA4B,GCiMjB,CAAA,MAAA,EDjM6B,mBCiM7B,CAAA,CAAA;;;;KAzLlB,qBAAA,GAAmB;ADxDZ,KCqGA,aAAA,GDrGgB,OAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA;AAE5B;AAKA;AAKA;AAA4B,cCqOf,UAAA,CDrOe;EAAA,QACb,SAAA;EAAkB,QAKC,yBAAA;EAAkB,QAE9B,SAAA;EAAyB,QACrB,eAAA;EAAwB,QAChB,YAAA;EAAG,QACf,eAAA;EAAgB,QAAA,mBAAA;EAI1B,WAAA,CAAA,QAAA,EC+Nc,YD/NI;EAElB;AAEZ;AAKA;EAEY,OAAA,CAAA,CAAA,EAAA,IAAA;EAQA;;;EAAyD,mBAA9B,CAAA,CAAA,EAAA,IAAA;EAAG;AAE1C;;EAAqC,SAAe,CAAA,IAAA,EC4OtC,aD5OsC,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EC4OzB,gBD5OyB,CAAA,EC+O7C,OD/O6C,CAAA;IAAZ,iBAAA,EC+OJ,qBD/OI,EAAA;IAAG,kBAAA,EAAA,MAAA;;;;AChBc;EAqE7C,SAAA,CAAA,IAAA,EAAa,MAAA,EAAA,OAAA,EA0LX,gBA1LW,CAAA,EAiRiD,OAjRjD,CAiR8C,oBAjR9C,EAAA,CAAA;;;;AA4IzB;EAAuB,kBAAA,CAAA,eAAA,EAAA;IASG,IAAA,EAAA,MAAA;IAkCZ,OAAA,EAAA,MAAA,GAAA,IAAA;EAAa,CAAA,EAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,EAiJpB,OAjJoB,CAAA;IAGS,IAAA,EAAA,MAAA;IAA7B,OAAA,EAAA,MAAA,GAAA,IAAA;IAAO,UAAA,EAAA,MAAA;IAuFyD,UAAA,EAAA,OAAA;IAAG,SAAA,EAAA,MAAA;IAuDnE,YAAA,EAAA,MAAA,GAAA,IAAA;IAAO,kBAAA,EAAA,OAAA"}
|