henkan 2.4.12 → 3.0.1

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 (87) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs.js +439 -46
  3. package/dist/index.cjs.js.map +2 -2
  4. package/dist/index.mjs +436 -46
  5. package/dist/index.mjs.map +2 -2
  6. package/dist/types/types.d.ts +106 -15
  7. package/dist/types/types.d.ts.map +1 -1
  8. package/dist/types/utils.d.ts +28 -6
  9. package/dist/types/utils.d.ts.map +1 -1
  10. package/docs/api/README.md +8 -2
  11. package/docs/api/functions/capitalizeString.md +1 -1
  12. package/docs/api/functions/convertJMdict.md +1 -1
  13. package/docs/api/functions/convertJMnedict.md +33 -0
  14. package/docs/api/functions/convertJawiktionaryAsync.md +1 -1
  15. package/docs/api/functions/convertJawiktionarySync.md +1 -1
  16. package/docs/api/functions/convertKanjiDic.md +1 -1
  17. package/docs/api/functions/convertKradFile.md +1 -1
  18. package/docs/api/functions/convertRadkFile.md +1 -1
  19. package/docs/api/functions/convertTanakaCorpus.md +1 -1
  20. package/docs/api/functions/convertTanakaCorpusWithFurigana.md +1 -1
  21. package/docs/api/functions/createEntryMaps.md +9 -3
  22. package/docs/api/functions/generateAnkiNote.md +2 -2
  23. package/docs/api/functions/generateAnkiNotesFile.md +1 -1
  24. package/docs/api/functions/generateFurigana.md +1 -1
  25. package/docs/api/functions/getKanji.md +1 -1
  26. package/docs/api/functions/getKanjiExtended.md +1 -1
  27. package/docs/api/functions/getName.md +57 -0
  28. package/docs/api/functions/getValidForms.md +1 -1
  29. package/docs/api/functions/getWord.md +3 -3
  30. package/docs/api/functions/getWordDefinitions.md +1 -1
  31. package/docs/api/functions/getWordDefinitionsWithFurigana.md +1 -1
  32. package/docs/api/functions/hiraganaToKatakana.md +1 -1
  33. package/docs/api/functions/isObjectArray.md +1 -1
  34. package/docs/api/functions/isStringArray.md +1 -1
  35. package/docs/api/functions/isValidArrayWithFirstElement.md +1 -1
  36. package/docs/api/functions/katakanaToHiragana.md +1 -1
  37. package/docs/api/functions/shuffleArray.md +1 -1
  38. package/docs/api/interfaces/DefaultNoteInfo.md +10 -10
  39. package/docs/api/interfaces/Definition.md +4 -4
  40. package/docs/api/interfaces/DictKanji.md +5 -5
  41. package/docs/api/interfaces/DictKanjiForm.md +2 -2
  42. package/docs/api/interfaces/DictKanjiMisc.md +5 -5
  43. package/docs/api/interfaces/DictKanjiReading.md +3 -3
  44. package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
  45. package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
  46. package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
  47. package/docs/api/interfaces/DictName.md +75 -0
  48. package/docs/api/interfaces/DictRadical.md +4 -4
  49. package/docs/api/interfaces/DictReading.md +2 -2
  50. package/docs/api/interfaces/EntryMaps.md +33 -9
  51. package/docs/api/interfaces/ExamplePart.md +7 -7
  52. package/docs/api/interfaces/GlossSpecificNumber.md +3 -3
  53. package/docs/api/interfaces/Grammar.md +15 -15
  54. package/docs/api/interfaces/GrammarMeaning.md +3 -3
  55. package/docs/api/interfaces/JaWiktionaryEntry.md +5 -5
  56. package/docs/api/interfaces/Kana.md +11 -11
  57. package/docs/api/interfaces/Kanji.md +23 -23
  58. package/docs/api/interfaces/KanjiComponent.md +3 -3
  59. package/docs/api/interfaces/KanjiForm.md +5 -5
  60. package/docs/api/interfaces/Name.md +163 -0
  61. package/docs/api/interfaces/NeDictMeaning.md +33 -0
  62. package/docs/api/interfaces/NoteAndTag.md +3 -3
  63. package/docs/api/interfaces/NoteHeaderKeys.md +7 -7
  64. package/docs/api/interfaces/Phrase.md +5 -5
  65. package/docs/api/interfaces/Radical.md +16 -16
  66. package/docs/api/interfaces/Reading.md +6 -6
  67. package/docs/api/interfaces/ResultEntry.md +8 -7
  68. package/docs/api/interfaces/TanakaExample.md +7 -7
  69. package/docs/api/interfaces/Translation.md +5 -5
  70. package/docs/api/interfaces/UsefulRegExps.md +8 -8
  71. package/docs/api/interfaces/Word.md +15 -15
  72. package/docs/api/interfaces/WordDefinitionPair.md +4 -4
  73. package/docs/api/type-aliases/Dict.md +1 -1
  74. package/docs/api/type-aliases/{DictName.md → DictNames.md} +3 -3
  75. package/docs/api/type-aliases/EntryExamplesMap.md +13 -0
  76. package/docs/api/type-aliases/EntryType.md +2 -2
  77. package/docs/api/type-aliases/KanjiEntryMap.md +1 -1
  78. package/docs/api/type-aliases/KanjiSVGMap.md +1 -1
  79. package/docs/api/type-aliases/KanjiWordsMap.md +1 -1
  80. package/docs/api/type-aliases/NameIDEntryMap.md +13 -0
  81. package/docs/api/type-aliases/Result.md +2 -2
  82. package/docs/api/type-aliases/WordDefinitionsMap.md +1 -1
  83. package/docs/api/type-aliases/WordIDEntryMap.md +1 -1
  84. package/package.json +8 -7
  85. package/src/types.ts +115 -15
  86. package/src/utils.ts +733 -162
  87. package/docs/api/type-aliases/WordExamplesMap.md +0 -13
package/dist/index.mjs CHANGED
@@ -1364,7 +1364,6 @@ function convertJMdict(xmlString, examples) {
1364
1364
  (example) => example.parts.flatMap((part) => [
1365
1365
  part.baseForm,
1366
1366
  ...part.reading !== void 0 ? [part.reading] : [],
1367
- ...part.inflectedForm !== void 0 ? [part.inflectedForm] : [],
1368
1367
  ...part.referenceID !== void 0 ? [part.referenceID] : []
1369
1368
  ])
1370
1369
  )
@@ -1476,6 +1475,89 @@ function convertJMdict(xmlString, examples) {
1476
1475
  });
1477
1476
  return dict;
1478
1477
  }
1478
+ function convertJMnedict(xmlString, examples) {
1479
+ const dictParsed = libxml.parseXml(xmlString, {
1480
+ dtdvalid: true,
1481
+ nonet: false,
1482
+ noent: true,
1483
+ recover: false
1484
+ });
1485
+ const dict = [];
1486
+ xml.parseString(dictParsed, (_err, result) => {
1487
+ const tanakaParts = examples !== void 0 && examples.length > 0 ? new Set(
1488
+ examples.flatMap(
1489
+ (example) => example.parts.flatMap((part) => [
1490
+ part.baseForm,
1491
+ ...part.reading !== void 0 ? [part.reading] : [],
1492
+ ...part.referenceID !== void 0 ? [part.referenceID] : []
1493
+ ])
1494
+ )
1495
+ ) : void 0;
1496
+ for (const entry of result.JMnedict.entry) {
1497
+ const entryObj = {
1498
+ id: entry.ent_seq[0],
1499
+ nameReadings: [],
1500
+ meanings: []
1501
+ };
1502
+ const kanjiForms = entry.k_ele;
1503
+ const readings = entry.r_ele;
1504
+ const translations = entry.trans;
1505
+ if (isObjectArray(kanjiForms)) {
1506
+ entryObj.kanjiForms = [];
1507
+ for (const kanjiForm of kanjiForms)
1508
+ entryObj.kanjiForms.push({ form: kanjiForm.keb[0] });
1509
+ }
1510
+ for (const reading of readings) {
1511
+ const readingObj = {
1512
+ reading: reading.reb[0]
1513
+ };
1514
+ if (isStringArray(reading.re_restr))
1515
+ readingObj.kanjiFormRestrictions = reading.re_restr;
1516
+ if (isStringArray(reading.re_pri)) {
1517
+ readingObj.commonness = reading.re_pri;
1518
+ entryObj.isCommon = true;
1519
+ }
1520
+ entryObj.nameReadings.push(readingObj);
1521
+ }
1522
+ for (const trans of translations)
1523
+ entryObj.meanings.push({
1524
+ translations: trans.trans_det,
1525
+ ...isStringArray(trans.name_type) ? { nameTypes: trans.name_type } : {}
1526
+ });
1527
+ if (examples !== void 0) {
1528
+ let existsExample = false;
1529
+ const rkf = getValidForms(
1530
+ entryObj.nameReadings,
1531
+ entryObj.kanjiForms,
1532
+ entryObj.isCommon
1533
+ );
1534
+ const validReadings = new Set(
1535
+ rkf.readings.map((r) => r.reading)
1536
+ );
1537
+ const validKanjiForms = rkf.kanjiForms !== void 0 ? new Set(
1538
+ rkf.kanjiForms.map((kf) => kf.form)
1539
+ ) : void 0;
1540
+ if (validKanjiForms !== void 0 && validKanjiForms.size > 0 && tanakaParts !== void 0) {
1541
+ for (const kf of validKanjiForms)
1542
+ if (tanakaParts.has(kf)) {
1543
+ existsExample = true;
1544
+ break;
1545
+ }
1546
+ }
1547
+ if (entryObj.kanjiForms === void 0 && validReadings.size > 0 && tanakaParts !== void 0) {
1548
+ for (const r of validReadings)
1549
+ if (tanakaParts.has(r)) {
1550
+ existsExample = true;
1551
+ break;
1552
+ }
1553
+ }
1554
+ if (existsExample) entryObj.hasPhrases = true;
1555
+ }
1556
+ dict.push(entryObj);
1557
+ }
1558
+ });
1559
+ return dict;
1560
+ }
1479
1561
  function convertKanjiDic(xmlString) {
1480
1562
  const dictParsed = libxml.parseXml(xmlString, {
1481
1563
  dtdvalid: true,
@@ -1678,16 +1760,15 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
1678
1760
  }
1679
1761
  return kanjiWithRadicals;
1680
1762
  }
1681
- function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs, svgList) {
1763
+ function createEntryMaps(jmDict, jmNedict, kanjiDic, tanakaExamples, wordDefinitionPairs, svgList) {
1682
1764
  const kanjiEntryMap = /* @__PURE__ */ new Map();
1683
1765
  const wordIDEntryMap = /* @__PURE__ */ new Map();
1766
+ const nameIDEntryMap = /* @__PURE__ */ new Map();
1684
1767
  const kanjiWordsMap = /* @__PURE__ */ new Map();
1685
1768
  const wordExamplesMap = /* @__PURE__ */ new Map();
1769
+ const nameExamplesMap = /* @__PURE__ */ new Map();
1686
1770
  const wordDefinitionsMap = /* @__PURE__ */ new Map();
1687
1771
  const kanjiSVGMap = /* @__PURE__ */ new Map();
1688
- const wordPartsMap = /* @__PURE__ */ new Map();
1689
- const partExamplesMap = /* @__PURE__ */ new Map();
1690
- const entryParts = /* @__PURE__ */ new Set();
1691
1772
  if (kanjiDic !== void 0)
1692
1773
  for (const kanji of kanjiDic) kanjiEntryMap.set(kanji.kanji, kanji);
1693
1774
  if (wordDefinitionPairs !== void 0)
@@ -1703,6 +1784,9 @@ function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs,
1703
1784
  if (svg !== void 0) kanjiSVGMap.set(kanji.kanji, svg);
1704
1785
  }
1705
1786
  if (jmDict !== void 0) {
1787
+ const wordPartsMap = /* @__PURE__ */ new Map();
1788
+ const partExamplesMap = /* @__PURE__ */ new Map();
1789
+ const entryParts = /* @__PURE__ */ new Set();
1706
1790
  for (const word of jmDict) {
1707
1791
  wordIDEntryMap.set(word.id, word);
1708
1792
  if (word.kanjiForms !== void 0)
@@ -1748,14 +1832,6 @@ function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs,
1748
1832
  if (exList === void 0) partExamplesMap.set(part.reading, [ex]);
1749
1833
  else exList.push(ex);
1750
1834
  }
1751
- if (part.inflectedForm !== void 0 && entryParts.has(part.inflectedForm)) {
1752
- const exList = partExamplesMap.get(
1753
- part.inflectedForm
1754
- );
1755
- if (exList === void 0)
1756
- partExamplesMap.set(part.inflectedForm, [ex]);
1757
- else exList.push(ex);
1758
- }
1759
1835
  if (part.referenceID !== void 0 && entryParts.has(part.referenceID)) {
1760
1836
  const exList = partExamplesMap.get(
1761
1837
  part.referenceID
@@ -1781,11 +1857,74 @@ function createEntryMaps(jmDict, kanjiDic, tanakaExamples, wordDefinitionPairs,
1781
1857
  }
1782
1858
  }
1783
1859
  }
1860
+ if (jmNedict !== void 0) {
1861
+ const namePartsMap = /* @__PURE__ */ new Map();
1862
+ const partExamplesMap = /* @__PURE__ */ new Map();
1863
+ const entryParts = /* @__PURE__ */ new Set();
1864
+ for (const name of jmNedict) {
1865
+ nameIDEntryMap.set(name.id, name);
1866
+ if (tanakaExamples !== void 0) {
1867
+ const rkf = getValidForms(
1868
+ name.nameReadings,
1869
+ name.kanjiForms,
1870
+ name.isCommon
1871
+ );
1872
+ const localPartParts = /* @__PURE__ */ new Set();
1873
+ for (const reading of rkf.readings) {
1874
+ entryParts.add(reading.reading);
1875
+ localPartParts.add(reading.reading);
1876
+ }
1877
+ if (rkf.kanjiForms !== void 0 && rkf.kanjiForms.length > 0)
1878
+ for (const kanjiForm of rkf.kanjiForms) {
1879
+ entryParts.add(kanjiForm.form);
1880
+ localPartParts.add(kanjiForm.form);
1881
+ }
1882
+ entryParts.add(name.id);
1883
+ localPartParts.add(name.id);
1884
+ namePartsMap.set(name.id, localPartParts);
1885
+ }
1886
+ }
1887
+ if (tanakaExamples !== void 0) {
1888
+ for (const ex of tanakaExamples)
1889
+ for (const part of ex.parts) {
1890
+ if (entryParts.has(part.baseForm)) {
1891
+ const exList = partExamplesMap.get(
1892
+ part.baseForm
1893
+ );
1894
+ if (exList === void 0) partExamplesMap.set(part.baseForm, [ex]);
1895
+ else exList.push(ex);
1896
+ }
1897
+ if (part.reading !== void 0 && entryParts.has(part.reading)) {
1898
+ const exList = partExamplesMap.get(
1899
+ part.reading
1900
+ );
1901
+ if (exList === void 0) partExamplesMap.set(part.reading, [ex]);
1902
+ else exList.push(ex);
1903
+ }
1904
+ }
1905
+ for (const name of jmNedict) {
1906
+ const seenEx = /* @__PURE__ */ new Set();
1907
+ const validExamples = [];
1908
+ for (const p of namePartsMap.get(name.id)) {
1909
+ const examplesForPart = partExamplesMap.get(p)?.filter((ex) => !seenEx.has(ex.id));
1910
+ if (examplesForPart === void 0) continue;
1911
+ for (const ex of examplesForPart) {
1912
+ seenEx.add(ex.id);
1913
+ validExamples.push(ex);
1914
+ }
1915
+ }
1916
+ if (validExamples.length > 0)
1917
+ nameExamplesMap.set(name.id, validExamples);
1918
+ }
1919
+ }
1920
+ }
1784
1921
  return {
1785
1922
  ...wordIDEntryMap.size > 0 ? { wordIDEntryMap } : {},
1923
+ ...nameIDEntryMap.size > 0 ? { nameIDEntryMap } : {},
1786
1924
  ...kanjiWordsMap.size > 0 ? { kanjiWordsMap } : {},
1787
1925
  ...kanjiEntryMap.size > 0 ? { kanjiEntryMap } : {},
1788
1926
  ...wordExamplesMap.size > 0 ? { wordExamplesMap } : {},
1927
+ ...nameExamplesMap.size > 0 ? { nameExamplesMap } : {},
1789
1928
  ...wordDefinitionsMap.size > 0 ? { wordDefinitionsMap } : {},
1790
1929
  ...kanjiSVGMap.size > 0 ? { kanjiSVGMap } : {}
1791
1930
  };
@@ -2562,43 +2701,45 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2562
2701
  rkf.readings.map((r) => r.reading)
2563
2702
  );
2564
2703
  const kanjiForms = rkf.kanjiForms !== void 0 ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
2565
- let readingMatchingKanjiFormExamples = [];
2704
+ const readingMatchingKanjiFormExamples = [];
2566
2705
  let kanjiFormExamples = [];
2567
2706
  let readingExamples = [];
2568
- let hasReadingMatchingKanjiFormWithTranslation = false;
2707
+ let hasKanjiFormExamplesWithTranslation = false;
2708
+ let hasReadingExamplesWithTranslation = false;
2569
2709
  for (const example of exampleList)
2570
2710
  for (let i = 0; i < example.parts.length; i++) {
2571
2711
  if (seenPhrases.has(example.phrase)) break;
2572
- const includesTranslation = meanings.some(
2573
- (m) => example.translation.includes(m)
2574
- );
2575
2712
  const part = example.parts[i];
2576
2713
  const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
2577
- const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
2578
2714
  const referenceIDMatch = part.referenceID === dictWord.id;
2579
2715
  if (kanjiForms !== void 0 && kanjiForms.has(part.baseForm)) {
2580
- if (readingAsReadingMatch || readingAsInflectedFormMatch || referenceIDMatch) {
2716
+ if (readingAsReadingMatch || referenceIDMatch)
2581
2717
  readingMatchingKanjiFormExamples.push({
2582
2718
  ex: example,
2583
- partIndex: i,
2584
- form: part.baseForm,
2585
- ...referenceIDMatch ? { referenceIDMatch: true } : {},
2586
- ...includesTranslation ? { includesTranslation: true } : {}
2719
+ partIndex: i
2587
2720
  });
2588
- if (!hasReadingMatchingKanjiFormWithTranslation && includesTranslation)
2589
- hasReadingMatchingKanjiFormWithTranslation = true;
2590
- } else
2721
+ else {
2722
+ const includesTranslation = meanings.some(
2723
+ (m) => example.translation.includes(m)
2724
+ );
2725
+ if (!hasKanjiFormExamplesWithTranslation && includesTranslation)
2726
+ hasKanjiFormExamplesWithTranslation = true;
2591
2727
  kanjiFormExamples.push({
2592
2728
  ex: example,
2593
2729
  partIndex: i,
2594
- form: part.baseForm,
2595
2730
  ...includesTranslation ? { includesTranslation: true } : {}
2596
2731
  });
2732
+ }
2597
2733
  seenPhrases.add(example.phrase);
2598
2734
  break;
2599
2735
  }
2600
2736
  const readingAsBaseFormMatch = readings.has(part.baseForm);
2601
2737
  if ((readingAsBaseFormMatch || referenceIDMatch) && kanjiForms === void 0) {
2738
+ const includesTranslation = meanings.some(
2739
+ (m) => example.translation.includes(m)
2740
+ );
2741
+ if (!hasReadingExamplesWithTranslation && includesTranslation)
2742
+ hasReadingExamplesWithTranslation = true;
2602
2743
  readingExamples.push({
2603
2744
  ex: example,
2604
2745
  partIndex: i,
@@ -2609,26 +2750,13 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2609
2750
  break;
2610
2751
  }
2611
2752
  }
2612
- if (readingMatchingKanjiFormExamples.length > 0) {
2613
- if (hasReadingMatchingKanjiFormWithTranslation)
2614
- readingMatchingKanjiFormExamples = readingMatchingKanjiFormExamples.filter(
2615
- (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true || ex.ex.parts.some(
2616
- (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2617
- )
2618
- );
2619
- kanjiFormExamples.length = 0;
2620
- }
2621
- if (kanjiFormExamples.length > 0 && kanjiFormExamples.some(
2622
- (ex) => ex.includesTranslation === true
2623
- ))
2753
+ if (kanjiFormExamples.length > 0 && hasKanjiFormExamplesWithTranslation)
2624
2754
  kanjiFormExamples = kanjiFormExamples.filter(
2625
- (ex) => ex.includesTranslation === true || ex.ex.parts.some(
2626
- (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2627
- )
2755
+ (ex) => ex.includesTranslation === true
2628
2756
  );
2629
- if (readingExamples.length > 0 && readingExamples.some(
2630
- (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true
2631
- ))
2757
+ else if (kanjiFormExamples.length > 0 && readingMatchingKanjiFormExamples.length > 0)
2758
+ kanjiFormExamples.length = 0;
2759
+ if (readingExamples.length > 0 && hasReadingExamplesWithTranslation)
2632
2760
  readingExamples = readingExamples.filter(
2633
2761
  (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true
2634
2762
  );
@@ -2694,9 +2822,182 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2694
2822
  return word;
2695
2823
  } else return void 0;
2696
2824
  }
2825
+ function getName(searchedName, dict, kanjiDic, examples, noteTypeName, deckPath) {
2826
+ let dictName = void 0;
2827
+ if (typeof searchedName === "string" && dict !== void 0) {
2828
+ if (Array.isArray(dict))
2829
+ dictName = dict.find(
2830
+ (entry) => entry.id === searchedName
2831
+ );
2832
+ if (dict instanceof Map) dictName = dict.get(searchedName);
2833
+ }
2834
+ if (typeof searchedName === "object") dictName = searchedName;
2835
+ if (dictName !== void 0) {
2836
+ const name = {
2837
+ id: dictName.id,
2838
+ nameReadings: [],
2839
+ translations: [],
2840
+ noteID: `name_${dictName.id}`,
2841
+ noteTypeName,
2842
+ deckPath,
2843
+ tags: []
2844
+ };
2845
+ if (dictName.isCommon === true) {
2846
+ name.common = true;
2847
+ name.tags.push("name::common");
2848
+ }
2849
+ if (dictName.kanjiForms !== void 0)
2850
+ name.kanjiForms = dictName.kanjiForms.map(
2851
+ (dictKanjiForm) => ({
2852
+ kanjiForm: dictKanjiForm.form
2853
+ })
2854
+ );
2855
+ name.nameReadings = dictName.nameReadings.map(
2856
+ (dictReading) => ({
2857
+ reading: dictReading.reading,
2858
+ ...dictReading.kanjiFormRestrictions !== void 0 ? {
2859
+ notes: dictReading.kanjiFormRestrictions.map(
2860
+ (restriction) => `Reading restricted to ${restriction}`
2861
+ )
2862
+ } : {},
2863
+ ...dictReading.commonness !== void 0 && dictReading.commonness.length > 0 ? { common: true } : {}
2864
+ })
2865
+ );
2866
+ name.translations = [];
2867
+ const meanings = dictName.hasPhrases === true && examples !== void 0 ? [] : void 0;
2868
+ const seenPhrases = /* @__PURE__ */ new Set();
2869
+ let hasNameTypes = false;
2870
+ for (const dictMeaning of dictName.meanings) {
2871
+ if (!hasNameTypes && dictMeaning.nameTypes !== void 0)
2872
+ hasNameTypes = true;
2873
+ name.translations.push({
2874
+ translation: dictMeaning.translations.map((translation) => {
2875
+ if (meanings !== void 0) {
2876
+ const cleanTranslation = translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2877
+ if (!seenPhrases.has(cleanTranslation)) {
2878
+ seenPhrases.add(cleanTranslation);
2879
+ meanings.push(cleanTranslation);
2880
+ }
2881
+ }
2882
+ return translation;
2883
+ }).join("; "),
2884
+ ...dictMeaning.nameTypes !== void 0 ? {
2885
+ notes: dictMeaning.nameTypes.map((type) => {
2886
+ const noteAndTag = lookupWordNote(
2887
+ type,
2888
+ [],
2889
+ name.tags
2890
+ );
2891
+ return capitalizeString(noteAndTag.note);
2892
+ })
2893
+ } : {}
2894
+ });
2895
+ }
2896
+ if (!hasNameTypes) name.tags.push("name::no_name_types");
2897
+ seenPhrases.clear();
2898
+ if (kanjiDic !== void 0 && name.kanjiForms !== void 0) {
2899
+ const kanji = [];
2900
+ const seenChars = /* @__PURE__ */ new Set();
2901
+ for (const kanjiForm of name.kanjiForms)
2902
+ for (const char of kanjiForm.kanjiForm.split("").filter((c) => regexps.kanji.test(c))) {
2903
+ if (seenChars.has(char)) continue;
2904
+ seenChars.add(char);
2905
+ const kanjiEntry = kanjiDic instanceof Map ? kanjiDic.get(char) : void 0;
2906
+ const kanjiObj = getKanji(
2907
+ kanjiEntry ?? char,
2908
+ !(kanjiDic instanceof Map) ? kanjiDic : void 0
2909
+ );
2910
+ if (kanjiObj !== void 0)
2911
+ kanji.push({
2912
+ kanji: kanjiObj.kanji,
2913
+ ...kanjiObj.meanings !== void 0 && kanjiObj.meanings.length > 0 ? { meanings: kanjiObj.meanings } : {}
2914
+ });
2915
+ }
2916
+ if (kanji.length > 0) name.kanji = kanji;
2917
+ }
2918
+ if (meanings !== void 0) {
2919
+ const exampleList = examples instanceof Map ? examples.get(dictName.id) ?? [] : examples;
2920
+ const rkf = getValidForms(
2921
+ dictName.nameReadings,
2922
+ dictName.kanjiForms,
2923
+ dictName.isCommon
2924
+ );
2925
+ const readings = new Set(
2926
+ rkf.readings.map((r) => r.reading)
2927
+ );
2928
+ const kanjiForms = rkf.kanjiForms !== void 0 ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
2929
+ let readingMatchingKanjiFormExamples = [];
2930
+ let readingExamples = [];
2931
+ let hasReadingMatchingKanjiFormWithTranslation = false;
2932
+ let hasReadingWithTranslation = false;
2933
+ for (const example of exampleList)
2934
+ for (let i = 0; i < example.parts.length; i++) {
2935
+ if (seenPhrases.has(example.phrase)) break;
2936
+ const part = example.parts[i];
2937
+ const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
2938
+ if (kanjiForms !== void 0 && kanjiForms.has(part.baseForm) && readingAsReadingMatch) {
2939
+ const includesTranslation = meanings.some(
2940
+ (m) => example.translation.includes(m)
2941
+ );
2942
+ if (!hasReadingMatchingKanjiFormWithTranslation && includesTranslation)
2943
+ hasReadingMatchingKanjiFormWithTranslation = true;
2944
+ readingMatchingKanjiFormExamples.push({
2945
+ ex: example,
2946
+ ...includesTranslation ? { includesTranslation: true } : {}
2947
+ });
2948
+ seenPhrases.add(example.phrase);
2949
+ break;
2950
+ }
2951
+ const readingAsBaseFormMatch = readings.has(part.baseForm);
2952
+ if (readingAsBaseFormMatch && kanjiForms === void 0) {
2953
+ const includesTranslation = meanings.some(
2954
+ (m) => example.translation.includes(m)
2955
+ );
2956
+ if (!hasReadingWithTranslation && includesTranslation)
2957
+ hasReadingWithTranslation = true;
2958
+ readingExamples.push({
2959
+ ex: example,
2960
+ ...includesTranslation ? { includesTranslation: true } : {}
2961
+ });
2962
+ seenPhrases.add(example.phrase);
2963
+ break;
2964
+ }
2965
+ }
2966
+ if (readingMatchingKanjiFormExamples.length > 0) {
2967
+ if (hasReadingMatchingKanjiFormWithTranslation)
2968
+ readingMatchingKanjiFormExamples = readingMatchingKanjiFormExamples.filter(
2969
+ (ex) => ex.includesTranslation === true
2970
+ );
2971
+ }
2972
+ if (readingExamples.length > 0 && hasReadingWithTranslation)
2973
+ readingExamples = readingExamples.filter(
2974
+ (ex) => ex.includesTranslation === true
2975
+ );
2976
+ const wordExamples = [
2977
+ ...name.kanjiForms !== void 0 ? readingMatchingKanjiFormExamples : readingExamples
2978
+ ];
2979
+ if (wordExamples.length > 0) {
2980
+ name.phrases = wordExamples.slice(0, 5).map(
2981
+ (ex) => ({
2982
+ phrase: ex.ex.furigana ?? ex.ex.phrase,
2983
+ translation: ex.ex.translation,
2984
+ originalPhrase: ex.ex.phrase
2985
+ })
2986
+ );
2987
+ name.tags.push("name::has_phrases");
2988
+ }
2989
+ }
2990
+ return name;
2991
+ } else return void 0;
2992
+ }
2697
2993
  function isWord(entry) {
2698
2994
  return isObjectArray(Object.getOwnPropertyDescriptor(entry, "readings")?.value) && isObjectArray(Object.getOwnPropertyDescriptor(entry, "translations")?.value);
2699
2995
  }
2996
+ function isName(entry) {
2997
+ return isObjectArray(
2998
+ Object.getOwnPropertyDescriptor(entry, "nameReadings")?.value
2999
+ ) && isObjectArray(Object.getOwnPropertyDescriptor(entry, "translations")?.value);
3000
+ }
2700
3001
  function isRadical(entry) {
2701
3002
  return typeof Object.getOwnPropertyDescriptor(entry, "radical")?.value === "string";
2702
3003
  }
@@ -2834,6 +3135,92 @@ function generateAnkiNote(entry, customData, additionalTags) {
2834
3135
  searchField
2835
3136
  );
2836
3137
  }
3138
+ if (isName(entry)) {
3139
+ const firstReading = createEntry(
3140
+ `<span class="name name-reading">${entry.nameReadings[0].reading}${entry.nameReadings[0].audio !== void 0 ? `<br>[sound:${entry.nameReadings[0].audio}]` : ""}</span>`,
3141
+ entry.nameReadings[0].notes
3142
+ );
3143
+ const otherReadings = entry.nameReadings.length > 1 ? `<details><summary>Show other readings</summary>${entry.nameReadings.slice(1).map(
3144
+ (readingEntry) => createEntry(
3145
+ `<span class="name name-reading">${readingEntry.reading}${readingEntry.audio !== void 0 ? `<br>[sound:${readingEntry.audio}]` : ""}</span>`,
3146
+ readingEntry.notes
3147
+ )
3148
+ ).join("")}</details>` : "";
3149
+ const readingsField = `${firstReading}${otherReadings}`;
3150
+ let readingsFieldWithoutAudio = '<div id="no-r-audio" style="display: none"></div>';
3151
+ let hasAudio = false;
3152
+ if (entry.nameReadings.some((r) => r.audio !== void 0)) {
3153
+ const firstReadingWithoutAudio = createEntry(
3154
+ `<span class="name name-reading">${entry.nameReadings[0].reading}</span>`,
3155
+ entry.nameReadings[0].notes
3156
+ );
3157
+ const otherReadingsWithoutAudio = entry.nameReadings.length > 1 ? `<details><summary>Show other readings</summary>${entry.nameReadings.slice(1).map(
3158
+ (readingEntry) => createEntry(
3159
+ `<span class="name name-reading">${readingEntry.reading}</span>`,
3160
+ readingEntry.notes
3161
+ )
3162
+ ).join("")}</details>` : "";
3163
+ readingsFieldWithoutAudio = `${firstReadingWithoutAudio}${otherReadingsWithoutAudio}`;
3164
+ hasAudio = true;
3165
+ }
3166
+ const firstKanjiForm = entry.kanjiForms !== void 0 ? createEntry(
3167
+ `<span class="name name-kanjiform"><ruby><rb>${entry.kanjiForms[0].kanjiForm}</rb><rt>${entry.nameReadings[0].reading}</rt></ruby></span>`,
3168
+ entry.kanjiForms[0].notes
3169
+ ) : void 0;
3170
+ const otherKanjiForms = entry.kanjiForms !== void 0 && entry.kanjiForms.length > 1 ? `<details><summary>Show other kanji forms</summary>${entry.kanjiForms.slice(1).map((kanjiFormEntry) => {
3171
+ const restrictedReading = entry.nameReadings.find(
3172
+ (r) => r.notes !== void 0 && r.notes.includes(
3173
+ `Reading restricted to ${kanjiFormEntry.kanjiForm}`
3174
+ )
3175
+ );
3176
+ return createEntry(
3177
+ `<span class="name name-kanjiform">${restrictedReading !== void 0 ? "<ruby><rb>" : ""}${kanjiFormEntry.kanjiForm}${restrictedReading !== void 0 ? `</rb><rt>${restrictedReading.reading}</rt></ruby>` : ""}</span>`,
3178
+ kanjiFormEntry.notes
3179
+ );
3180
+ }).join("")}</details>` : "";
3181
+ const kanjiFormsField = firstKanjiForm !== void 0 ? `${firstKanjiForm}${otherKanjiForms}` : '<span class="name name-kanjiform" id="no-kanjiforms">(no kanji forms)</span>';
3182
+ const firstThreeTranslations = entry.translations.slice(0, 3).map(
3183
+ (translationEntry) => createEntry(
3184
+ `<span class="name name-translation">${translationEntry.translation}</span>`,
3185
+ translationEntry.notes
3186
+ )
3187
+ ).join("");
3188
+ const otherTranslations = entry.translations.length > 3 ? `<details><summary>Show other translations</summary>${entry.translations.map((translationEntry, index) => {
3189
+ if (index < 3) return "null";
3190
+ return createEntry(
3191
+ `<span class="name name-translation">${translationEntry.translation}</span>`,
3192
+ translationEntry.notes
3193
+ );
3194
+ }).filter((translation) => translation !== "null").join("")}</details>` : "";
3195
+ const translationsField = `${firstThreeTranslations}${otherTranslations}`;
3196
+ const phrasesField = entry.phrases !== void 0 ? entry.phrases.map(
3197
+ (phraseEntry) => createEntry(
3198
+ `<span class="name name-phrase"><span class="name name-phrase-original">${phraseEntry.originalPhrase}</span><span class="name name-phrase-furigana">${phraseEntry.phrase}</span></span>`,
3199
+ [phraseEntry.translation],
3200
+ true
3201
+ )
3202
+ ).join("") : '<span class="name name-phrase" id="no-phrases">(no phrases)</span>';
3203
+ const searchField = `${entry.nameReadings.map((r) => r.reading).join(" ")}${entry.kanjiForms !== void 0 ? ` ${entry.kanjiForms.map((kf) => kf.kanjiForm).join(" ")}` : ""} ${entry.id}`;
3204
+ fields.push(
3205
+ ...entry.kanjiForms !== void 0 ? [
3206
+ `${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>`,
3207
+ `${hasAudio ? readingsFieldWithoutAudio : readingsField}<div id="r-pos" style="display: none" data-pos="2"></div>`
3208
+ ] : [
3209
+ `${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>`,
3210
+ `${hasAudio ? readingsFieldWithoutAudio : readingsField}<div id="r-pos" style="display: none" data-pos="1"></div>`
3211
+ ],
3212
+ `${hasAudio ? readingsField : readingsFieldWithoutAudio}<div id="r-pos" style="display: none" data-pos="${entry.kanjiForms !== void 0 ? "2" : "1"}"></div>`,
3213
+ translationsField,
3214
+ phrasesField,
3215
+ entry.kanji !== void 0 ? entry.kanji.map(
3216
+ (kanjiEntry) => createEntry(
3217
+ `<span class="name name-kanji">${kanjiEntry.kanji}${kanjiEntry.meanings === void 0 ? " (no meanings)" : ""}</span>`,
3218
+ kanjiEntry.meanings
3219
+ )
3220
+ ).join("") : '<span class="name name-kanji" id="no-kanji">(no kanji)</span>',
3221
+ searchField
3222
+ );
3223
+ }
2837
3224
  if (isRadical(entry))
2838
3225
  fields.push(
2839
3226
  `${customData !== void 0 ? `<div id="custom-data" style="display: none" data-custom="${customData}"></div>` : ""}${createEntry(
@@ -3011,6 +3398,7 @@ ${ankiNotes}`;
3011
3398
  export {
3012
3399
  capitalizeString,
3013
3400
  convertJMdict,
3401
+ convertJMnedict,
3014
3402
  convertJawiktionaryAsync,
3015
3403
  convertJawiktionarySync,
3016
3404
  convertKanjiDic,
@@ -3024,6 +3412,7 @@ export {
3024
3412
  generateFurigana,
3025
3413
  getKanji,
3026
3414
  getKanjiExtended,
3415
+ getName,
3027
3416
  getValidForms,
3028
3417
  getWord,
3029
3418
  getWordDefinitions,
@@ -3032,6 +3421,7 @@ export {
3032
3421
  isGrammar,
3033
3422
  isKana,
3034
3423
  isKanji,
3424
+ isName,
3035
3425
  isObjectArray,
3036
3426
  isRadical,
3037
3427
  isStringArray,