henkan 2.4.12 → 3.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 (86) hide show
  1. package/dist/index.cjs.js +431 -20
  2. package/dist/index.cjs.js.map +2 -2
  3. package/dist/index.mjs +428 -20
  4. package/dist/index.mjs.map +2 -2
  5. package/dist/types/types.d.ts +106 -15
  6. package/dist/types/types.d.ts.map +1 -1
  7. package/dist/types/utils.d.ts +28 -6
  8. package/dist/types/utils.d.ts.map +1 -1
  9. package/docs/api/README.md +8 -2
  10. package/docs/api/functions/capitalizeString.md +1 -1
  11. package/docs/api/functions/convertJMdict.md +1 -1
  12. package/docs/api/functions/convertJMnedict.md +33 -0
  13. package/docs/api/functions/convertJawiktionaryAsync.md +1 -1
  14. package/docs/api/functions/convertJawiktionarySync.md +1 -1
  15. package/docs/api/functions/convertKanjiDic.md +1 -1
  16. package/docs/api/functions/convertKradFile.md +1 -1
  17. package/docs/api/functions/convertRadkFile.md +1 -1
  18. package/docs/api/functions/convertTanakaCorpus.md +1 -1
  19. package/docs/api/functions/convertTanakaCorpusWithFurigana.md +1 -1
  20. package/docs/api/functions/createEntryMaps.md +9 -3
  21. package/docs/api/functions/generateAnkiNote.md +2 -2
  22. package/docs/api/functions/generateAnkiNotesFile.md +1 -1
  23. package/docs/api/functions/generateFurigana.md +1 -1
  24. package/docs/api/functions/getKanji.md +1 -1
  25. package/docs/api/functions/getKanjiExtended.md +1 -1
  26. package/docs/api/functions/getName.md +57 -0
  27. package/docs/api/functions/getValidForms.md +1 -1
  28. package/docs/api/functions/getWord.md +3 -3
  29. package/docs/api/functions/getWordDefinitions.md +1 -1
  30. package/docs/api/functions/getWordDefinitionsWithFurigana.md +1 -1
  31. package/docs/api/functions/hiraganaToKatakana.md +1 -1
  32. package/docs/api/functions/isObjectArray.md +1 -1
  33. package/docs/api/functions/isStringArray.md +1 -1
  34. package/docs/api/functions/isValidArrayWithFirstElement.md +1 -1
  35. package/docs/api/functions/katakanaToHiragana.md +1 -1
  36. package/docs/api/functions/shuffleArray.md +1 -1
  37. package/docs/api/interfaces/DefaultNoteInfo.md +10 -10
  38. package/docs/api/interfaces/Definition.md +4 -4
  39. package/docs/api/interfaces/DictKanji.md +5 -5
  40. package/docs/api/interfaces/DictKanjiForm.md +2 -2
  41. package/docs/api/interfaces/DictKanjiMisc.md +5 -5
  42. package/docs/api/interfaces/DictKanjiReading.md +3 -3
  43. package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
  44. package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
  45. package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
  46. package/docs/api/interfaces/DictName.md +75 -0
  47. package/docs/api/interfaces/DictRadical.md +4 -4
  48. package/docs/api/interfaces/DictReading.md +2 -2
  49. package/docs/api/interfaces/EntryMaps.md +33 -9
  50. package/docs/api/interfaces/ExamplePart.md +7 -7
  51. package/docs/api/interfaces/GlossSpecificNumber.md +3 -3
  52. package/docs/api/interfaces/Grammar.md +15 -15
  53. package/docs/api/interfaces/GrammarMeaning.md +3 -3
  54. package/docs/api/interfaces/JaWiktionaryEntry.md +5 -5
  55. package/docs/api/interfaces/Kana.md +11 -11
  56. package/docs/api/interfaces/Kanji.md +23 -23
  57. package/docs/api/interfaces/KanjiComponent.md +3 -3
  58. package/docs/api/interfaces/KanjiForm.md +5 -5
  59. package/docs/api/interfaces/Name.md +163 -0
  60. package/docs/api/interfaces/NeDictMeaning.md +33 -0
  61. package/docs/api/interfaces/NoteAndTag.md +3 -3
  62. package/docs/api/interfaces/NoteHeaderKeys.md +7 -7
  63. package/docs/api/interfaces/Phrase.md +5 -5
  64. package/docs/api/interfaces/Radical.md +16 -16
  65. package/docs/api/interfaces/Reading.md +6 -6
  66. package/docs/api/interfaces/ResultEntry.md +8 -7
  67. package/docs/api/interfaces/TanakaExample.md +7 -7
  68. package/docs/api/interfaces/Translation.md +5 -5
  69. package/docs/api/interfaces/UsefulRegExps.md +8 -8
  70. package/docs/api/interfaces/Word.md +15 -15
  71. package/docs/api/interfaces/WordDefinitionPair.md +4 -4
  72. package/docs/api/type-aliases/Dict.md +1 -1
  73. package/docs/api/type-aliases/{DictName.md → DictNames.md} +3 -3
  74. package/docs/api/type-aliases/EntryExamplesMap.md +13 -0
  75. package/docs/api/type-aliases/EntryType.md +2 -2
  76. package/docs/api/type-aliases/KanjiEntryMap.md +1 -1
  77. package/docs/api/type-aliases/KanjiSVGMap.md +1 -1
  78. package/docs/api/type-aliases/KanjiWordsMap.md +1 -1
  79. package/docs/api/type-aliases/NameIDEntryMap.md +13 -0
  80. package/docs/api/type-aliases/Result.md +2 -2
  81. package/docs/api/type-aliases/WordDefinitionsMap.md +1 -1
  82. package/docs/api/type-aliases/WordIDEntryMap.md +1 -1
  83. package/package.json +8 -7
  84. package/src/types.ts +115 -15
  85. package/src/utils.ts +735 -80
  86. package/docs/api/type-aliases/WordExamplesMap.md +0 -13
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
+ convertJMnedict: () => convertJMnedict,
35
36
  convertJawiktionaryAsync: () => convertJawiktionaryAsync,
36
37
  convertJawiktionarySync: () => convertJawiktionarySync,
37
38
  convertKanjiDic: () => convertKanjiDic,
@@ -45,6 +46,7 @@ __export(index_exports, {
45
46
  generateFurigana: () => generateFurigana,
46
47
  getKanji: () => getKanji,
47
48
  getKanjiExtended: () => getKanjiExtended,
49
+ getName: () => getName,
48
50
  getValidForms: () => getValidForms,
49
51
  getWord: () => getWord,
50
52
  getWordDefinitions: () => getWordDefinitions,
@@ -53,6 +55,7 @@ __export(index_exports, {
53
55
  isGrammar: () => isGrammar,
54
56
  isKana: () => isKana,
55
57
  isKanji: () => isKanji,
58
+ isName: () => isName,
56
59
  isObjectArray: () => isObjectArray,
57
60
  isRadical: () => isRadical,
58
61
  isStringArray: () => isStringArray,
@@ -1539,6 +1542,90 @@ function convertJMdict(xmlString, examples) {
1539
1542
  });
1540
1543
  return dict;
1541
1544
  }
1545
+ function convertJMnedict(xmlString, examples) {
1546
+ const dictParsed = import_libxmljs2.default.parseXml(xmlString, {
1547
+ dtdvalid: true,
1548
+ nonet: false,
1549
+ noent: true,
1550
+ recover: false
1551
+ });
1552
+ const dict = [];
1553
+ import_xml2js.default.parseString(dictParsed, (_err, result) => {
1554
+ const tanakaParts = examples !== void 0 && examples.length > 0 ? new Set(
1555
+ examples.flatMap(
1556
+ (example) => example.parts.flatMap((part) => [
1557
+ part.baseForm,
1558
+ ...part.reading !== void 0 ? [part.reading] : [],
1559
+ ...part.inflectedForm !== void 0 ? [part.inflectedForm] : [],
1560
+ ...part.referenceID !== void 0 ? [part.referenceID] : []
1561
+ ])
1562
+ )
1563
+ ) : void 0;
1564
+ for (const entry of result.JMnedict.entry) {
1565
+ const entryObj = {
1566
+ id: entry.ent_seq[0],
1567
+ nameReadings: [],
1568
+ meanings: []
1569
+ };
1570
+ const kanjiForms = entry.k_ele;
1571
+ const readings = entry.r_ele;
1572
+ const translations = entry.trans;
1573
+ if (isObjectArray(kanjiForms)) {
1574
+ entryObj.kanjiForms = [];
1575
+ for (const kanjiForm of kanjiForms)
1576
+ entryObj.kanjiForms.push({ form: kanjiForm.keb[0] });
1577
+ }
1578
+ for (const reading of readings) {
1579
+ const readingObj = {
1580
+ reading: reading.reb[0]
1581
+ };
1582
+ if (isStringArray(reading.re_restr))
1583
+ readingObj.kanjiFormRestrictions = reading.re_restr;
1584
+ if (isStringArray(reading.re_pri)) {
1585
+ readingObj.commonness = reading.re_pri;
1586
+ entryObj.isCommon = true;
1587
+ }
1588
+ entryObj.nameReadings.push(readingObj);
1589
+ }
1590
+ for (const trans of translations)
1591
+ entryObj.meanings.push({
1592
+ translations: trans.trans_det,
1593
+ ...isStringArray(trans.name_type) ? { nameTypes: trans.name_type } : {}
1594
+ });
1595
+ if (examples !== void 0) {
1596
+ let existsExample = false;
1597
+ const rkf = getValidForms(
1598
+ entryObj.nameReadings,
1599
+ entryObj.kanjiForms,
1600
+ entryObj.isCommon
1601
+ );
1602
+ const validReadings = new Set(
1603
+ rkf.readings.map((r) => r.reading)
1604
+ );
1605
+ const validKanjiForms = rkf.kanjiForms !== void 0 ? new Set(
1606
+ rkf.kanjiForms.map((kf) => kf.form)
1607
+ ) : void 0;
1608
+ if (validKanjiForms !== void 0 && validKanjiForms.size > 0 && tanakaParts !== void 0) {
1609
+ for (const kf of validKanjiForms)
1610
+ if (tanakaParts.has(kf)) {
1611
+ existsExample = true;
1612
+ break;
1613
+ }
1614
+ }
1615
+ if (entryObj.kanjiForms === void 0 && validReadings.size > 0 && tanakaParts !== void 0) {
1616
+ for (const r of validReadings)
1617
+ if (tanakaParts.has(r)) {
1618
+ existsExample = true;
1619
+ break;
1620
+ }
1621
+ }
1622
+ if (existsExample) entryObj.hasPhrases = true;
1623
+ }
1624
+ dict.push(entryObj);
1625
+ }
1626
+ });
1627
+ return dict;
1628
+ }
1542
1629
  function convertKanjiDic(xmlString) {
1543
1630
  const dictParsed = import_libxmljs2.default.parseXml(xmlString, {
1544
1631
  dtdvalid: true,
@@ -1741,16 +1828,15 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
1741
1828
  }
1742
1829
  return kanjiWithRadicals;
1743
1830
  }
1744
- function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs, svgList) {
1831
+ function createEntryMaps(jmDict, jmNedict, kanjiDic, tanakaExamples, wordDefinitionPairs, svgList) {
1745
1832
  const kanjiEntryMap = /* @__PURE__ */ new Map();
1746
1833
  const wordIDEntryMap = /* @__PURE__ */ new Map();
1834
+ const nameIDEntryMap = /* @__PURE__ */ new Map();
1747
1835
  const kanjiWordsMap = /* @__PURE__ */ new Map();
1748
1836
  const wordExamplesMap = /* @__PURE__ */ new Map();
1837
+ const nameExamplesMap = /* @__PURE__ */ new Map();
1749
1838
  const wordDefinitionsMap = /* @__PURE__ */ new Map();
1750
1839
  const kanjiSVGMap = /* @__PURE__ */ new Map();
1751
- const wordPartsMap = /* @__PURE__ */ new Map();
1752
- const partExamplesMap = /* @__PURE__ */ new Map();
1753
- const entryParts = /* @__PURE__ */ new Set();
1754
1840
  if (kanjiDic !== void 0)
1755
1841
  for (const kanji of kanjiDic) kanjiEntryMap.set(kanji.kanji, kanji);
1756
1842
  if (wordDefinitionPairs !== void 0)
@@ -1766,6 +1852,9 @@ function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs,
1766
1852
  if (svg !== void 0) kanjiSVGMap.set(kanji.kanji, svg);
1767
1853
  }
1768
1854
  if (jmDict !== void 0) {
1855
+ const wordPartsMap = /* @__PURE__ */ new Map();
1856
+ const partExamplesMap = /* @__PURE__ */ new Map();
1857
+ const entryParts = /* @__PURE__ */ new Set();
1769
1858
  for (const word of jmDict) {
1770
1859
  wordIDEntryMap.set(word.id, word);
1771
1860
  if (word.kanjiForms !== void 0)
@@ -1844,11 +1933,82 @@ function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs,
1844
1933
  }
1845
1934
  }
1846
1935
  }
1936
+ if (jmNedict !== void 0) {
1937
+ const namePartsMap = /* @__PURE__ */ new Map();
1938
+ const partExamplesMap = /* @__PURE__ */ new Map();
1939
+ const entryParts = /* @__PURE__ */ new Set();
1940
+ for (const name of jmNedict) {
1941
+ nameIDEntryMap.set(name.id, name);
1942
+ if (tanakaExamples !== void 0) {
1943
+ const rkf = getValidForms(
1944
+ name.nameReadings,
1945
+ name.kanjiForms,
1946
+ name.isCommon
1947
+ );
1948
+ const localPartParts = /* @__PURE__ */ new Set();
1949
+ for (const reading of rkf.readings) {
1950
+ entryParts.add(reading.reading);
1951
+ localPartParts.add(reading.reading);
1952
+ }
1953
+ if (rkf.kanjiForms !== void 0 && rkf.kanjiForms.length > 0)
1954
+ for (const kanjiForm of rkf.kanjiForms) {
1955
+ entryParts.add(kanjiForm.form);
1956
+ localPartParts.add(kanjiForm.form);
1957
+ }
1958
+ entryParts.add(name.id);
1959
+ localPartParts.add(name.id);
1960
+ namePartsMap.set(name.id, localPartParts);
1961
+ }
1962
+ }
1963
+ if (tanakaExamples !== void 0) {
1964
+ for (const ex of tanakaExamples)
1965
+ for (const part of ex.parts) {
1966
+ if (entryParts.has(part.baseForm)) {
1967
+ const exList = partExamplesMap.get(
1968
+ part.baseForm
1969
+ );
1970
+ if (exList === void 0) partExamplesMap.set(part.baseForm, [ex]);
1971
+ else exList.push(ex);
1972
+ }
1973
+ if (part.reading !== void 0 && entryParts.has(part.reading)) {
1974
+ const exList = partExamplesMap.get(
1975
+ part.reading
1976
+ );
1977
+ if (exList === void 0) partExamplesMap.set(part.reading, [ex]);
1978
+ else exList.push(ex);
1979
+ }
1980
+ if (part.inflectedForm !== void 0 && entryParts.has(part.inflectedForm)) {
1981
+ const exList = partExamplesMap.get(
1982
+ part.inflectedForm
1983
+ );
1984
+ if (exList === void 0)
1985
+ partExamplesMap.set(part.inflectedForm, [ex]);
1986
+ else exList.push(ex);
1987
+ }
1988
+ }
1989
+ for (const name of jmNedict) {
1990
+ const seenEx = /* @__PURE__ */ new Set();
1991
+ const validExamples = [];
1992
+ for (const p of namePartsMap.get(name.id)) {
1993
+ const examplesForPart = partExamplesMap.get(p)?.filter((ex) => !seenEx.has(ex.id));
1994
+ if (examplesForPart === void 0) continue;
1995
+ for (const ex of examplesForPart) {
1996
+ seenEx.add(ex.id);
1997
+ validExamples.push(ex);
1998
+ }
1999
+ }
2000
+ if (validExamples.length > 0)
2001
+ nameExamplesMap.set(name.id, validExamples);
2002
+ }
2003
+ }
2004
+ }
1847
2005
  return {
1848
2006
  ...wordIDEntryMap.size > 0 ? { wordIDEntryMap } : {},
2007
+ ...nameIDEntryMap.size > 0 ? { nameIDEntryMap } : {},
1849
2008
  ...kanjiWordsMap.size > 0 ? { kanjiWordsMap } : {},
1850
2009
  ...kanjiEntryMap.size > 0 ? { kanjiEntryMap } : {},
1851
2010
  ...wordExamplesMap.size > 0 ? { wordExamplesMap } : {},
2011
+ ...nameExamplesMap.size > 0 ? { nameExamplesMap } : {},
1852
2012
  ...wordDefinitionsMap.size > 0 ? { wordDefinitionsMap } : {},
1853
2013
  ...kanjiSVGMap.size > 0 ? { kanjiSVGMap } : {}
1854
2014
  };
@@ -2625,10 +2785,9 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2625
2785
  rkf.readings.map((r) => r.reading)
2626
2786
  );
2627
2787
  const kanjiForms = rkf.kanjiForms !== void 0 ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
2628
- let readingMatchingKanjiFormExamples = [];
2788
+ const readingMatchingKanjiFormExamples = [];
2629
2789
  let kanjiFormExamples = [];
2630
2790
  let readingExamples = [];
2631
- let hasReadingMatchingKanjiFormWithTranslation = false;
2632
2791
  for (const example of exampleList)
2633
2792
  for (let i = 0; i < example.parts.length; i++) {
2634
2793
  if (seenPhrases.has(example.phrase)) break;
@@ -2640,7 +2799,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2640
2799
  const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
2641
2800
  const referenceIDMatch = part.referenceID === dictWord.id;
2642
2801
  if (kanjiForms !== void 0 && kanjiForms.has(part.baseForm)) {
2643
- if (readingAsReadingMatch || readingAsInflectedFormMatch || referenceIDMatch) {
2802
+ if (readingAsReadingMatch || readingAsInflectedFormMatch || referenceIDMatch)
2644
2803
  readingMatchingKanjiFormExamples.push({
2645
2804
  ex: example,
2646
2805
  partIndex: i,
@@ -2648,9 +2807,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2648
2807
  ...referenceIDMatch ? { referenceIDMatch: true } : {},
2649
2808
  ...includesTranslation ? { includesTranslation: true } : {}
2650
2809
  });
2651
- if (!hasReadingMatchingKanjiFormWithTranslation && includesTranslation)
2652
- hasReadingMatchingKanjiFormWithTranslation = true;
2653
- } else
2810
+ else
2654
2811
  kanjiFormExamples.push({
2655
2812
  ex: example,
2656
2813
  partIndex: i,
@@ -2672,23 +2829,18 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2672
2829
  break;
2673
2830
  }
2674
2831
  }
2675
- if (readingMatchingKanjiFormExamples.length > 0) {
2676
- if (hasReadingMatchingKanjiFormWithTranslation)
2677
- readingMatchingKanjiFormExamples = readingMatchingKanjiFormExamples.filter(
2678
- (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true || ex.ex.parts.some(
2679
- (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2680
- )
2681
- );
2682
- kanjiFormExamples.length = 0;
2683
- }
2684
2832
  if (kanjiFormExamples.length > 0 && kanjiFormExamples.some(
2685
- (ex) => ex.includesTranslation === true
2833
+ (ex) => ex.includesTranslation === true || ex.ex.parts.some(
2834
+ (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2835
+ )
2686
2836
  ))
2687
2837
  kanjiFormExamples = kanjiFormExamples.filter(
2688
2838
  (ex) => ex.includesTranslation === true || ex.ex.parts.some(
2689
2839
  (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2690
2840
  )
2691
2841
  );
2842
+ else if (kanjiFormExamples.length > 0 && readingMatchingKanjiFormExamples.length > 0)
2843
+ kanjiFormExamples.length = 0;
2692
2844
  if (readingExamples.length > 0 && readingExamples.some(
2693
2845
  (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true
2694
2846
  ))
@@ -2757,9 +2909,179 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2757
2909
  return word;
2758
2910
  } else return void 0;
2759
2911
  }
2912
+ function getName(searchedName, dict, kanjiDic, examples, noteTypeName, deckPath) {
2913
+ let dictName = void 0;
2914
+ if (typeof searchedName === "string" && dict !== void 0) {
2915
+ if (Array.isArray(dict))
2916
+ dictName = dict.find(
2917
+ (entry) => entry.id === searchedName
2918
+ );
2919
+ if (dict instanceof Map) dictName = dict.get(searchedName);
2920
+ }
2921
+ if (typeof searchedName === "object") dictName = searchedName;
2922
+ if (dictName !== void 0) {
2923
+ const name = {
2924
+ id: dictName.id,
2925
+ nameReadings: [],
2926
+ translations: [],
2927
+ noteID: `name_${dictName.id}`,
2928
+ noteTypeName,
2929
+ deckPath,
2930
+ tags: []
2931
+ };
2932
+ if (dictName.isCommon === true) {
2933
+ name.common = true;
2934
+ name.tags.push("name::common");
2935
+ }
2936
+ if (dictName.kanjiForms !== void 0)
2937
+ name.kanjiForms = dictName.kanjiForms.map(
2938
+ (dictKanjiForm) => ({
2939
+ kanjiForm: dictKanjiForm.form
2940
+ })
2941
+ );
2942
+ name.nameReadings = dictName.nameReadings.map(
2943
+ (dictReading) => ({
2944
+ reading: dictReading.reading,
2945
+ ...dictReading.kanjiFormRestrictions !== void 0 ? {
2946
+ notes: dictReading.kanjiFormRestrictions.map(
2947
+ (restriction) => `Reading restricted to ${restriction}`
2948
+ )
2949
+ } : {},
2950
+ ...dictReading.commonness !== void 0 && dictReading.commonness.length > 0 ? { common: true } : {}
2951
+ })
2952
+ );
2953
+ name.translations = [];
2954
+ const meanings = dictName.hasPhrases === true && examples !== void 0 ? [] : void 0;
2955
+ const seenPhrases = /* @__PURE__ */ new Set();
2956
+ let hasNameTypes = false;
2957
+ for (const dictMeaning of dictName.meanings) {
2958
+ if (!hasNameTypes && dictMeaning.nameTypes !== void 0)
2959
+ hasNameTypes = true;
2960
+ name.translations.push({
2961
+ translation: dictMeaning.translations.map((translation) => {
2962
+ if (meanings !== void 0) {
2963
+ const cleanTranslation = translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2964
+ if (!seenPhrases.has(cleanTranslation)) {
2965
+ seenPhrases.add(cleanTranslation);
2966
+ meanings.push(cleanTranslation);
2967
+ }
2968
+ }
2969
+ return translation;
2970
+ }).join("; "),
2971
+ ...dictMeaning.nameTypes !== void 0 ? {
2972
+ notes: dictMeaning.nameTypes.map((type) => {
2973
+ const noteAndTag = lookupWordNote(
2974
+ type,
2975
+ [],
2976
+ name.tags
2977
+ );
2978
+ return capitalizeString(noteAndTag.note);
2979
+ })
2980
+ } : {}
2981
+ });
2982
+ }
2983
+ if (!hasNameTypes) name.tags.push("name::no_name_types");
2984
+ seenPhrases.clear();
2985
+ if (kanjiDic !== void 0 && name.kanjiForms !== void 0) {
2986
+ const kanji = [];
2987
+ const seenChars = /* @__PURE__ */ new Set();
2988
+ for (const kanjiForm of name.kanjiForms)
2989
+ for (const char of kanjiForm.kanjiForm.split("").filter((c) => regexps.kanji.test(c))) {
2990
+ if (seenChars.has(char)) continue;
2991
+ seenChars.add(char);
2992
+ const kanjiEntry = kanjiDic instanceof Map ? kanjiDic.get(char) : void 0;
2993
+ const kanjiObj = getKanji(
2994
+ kanjiEntry ?? char,
2995
+ !(kanjiDic instanceof Map) ? kanjiDic : void 0
2996
+ );
2997
+ if (kanjiObj !== void 0)
2998
+ kanji.push({
2999
+ kanji: kanjiObj.kanji,
3000
+ ...kanjiObj.meanings !== void 0 && kanjiObj.meanings.length > 0 ? { meanings: kanjiObj.meanings } : {}
3001
+ });
3002
+ }
3003
+ if (kanji.length > 0) name.kanji = kanji;
3004
+ }
3005
+ if (meanings !== void 0) {
3006
+ const exampleList = examples instanceof Map ? examples.get(dictName.id) ?? [] : examples;
3007
+ const rkf = getValidForms(
3008
+ dictName.nameReadings,
3009
+ dictName.kanjiForms,
3010
+ dictName.isCommon
3011
+ );
3012
+ const readings = new Set(
3013
+ rkf.readings.map((r) => r.reading)
3014
+ );
3015
+ const kanjiForms = rkf.kanjiForms !== void 0 ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
3016
+ let readingMatchingKanjiFormExamples = [];
3017
+ let readingExamples = [];
3018
+ let hasReadingMatchingKanjiFormWithTranslation = false;
3019
+ let hasReadingWithTranslation = false;
3020
+ for (const example of exampleList)
3021
+ for (let i = 0; i < example.parts.length; i++) {
3022
+ if (seenPhrases.has(example.phrase)) break;
3023
+ const includesTranslation = meanings.some(
3024
+ (m) => example.translation.includes(m)
3025
+ );
3026
+ const part = example.parts[i];
3027
+ const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
3028
+ if (kanjiForms !== void 0 && kanjiForms.has(part.baseForm) && readingAsReadingMatch) {
3029
+ readingMatchingKanjiFormExamples.push({
3030
+ ex: example,
3031
+ ...includesTranslation ? { includesTranslation: true } : {}
3032
+ });
3033
+ if (!hasReadingMatchingKanjiFormWithTranslation && includesTranslation)
3034
+ hasReadingMatchingKanjiFormWithTranslation = true;
3035
+ seenPhrases.add(example.phrase);
3036
+ break;
3037
+ }
3038
+ const readingAsBaseFormMatch = readings.has(part.baseForm);
3039
+ if (readingAsBaseFormMatch && kanjiForms === void 0) {
3040
+ readingExamples.push({
3041
+ ex: example,
3042
+ ...includesTranslation ? { includesTranslation: true } : {}
3043
+ });
3044
+ if (!hasReadingWithTranslation && includesTranslation)
3045
+ hasReadingWithTranslation = true;
3046
+ seenPhrases.add(example.phrase);
3047
+ break;
3048
+ }
3049
+ }
3050
+ if (readingMatchingKanjiFormExamples.length > 0) {
3051
+ if (hasReadingMatchingKanjiFormWithTranslation)
3052
+ readingMatchingKanjiFormExamples = readingMatchingKanjiFormExamples.filter(
3053
+ (ex) => ex.includesTranslation === true
3054
+ );
3055
+ }
3056
+ if (readingExamples.length > 0 && hasReadingWithTranslation)
3057
+ readingExamples = readingExamples.filter(
3058
+ (ex) => ex.includesTranslation === true
3059
+ );
3060
+ const wordExamples = [
3061
+ ...name.kanjiForms !== void 0 ? readingMatchingKanjiFormExamples : readingExamples
3062
+ ];
3063
+ if (wordExamples.length > 0) {
3064
+ name.phrases = wordExamples.slice(0, 5).map(
3065
+ (ex) => ({
3066
+ phrase: ex.ex.furigana ?? ex.ex.phrase,
3067
+ translation: ex.ex.translation,
3068
+ originalPhrase: ex.ex.phrase
3069
+ })
3070
+ );
3071
+ name.tags.push("name::has_phrases");
3072
+ }
3073
+ }
3074
+ return name;
3075
+ } else return void 0;
3076
+ }
2760
3077
  function isWord(entry) {
2761
3078
  return isObjectArray(Object.getOwnPropertyDescriptor(entry, "readings")?.value) && isObjectArray(Object.getOwnPropertyDescriptor(entry, "translations")?.value);
2762
3079
  }
3080
+ function isName(entry) {
3081
+ return isObjectArray(
3082
+ Object.getOwnPropertyDescriptor(entry, "nameReadings")?.value
3083
+ ) && isObjectArray(Object.getOwnPropertyDescriptor(entry, "translations")?.value);
3084
+ }
2763
3085
  function isRadical(entry) {
2764
3086
  return typeof Object.getOwnPropertyDescriptor(entry, "radical")?.value === "string";
2765
3087
  }
@@ -2897,6 +3219,92 @@ function generateAnkiNote(entry, customData, additionalTags) {
2897
3219
  searchField
2898
3220
  );
2899
3221
  }
3222
+ if (isName(entry)) {
3223
+ const firstReading = createEntry(
3224
+ `<span class="name name-reading">${entry.nameReadings[0].reading}${entry.nameReadings[0].audio !== void 0 ? `<br>[sound:${entry.nameReadings[0].audio}]` : ""}</span>`,
3225
+ entry.nameReadings[0].notes
3226
+ );
3227
+ const otherReadings = entry.nameReadings.length > 1 ? `<details><summary>Show other readings</summary>${entry.nameReadings.slice(1).map(
3228
+ (readingEntry) => createEntry(
3229
+ `<span class="name name-reading">${readingEntry.reading}${readingEntry.audio !== void 0 ? `<br>[sound:${readingEntry.audio}]` : ""}</span>`,
3230
+ readingEntry.notes
3231
+ )
3232
+ ).join("")}</details>` : "";
3233
+ const readingsField = `${firstReading}${otherReadings}`;
3234
+ let readingsFieldWithoutAudio = '<div id="no-r-audio" style="display: none"></div>';
3235
+ let hasAudio = false;
3236
+ if (entry.nameReadings.some((r) => r.audio !== void 0)) {
3237
+ const firstReadingWithoutAudio = createEntry(
3238
+ `<span class="name name-reading">${entry.nameReadings[0].reading}</span>`,
3239
+ entry.nameReadings[0].notes
3240
+ );
3241
+ const otherReadingsWithoutAudio = entry.nameReadings.length > 1 ? `<details><summary>Show other readings</summary>${entry.nameReadings.slice(1).map(
3242
+ (readingEntry) => createEntry(
3243
+ `<span class="name name-reading">${readingEntry.reading}</span>`,
3244
+ readingEntry.notes
3245
+ )
3246
+ ).join("")}</details>` : "";
3247
+ readingsFieldWithoutAudio = `${firstReadingWithoutAudio}${otherReadingsWithoutAudio}`;
3248
+ hasAudio = true;
3249
+ }
3250
+ const firstKanjiForm = entry.kanjiForms !== void 0 ? createEntry(
3251
+ `<span class="name name-kanjiform"><ruby><rb>${entry.kanjiForms[0].kanjiForm}</rb><rt>${entry.nameReadings[0].reading}</rt></ruby></span>`,
3252
+ entry.kanjiForms[0].notes
3253
+ ) : void 0;
3254
+ const otherKanjiForms = entry.kanjiForms !== void 0 && entry.kanjiForms.length > 1 ? `<details><summary>Show other kanji forms</summary>${entry.kanjiForms.slice(1).map((kanjiFormEntry) => {
3255
+ const restrictedReading = entry.nameReadings.find(
3256
+ (r) => r.notes !== void 0 && r.notes.includes(
3257
+ `Reading restricted to ${kanjiFormEntry.kanjiForm}`
3258
+ )
3259
+ );
3260
+ return createEntry(
3261
+ `<span class="name name-kanjiform">${restrictedReading !== void 0 ? "<ruby><rb>" : ""}${kanjiFormEntry.kanjiForm}${restrictedReading !== void 0 ? `</rb><rt>${restrictedReading.reading}</rt></ruby>` : ""}</span>`,
3262
+ kanjiFormEntry.notes
3263
+ );
3264
+ }).join("")}</details>` : "";
3265
+ const kanjiFormsField = firstKanjiForm !== void 0 ? `${firstKanjiForm}${otherKanjiForms}` : '<span class="name name-kanjiform" id="no-kanjiforms">(no kanji forms)</span>';
3266
+ const firstThreeTranslations = entry.translations.slice(0, 3).map(
3267
+ (translationEntry) => createEntry(
3268
+ `<span class="name name-translation">${translationEntry.translation}</span>`,
3269
+ translationEntry.notes
3270
+ )
3271
+ ).join("");
3272
+ const otherTranslations = entry.translations.length > 3 ? `<details><summary>Show other translations</summary>${entry.translations.map((translationEntry, index) => {
3273
+ if (index < 3) return "null";
3274
+ return createEntry(
3275
+ `<span class="name name-translation">${translationEntry.translation}</span>`,
3276
+ translationEntry.notes
3277
+ );
3278
+ }).filter((translation) => translation !== "null").join("")}</details>` : "";
3279
+ const translationsField = `${firstThreeTranslations}${otherTranslations}`;
3280
+ const phrasesField = entry.phrases !== void 0 ? entry.phrases.map(
3281
+ (phraseEntry) => createEntry(
3282
+ `<span class="name name-phrase"><span class="name name-phrase-original">${phraseEntry.originalPhrase}</span><span class="name name-phrase-furigana">${phraseEntry.phrase}</span></span>`,
3283
+ [phraseEntry.translation],
3284
+ true
3285
+ )
3286
+ ).join("") : '<span class="name name-phrase" id="no-phrases">(no phrases)</span>';
3287
+ const searchField = `${entry.nameReadings.map((r) => r.reading).join(" ")}${entry.kanjiForms !== void 0 ? ` ${entry.kanjiForms.map((kf) => kf.kanjiForm).join(" ")}` : ""} ${entry.id}`;
3288
+ fields.push(
3289
+ ...entry.kanjiForms !== void 0 ? [
3290
+ `${customData !== void 0 ? `<div id="custom-data" style="display: none" data-custom="${customData}"></div>` : ""}${kanjiFormsField}<div id="kf-pos" style="display: none" data-pos="1"></div>`,
3291
+ `${hasAudio ? readingsFieldWithoutAudio : readingsField}<div id="r-pos" style="display: none" data-pos="2"></div>`
3292
+ ] : [
3293
+ `${customData !== void 0 ? `<div id="custom-data" style="display: none" data-custom="${customData}"></div>` : ""}${kanjiFormsField}<div id="kf-pos" style="display: none" data-pos="2"></div>`,
3294
+ `${hasAudio ? readingsFieldWithoutAudio : readingsField}<div id="r-pos" style="display: none" data-pos="1"></div>`
3295
+ ],
3296
+ `${hasAudio ? readingsField : readingsFieldWithoutAudio}<div id="r-pos" style="display: none" data-pos="${entry.kanjiForms !== void 0 ? "2" : "1"}"></div>`,
3297
+ translationsField,
3298
+ phrasesField,
3299
+ entry.kanji !== void 0 ? entry.kanji.map(
3300
+ (kanjiEntry) => createEntry(
3301
+ `<span class="name name-kanji">${kanjiEntry.kanji}${kanjiEntry.meanings === void 0 ? " (no meanings)" : ""}</span>`,
3302
+ kanjiEntry.meanings
3303
+ )
3304
+ ).join("") : '<span class="name name-kanji" id="no-kanji">(no kanji)</span>',
3305
+ searchField
3306
+ );
3307
+ }
2900
3308
  if (isRadical(entry))
2901
3309
  fields.push(
2902
3310
  `${customData !== void 0 ? `<div id="custom-data" style="display: none" data-custom="${customData}"></div>` : ""}${createEntry(
@@ -3075,6 +3483,7 @@ ${ankiNotes}`;
3075
3483
  0 && (module.exports = {
3076
3484
  capitalizeString,
3077
3485
  convertJMdict,
3486
+ convertJMnedict,
3078
3487
  convertJawiktionaryAsync,
3079
3488
  convertJawiktionarySync,
3080
3489
  convertKanjiDic,
@@ -3088,6 +3497,7 @@ ${ankiNotes}`;
3088
3497
  generateFurigana,
3089
3498
  getKanji,
3090
3499
  getKanjiExtended,
3500
+ getName,
3091
3501
  getValidForms,
3092
3502
  getWord,
3093
3503
  getWordDefinitions,
@@ -3096,6 +3506,7 @@ ${ankiNotes}`;
3096
3506
  isGrammar,
3097
3507
  isKana,
3098
3508
  isKanji,
3509
+ isName,
3099
3510
  isObjectArray,
3100
3511
  isRadical,
3101
3512
  isStringArray,