henkan 0.9.2 → 1.0.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.
Files changed (68) hide show
  1. package/CONTRIBUTING.md +0 -0
  2. package/LICENSE.md +0 -0
  3. package/README.md +1 -1
  4. package/SECURITY.md +0 -0
  5. package/dist/index.cjs.js +432 -77
  6. package/dist/index.cjs.js.map +2 -2
  7. package/dist/index.mjs +427 -77
  8. package/dist/index.mjs.map +2 -2
  9. package/dist/types/types.d.ts +43 -5
  10. package/dist/types/types.d.ts.map +1 -1
  11. package/dist/types/utils.d.ts +32 -11
  12. package/dist/types/utils.d.ts.map +1 -1
  13. package/docs/api/README.md +5 -0
  14. package/docs/api/functions/capitalizeString.md +1 -1
  15. package/docs/api/functions/convertJMdict.md +1 -1
  16. package/docs/api/functions/convertJawiktionary.md +29 -0
  17. package/docs/api/functions/convertKanjiDic.md +1 -1
  18. package/docs/api/functions/convertKradFile.md +1 -1
  19. package/docs/api/functions/convertRadkFile.md +1 -1
  20. package/docs/api/functions/convertTanakaCorpus.md +2 -2
  21. package/docs/api/functions/generateAnkiNote.md +1 -1
  22. package/docs/api/functions/generateAnkiNotesFile.md +4 -4
  23. package/docs/api/functions/getKanji.md +12 -6
  24. package/docs/api/functions/getKanjiExtended.md +17 -11
  25. package/docs/api/functions/getWord.md +8 -2
  26. package/docs/api/functions/getWordDefinitions.md +45 -0
  27. package/docs/api/functions/isStringArray.md +1 -1
  28. package/docs/api/functions/isValidArray.md +1 -1
  29. package/docs/api/functions/isValidArrayWithFirstElement.md +1 -1
  30. package/docs/api/functions/shuffleArray.md +1 -1
  31. package/docs/api/functions/synthesizeSpeech.md +1 -1
  32. package/docs/api/interfaces/Definition.md +41 -0
  33. package/docs/api/interfaces/DictKanji.md +7 -7
  34. package/docs/api/interfaces/DictKanjiForm.md +4 -4
  35. package/docs/api/interfaces/DictKanjiMisc.md +5 -5
  36. package/docs/api/interfaces/DictKanjiReading.md +3 -3
  37. package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
  38. package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
  39. package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
  40. package/docs/api/interfaces/DictMeaning.md +12 -12
  41. package/docs/api/interfaces/DictRadical.md +4 -4
  42. package/docs/api/interfaces/DictReading.md +5 -5
  43. package/docs/api/interfaces/DictWord.md +8 -8
  44. package/docs/api/interfaces/ExamplePart.md +7 -7
  45. package/docs/api/interfaces/GlossSpecificNumber.md +3 -3
  46. package/docs/api/interfaces/Grammar.md +15 -15
  47. package/docs/api/interfaces/GrammarMeaning.md +3 -3
  48. package/docs/api/interfaces/Kana.md +11 -11
  49. package/docs/api/interfaces/Kanji.md +22 -22
  50. package/docs/api/interfaces/KanjiComponent.md +3 -3
  51. package/docs/api/interfaces/KanjiForm.md +4 -4
  52. package/docs/api/interfaces/NoteAndTag.md +3 -3
  53. package/docs/api/interfaces/Phrase.md +5 -5
  54. package/docs/api/interfaces/Radical.md +16 -16
  55. package/docs/api/interfaces/Reading.md +5 -5
  56. package/docs/api/interfaces/ResultEntry.md +7 -7
  57. package/docs/api/interfaces/TanakaExample.md +7 -7
  58. package/docs/api/interfaces/Translation.md +3 -3
  59. package/docs/api/interfaces/UsefulRegExps.md +8 -8
  60. package/docs/api/interfaces/Word.md +24 -14
  61. package/docs/api/interfaces/WordDefinitionPair.md +31 -0
  62. package/docs/api/type-aliases/Dict.md +1 -1
  63. package/docs/api/type-aliases/DictName.md +1 -1
  64. package/docs/api/type-aliases/DictTranslation.md +13 -0
  65. package/docs/api/type-aliases/EntryType.md +1 -1
  66. package/docs/api/type-aliases/JLPT.md +1 -1
  67. package/docs/api/type-aliases/Result.md +1 -1
  68. package/package.json +16 -9
package/dist/index.cjs.js CHANGED
@@ -32,6 +32,7 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  capitalizeString: () => capitalizeString,
34
34
  convertJMdict: () => convertJMdict,
35
+ convertJawiktionary: () => convertJawiktionary,
35
36
  convertKanjiDic: () => convertKanjiDic,
36
37
  convertKradFile: () => convertKradFile,
37
38
  convertRadkFile: () => convertRadkFile,
@@ -41,6 +42,7 @@ __export(index_exports, {
41
42
  getKanji: () => getKanji,
42
43
  getKanjiExtended: () => getKanjiExtended,
43
44
  getWord: () => getWord,
45
+ getWordDefinitions: () => getWordDefinitions,
44
46
  isGrammar: () => isGrammar,
45
47
  isKana: () => isKana,
46
48
  isKanji: () => isKanji,
@@ -1135,6 +1137,7 @@ var import_libxmljs2 = __toESM(require("libxmljs2"));
1135
1137
  var import_xml2js = __toESM(require("xml2js"));
1136
1138
  var import_iconv_lite = __toESM(require("iconv-lite"));
1137
1139
  var import_client_polly = require("@aws-sdk/client-polly");
1140
+ var import_readline = require("readline");
1138
1141
  var Kuroshiro = require("kuroshiro");
1139
1142
  var KuromojiAnalyzer = require("kuroshiro-analyzer-kuromoji");
1140
1143
  function capitalizeString(value) {
@@ -1150,6 +1153,7 @@ function isStringArray(arg) {
1150
1153
  return arg !== null && arg !== void 0 && Array.isArray(arg) && arg.every((element) => typeof element === "string");
1151
1154
  }
1152
1155
  function shuffleArray(arr) {
1156
+ if (arr.length < 2) return arr;
1153
1157
  const a = arr.slice();
1154
1158
  for (let i = a.length - 1; i > 0; i--) {
1155
1159
  const j = Math.floor(Math.random() * (i + 1));
@@ -1265,7 +1269,7 @@ function convertJMdict(xmlString, examples) {
1265
1269
  }
1266
1270
  if (isStringArray(meaning.dial))
1267
1271
  meaningObj.dialects = meaning.dial;
1268
- if (meaningObj.partOfSpeech && meaningObj.partOfSpeech.length > 0 || meaningObj.translations && meaningObj.translations.length > 0)
1272
+ if (meaningObj.partOfSpeech && meaningObj.partOfSpeech.length > 0 || meaningObj.translations)
1269
1273
  entryObj.meanings.push(meaningObj);
1270
1274
  }
1271
1275
  if (entryObj.meanings.length === usuallyInKanaMeanings)
@@ -1274,9 +1278,9 @@ function convertJMdict(xmlString, examples) {
1274
1278
  if (examples) {
1275
1279
  const readings2 = new Set(
1276
1280
  entryObj.readings.filter(
1277
- (reading) => (!reading.notes || !reading.notes.some(
1281
+ (reading) => reading.notes === void 0 || !reading.notes.some(
1278
1282
  (note) => notSearchedForms.has(note)
1279
- )) && (entryObj.isCommon === void 0 || reading.commonness && reading.commonness.length > 0)
1283
+ ) || reading.commonness
1280
1284
  ).map((reading) => reading.reading)
1281
1285
  );
1282
1286
  const kanjiForms2 = entryObj.kanjiForms ? new Set(
@@ -1377,9 +1381,13 @@ function convertKanjiDic(xmlString) {
1377
1381
  rmObj.groups.push(groupObj);
1378
1382
  }
1379
1383
  if (isStringArray(rm.nanori)) rmObj.nanori = rm.nanori;
1380
- if (rmObj.groups.length > 0) kanjiObj.readingMeaning.push(rmObj);
1384
+ if (rmObj.groups.length > 0 && kanjiObj.readingMeaning)
1385
+ kanjiObj.readingMeaning.push(rmObj);
1381
1386
  }
1382
- if (kanjiObj.kanji.length > 0) dict.push(kanjiObj);
1387
+ if (kanjiObj.readingMeaning && kanjiObj.readingMeaning.length === 0)
1388
+ delete kanjiObj.readingMeaning;
1389
+ if (kanjiObj.kanji.length === 1 && kanjiObj.misc && kanjiObj.misc.strokeNumber.length > 0)
1390
+ dict.push(kanjiObj);
1383
1391
  }
1384
1392
  });
1385
1393
  return dict;
@@ -1483,7 +1491,7 @@ function convertRadkFile(radkBuffer, kanjiDic) {
1483
1491
  (dictKanji) => dictKanji.kanji === kanji
1484
1492
  );
1485
1493
  if (foundKanji) kanjiList.push(foundKanji);
1486
- else kanjiList.push({ kanji, readingMeaning: [] });
1494
+ else kanjiList.push({ kanji });
1487
1495
  }
1488
1496
  j++;
1489
1497
  kanjiLine = fileParsed[j];
@@ -1491,7 +1499,7 @@ function convertRadkFile(radkBuffer, kanjiDic) {
1491
1499
  if (kanjiLine.startsWith("$ ")) i = j - 1;
1492
1500
  }
1493
1501
  if (kanjiList.length > 0) radical.kanji = kanjiList;
1494
- if (radical.radical.length > 0 && radical.strokes.length > 0)
1502
+ if (radical.radical.length === 1 && radical.strokes.length > 0)
1495
1503
  radicals.push(radical);
1496
1504
  }
1497
1505
  }
@@ -1552,6 +1560,265 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
1552
1560
  throw err;
1553
1561
  }
1554
1562
  }
1563
+ async function convertJawiktionary(stream) {
1564
+ const rl = (0, import_readline.createInterface)({
1565
+ input: stream,
1566
+ crlfDelay: Infinity
1567
+ });
1568
+ let lineNumber = 0;
1569
+ return await new Promise(
1570
+ async (resolve, reject) => {
1571
+ try {
1572
+ const entries = [];
1573
+ for await (const line of rl) {
1574
+ lineNumber++;
1575
+ let obj = void 0;
1576
+ try {
1577
+ obj = JSON.parse(line.trim());
1578
+ } catch (err) {
1579
+ rl.close();
1580
+ throw new Error(
1581
+ `Invalid JSONL at line ${lineNumber}: ${err.message}`
1582
+ );
1583
+ }
1584
+ if (obj !== void 0 && obj !== null && typeof obj === "object" && obj.lang_code === "ja" && obj.lang === "\u65E5\u672C\u8A9E")
1585
+ entries.push(obj);
1586
+ }
1587
+ rl.close();
1588
+ stream.close();
1589
+ stream.destroy();
1590
+ resolve(entries);
1591
+ } catch (err) {
1592
+ reject(err);
1593
+ }
1594
+ }
1595
+ );
1596
+ }
1597
+ function parseEntry(entry, definitions, definitionMap) {
1598
+ if (isValidArray(entry.senses)) {
1599
+ for (const sense of entry.senses)
1600
+ if (isStringArray(sense.glosses)) {
1601
+ const definition = sense.glosses.join("<br>");
1602
+ if (!definitions.some((def) => def.definition === definition)) {
1603
+ if (!definitionMap.has(definition))
1604
+ definitionMap.set(definition, { count: 1 });
1605
+ else definitionMap.get(definition).count++;
1606
+ definitions.push({ definition });
1607
+ }
1608
+ }
1609
+ }
1610
+ }
1611
+ async function getWordDefinitions(entries, jmDict, kanjiDic, generateFurigana) {
1612
+ return await new Promise(async (resolve, reject) => {
1613
+ try {
1614
+ const japaneseDefinitions = [];
1615
+ const definitionMap = /* @__PURE__ */ new Map();
1616
+ const validWords = [];
1617
+ const validReadings = /* @__PURE__ */ new Set();
1618
+ const validKanjiForms = /* @__PURE__ */ new Set();
1619
+ for (const word of jmDict) {
1620
+ let valid = false;
1621
+ for (const r of word.readings)
1622
+ if ((r.notes === void 0 || !r.notes.some((note) => notSearchedForms.has(note)) || r.commonness !== void 0) && !validReadings.has(r.reading)) {
1623
+ validReadings.add(r.reading);
1624
+ if (!valid) valid = true;
1625
+ }
1626
+ if (word.kanjiForms) {
1627
+ for (const kf of word.kanjiForms)
1628
+ if ((kf.notes === void 0 || !kf.notes.some((note) => notSearchedForms.has(note)) || kf.commonness !== void 0) && !validKanjiForms.has(kf.form)) {
1629
+ validKanjiForms.add(kf.form);
1630
+ if (!valid) valid = true;
1631
+ }
1632
+ }
1633
+ if (valid)
1634
+ validWords.push(
1635
+ getWord(void 0, void 0, kanjiDic, void 0, void 0, word)
1636
+ );
1637
+ }
1638
+ const validTitleEntries = [];
1639
+ const entriesWithFormTitlesGlobal = [];
1640
+ const entriesWithFormsGlobal = [];
1641
+ const validFormOfEntries = /* @__PURE__ */ new Set();
1642
+ const validGlossesEntries = /* @__PURE__ */ new Set();
1643
+ const validFormsEntries = /* @__PURE__ */ new Set();
1644
+ for (const entry of entries) {
1645
+ let valid = false;
1646
+ if (validKanjiForms && validKanjiForms.has(entry.word)) {
1647
+ valid = true;
1648
+ if (isValidArray(entry.senses))
1649
+ for (const sense of entry.senses) {
1650
+ if (isValidArray(sense.form_of) && sense.form_of.some(
1651
+ (form) => form.word && typeof form.word === "string" && validReadings.has(form.word)
1652
+ ))
1653
+ validFormOfEntries.add(entry.word);
1654
+ else if (isValidArray(sense.glosses) && sense.glosses.length === 1) {
1655
+ const gloss = sense.glosses[0];
1656
+ let reading = void 0;
1657
+ if (gloss !== void 0) {
1658
+ if (gloss.trim().includes("\u6F22\u5B57\u8868\u8A18\u3002") || gloss.trim().includes("\u53C2\u7167\u3002")) {
1659
+ for (const r of validReadings)
1660
+ if (gloss.trim().includes(r)) {
1661
+ reading = r;
1662
+ break;
1663
+ }
1664
+ }
1665
+ }
1666
+ if (reading) validGlossesEntries.add(entry.word);
1667
+ }
1668
+ }
1669
+ if (isValidArray(entry.forms)) {
1670
+ for (const form of entry.forms)
1671
+ if (form.form && typeof form.form === "string" && validReadings.has(form.form))
1672
+ validFormsEntries.add(entry.word);
1673
+ }
1674
+ } else if (validReadings.has(entry.word) && isValidArray(entry.forms) && entry.forms.some((form) => validKanjiForms.has(form.form))) {
1675
+ valid = true;
1676
+ entriesWithFormTitlesGlobal.push(entry);
1677
+ } else if (validReadings.has(entry.word)) {
1678
+ valid = true;
1679
+ entriesWithFormTitlesGlobal.push(entry);
1680
+ }
1681
+ if (valid) validTitleEntries.push(entry);
1682
+ if (isValidArray(entry.forms) && (validKanjiForms.has(entry.word) || validReadings.has(entry.word)) && entry.forms.some(
1683
+ (form) => validKanjiForms.has(form.form) || validReadings.has(form.form)
1684
+ ))
1685
+ entriesWithFormsGlobal.push(entry);
1686
+ }
1687
+ for (const word of validWords) {
1688
+ const definitions = [];
1689
+ const kanjiFormEntries = [];
1690
+ const readingWithFormsEntries = [];
1691
+ const readingEntries = [];
1692
+ const titleFormMap = /* @__PURE__ */ new Map();
1693
+ const readingForms = /* @__PURE__ */ new Set();
1694
+ const validWordReadings = new Set(
1695
+ word.readings.filter(
1696
+ (r) => r.notes === void 0 || !r.notes.some((note) => notSearchedForms.has(note)) || r.common === true
1697
+ ).map((r) => r.reading)
1698
+ );
1699
+ const validWordKanjiForms = word.kanjiForms ? new Set(
1700
+ word.kanjiForms.filter(
1701
+ (kf) => kf.notes === void 0 || !kf.notes.some(
1702
+ (note) => notSearchedForms.has(note)
1703
+ ) || kf.common === true
1704
+ ).map((kf) => kf.kanjiForm)
1705
+ ) : void 0;
1706
+ const entriesWithFormTitles = entriesWithFormTitlesGlobal.filter(
1707
+ (entry) => validWordReadings.has(entry.word)
1708
+ );
1709
+ const entriesWithForms = entriesWithFormsGlobal.filter(
1710
+ (entry) => isValidArray(entry.forms) && (validWordKanjiForms && validWordKanjiForms.has(entry.word) || validWordReadings.has(entry.word)) && entry.forms.some(
1711
+ (form) => validWordKanjiForms && validWordKanjiForms.has(form.form) || validWordReadings.has(form.form)
1712
+ )
1713
+ );
1714
+ for (const ent of validTitleEntries) {
1715
+ const validFormOf = validFormOfEntries.has(ent.word);
1716
+ const validGlosses = validGlossesEntries.has(ent.word);
1717
+ const validForms = validFormsEntries.has(ent.word);
1718
+ if (word.kanjiForms && validWordKanjiForms && validWordKanjiForms.has(ent.word) && (validFormOf || validGlosses || validForms)) {
1719
+ kanjiFormEntries.push(ent);
1720
+ if ((validFormOf || validGlosses) && isValidArray(ent.senses))
1721
+ for (const sense of ent.senses) {
1722
+ if (validFormOf && isValidArray(sense.form_of)) {
1723
+ for (const form of sense.form_of)
1724
+ if (form.word && typeof form.word === "string" && validWordReadings.has(form.word)) {
1725
+ const elem = titleFormMap.get(
1726
+ form.word
1727
+ );
1728
+ if (!elem)
1729
+ titleFormMap.set(
1730
+ form.word,
1731
+ /* @__PURE__ */ new Set([ent.word])
1732
+ );
1733
+ else elem.add(ent.word);
1734
+ }
1735
+ } else if (validGlosses && isStringArray(sense.glosses) && sense.glosses.length === 1) {
1736
+ const gloss = sense.glosses[0];
1737
+ let reading = void 0;
1738
+ if (gloss !== void 0) {
1739
+ if (gloss.trim().includes("\u6F22\u5B57\u8868\u8A18\u3002") || gloss.trim().includes("\u53C2\u7167\u3002")) {
1740
+ for (const r of validWordReadings)
1741
+ if (gloss.trim().includes(r)) {
1742
+ reading = r;
1743
+ break;
1744
+ }
1745
+ }
1746
+ }
1747
+ if (reading) {
1748
+ const elem = titleFormMap.get(reading);
1749
+ if (!elem)
1750
+ titleFormMap.set(reading, /* @__PURE__ */ new Set([ent.word]));
1751
+ else elem.add(ent.word);
1752
+ }
1753
+ }
1754
+ }
1755
+ if (validForms && isValidArray(ent.forms)) {
1756
+ for (const form of ent.forms)
1757
+ if (form.form && typeof form.form === "string" && validWordReadings.has(form.form))
1758
+ readingForms.add(form.form);
1759
+ }
1760
+ } else if (validWordReadings.has(ent.word) && isValidArray(ent.forms) && word.kanjiForms && validWordKanjiForms && ent.forms.some((form) => validWordKanjiForms.has(form.form)))
1761
+ readingWithFormsEntries.push(ent);
1762
+ else if (word.kanjiForms === void 0 && validWordReadings.has(ent.word))
1763
+ readingEntries.push(ent);
1764
+ }
1765
+ for (const entry of entriesWithForms) {
1766
+ const elem = titleFormMap.get(entry.word);
1767
+ if (elem && entry.forms.some((form) => elem.has(form.form)))
1768
+ readingWithFormsEntries.push(entry);
1769
+ }
1770
+ for (const entry of entriesWithFormTitles)
1771
+ if (readingForms.has(entry.word)) readingWithFormsEntries.push(entry);
1772
+ let parsedReadingWithFormsEntries = false;
1773
+ for (const entry of kanjiFormEntries)
1774
+ if (entry.pos_title === "\u548C\u8A9E\u306E\u6F22\u5B57\u8868\u8A18" && readingWithFormsEntries.length > 0) {
1775
+ if (!parsedReadingWithFormsEntries)
1776
+ parsedReadingWithFormsEntries = true;
1777
+ for (const ref of readingWithFormsEntries)
1778
+ parseEntry(ref, definitions, definitionMap);
1779
+ } else parseEntry(entry, definitions, definitionMap);
1780
+ if (!parsedReadingWithFormsEntries && readingWithFormsEntries.length > 0) {
1781
+ parsedReadingWithFormsEntries = true;
1782
+ for (const ref of readingWithFormsEntries)
1783
+ parseEntry(ref, definitions, definitionMap);
1784
+ }
1785
+ if (readingEntries.length > 0)
1786
+ for (const readingEntry of readingEntries)
1787
+ parseEntry(readingEntry, definitions, definitionMap);
1788
+ if (definitions.length > 0)
1789
+ japaneseDefinitions.push({
1790
+ wordID: word.id,
1791
+ definitions
1792
+ });
1793
+ }
1794
+ const kuroshiro = generateFurigana === true ? new Kuroshiro.default() : null;
1795
+ if (kuroshiro !== null) await kuroshiro.init(new KuromojiAnalyzer());
1796
+ const convert = kuroshiro !== null ? kuroshiro.convert.bind(kuroshiro) : null;
1797
+ for (let i = 0; i < japaneseDefinitions.length; i++) {
1798
+ const pair = japaneseDefinitions[i];
1799
+ for (let j = 0; j < pair.definitions.length; j++) {
1800
+ const defCount = definitionMap.get(
1801
+ pair.definitions[j].definition
1802
+ );
1803
+ if (defCount && defCount.count > 1)
1804
+ pair.definitions[j].mayNotBeAccurate = true;
1805
+ if (convert !== null && !pair.definitions[j].definition.includes("\u30FB"))
1806
+ pair.definitions[j].furigana = await convert(
1807
+ pair.definitions[j].definition,
1808
+ {
1809
+ to: "hiragana",
1810
+ mode: "furigana"
1811
+ }
1812
+ );
1813
+ }
1814
+ japaneseDefinitions[i] = pair;
1815
+ }
1816
+ resolve(japaneseDefinitions);
1817
+ } catch (err) {
1818
+ reject(err);
1819
+ }
1820
+ });
1821
+ }
1555
1822
  function lookupWordNote(key, notes, tags, required, fallback) {
1556
1823
  const info = noteMap.get(
1557
1824
  key.toLowerCase()
@@ -1570,7 +1837,7 @@ var wordAddNoteArray = (arr, cb) => {
1570
1837
  if (!arr) return;
1571
1838
  for (const v of arr) cb(v);
1572
1839
  };
1573
- function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath) {
1840
+ function getWord(dict, id, kanjiDic, examples, definitions, dictWord, noteTypeName, deckPath) {
1574
1841
  try {
1575
1842
  if (!dictWord && id && dict)
1576
1843
  dictWord = dict.find((entry) => entry.id === id);
@@ -1584,7 +1851,10 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1584
1851
  ...deckPath ? { deckPath } : {},
1585
1852
  tags: []
1586
1853
  };
1587
- if (dictWord.isCommon === true) word.common = true;
1854
+ if (dictWord.isCommon === true) {
1855
+ word.common = true;
1856
+ word.tags.push("word::common");
1857
+ }
1588
1858
  if (dictWord.kanjiForms)
1589
1859
  word.kanjiForms = dictWord.kanjiForms.map(
1590
1860
  (dictKanjiForm) => ({
@@ -1635,12 +1905,16 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1635
1905
  (translation) => {
1636
1906
  if (typeof translation === "string") return translation;
1637
1907
  else {
1638
- if (translation.type === "lit")
1908
+ if (translation.type === "lit") {
1639
1909
  translationTypes.push("Literal meaning");
1640
- else if (translation.type === "expl")
1910
+ word.tags.push("word::literal_meaning");
1911
+ } else if (translation.type === "expl") {
1641
1912
  translationTypes.push("Explanation");
1642
- else if (translation.type === "tm")
1913
+ word.tags.push("word::explanation");
1914
+ } else if (translation.type === "tm") {
1643
1915
  translationTypes.push("Trademark");
1916
+ word.tags.push("word::trademark");
1917
+ }
1644
1918
  return translation.translation;
1645
1919
  }
1646
1920
  }
@@ -1690,7 +1964,10 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1690
1964
  notes
1691
1965
  };
1692
1966
  });
1693
- if (dictWord.usuallyInKana === true) word.usuallyInKana = true;
1967
+ if (dictWord.usuallyInKana === true) {
1968
+ word.usuallyInKana = true;
1969
+ word.tags.push("word::usually_in_kana_for_all_senses");
1970
+ }
1694
1971
  if (kanjiDic && word.kanjiForms) {
1695
1972
  word.kanji = [];
1696
1973
  for (const kanjiForm of word.kanjiForms)
@@ -1701,35 +1978,44 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1701
1978
  (kanji) => kanji.kanji === char
1702
1979
  );
1703
1980
  if (dictKanji) {
1704
- const kanjiObj = getKanji(
1705
- dictKanji.kanji,
1706
- kanjiDic,
1707
- void 0
1708
- );
1981
+ const kanjiObj = getKanji(kanjiDic, void 0, dictKanji);
1709
1982
  word.kanji.push({
1710
1983
  kanji: kanjiObj.kanji,
1711
1984
  ...kanjiObj.meanings ? { meanings: kanjiObj.meanings } : {}
1712
1985
  });
1713
1986
  }
1714
1987
  }
1715
- if (word.kanji.length === 0) delete word.kanji;
1988
+ if (word.kanji.length === 0) {
1989
+ delete word.kanji;
1990
+ word.tags.push("word::no_kanji");
1991
+ }
1716
1992
  }
1717
1993
  if (dictWord.hasPhrases === true && examples) {
1718
1994
  const readings = new Set(
1719
1995
  word.readings.filter(
1720
- (reading) => (!reading.notes || !reading.notes.some(
1996
+ (reading) => (reading.notes === void 0 || !reading.notes.some(
1721
1997
  (note) => notSearchedForms.has(note)
1722
1998
  )) && (word.common === void 0 || reading.common === true)
1723
1999
  ).map((reading) => reading.reading)
1724
2000
  );
2001
+ const existValidKf = word.kanjiForms && word.kanjiForms.length > 0 ? word.kanjiForms.some(
2002
+ (kf) => (kf.notes === void 0 || !kf.notes.some(
2003
+ (note) => notSearchedForms.has(note)
2004
+ )) && (word.common === void 0 || kf.common === true)
2005
+ ) : void 0;
1725
2006
  const kanjiForms = word.kanjiForms && word.kanjiForms.length > 0 ? new Set(
1726
- word.kanjiForms.map(
1727
- (kanjiForm) => kanjiForm.kanjiForm
1728
- )
2007
+ word.kanjiForms.filter((kanjiForm) => {
2008
+ if (existValidKf === true)
2009
+ return (kanjiForm.notes === void 0 || !kanjiForm.notes.some(
2010
+ (note) => notSearchedForms.has(note)
2011
+ )) && (word.common === void 0 || kanjiForm.common === true);
2012
+ else return true;
2013
+ }).map((kanjiForm) => kanjiForm.kanjiForm)
1729
2014
  ) : void 0;
1730
- const kanjiFormExamples = [];
2015
+ let kanjiFormExamples = [];
1731
2016
  const readingMatchingKanjiFormExamples = [];
1732
2017
  const readingExamples = [];
2018
+ const readingMatchingKanjiForms = /* @__PURE__ */ new Set();
1733
2019
  for (const example of examples)
1734
2020
  for (let i = 0; i < example.parts.length; i++) {
1735
2021
  const part = example.parts[i];
@@ -1737,12 +2023,18 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1737
2023
  const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
1738
2024
  const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
1739
2025
  if (kanjiForms && kanjiForms.has(part.baseForm) || referenceIDMatch) {
1740
- if (readingAsReadingMatch || readingAsInflectedFormMatch)
2026
+ if (readingAsReadingMatch || readingAsInflectedFormMatch) {
1741
2027
  readingMatchingKanjiFormExamples.push({
1742
2028
  ex: example,
1743
2029
  partIndex: i
1744
2030
  });
1745
- else kanjiFormExamples.push({ ex: example, partIndex: i });
2031
+ readingMatchingKanjiForms.add(part.baseForm);
2032
+ } else
2033
+ kanjiFormExamples.push({
2034
+ ex: example,
2035
+ partIndex: i,
2036
+ form: part.baseForm
2037
+ });
1746
2038
  break;
1747
2039
  }
1748
2040
  const readingAsBaseFormMatch = readings.has(part.baseForm);
@@ -1751,11 +2043,16 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1751
2043
  break;
1752
2044
  }
1753
2045
  }
2046
+ if (readingMatchingKanjiForms.size > 0)
2047
+ kanjiFormExamples = kanjiFormExamples.filter(
2048
+ (ex) => ex.form && readingMatchingKanjiForms.has(ex.form)
2049
+ );
1754
2050
  const includeKanjiFormExamples = word.kanjiForms !== void 0;
1755
2051
  let wordExamples = [
1756
2052
  ...includeKanjiFormExamples ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : [],
1757
2053
  ...!includeKanjiFormExamples ? readingExamples : []
1758
2054
  ];
2055
+ readingMatchingKanjiForms.clear();
1759
2056
  const glossSpecificExamples = [];
1760
2057
  const seenPhrases = /* @__PURE__ */ new Set();
1761
2058
  for (let i = 0; i < word.translations.length; i++) {
@@ -1785,7 +2082,7 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1785
2082
  (ex) => !seenPhrases.has(ex.ex.phrase)
1786
2083
  ).slice(0, 5 - glossSpecificExamples.length)
1787
2084
  ];
1788
- if (wordExamples.length > 0)
2085
+ if (wordExamples.length > 0) {
1789
2086
  word.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => {
1790
2087
  var _a;
1791
2088
  return {
@@ -1795,6 +2092,16 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1795
2092
  ...ex.ex.glossNumber ? { glossNumber: ex.ex.glossNumber } : {}
1796
2093
  };
1797
2094
  });
2095
+ word.tags.push("word::has_phrases");
2096
+ if (glossSpecificExamples.length > 0)
2097
+ word.tags.push("word::has_meaning-specific_phrases");
2098
+ }
2099
+ }
2100
+ if (definitions) {
2101
+ const pair = definitions.find(
2102
+ (wdp) => wdp.wordID === word.id
2103
+ );
2104
+ if (pair) word.definitions = pair.definitions;
1798
2105
  }
1799
2106
  return word;
1800
2107
  } else throw new Error(`Word${id ? ` ${id}` : ""} not found`);
@@ -1802,35 +2109,46 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1802
2109
  throw err;
1803
2110
  }
1804
2111
  }
1805
- function getKanji(kanjiChar, dict, jmDict, svgList, noteTypeName, deckPath) {
2112
+ function getKanji(dict, kanjiChar, dictKanji, jmDict, svgList, noteTypeName, deckPath) {
1806
2113
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1807
2114
  try {
1808
- const dictKanji = dict.find(
1809
- (entry) => entry.kanji === kanjiChar
1810
- );
2115
+ if (!dictKanji && kanjiChar)
2116
+ dictKanji = dict.find((entry) => entry.kanji === kanjiChar);
1811
2117
  if (dictKanji) {
1812
2118
  const kanji = {
1813
2119
  kanji: dictKanji.kanji,
1814
2120
  ...dictKanji.misc ? { strokes: dictKanji.misc.strokeNumber } : {},
1815
2121
  ...dictKanji.misc && dictKanji.misc.grade ? { grade: dictKanji.misc.grade } : {},
1816
- ...dictKanji.misc && dictKanji.misc.frequency ? { grade: dictKanji.misc.frequency } : {},
2122
+ ...dictKanji.misc && dictKanji.misc.frequency ? { frequency: dictKanji.misc.frequency } : {},
1817
2123
  noteID: `kanji_${dictKanji.kanji}`,
1818
2124
  ...noteTypeName ? { noteTypeName } : {},
1819
2125
  ...deckPath ? { deckPath } : {}
1820
2126
  };
1821
- for (const rm of dictKanji.readingMeaning) {
1822
- if (rm.nanori && rm.nanori.length > 0) {
1823
- if (kanji.nanori === void 0) kanji.nanori = [];
1824
- kanji.nanori.push(...rm.nanori);
1825
- }
1826
- for (const group of rm.groups) {
1827
- kanji.onyomi = group.readings.filter((reading) => reading.type === "ja_on").map((reading) => reading.reading);
1828
- kanji.kunyomi = group.readings.filter((reading) => reading.type === "ja_kun").map((reading) => reading.reading);
1829
- if (kanji.onyomi.length === 0) delete kanji.onyomi;
1830
- if (kanji.kunyomi.length === 0) delete kanji.kunyomi;
1831
- kanji.meanings = group.meanings;
1832
- if (kanji.meanings.length === 0) delete kanji.meanings;
2127
+ if (dictKanji.readingMeaning) {
2128
+ kanji.meanings = [];
2129
+ kanji.nanori = [];
2130
+ kanji.onyomi = [];
2131
+ kanji.kunyomi = [];
2132
+ for (const rm of dictKanji.readingMeaning) {
2133
+ if (rm.nanori && rm.nanori.length > 0)
2134
+ kanji.nanori.push(...rm.nanori);
2135
+ for (const group of rm.groups) {
2136
+ kanji.onyomi.push(
2137
+ ...group.readings.filter((reading) => reading.type === "ja_on").map((reading) => reading.reading)
2138
+ );
2139
+ kanji.kunyomi.push(
2140
+ ...group.readings.filter(
2141
+ (reading) => reading.type === "ja_kun"
2142
+ ).map((reading) => reading.reading)
2143
+ );
2144
+ kanji.meanings.push(...group.meanings);
2145
+ }
1833
2146
  }
2147
+ if (kanji.meanings && kanji.meanings.length === 0)
2148
+ delete kanji.meanings;
2149
+ if (kanji.nanori && kanji.nanori.length === 0) delete kanji.nanori;
2150
+ if (kanji.onyomi && kanji.onyomi.length === 0) delete kanji.onyomi;
2151
+ if (kanji.kunyomi && kanji.kunyomi.length === 0) delete kanji.kunyomi;
1834
2152
  }
1835
2153
  if (jmDict) {
1836
2154
  let kanjiWords = jmDict.filter(
@@ -1844,6 +2162,7 @@ function getKanji(kanjiChar, dict, jmDict, svgList, noteTypeName, deckPath) {
1844
2162
  void 0,
1845
2163
  void 0,
1846
2164
  void 0,
2165
+ void 0,
1847
2166
  word,
1848
2167
  void 0
1849
2168
  );
@@ -1880,6 +2199,7 @@ function getKanji(kanjiChar, dict, jmDict, svgList, noteTypeName, deckPath) {
1880
2199
  void 0,
1881
2200
  void 0,
1882
2201
  void 0,
2202
+ void 0,
1883
2203
  word,
1884
2204
  void 0
1885
2205
  );
@@ -1949,17 +2269,19 @@ function getKanji(kanjiChar, dict, jmDict, svgList, noteTypeName, deckPath) {
1949
2269
  ...kanji.svg ? ["kanji::has_svg"] : []
1950
2270
  );
1951
2271
  return kanji;
1952
- } else throw new Error(`Kanji ${kanjiChar} not found`);
2272
+ } else
2273
+ throw new Error(`Kanji not found${kanjiChar ? `: ${kanjiChar}` : ""}`);
1953
2274
  } catch (err) {
1954
2275
  throw err;
1955
2276
  }
1956
2277
  }
1957
- function getKanjiExtended(kanjiChar, info, dict, useJpdbWords, jmDict, svgList, noteTypeName, deckPath) {
2278
+ function getKanjiExtended(info, dict, kanjiChar, dictKanji, useWords, jmDict, svgList, noteTypeName, deckPath) {
1958
2279
  var _a, _b, _c, _d;
1959
2280
  try {
1960
2281
  const kanji = getKanji(
1961
- kanjiChar,
1962
2282
  dict,
2283
+ kanjiChar,
2284
+ dictKanji,
1963
2285
  jmDict,
1964
2286
  svgList,
1965
2287
  noteTypeName,
@@ -1969,13 +2291,13 @@ function getKanjiExtended(kanjiChar, info, dict, useJpdbWords, jmDict, svgList,
1969
2291
  kanji.components = info.components;
1970
2292
  if (info.mnemonic && info.mnemonic.length > 0)
1971
2293
  kanji.mnemonic = info.mnemonic;
1972
- if (useJpdbWords === true && info.words && info.words.length > 0)
2294
+ if (useWords === true && info.words && info.words.length > 0)
1973
2295
  kanji.words = info.words;
1974
2296
  if (kanji.tags) {
1975
2297
  kanji.tags.push(`kanji::components::${(_b = (_a = kanji.components) == null ? void 0 : _a.length) != null ? _b : 0}`);
1976
2298
  if (kanji.mnemonic && kanji.mnemonic.length > 0)
1977
2299
  kanji.tags.push("kanji::has_mnemonic");
1978
- if (useJpdbWords === true && kanji.words) {
2300
+ if (useWords === true && kanji.words) {
1979
2301
  if (!kanji.tags.some((tag, index) => {
1980
2302
  var _a2, _b2;
1981
2303
  if (tag.startsWith("kanji::words::")) {
@@ -1990,8 +2312,8 @@ function getKanjiExtended(kanjiChar, info, dict, useJpdbWords, jmDict, svgList,
1990
2312
  kanji.tags.push(`kanji::words::${(_d = (_c = kanji.words) == null ? void 0 : _c.length) != null ? _d : 0}`);
1991
2313
  }
1992
2314
  }
1993
- if (kanji.fromJpdb === true && (kanji.mnemonic || kanji.components && kanji.components.length > 0 || kanji.words))
1994
- kanji.source = `https://jpdb.io/kanji/${kanji.kanji}#a`;
2315
+ if (info.fromJpdb === true && (kanji.mnemonic || kanji.components || kanji.words && useWords === true))
2316
+ kanji.source = `https://jpdb.io/kanji/${kanji.kanji}`;
1995
2317
  return kanji;
1996
2318
  } catch (err) {
1997
2319
  throw err;
@@ -2036,32 +2358,50 @@ function generateAnkiNote(entry) {
2036
2358
  if (!entry.noteID) throw new Error("Invalid note ID");
2037
2359
  const fields = [];
2038
2360
  if (isWord(entry)) {
2039
- if (!entry.translations) throw new Error(`Invalid word: ${entry.noteID}`);
2361
+ if (!entry.translations || entry.readings.length === 0)
2362
+ throw new Error(`Invalid word: ${entry.noteID}`);
2363
+ const firstReading = createEntry(
2364
+ `<span class="word word-reading">${entry.readings[0].reading}${entry.readings[0].audio !== void 0 ? `<br>[sound:${entry.readings[0].audio}]` : ""}</span>`,
2365
+ entry.readings[0].notes
2366
+ );
2367
+ const otherReadings = entry.readings.length > 1 ? `<details><summary>Show other readings</summary>${entry.readings.slice(1).map(
2368
+ (readingEntry) => createEntry(
2369
+ `<span class="word word-reading">${readingEntry.reading}${readingEntry.audio !== void 0 ? `<br>[sound:${readingEntry.audio}]` : ""}</span>`,
2370
+ readingEntry.notes
2371
+ )
2372
+ ).join("")}</details>` : void 0;
2373
+ const readingsField = [firstReading, ...otherReadings != null ? otherReadings : []].join(
2374
+ ""
2375
+ );
2376
+ const firstKanjiForm = entry.kanjiForms ? createEntry(
2377
+ `<span class="word word-kanjiform"><ruby><rb>${entry.kanjiForms[0].kanjiForm}</rb><rt>${entry.readings[0].reading}</rt></ruby></span>`,
2378
+ entry.kanjiForms[0].notes
2379
+ ) : void 0;
2380
+ const otherKanjiForms = entry.kanjiForms && entry.kanjiForms.length > 1 ? `<details><summary>Show other kanji forms</summary>${entry.kanjiForms.slice(1).map((kanjiFormEntry) => {
2381
+ const restrictedReading = entry.readings.find(
2382
+ (r) => r.notes && r.notes.includes(
2383
+ `Reading restricted to ${kanjiFormEntry.kanjiForm}`
2384
+ )
2385
+ );
2386
+ return `${createEntry(`<span class="word word-kanjiform">${restrictedReading ? "<ruby><rb>" : ""}${kanjiFormEntry.kanjiForm}${restrictedReading ? `</rb><rt>${restrictedReading.reading}</rt></ruby>` : ""}</span>`, kanjiFormEntry.notes)}`;
2387
+ }).join("")}</details>` : void 0;
2388
+ const kanjiFormsField = firstKanjiForm ? [firstKanjiForm, ...otherKanjiForms != null ? otherKanjiForms : []].join("") : void 0;
2389
+ const firstThreeTranslations = entry.translations.slice(0, 3).map(
2390
+ (translationEntry, index) => `${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes, void 0, entry.phrases && entry.phrases.some((phrase, index2) => index === index2 && phrase.glossNumber && phrase.glossNumber.wordId === entry.id && phrase.glossNumber.glossNumber === index + 1) ? true : void 0)}`
2391
+ ).join("");
2392
+ const otherTranslations = entry.translations.length > 3 ? `<details><summary>Show other translations</summary>${entry.translations.map(
2393
+ (translationEntry, index) => index > 2 ? `${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes, void 0, entry.phrases && entry.phrases.some((phrase, index2) => index === index2 && phrase.glossNumber && phrase.glossNumber.wordId === entry.id && phrase.glossNumber.glossNumber === index + 1) ? true : void 0)}` : "null"
2394
+ ).filter((translation) => translation !== "null").join("")}</details>` : void 0;
2395
+ const translationsField = [
2396
+ firstThreeTranslations,
2397
+ ...otherTranslations != null ? otherTranslations : []
2398
+ ].join("");
2040
2399
  fields.push(
2041
- ...entry.kanjiForms && !entry.usuallyInKana ? [
2042
- entry.kanjiForms.map(
2043
- (kanjiFormEntry, index) => `${index > 0 ? "<details><summary>Show kanji form</summary>" : ""}${createEntry(`<span class="word word-kanjiform">${index === 0 ? "<ruby><rb>" : ""}${kanjiFormEntry.kanjiForm}${index === 0 ? `</rb><rt>${entry.readings[0].reading}</rt></ruby>` : ""}</span>`, kanjiFormEntry.notes)}${index > 0 ? "</details>" : ""}`
2044
- ).join(""),
2045
- entry.readings.map(
2046
- (readingEntry, index) => `${index > 0 ? "<details><summary>Show reading</summary>" : ""}${createEntry(`<span class="word word-reading">${readingEntry.reading}${readingEntry.audio !== void 0 ? `<br>[sound:${readingEntry.audio}]` : ""}</span>`, readingEntry.notes)}${index > 0 ? "</details>" : ""}`
2047
- ).join("")
2048
- ] : [
2049
- entry.readings.map(
2050
- (readingEntry, index) => `${index > 0 ? "<details><summary>Show reading</summary>" : ""}${createEntry(`<span class="word word-reading">${readingEntry.reading}${readingEntry.audio !== void 0 ? `<br>[sound:${readingEntry.audio}]` : ""}</span>`, readingEntry.notes)}${index > 0 ? "</details>" : ""}`
2051
- ).join(""),
2052
- entry.kanjiForms ? entry.kanjiForms.map(
2053
- (kanjiFormEntry, index) => `${index > 0 ? "<details><summary>Show kanji form</summary>" : ""}${createEntry(`<span class="word word-kanjiform">${index === 0 ? "<ruby><rb>" : ""}${kanjiFormEntry.kanjiForm}${index === 0 ? `</rb><rt>${entry.readings[0].reading}</rt></ruby>` : ""}</span>`, kanjiFormEntry.notes)}${index > 0 ? "</details>" : ""}`
2054
- ).join("") : noKanjiForms
2400
+ ...entry.kanjiForms && kanjiFormsField && !entry.usuallyInKana ? [kanjiFormsField, readingsField] : [
2401
+ readingsField,
2402
+ entry.kanjiForms && kanjiFormsField ? kanjiFormsField : noKanjiForms
2055
2403
  ],
2056
- entry.translations.map(
2057
- (translationEntry, index) => `${index > 2 ? "<details><summary>Show translation</summary>" : ""}${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes, void 0, entry.phrases && entry.phrases.some((phrase, index2) => index === index2 && phrase.glossNumber && phrase.glossNumber.wordId === entry.id && phrase.glossNumber.glossNumber === index + 1) ? true : void 0)}${index > 2 ? "</details>" : ""}`
2058
- ).join(""),
2059
- entry.kanji ? entry.kanji.map(
2060
- (kanjiEntry) => createEntry(
2061
- `<span class="word word-kanji">${kanjiEntry.kanji}${kanjiEntry.meanings === void 0 ? " (no meanings)" : ""}</span>`,
2062
- kanjiEntry.meanings
2063
- )
2064
- ).join("") : '<span class="word word-kanji">(no kanji)</span>',
2404
+ translationsField,
2065
2405
  entry.phrases ? entry.phrases.map(
2066
2406
  (phraseEntry, index) => createEntry(
2067
2407
  `<span class="word word-phrase"><span class="word word-phrase-original">${phraseEntry.originalPhrase}</span><span class="word word-phrase-furigana">${phraseEntry.phrase}</span></span>`,
@@ -2072,6 +2412,20 @@ function generateAnkiNote(entry) {
2072
2412
  ) ? true : void 0
2073
2413
  )
2074
2414
  ).join("") : '<span class="word word-phrase">(no phrases) (Search on dictionaries!)</span>',
2415
+ entry.definitions ? entry.definitions.map(
2416
+ (definitionEntry) => {
2417
+ var _a;
2418
+ return createEntry(
2419
+ `<span class="word word-definition>"<span class="word word-definition-original">${definitionEntry.definition}</span><span class="word word-definition-furigana">${(_a = definitionEntry.furigana) != null ? _a : definitionEntry.definition}</span></span>`
2420
+ );
2421
+ }
2422
+ ).join("") : '<span class="word word-definition">(no definitions) (Search on ja.wiktionary.org)</span>',
2423
+ entry.kanji ? entry.kanji.map(
2424
+ (kanjiEntry) => createEntry(
2425
+ `<span class="word word-kanji">${kanjiEntry.kanji}${kanjiEntry.meanings === void 0 ? " (no meanings)" : ""}</span>`,
2426
+ kanjiEntry.meanings
2427
+ )
2428
+ ).join("") : '<span class="word word-kanji">(no kanji)</span>',
2075
2429
  ...entry.tags && entry.tags.length > 0 ? [
2076
2430
  entry.tags.map(
2077
2431
  (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
@@ -2228,13 +2582,13 @@ function generateAnkiNotesFile(list) {
2228
2582
  if (ankiNotes.length === 0) throw new Error("Invalid list");
2229
2583
  return `${headers.join("\n")}
2230
2584
  ${ankiNotes}`;
2231
- } else console.log("No entries available for Anki notes creation");
2232
- return void 0;
2585
+ } else throw new Error("No entries available for Anki notes creation");
2233
2586
  }
2234
2587
  // Annotate the CommonJS export names for ESM import in node:
2235
2588
  0 && (module.exports = {
2236
2589
  capitalizeString,
2237
2590
  convertJMdict,
2591
+ convertJawiktionary,
2238
2592
  convertKanjiDic,
2239
2593
  convertKradFile,
2240
2594
  convertRadkFile,
@@ -2244,6 +2598,7 @@ ${ankiNotes}`;
2244
2598
  getKanji,
2245
2599
  getKanjiExtended,
2246
2600
  getWord,
2601
+ getWordDefinitions,
2247
2602
  isGrammar,
2248
2603
  isKana,
2249
2604
  isKanji,