@natlibfi/marc-record-validators-melinda 12.0.7 → 12.0.8

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 (101) hide show
  1. package/dist/addMissingField041.js +6 -3
  2. package/dist/addMissingField041.js.map +2 -2
  3. package/dist/addMissingField336.js +7 -4
  4. package/dist/addMissingField336.js.map +2 -2
  5. package/dist/addMissingField337.js +6 -3
  6. package/dist/addMissingField337.js.map +2 -2
  7. package/dist/addMissingField338.js +8 -5
  8. package/dist/addMissingField338.js.map +2 -2
  9. package/dist/cyrillux-usemarcon-replacement.js +5 -2
  10. package/dist/cyrillux-usemarcon-replacement.js.map +2 -2
  11. package/dist/cyrillux.js +10 -7
  12. package/dist/cyrillux.js.map +2 -2
  13. package/dist/disambiguateSeriesStatements.js +2 -1
  14. package/dist/disambiguateSeriesStatements.js.map +2 -2
  15. package/dist/drop-terms.js +5 -4
  16. package/dist/drop-terms.js.map +2 -2
  17. package/dist/fix-33X.js +7 -4
  18. package/dist/fix-33X.js.map +2 -2
  19. package/dist/fix-country-codes.js +5 -0
  20. package/dist/fix-country-codes.js.map +2 -2
  21. package/dist/fix-language-codes.js +5 -1
  22. package/dist/fix-language-codes.js.map +2 -2
  23. package/dist/fix-sami-041.js +11 -10
  24. package/dist/fix-sami-041.js.map +2 -2
  25. package/dist/indicator-fixes.js +5 -1
  26. package/dist/indicator-fixes.js.map +2 -2
  27. package/dist/merge-fields/counterpartField.js +6 -6
  28. package/dist/merge-fields/counterpartField.js.map +2 -2
  29. package/dist/merge-fields/mergableIndicator.js +0 -3
  30. package/dist/merge-fields/mergableIndicator.js.map +2 -2
  31. package/dist/merge-fields/worldKnowledge.js.map +2 -2
  32. package/dist/mergeRelatorTermFields.js +9 -6
  33. package/dist/mergeRelatorTermFields.js.map +2 -2
  34. package/dist/normalize-dashes.js +7 -4
  35. package/dist/normalize-dashes.js.map +2 -2
  36. package/dist/normalize-identifiers.js.map +2 -2
  37. package/dist/normalize-utf8-diacritics.js.map +2 -2
  38. package/dist/normalizeFieldForComparison.js.map +1 -1
  39. package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
  40. package/dist/punctuation2.js +5 -2
  41. package/dist/punctuation2.js.map +2 -2
  42. package/dist/reindexSubfield6OccurenceNumbers.js +11 -10
  43. package/dist/reindexSubfield6OccurenceNumbers.js.map +2 -2
  44. package/dist/removeDuplicateDataFields.js +3 -2
  45. package/dist/removeDuplicateDataFields.js.map +2 -2
  46. package/dist/removeInferiorDataFields.js.map +2 -2
  47. package/dist/resolveOrphanedSubfield6s.js +3 -2
  48. package/dist/resolveOrphanedSubfield6s.js.map +2 -2
  49. package/dist/sortSubfields.js +1 -1
  50. package/dist/sortSubfields.js.map +2 -2
  51. package/dist/stripPunctuation.js +4 -3
  52. package/dist/stripPunctuation.js.map +2 -2
  53. package/dist/subfield6Utils.js +4 -1
  54. package/dist/subfield6Utils.js.map +2 -2
  55. package/dist/subfield8Utils.js.map +2 -2
  56. package/dist/translate-terms.js +4 -3
  57. package/dist/translate-terms.js.map +2 -2
  58. package/dist/typeOfDate-008.js +3 -1
  59. package/dist/typeOfDate-008.js.map +2 -2
  60. package/dist/update-field-540.js.map +2 -2
  61. package/dist/urn.js +13 -12
  62. package/dist/urn.js.map +2 -2
  63. package/package.json +7 -7
  64. package/src/addMissingField041.js +8 -4
  65. package/src/addMissingField336.js +10 -5
  66. package/src/addMissingField337.js +9 -5
  67. package/src/addMissingField338.js +11 -6
  68. package/src/cyrillux-usemarcon-replacement.js +9 -5
  69. package/src/cyrillux.js +18 -12
  70. package/src/disambiguateSeriesStatements.js +4 -1
  71. package/src/drop-terms.js +8 -6
  72. package/src/fix-33X.js +10 -6
  73. package/src/fix-country-codes.js +7 -3
  74. package/src/fix-language-codes.js +8 -4
  75. package/src/fix-sami-041.js +13 -11
  76. package/src/indicator-fixes.js +10 -7
  77. package/src/merge-fields/counterpartField.js +10 -10
  78. package/src/merge-fields/mergableIndicator.js +3 -3
  79. package/src/merge-fields/worldKnowledge.js +11 -6
  80. package/src/mergeRelatorTermFields.js +12 -11
  81. package/src/normalize-dashes.js +11 -5
  82. package/src/normalize-identifiers.js +12 -19
  83. package/src/normalize-utf8-diacritics.js +6 -3
  84. package/src/normalizeFieldForComparison.js +2 -2
  85. package/src/normalizeSubfieldValueForComparison.js +2 -2
  86. package/src/punctuation2.js +34 -30
  87. package/src/reindexSubfield6OccurenceNumbers.js +13 -11
  88. package/src/removeDuplicateDataFields.js +29 -27
  89. package/src/removeInferiorDataFields.js +28 -24
  90. package/src/resolveOrphanedSubfield6s.js +6 -4
  91. package/src/sortSubfields.js +5 -5
  92. package/src/stripPunctuation.js +5 -3
  93. package/src/subfield6Utils.js +33 -35
  94. package/src/subfield8Utils.js +10 -7
  95. package/src/translate-terms.js +13 -9
  96. package/src/typeOfDate-008.js +4 -1
  97. package/src/update-field-540.js +7 -5
  98. package/src/urn.js +17 -13
  99. package/test-fixtures/drop-terms/02/metadata.json +1 -1
  100. package/test-fixtures/drop-terms/03/metadata.json +1 -1
  101. package/test-fixtures/drop-terms/04/metadata.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/fix-33X.js"],
4
- "sourcesContent": ["//import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString, getCatalogingLanguage, nvdebug} from './utils.js';\nimport {map336CodeToTerm, map337CodeToTerm, map338CodeToTerm} from './field33XUtils.js';\n\nconst description = 'Fix non-RDA 33X field(s)';\n\n\nconst map336 = {\n 'Bild (kartografisk ; att vidra)': 'crt',\n 'Bild (kartografisk ; r\u00F6rlig)': 'crm',\n 'Bild (kartografisk)': 'cri',\n 'Bild (r\u00F6rlig ; tredimensionell)': 'tdm',\n 'Bild (r\u00F6rlig ; tv\u00E5dimensionell)': 'tdi',\n 'Bild (still ; att vidra)': 'tci',\n 'Bild (still ; tredimensionell)': 'sti',\n 'Bild (still)': 'sti',\n 'Data': 'cod',\n 'Data (kartografinen)': 'crd',\n 'Dataset': 'cod',\n 'Dataset (kartografisk)': 'crd',\n 'Datorprogram': 'cop',\n 'Esine': 'tdf',\n 'Esine (kartografinen ; kosketeltava)': 'crn',\n 'Esine (kartografinen)': 'crf',\n 'Esine (kartogragrafinen ; kolmiulotteinen)': 'crf',\n 'Esine (kolmiulotteinen)': 'tdf',\n 'Esine (kosketeltava)': 'tcf',\n 'Flera inneh\u00E5llstyper': 'zzz',\n 'F\u00F6remal': 'tdf',\n 'F\u00F6rem\u00E5l (att vidra)': 'tcf',\n 'F\u00F6rem\u00E5l (kartografisk ; att vidra)': 'crn',\n 'F\u00F6rem\u00E5l (kartografisk ; tredimensionell)': 'crn',\n 'F\u00F6rem\u00E5l (tredimensionell)': 'tdf',\n 'Ger\u00E4usche': 'snd',\n 'Kuva': 'sti',\n 'Kuva (kartografinen ; kosketeltava)': 'crt',\n 'Kuva (kartografinen ; liikkuva)': 'crm',\n 'Kuva (kartografinen)': 'cri',\n 'Kuva (liikkuva ; kaksiulotteinen)': 'tdi',\n 'Kuva (liikkuva ; kolmiulotteinen)': 'tdm',\n 'Kuva (still ; kaksiulotteinen)': 'sti',\n 'Kuva (still ; kolmiulotteinen)': 'sti',\n 'Kuva (still ; kosketeltava)': 'tci',\n 'Kuva (still)': 'sti',\n 'Liike (kosketeltava ; notatoitu)': 'tcn',\n 'Liike (notatoitu ; kosketeltava': 'tcn',\n 'Liike (notatoitu)': 'ntv',\n 'Ljud': 'snd',\n 'Musiikki (esitetty)': 'prm',\n 'Musiikki (kosketeltava ; notatoitu)': 'tcm',\n 'Musiikki (notatoitu ; kosketeltava)': 'tcm',\n 'Musiikki (notatoitu)': 'ntm',\n 'Musik (notation ; att vidra)': 'tcm',\n 'Musik (notation)': 'ntm',\n 'Musik (performance)': 'prm',\n 'M\u00E4\u00E4rittelem\u00E4t\u00F6n': 'zzz',\n 'M\u00E4\u00E4rittelem\u00E4t\u00F6n sis\u00E4lt\u00F6tyyppi': 'zzz',\n 'Obest\u00E4md inneh\u00E5llstyp': 'zzz',\n 'Ospecificerad inneh\u00E5llstyp': 'zzz',\n 'Puhe': 'spw',\n 'R\u00F6relse (notation ; att vidra)': 'tcn',\n 'R\u00F6relse (notation)': 'ntv',\n 'Tal': 'spw',\n 'Teksti': 'txt',\n 'Teksti (kosketeltava); Text (att vidra)': 'tct',\n 'Text': 'txt',\n 'Tietokoneohjelma': 'cop',\n 'Useita sis\u00E4lt\u00F6tyyppej\u00E4': 'zzz',\n 'Vild (still ; tv\u00E5dimensionell)': 'sti',\n 'annan': 'xxx',\n 'cartographic dataset': 'crd',\n 'cartographic image': 'cri',\n 'cartographic moving image': 'crm',\n 'cartographic tactile image': 'crt',\n 'cartographic tactile three-dimensional form': 'crn',\n 'cartographic three-dimensional form': 'crf',\n 'cartographic three-dimensional tactile form': 'crn',\n 'computer dataset': 'cod',\n 'computer program': 'cop',\n 'dataset': 'cod',\n 'datorprogram': 'cop',\n 'digitaalinen data': 'cod',\n 'digitalt dataset': 'cod',\n 'esitetty musiikki': 'prm',\n 'framf\u00F6rd musik': 'prm',\n 'gesprochenes Wort': 'spw',\n 'kaksiulotteinen liikkuva kuva': 'tdi',\n 'kartografinen data': 'crd',\n 'kartografinen kolmiulotteinen muoto': 'crf',\n 'kartografinen kuva': 'cri',\n 'kartografinen liikkuva kuva': 'crm',\n 'kartografinen taktiili kolmiulotteinen muoto': 'crn',\n 'kartografinen taktiili kuva': 'crt',\n 'kartografisk bild': 'cri',\n 'kartografisk data': 'crd',\n 'kartografisk r\u00F6rlig bild': 'crm',\n 'kartografisk taktil bild': 'crt',\n 'kartografisk taktil tredimensionell form': 'crn',\n 'kartografisk tredimensionell form': 'crf',\n 'kolmiulotteinen liikkuva kuva': 'tdm',\n 'kolmiulotteinen muoto': 'tdf',\n 'liikenotaatio': 'ntv',\n 'ljud': 'snd',\n 'muu': 'xxx',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n': 'zzz',\n 'notated movement': 'ntv',\n 'notated music': 'ntm',\n 'noterad musik': 'ntm',\n 'nuottikirjoitus': 'ntm',\n 'ospecificerad': 'zzz',\n 'other': 'xxx',\n 'performed music': 'prm',\n 'puhe': 'spw',\n 'r\u00F6relsenotation': 'ntv',\n 'sounds': 'snd',\n 'spoken word': 'spw',\n 'still image': 'sti',\n 'stillbild': 'sti',\n 'stillkuva': 'sti',\n 'tactile image': 'tci',\n 'tactile notated movement': 'tcn',\n 'tactile notated music': 'tcm',\n 'tactile text': 'tct',\n 'tactile three-dimensional form': 'tcf',\n 'taktiili kolmiulotteinen muoto': 'tcf',\n 'taktiili kuva': 'tci',\n 'taktiili liikenotaatio': 'tcn',\n 'taktiili nuottikirjoitus': 'tcm',\n 'taktiili teksti': 'tct',\n 'taktil bild': 'tci',\n 'taktil musiknotation': 'tcm',\n 'taktil noterad r\u00F6relse': 'tcn',\n 'taktil text': 'tct',\n 'taktil tredimensionell form': 'tcf',\n 'tal': 'spw',\n 'teksti': 'txt',\n 'text': 'txt',\n 'texte': 'txt',\n 'texte tactile': 'tct',\n 'three-dimensional form': 'tdf',\n 'three-dimensional moving image': 'tdm',\n 'tietokoneohjelma': 'cop',\n 'tredimensionell form': 'tdf',\n 'tredimensionell r\u00F6rlig bild': 'tdm',\n 'tv\u00E5dimensionell r\u00F6rlig bild': 'tdi',\n 'two-dimensional moving image': 'tdi',\n 'unbewegtes Bild': 'sti',\n 'unspecified': 'zzz',\n '\u00C4\u00E4ni': 'snd',\n '\u00E4\u00E4ni': 'snd',\n '\u042D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u0430\u044F \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430': 'cop', // computer program\n '\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 (\u043A\u0430\u0440\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0435)': 'cri',\n '\u041C\u0443\u0437\u044B\u043A\u0430 (\u0437\u043D\u0430\u043A\u043E\u0432\u0430\u044F)': 'ntm', // notated music\n '\u041C\u0443\u0437\u044B\u043A\u0430 (\u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u0441\u043A\u0430\u044F)': 'prm', // performed music\n '\u0423\u0441\u0442\u043D\u0430\u044F \u0440\u0435\u0447\u044C': 'spw',\n '\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 (\u043D\u0435\u043F\u043E\u0434\u0432\u0438\u0436\u043D\u043E\u0435)': 'sti',\n '\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 (\u0434\u0432\u0438\u0436\u0443\u0449\u0435\u0435\u0441\u044F)': 'tdi', // 2D moving image\n '\u0422\u0435\u043A\u0441\u0442': 'txt',\n '\u0422\u0435\u043A\u0441\u0442 (\u0432\u0438\u0437\u0443\u0430\u043B\u044C\u043D\u044B\u0439)': 'txt'\n};\n\nconst map337 = {\n 'Computermedien': 'c',\n 'Mikroform': 'h',\n 'annan': 'x',\n 'audio': 's',\n 'computer': 'c',\n 'dator': 'c',\n 'datoranv\u00E4ndbar': 'c',\n 'ei v\u00E4litt\u00E4v\u00E4\u00E4 laitetta': 'n',\n 'elektroninen': 'c',\n 'elektronisk': 'c',\n 'heijastettava': 'g',\n 'ingen medietyp': 'n',\n 'k\u00E4ytett\u00E4viss\u00E4 ilman laitetta': 'n',\n 'microform': 'h',\n 'microscopic': 'p',\n 'mikroform': 'h',\n 'mikromuoto': 'h',\n 'mikroskooppinen': 'p',\n 'mikroskopisch': 'p',\n 'mikroskopisk': 'p',\n 'muu': 'x',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n': 'z',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n v\u00E4litt\u00E4v\u00E4 laite': 'z',\n 'of\u00F6rmedlad': 'n',\n 'ohne Hilfsmittel zu benutzen': 'n',\n 'omedierad': 'n',\n 'ospecificerad': 'z',\n 'ospecificerad medietyp': 'z',\n 'other': 'x',\n 'projected': 'g',\n 'projektion': 'g',\n 'projicerad': 'g',\n 'projicerbar': 'g',\n 'projizierbar': 'g',\n 'stereografinen': 'e',\n 'stereografisch': 'e',\n 'stereografisk': 'e',\n 'stereographic': 'e',\n 'tietokonek\u00E4ytt\u00F6inen': 'c',\n 'unmediated': 'n',\n 'unspecified': 'z',\n 'useita mediatyyppej\u00E4': 'z',\n 'video': 'v',\n '\u00F6vrig': 'x',\n // Cyrillic (sorted by result):\n '\u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D': 'c',\n '\u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u044B\u0439': 'c',\n '\u043D\u0435\u043F\u043E\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043D\u043D': 'n',\n '\u043D\u0435\u043F\u043E\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439': 'n',\n '\u0430\u0443\u0434\u0438\u043E': 's', // audio\n '\u0432\u0438\u0434\u0435\u043E': 'v'\n};\n\nconst map338 = {\n 'aperture card': 'ha',\n 'ark': 'nb',\n 'arkki': 'nb',\n 'audio belt': 'sb',\n 'audio cartridge': 'sg',\n 'audio cylinder': 'se',\n 'audio disc': 'sd',\n 'audio roll': 'sq',\n 'audio wire reel': 'sw',\n 'audiocassette': 'ss',\n 'audiotape reel': 'st',\n 'bildband': 'gf',\n 'bildbandsmagasin': 'gc',\n 'bl\u00E4dderblock': 'nn',\n 'card': 'no',\n 'computer card': 'ck',\n 'computer cartridge': 'cb',\n 'computer disc': 'cd',\n 'computer disc cartridge': 'ce',\n 'computer tape cartridge': 'ca',\n 'computer tape cassette': 'cf',\n 'computer tape reel': 'ch',\n 'datorbandmagasin': 'ca',\n 'datorbandspole': 'ch',\n 'datorkassett': 'cf',\n 'datorkort': 'ck',\n 'datorminnesmodul': 'cb',\n 'datorskiva': 'cd',\n 'datorskivmagasin': 'ce',\n 'dia': 'gs',\n 'diabild': 'gs',\n 'film cartridge': 'mc',\n 'film cassette': 'mf',\n 'film reel': 'mr',\n 'film roll': 'mo',\n 'filmikasetti': 'mf',\n 'filmikela': 'mr',\n 'filmiliuska': 'gd',\n 'filmirulla': 'mo',\n 'filmisilmukkakasetti': 'mc',\n 'filmkassett': 'mf',\n 'filmljudspole': 'si',\n 'filmmagasin': 'mc',\n 'filmremsa': 'gd',\n 'filmrulle': 'mo',\n 'filmslip': 'gd',\n 'filmspole': 'mr',\n 'filmstrip': 'gf',\n 'filmstrip cartridge': 'gc',\n 'flipchart': 'nn',\n 'f\u00F6nsterkort': 'ha',\n 'f\u00F6rem\u00E5l': 'nr',\n 'ikkunakortti': 'ha',\n 'kort': 'no',\n 'kortti': 'no',\n 'lehti\u00F6taulu': 'nn',\n 'ljudcylinder': 'se',\n 'ljudkassett': 'ss',\n 'ljudmagasin': 'sg',\n 'ljudrulle': 'sq',\n 'ljudskiva': 'sd',\n 'ljudslinga': 'sb',\n 'ljudspole': 'st',\n 'ljudtr\u00E5d': 'sw',\n 'microfiche': 'he',\n 'microfiche cassette': 'hf',\n 'microfilm cartridge': 'hb',\n 'microfilm cassette': 'hc',\n 'microfilm reel': 'hd',\n 'microfilm roll': 'hj',\n 'microfilm slip': 'hh',\n 'microopaque': 'hg',\n 'microscope slide': 'pp',\n 'mikrofiche': 'he',\n 'mikrofiche (ogenomskinlig)': 'hg',\n 'mikrofichekassett': 'hf',\n 'mikrofilmikasetti': 'hc',\n 'mikrofilmikela': 'hd',\n 'mikrofilmiliuska': 'hh',\n 'mikrofilmirulla': 'hj',\n 'mikrofilmisilmukkakasetti': 'hb',\n 'mikrofilmskassett': 'hc',\n 'mikrofilmsmagasin': 'hb',\n 'mikrofilmsremsa': 'hh',\n 'mikrofilmsrulle': 'hj',\n 'mikrofilmsspole': 'hd',\n 'mikrokortti': 'he',\n 'mikrokortti (l\u00E4pin\u00E4kym\u00E4t\u00F6n)': 'hg',\n 'mikrokorttikasetti': 'hf',\n 'mikroskoperingspreparat': 'pp',\n 'muistikortti': 'ck',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n': 'zu',\n 'nide': 'nc',\n 'object': 'nr',\n 'objekti': 'nr',\n 'online resource': 'cr',\n 'onlineresurs': 'cr',\n 'ospecificerad': 'zu',\n 'overhead transparency': 'gt',\n 'piirikotelo': 'cb',\n 'piirtoheitinkalvo': 'gt',\n 'preparaattilasi': 'pp',\n 'raina': 'gf',\n 'rainakasetti': 'gc',\n 'roll': 'na',\n 'rulla': 'na',\n 'rulle': 'na',\n 'sheet': 'nb',\n 'slide': 'gs',\n 'sound-track reel': 'si',\n 'stereografinen kortti': 'eh',\n 'stereografinen levy': 'es',\n 'stereografisk skiva': 'es',\n 'stereografiskt kort': 'eh',\n 'stereograph card': 'eh',\n 'stereograph disc': 'es',\n 'tietokasetti': 'cf',\n 'tietolevy': 'cd',\n 'tietolevykotelo': 'ce',\n 'tietonauhakela': 'ch',\n 'tietonauhan silmukkakasetti': 'ca',\n 'transparang': 'gt',\n 'unspecified': 'zu',\n 'verkkoaineisto': 'cr',\n 'video cartridge': 'vc',\n 'videocassette': 'vf',\n 'videodisc': 'vd',\n 'videokasetti': 'vf',\n 'videokassett': 'vf',\n 'videokela': 'vr',\n 'videolevy': 'vd',\n 'videomagasin': 'vc',\n 'videosilmukkakasetti': 'vc',\n 'videoskiva': 'vd',\n 'videospole': 'vr',\n 'videotape reel': 'vr',\n 'volume': 'nc',\n 'volym': 'nc',\n '\u00E4\u00E4nihihna': 'sb',\n '\u00E4\u00E4nikasetti': 'ss',\n '\u00E4\u00E4nikela': 'st',\n '\u00E4\u00E4nilankakela': 'sw',\n '\u00E4\u00E4nilevy': 'sd',\n '\u00E4\u00E4niraitakela': 'si',\n '\u00E4\u00E4nirulla': 'sq',\n '\u00E4\u00E4nisilmukkakasetti': 'sg',\n '\u00E4\u00E4nisylinteri': 'se'\n};\n\n// const multimediaRegexp = /multimedia/ui;\n\nexport default function () {\n\n return {\n description, validate, fix\n };\n\n function fix(record) {\n nvdebug(`FIX ${description}...`);\n const catLang = getCatalogingLanguage(record) || 'fin';\n const fields = getRelevantFields(record);\n fields.forEach(f => fixField(f, catLang));\n nvdebug(` GOT ${fields.length}...`);\n // FFS: we actually need newFields array here! Videogame, for example, might be\n // 336 ## \u2021a kaksiulotteinen liikkuva kuva \u2021b tdi \u20212 rdacontent\n // 336 ## \u2021a tietokoneohjelma \u2021b cop \u20212 rdacontent\n const res = {message: [], fix: [], valid: true};\n\n return res;\n }\n\n function validate(record) {\n nvdebug(`VALIDATE ${description}...`); // NOT READY YET\n const catLang = getCatalogingLanguage(record) || 'fin';\n const fields = getRelevantFields(record);\n if (fields.length === 0) {\n return {message: [], valid: true};\n }\n const originalStrings = fields.map(f => fieldToString(f));\n const clonedFields = fields.map(f => clone(f));\n clonedFields.forEach(f => fixField(f, catLang));\n const modifiedStrings = clonedFields.map(f => fieldToString(f));\n\n const changes = originalStrings.map((str, i) => `'${str}' => '${modifiedStrings[i]}'`);\n\n return {message: changes, valid: false};\n }\n\n\n function getA(field) {\n const as = field.subfields.filter(f => f.code === 'a');\n if (as.length === 1) {\n return as[0];\n }\n return undefined;\n }\n\n\n function mapTermToCode(term, tag) {\n nvdebug(`TERM/${tag}: '${term}'`);\n if (tag === '336' && term in map336) {\n return map336[term];\n }\n if (tag === '337' && term in map337) {\n return map337[term];\n }\n if (tag === '338' && term in map338) {\n return map338[term];\n }\n return undefined;\n }\n\n function mapFieldToCode(field) {\n const subfieldA = getA(field);\n if (subfieldA) {\n return mapTermToCode(subfieldA.value, field.tag);\n }\n return undefined;\n }\n\n function getRelevantFields(record) {\n const fields = record.get('33[678]');\n // Currently not handline $3 etc\n return fields.filter(f => f.subfields.length === 1 && mapFieldToCode(f));\n }\n\n function tagToSubfield2(tag) {\n if (tag === '336') {\n return {'code': '2', 'value': 'rdacontent'};\n }\n if (tag === '337') {\n return {'code': '2', 'value': 'rdamedia'};\n }\n if (tag === '338') {\n return {'code': '2', 'value': 'rdacarrier'};\n }\n }\n\n function fixField(field, catalogingLanguage = 'fin') {\n const subfieldA = getA(field);\n if (!subfieldA) {\n return;\n }\n const code = mapTermToCode(subfieldA.value, field.tag);\n if (!code) {\n return;\n }\n const newTerm = codeToTerm(code);\n if (!newTerm) {\n return;\n }\n\n subfieldA.value = newTerm;\n field.subfields.push({'code': 'b', 'value': code});\n field.subfields.push(tagToSubfield2(field.tag));\n\n function codeToTerm(code) {\n if (field.tag === '336') {\n return map336CodeToTerm(code, catalogingLanguage);\n }\n if (field.tag === '337') {\n return map337CodeToTerm(code, catalogingLanguage);\n }\n if (field.tag === '338') {\n return map338CodeToTerm(code, catalogingLanguage);\n }\n return undefined;\n }\n }\n\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import createDebugLogger from 'debug';\nimport clone from 'clone';\nimport {fieldToString, getCatalogingLanguage, nvdebug} from './utils.js';\nimport {map336CodeToTerm, map337CodeToTerm, map338CodeToTerm} from './field33XUtils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:fix-33X');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst description = 'Fix non-RDA 33X field(s)';\n\nconst map336 = {\n 'Bild (kartografisk ; att vidra)': 'crt',\n 'Bild (kartografisk ; r\u00F6rlig)': 'crm',\n 'Bild (kartografisk)': 'cri',\n 'Bild (r\u00F6rlig ; tredimensionell)': 'tdm',\n 'Bild (r\u00F6rlig ; tv\u00E5dimensionell)': 'tdi',\n 'Bild (still ; att vidra)': 'tci',\n 'Bild (still ; tredimensionell)': 'sti',\n 'Bild (still)': 'sti',\n 'Data': 'cod',\n 'Data (kartografinen)': 'crd',\n 'Dataset': 'cod',\n 'Dataset (kartografisk)': 'crd',\n 'Datorprogram': 'cop',\n 'Esine': 'tdf',\n 'Esine (kartografinen ; kosketeltava)': 'crn',\n 'Esine (kartografinen)': 'crf',\n 'Esine (kartogragrafinen ; kolmiulotteinen)': 'crf',\n 'Esine (kolmiulotteinen)': 'tdf',\n 'Esine (kosketeltava)': 'tcf',\n 'Flera inneh\u00E5llstyper': 'zzz',\n 'F\u00F6remal': 'tdf',\n 'F\u00F6rem\u00E5l (att vidra)': 'tcf',\n 'F\u00F6rem\u00E5l (kartografisk ; att vidra)': 'crn',\n 'F\u00F6rem\u00E5l (kartografisk ; tredimensionell)': 'crn',\n 'F\u00F6rem\u00E5l (tredimensionell)': 'tdf',\n 'Ger\u00E4usche': 'snd',\n 'Kuva': 'sti',\n 'Kuva (kartografinen ; kosketeltava)': 'crt',\n 'Kuva (kartografinen ; liikkuva)': 'crm',\n 'Kuva (kartografinen)': 'cri',\n 'Kuva (liikkuva ; kaksiulotteinen)': 'tdi',\n 'Kuva (liikkuva ; kolmiulotteinen)': 'tdm',\n 'Kuva (still ; kaksiulotteinen)': 'sti',\n 'Kuva (still ; kolmiulotteinen)': 'sti',\n 'Kuva (still ; kosketeltava)': 'tci',\n 'Kuva (still)': 'sti',\n 'Liike (kosketeltava ; notatoitu)': 'tcn',\n 'Liike (notatoitu ; kosketeltava': 'tcn',\n 'Liike (notatoitu)': 'ntv',\n 'Ljud': 'snd',\n 'Musiikki (esitetty)': 'prm',\n 'Musiikki (kosketeltava ; notatoitu)': 'tcm',\n 'Musiikki (notatoitu ; kosketeltava)': 'tcm',\n 'Musiikki (notatoitu)': 'ntm',\n 'Musik (notation ; att vidra)': 'tcm',\n 'Musik (notation)': 'ntm',\n 'Musik (performance)': 'prm',\n 'M\u00E4\u00E4rittelem\u00E4t\u00F6n': 'zzz',\n 'M\u00E4\u00E4rittelem\u00E4t\u00F6n sis\u00E4lt\u00F6tyyppi': 'zzz',\n 'Obest\u00E4md inneh\u00E5llstyp': 'zzz',\n 'Ospecificerad inneh\u00E5llstyp': 'zzz',\n 'Puhe': 'spw',\n 'R\u00F6relse (notation ; att vidra)': 'tcn',\n 'R\u00F6relse (notation)': 'ntv',\n 'Tal': 'spw',\n 'Teksti': 'txt',\n 'Teksti (kosketeltava); Text (att vidra)': 'tct',\n 'Text': 'txt',\n 'Tietokoneohjelma': 'cop',\n 'Useita sis\u00E4lt\u00F6tyyppej\u00E4': 'zzz',\n 'Vild (still ; tv\u00E5dimensionell)': 'sti',\n 'annan': 'xxx',\n 'cartographic dataset': 'crd',\n 'cartographic image': 'cri',\n 'cartographic moving image': 'crm',\n 'cartographic tactile image': 'crt',\n 'cartographic tactile three-dimensional form': 'crn',\n 'cartographic three-dimensional form': 'crf',\n 'cartographic three-dimensional tactile form': 'crn',\n 'computer dataset': 'cod',\n 'computer program': 'cop',\n 'dataset': 'cod',\n 'datorprogram': 'cop',\n 'digitaalinen data': 'cod',\n 'digitalt dataset': 'cod',\n 'esitetty musiikki': 'prm',\n 'framf\u00F6rd musik': 'prm',\n 'gesprochenes Wort': 'spw',\n 'kaksiulotteinen liikkuva kuva': 'tdi',\n 'kartografinen data': 'crd',\n 'kartografinen kolmiulotteinen muoto': 'crf',\n 'kartografinen kuva': 'cri',\n 'kartografinen liikkuva kuva': 'crm',\n 'kartografinen taktiili kolmiulotteinen muoto': 'crn',\n 'kartografinen taktiili kuva': 'crt',\n 'kartografisk bild': 'cri',\n 'kartografisk data': 'crd',\n 'kartografisk r\u00F6rlig bild': 'crm',\n 'kartografisk taktil bild': 'crt',\n 'kartografisk taktil tredimensionell form': 'crn',\n 'kartografisk tredimensionell form': 'crf',\n 'kolmiulotteinen liikkuva kuva': 'tdm',\n 'kolmiulotteinen muoto': 'tdf',\n 'liikenotaatio': 'ntv',\n 'ljud': 'snd',\n 'muu': 'xxx',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n': 'zzz',\n 'notated movement': 'ntv',\n 'notated music': 'ntm',\n 'noterad musik': 'ntm',\n 'nuottikirjoitus': 'ntm',\n 'ospecificerad': 'zzz',\n 'other': 'xxx',\n 'performed music': 'prm',\n 'puhe': 'spw',\n 'r\u00F6relsenotation': 'ntv',\n 'sounds': 'snd',\n 'spoken word': 'spw',\n 'still image': 'sti',\n 'stillbild': 'sti',\n 'stillkuva': 'sti',\n 'tactile image': 'tci',\n 'tactile notated movement': 'tcn',\n 'tactile notated music': 'tcm',\n 'tactile text': 'tct',\n 'tactile three-dimensional form': 'tcf',\n 'taktiili kolmiulotteinen muoto': 'tcf',\n 'taktiili kuva': 'tci',\n 'taktiili liikenotaatio': 'tcn',\n 'taktiili nuottikirjoitus': 'tcm',\n 'taktiili teksti': 'tct',\n 'taktil bild': 'tci',\n 'taktil musiknotation': 'tcm',\n 'taktil noterad r\u00F6relse': 'tcn',\n 'taktil text': 'tct',\n 'taktil tredimensionell form': 'tcf',\n 'tal': 'spw',\n 'teksti': 'txt',\n 'text': 'txt',\n 'texte': 'txt',\n 'texte tactile': 'tct',\n 'three-dimensional form': 'tdf',\n 'three-dimensional moving image': 'tdm',\n 'tietokoneohjelma': 'cop',\n 'tredimensionell form': 'tdf',\n 'tredimensionell r\u00F6rlig bild': 'tdm',\n 'tv\u00E5dimensionell r\u00F6rlig bild': 'tdi',\n 'two-dimensional moving image': 'tdi',\n 'unbewegtes Bild': 'sti',\n 'unspecified': 'zzz',\n '\u00C4\u00E4ni': 'snd',\n '\u00E4\u00E4ni': 'snd',\n '\u042D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u0430\u044F \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430': 'cop', // computer program\n '\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 (\u043A\u0430\u0440\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0435)': 'cri',\n '\u041C\u0443\u0437\u044B\u043A\u0430 (\u0437\u043D\u0430\u043A\u043E\u0432\u0430\u044F)': 'ntm', // notated music\n '\u041C\u0443\u0437\u044B\u043A\u0430 (\u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u0441\u043A\u0430\u044F)': 'prm', // performed music\n '\u0423\u0441\u0442\u043D\u0430\u044F \u0440\u0435\u0447\u044C': 'spw',\n '\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 (\u043D\u0435\u043F\u043E\u0434\u0432\u0438\u0436\u043D\u043E\u0435)': 'sti',\n '\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 (\u0434\u0432\u0438\u0436\u0443\u0449\u0435\u0435\u0441\u044F)': 'tdi', // 2D moving image\n '\u0422\u0435\u043A\u0441\u0442': 'txt',\n '\u0422\u0435\u043A\u0441\u0442 (\u0432\u0438\u0437\u0443\u0430\u043B\u044C\u043D\u044B\u0439)': 'txt'\n};\n\nconst map337 = {\n 'Computermedien': 'c',\n 'Mikroform': 'h',\n 'annan': 'x',\n 'audio': 's',\n 'computer': 'c',\n 'dator': 'c',\n 'datoranv\u00E4ndbar': 'c',\n 'ei v\u00E4litt\u00E4v\u00E4\u00E4 laitetta': 'n',\n 'elektroninen': 'c',\n 'elektronisk': 'c',\n 'heijastettava': 'g',\n 'ingen medietyp': 'n',\n 'k\u00E4ytett\u00E4viss\u00E4 ilman laitetta': 'n',\n 'microform': 'h',\n 'microscopic': 'p',\n 'mikroform': 'h',\n 'mikromuoto': 'h',\n 'mikroskooppinen': 'p',\n 'mikroskopisch': 'p',\n 'mikroskopisk': 'p',\n 'muu': 'x',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n': 'z',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n v\u00E4litt\u00E4v\u00E4 laite': 'z',\n 'of\u00F6rmedlad': 'n',\n 'ohne Hilfsmittel zu benutzen': 'n',\n 'omedierad': 'n',\n 'ospecificerad': 'z',\n 'ospecificerad medietyp': 'z',\n 'other': 'x',\n 'projected': 'g',\n 'projektion': 'g',\n 'projicerad': 'g',\n 'projicerbar': 'g',\n 'projizierbar': 'g',\n 'stereografinen': 'e',\n 'stereografisch': 'e',\n 'stereografisk': 'e',\n 'stereographic': 'e',\n 'tietokonek\u00E4ytt\u00F6inen': 'c',\n 'unmediated': 'n',\n 'unspecified': 'z',\n 'useita mediatyyppej\u00E4': 'z',\n 'video': 'v',\n '\u00F6vrig': 'x',\n // Cyrillic (sorted by result):\n '\u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D': 'c',\n '\u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u044B\u0439': 'c',\n '\u043D\u0435\u043F\u043E\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043D\u043D': 'n',\n '\u043D\u0435\u043F\u043E\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439': 'n',\n '\u0430\u0443\u0434\u0438\u043E': 's', // audio\n '\u0432\u0438\u0434\u0435\u043E': 'v'\n};\n\nconst map338 = {\n 'aperture card': 'ha',\n 'ark': 'nb',\n 'arkki': 'nb',\n 'audio belt': 'sb',\n 'audio cartridge': 'sg',\n 'audio cylinder': 'se',\n 'audio disc': 'sd',\n 'audio roll': 'sq',\n 'audio wire reel': 'sw',\n 'audiocassette': 'ss',\n 'audiotape reel': 'st',\n 'bildband': 'gf',\n 'bildbandsmagasin': 'gc',\n 'bl\u00E4dderblock': 'nn',\n 'card': 'no',\n 'computer card': 'ck',\n 'computer cartridge': 'cb',\n 'computer disc': 'cd',\n 'computer disc cartridge': 'ce',\n 'computer tape cartridge': 'ca',\n 'computer tape cassette': 'cf',\n 'computer tape reel': 'ch',\n 'datorbandmagasin': 'ca',\n 'datorbandspole': 'ch',\n 'datorkassett': 'cf',\n 'datorkort': 'ck',\n 'datorminnesmodul': 'cb',\n 'datorskiva': 'cd',\n 'datorskivmagasin': 'ce',\n 'dia': 'gs',\n 'diabild': 'gs',\n 'film cartridge': 'mc',\n 'film cassette': 'mf',\n 'film reel': 'mr',\n 'film roll': 'mo',\n 'filmikasetti': 'mf',\n 'filmikela': 'mr',\n 'filmiliuska': 'gd',\n 'filmirulla': 'mo',\n 'filmisilmukkakasetti': 'mc',\n 'filmkassett': 'mf',\n 'filmljudspole': 'si',\n 'filmmagasin': 'mc',\n 'filmremsa': 'gd',\n 'filmrulle': 'mo',\n 'filmslip': 'gd',\n 'filmspole': 'mr',\n 'filmstrip': 'gf',\n 'filmstrip cartridge': 'gc',\n 'flipchart': 'nn',\n 'f\u00F6nsterkort': 'ha',\n 'f\u00F6rem\u00E5l': 'nr',\n 'ikkunakortti': 'ha',\n 'kort': 'no',\n 'kortti': 'no',\n 'lehti\u00F6taulu': 'nn',\n 'ljudcylinder': 'se',\n 'ljudkassett': 'ss',\n 'ljudmagasin': 'sg',\n 'ljudrulle': 'sq',\n 'ljudskiva': 'sd',\n 'ljudslinga': 'sb',\n 'ljudspole': 'st',\n 'ljudtr\u00E5d': 'sw',\n 'microfiche': 'he',\n 'microfiche cassette': 'hf',\n 'microfilm cartridge': 'hb',\n 'microfilm cassette': 'hc',\n 'microfilm reel': 'hd',\n 'microfilm roll': 'hj',\n 'microfilm slip': 'hh',\n 'microopaque': 'hg',\n 'microscope slide': 'pp',\n 'mikrofiche': 'he',\n 'mikrofiche (ogenomskinlig)': 'hg',\n 'mikrofichekassett': 'hf',\n 'mikrofilmikasetti': 'hc',\n 'mikrofilmikela': 'hd',\n 'mikrofilmiliuska': 'hh',\n 'mikrofilmirulla': 'hj',\n 'mikrofilmisilmukkakasetti': 'hb',\n 'mikrofilmskassett': 'hc',\n 'mikrofilmsmagasin': 'hb',\n 'mikrofilmsremsa': 'hh',\n 'mikrofilmsrulle': 'hj',\n 'mikrofilmsspole': 'hd',\n 'mikrokortti': 'he',\n 'mikrokortti (l\u00E4pin\u00E4kym\u00E4t\u00F6n)': 'hg',\n 'mikrokorttikasetti': 'hf',\n 'mikroskoperingspreparat': 'pp',\n 'muistikortti': 'ck',\n 'm\u00E4\u00E4rittelem\u00E4t\u00F6n': 'zu',\n 'nide': 'nc',\n 'object': 'nr',\n 'objekti': 'nr',\n 'online resource': 'cr',\n 'onlineresurs': 'cr',\n 'ospecificerad': 'zu',\n 'overhead transparency': 'gt',\n 'piirikotelo': 'cb',\n 'piirtoheitinkalvo': 'gt',\n 'preparaattilasi': 'pp',\n 'raina': 'gf',\n 'rainakasetti': 'gc',\n 'roll': 'na',\n 'rulla': 'na',\n 'rulle': 'na',\n 'sheet': 'nb',\n 'slide': 'gs',\n 'sound-track reel': 'si',\n 'stereografinen kortti': 'eh',\n 'stereografinen levy': 'es',\n 'stereografisk skiva': 'es',\n 'stereografiskt kort': 'eh',\n 'stereograph card': 'eh',\n 'stereograph disc': 'es',\n 'tietokasetti': 'cf',\n 'tietolevy': 'cd',\n 'tietolevykotelo': 'ce',\n 'tietonauhakela': 'ch',\n 'tietonauhan silmukkakasetti': 'ca',\n 'transparang': 'gt',\n 'unspecified': 'zu',\n 'verkkoaineisto': 'cr',\n 'video cartridge': 'vc',\n 'videocassette': 'vf',\n 'videodisc': 'vd',\n 'videokasetti': 'vf',\n 'videokassett': 'vf',\n 'videokela': 'vr',\n 'videolevy': 'vd',\n 'videomagasin': 'vc',\n 'videosilmukkakasetti': 'vc',\n 'videoskiva': 'vd',\n 'videospole': 'vr',\n 'videotape reel': 'vr',\n 'volume': 'nc',\n 'volym': 'nc',\n '\u00E4\u00E4nihihna': 'sb',\n '\u00E4\u00E4nikasetti': 'ss',\n '\u00E4\u00E4nikela': 'st',\n '\u00E4\u00E4nilankakela': 'sw',\n '\u00E4\u00E4nilevy': 'sd',\n '\u00E4\u00E4niraitakela': 'si',\n '\u00E4\u00E4nirulla': 'sq',\n '\u00E4\u00E4nisilmukkakasetti': 'sg',\n '\u00E4\u00E4nisylinteri': 'se'\n};\n\n// const multimediaRegexp = /multimedia/ui;\n\n// eslint-disable-next-line max-lines-per-function\nexport default function () {\n\n return {\n description, validate, fix\n };\n\n function fix(record) {\n nvdebug(`FIX ${description}...`, debugDev);\n const catLang = getCatalogingLanguage(record) || 'fin';\n const fields = getRelevantFields(record);\n fields.forEach(f => fixField(f, catLang));\n nvdebug(` GOT ${fields.length}...`, debugDev);\n // FFS: we actually need newFields array here! Videogame, for example, might be\n // 336 ## \u2021a kaksiulotteinen liikkuva kuva \u2021b tdi \u20212 rdacontent\n // 336 ## \u2021a tietokoneohjelma \u2021b cop \u20212 rdacontent\n const res = {message: [], fix: [], valid: true};\n\n return res;\n }\n\n function validate(record) {\n nvdebug(`VALIDATE ${description}...`, debugDev); // NOT READY YET\n const catLang = getCatalogingLanguage(record) || 'fin';\n const fields = getRelevantFields(record);\n if (fields.length === 0) {\n return {message: [], valid: true};\n }\n const originalStrings = fields.map(f => fieldToString(f));\n const clonedFields = fields.map(f => clone(f));\n clonedFields.forEach(f => fixField(f, catLang));\n const modifiedStrings = clonedFields.map(f => fieldToString(f));\n\n const changes = originalStrings.map((str, i) => `'${str}' => '${modifiedStrings[i]}'`);\n\n return {message: changes, valid: false};\n }\n\n\n function getA(field) {\n const as = field.subfields.filter(f => f.code === 'a');\n if (as.length === 1) {\n return as[0];\n }\n return undefined;\n }\n\n\n function mapTermToCode(term, tag) {\n nvdebug(`TERM/${tag}: '${term}'`, debugDev);\n if (tag === '336' && term in map336) {\n return map336[term];\n }\n if (tag === '337' && term in map337) {\n return map337[term];\n }\n if (tag === '338' && term in map338) {\n return map338[term];\n }\n return undefined;\n }\n\n function mapFieldToCode(field) {\n const subfieldA = getA(field);\n if (subfieldA) {\n return mapTermToCode(subfieldA.value, field.tag);\n }\n return undefined;\n }\n\n function getRelevantFields(record) {\n const fields = record.get('33[678]');\n // Currently not handline $3 etc\n return fields.filter(f => f.subfields.length === 1 && mapFieldToCode(f));\n }\n\n function tagToSubfield2(tag) {\n if (tag === '336') {\n return {'code': '2', 'value': 'rdacontent'};\n }\n if (tag === '337') {\n return {'code': '2', 'value': 'rdamedia'};\n }\n if (tag === '338') {\n return {'code': '2', 'value': 'rdacarrier'};\n }\n }\n\n function fixField(field, catalogingLanguage = 'fin') {\n const subfieldA = getA(field);\n if (!subfieldA) {\n return;\n }\n const code = mapTermToCode(subfieldA.value, field.tag);\n if (!code) {\n return;\n }\n const newTerm = codeToTerm(code);\n if (!newTerm) {\n return;\n }\n\n subfieldA.value = newTerm;\n field.subfields.push({'code': 'b', 'value': code});\n field.subfields.push(tagToSubfield2(field.tag));\n\n function codeToTerm(code) {\n if (field.tag === '336') {\n return map336CodeToTerm(code, catalogingLanguage);\n }\n if (field.tag === '337') {\n return map337CodeToTerm(code, catalogingLanguage);\n }\n if (field.tag === '338') {\n return map338CodeToTerm(code, catalogingLanguage);\n }\n return undefined;\n }\n }\n\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": ["code"]
7
7
  }
@@ -1,3 +1,7 @@
1
+ import createDebugLogger from "debug";
2
+ import { nvdebug } from "./utils.js";
3
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:fix-country-codes");
4
+ const debugDev = debug.extend("dev");
1
5
  export default function() {
2
6
  return {
3
7
  description: "Fix deprecated country codes",
@@ -5,6 +9,7 @@ export default function() {
5
9
  fix
6
10
  };
7
11
  function fix(record) {
12
+ nvdebug(`FIX ME:`, debugDev);
8
13
  const res = { message: [], fix: [], valid: true };
9
14
  const [field008] = record.get("008");
10
15
  if (!field008) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/fix-country-codes.js"],
4
- "sourcesContent": ["// Fix country codes in 008/15-17\n//\n// This is proto. Extend later...\n//\n// Author(s): Nicholas Volk\n\n//import createDebugLogger from 'debug';\n//import {fieldToString, nvdebug} from './utils.js';\n\n\nexport default function () {\n\n return {\n description: 'Fix deprecated country codes',\n validate, fix\n };\n\n function fix(record) {\n //nvdebug(`FIX ME`);\n const res = {message: [], fix: [], valid: true};\n\n const [field008] = record.get('008');\n if (!field008) {\n return res;\n }\n\n fixCountryCode(field008);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: [], valid: true};\n\n const [field008] = record.get('008');\n\n if (!field008) {\n return res;\n }\n\n const originalCountryCode = getCountryCodeFromField008(field008);\n const modifiedCountryCode = deprecatedCountryCodeToCurrentCountryCode(originalCountryCode);\n if (originalCountryCode === modifiedCountryCode) {\n return res;\n }\n\n res.message.push(`Modify 008/15-17: '${originalCountryCode}' => '${modifiedCountryCode}'`);\n\n res.valid = false;\n return res;\n }\n\n function fixCountryCode(field008) {\n const originalCountryCode = getCountryCodeFromField008(field008);\n const modifiedCountryCode = deprecatedCountryCodeToCurrentCountryCode(originalCountryCode);\n if (originalCountryCode !== modifiedCountryCode && modifiedCountryCode.length === 3) {\n field008.value = `${field008.value.substring(0, 15)}${modifiedCountryCode}${field008.value.substring(18)}`;\n return;\n }\n }\n\n function getCountryCodeFromField008(field) {\n return field.value.substring(15, 18); // return 008/15-17\n }\n\n function deprecatedCountryCodeToCurrentCountryCode(countryCode) {\n if (countryCode === 'air') { // Armenia\n return 'ai ';\n }\n if (countryCode === 'ajr') { // Azerbaidzan\n return 'aj ';\n }\n // Australia\n if (['aca', 'qua', 'tma', 'vra', 'wea', 'xga', 'xna', 'xoa', 'xra'].includes(countryCode)) {\n return 'at ';\n }\n\n // Canada\n if (['abc', 'bcc', 'cn ', 'mbc', 'nfc', 'nkc', 'nsc', 'ntc', 'nuc', 'onc', 'pic', 'quc', 'snc', 'ykc'].includes(countryCode)) {\n return 'xxc';\n }\n // Great Britain:\n if (['enk', 'nik', 'stk', 'uik', 'uk ', 'wlk'].includes(countryCode)) {\n return 'xxk';\n }\n // United States:\n if (['aku', 'alu', 'aru', 'azu', 'cau', 'cou', 'ctu', 'dcu', 'deu', 'flu', 'gau', 'hiu', 'iau', 'idu', 'ilu', 'inu', 'kgr', 'ksu', 'kyu', 'lau', 'mau', 'mdu', 'meu', 'miu', 'mnu', 'mou', 'msu', 'mtu', 'nbu', 'ncu', 'nhu', 'nju', 'nmu', 'nvu', 'nyu', 'ohu', 'oku', 'oru', 'pau', 'riu', 'scu', 'sdu', 'tnu', 'txu', 'us ', 'utu', 'vau', 'vtu', 'wau', 'wiu', 'wvu', 'wyu'].includes(countryCode)) {\n return 'xxu';\n }\n return countryCode;\n }\n\n}\n"],
5
- "mappings": "AAUA,0BAA2B;AAEzB,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,IAAI,QAAQ;AAEnB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAE9C,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AACnC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,mBAAe,QAAQ;AAEvB,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,OAAO,KAAI;AAErC,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AAEnC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,2BAA2B,QAAQ;AAC/D,UAAM,sBAAsB,0CAA0C,mBAAmB;AACzF,QAAI,wBAAwB,qBAAqB;AAC/C,aAAO;AAAA,IACT;AAEA,QAAI,QAAQ,KAAK,sBAAsB,mBAAmB,SAAS,mBAAmB,GAAG;AAEzF,QAAI,QAAQ;AACZ,WAAO;AAAA,EACT;AAEA,WAAS,eAAe,UAAU;AAChC,UAAM,sBAAsB,2BAA2B,QAAQ;AAC/D,UAAM,sBAAsB,0CAA0C,mBAAmB;AACzF,QAAI,wBAAwB,uBAAuB,oBAAoB,WAAW,GAAG;AACnF,eAAS,QAAQ,GAAG,SAAS,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,mBAAmB,GAAG,SAAS,MAAM,UAAU,EAAE,CAAC;AACxG;AAAA,IACF;AAAA,EACF;AAEA,WAAS,2BAA2B,OAAO;AACzC,WAAO,MAAM,MAAM,UAAU,IAAI,EAAE;AAAA,EACrC;AAEA,WAAS,0CAA0C,aAAa;AAC9D,QAAI,gBAAgB,OAAO;AACzB,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,OAAO;AACzB,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AACzF,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AAC5H,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AACpE,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AACtY,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEF;",
4
+ "sourcesContent": ["// Fix country codes in 008/15-17\n//\n// This is proto. Extend later...\n//\n// Author(s): Nicholas Volk\n\nimport createDebugLogger from 'debug';\nimport {nvdebug} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:fix-country-codes');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\n\nexport default function () {\n\n return {\n description: 'Fix deprecated country codes',\n validate, fix\n };\n\n function fix(record) {\n nvdebug(`FIX ME:`, debugDev);\n const res = {message: [], fix: [], valid: true};\n\n const [field008] = record.get('008');\n if (!field008) {\n return res;\n }\n\n fixCountryCode(field008);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: [], valid: true};\n\n const [field008] = record.get('008');\n\n if (!field008) {\n return res;\n }\n\n const originalCountryCode = getCountryCodeFromField008(field008);\n const modifiedCountryCode = deprecatedCountryCodeToCurrentCountryCode(originalCountryCode);\n if (originalCountryCode === modifiedCountryCode) {\n return res;\n }\n\n res.message.push(`Modify 008/15-17: '${originalCountryCode}' => '${modifiedCountryCode}'`);\n\n res.valid = false;\n return res;\n }\n\n function fixCountryCode(field008) {\n const originalCountryCode = getCountryCodeFromField008(field008);\n const modifiedCountryCode = deprecatedCountryCodeToCurrentCountryCode(originalCountryCode);\n if (originalCountryCode !== modifiedCountryCode && modifiedCountryCode.length === 3) {\n field008.value = `${field008.value.substring(0, 15)}${modifiedCountryCode}${field008.value.substring(18)}`;\n return;\n }\n }\n\n function getCountryCodeFromField008(field) {\n return field.value.substring(15, 18); // return 008/15-17\n }\n\n function deprecatedCountryCodeToCurrentCountryCode(countryCode) {\n if (countryCode === 'air') { // Armenia\n return 'ai ';\n }\n if (countryCode === 'ajr') { // Azerbaidzan\n return 'aj ';\n }\n // Australia\n if (['aca', 'qua', 'tma', 'vra', 'wea', 'xga', 'xna', 'xoa', 'xra'].includes(countryCode)) {\n return 'at ';\n }\n\n // Canada\n if (['abc', 'bcc', 'cn ', 'mbc', 'nfc', 'nkc', 'nsc', 'ntc', 'nuc', 'onc', 'pic', 'quc', 'snc', 'ykc'].includes(countryCode)) {\n return 'xxc';\n }\n // Great Britain:\n if (['enk', 'nik', 'stk', 'uik', 'uk ', 'wlk'].includes(countryCode)) {\n return 'xxk';\n }\n // United States:\n if (['aku', 'alu', 'aru', 'azu', 'cau', 'cou', 'ctu', 'dcu', 'deu', 'flu', 'gau', 'hiu', 'iau', 'idu', 'ilu', 'inu', 'kgr', 'ksu', 'kyu', 'lau', 'mau', 'mdu', 'meu', 'miu', 'mnu', 'mou', 'msu', 'mtu', 'nbu', 'ncu', 'nhu', 'nju', 'nmu', 'nvu', 'nyu', 'ohu', 'oku', 'oru', 'pau', 'riu', 'scu', 'sdu', 'tnu', 'txu', 'us ', 'utu', 'vau', 'vtu', 'wau', 'wiu', 'wvu', 'wyu'].includes(countryCode)) {\n return 'xxu';\n }\n return countryCode;\n }\n\n}\n"],
5
+ "mappings": "AAMA,OAAO,uBAAuB;AAC9B,SAAQ,eAAc;AAEtB,MAAM,QAAQ,kBAAkB,4DAA4D;AAE5F,MAAM,WAAW,MAAM,OAAO,KAAK;AAGnC,0BAA2B;AAEzB,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACZ;AAEA,WAAS,IAAI,QAAQ;AACnB,YAAQ,WAAW,QAAQ;AAC3B,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAE9C,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AACnC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,mBAAe,QAAQ;AAEvB,WAAO;AAAA,EACT;AAEA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,OAAO,KAAI;AAErC,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AAEnC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,2BAA2B,QAAQ;AAC/D,UAAM,sBAAsB,0CAA0C,mBAAmB;AACzF,QAAI,wBAAwB,qBAAqB;AAC/C,aAAO;AAAA,IACT;AAEA,QAAI,QAAQ,KAAK,sBAAsB,mBAAmB,SAAS,mBAAmB,GAAG;AAEzF,QAAI,QAAQ;AACZ,WAAO;AAAA,EACT;AAEA,WAAS,eAAe,UAAU;AAChC,UAAM,sBAAsB,2BAA2B,QAAQ;AAC/D,UAAM,sBAAsB,0CAA0C,mBAAmB;AACzF,QAAI,wBAAwB,uBAAuB,oBAAoB,WAAW,GAAG;AACnF,eAAS,QAAQ,GAAG,SAAS,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,mBAAmB,GAAG,SAAS,MAAM,UAAU,EAAE,CAAC;AACxG;AAAA,IACF;AAAA,EACF;AAEA,WAAS,2BAA2B,OAAO;AACzC,WAAO,MAAM,MAAM,UAAU,IAAI,EAAE;AAAA,EACrC;AAEA,WAAS,0CAA0C,aAAa;AAC9D,QAAI,gBAAgB,OAAO;AACzB,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,OAAO;AACzB,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AACzF,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AAC5H,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AACpE,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,GAAG;AACtY,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,9 +1,13 @@
1
1
  import clone from "clone";
2
- import { fieldToString } from "./utils.js";
2
+ import { fieldToString, nvdebug } from "./utils.js";
3
+ import createDebugLogger from "debug";
4
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:fix-language-codes");
5
+ const debugDev = debug.extend("dev");
3
6
  const description = "Fix language codes";
4
7
  export default function() {
5
8
  return { description, validate, fix };
6
9
  function fix(record) {
10
+ nvdebug(`FIX ME`, debugDev);
7
11
  const res = { message: [], fix: [], valid: true };
8
12
  const [field008] = record.get("008");
9
13
  if (!field008) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/fix-language-codes.js"],
4
- "sourcesContent": ["import clone from 'clone';\nimport {fieldToString} from './utils.js';\n// Fix language codes in 008/35-37 and 041 (does not sync them)\n//\n// Author(s): Nicholas Volk\n\n//import createDebugLogger from 'debug';\n//import {fieldToString, nvdebug} from './utils.js';\n\nconst description = 'Fix language codes';\n\nexport default function () {\n\n return {description, validate, fix};\n\n function fix(record) {\n //nvdebug(`FIX ME`);\n const res = {message: [], fix: [], valid: true};\n\n const [field008] = record.get('008');\n if (!field008) {\n return res;\n }\n\n fixLanguageField008(field008);\n\n const f041 = record.get('041');\n f041.forEach(f => fixField041(f));\n\n return res;\n }\n\n\n function validate(record) {\n const res = {message: [], valid: true};\n\n validateField008(record, res);\n\n const f041 = record.get('041');\n\n f041.forEach(f => validateField041(f, res));\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField008(record, res) {\n const [field008] = record.get('008');\n\n if (!field008) {\n return;\n }\n\n const originalLanguage = getLanguageFromField008(field008);\n const modifiedLanguage = deprecatedLanguageToCurrentLanguage(originalLanguage);\n if (originalLanguage === modifiedLanguage) {\n return;\n }\n\n res.message.push(`Modify 008/35-37: '${originalLanguage}' => '${modifiedLanguage}'`);\n res.valid = false;\n }\n\n\n function isRelevantField041SubfieldCode(subfield) {\n return 'abdefghijkmnpqrt'.includes(subfield.code);\n }\n\n\n function validateField041(field, res) {\n\n const clonedField = clone(field);\n fixField041(clonedField);\n\n const originalString = fieldToString(field);\n const modifiedString = fieldToString(clonedField);\n\n if (originalString === modifiedString) {\n return;\n }\n const msg = `${originalString} => ${modifiedString}`;\n res.message.push(msg);\n\n }\n\n\n function fixLanguageField008(field008) {\n const originalLanguage = getLanguageFromField008(field008);\n const modifiedLanguage = deprecatedLanguageToCurrentLanguage(originalLanguage);\n if (originalLanguage !== modifiedLanguage && modifiedLanguage.length === 3) {\n field008.value = `${field008.value.substring(0, 35)}${modifiedLanguage}${field008.value.substring(38)}`;\n return;\n }\n }\n\n function fixField041(field) {\n if (field.subfields.some(sf => sf.code === '2')) {\n return;\n }\n\n field.subfields.forEach(sf => fixField041Subfield(sf));\n\n function fixField041Subfield(subfield) {\n if (!isRelevantField041SubfieldCode(subfield)) {\n return;\n }\n subfield.value = deprecatedLanguageToCurrentLanguage(subfield.value);\n }\n }\n\n function getLanguageFromField008(field) {\n return field.value.substring(35, 38); // return 008/35-37\n }\n\n function deprecatedLanguageToCurrentLanguage(language) {\n if (language === 'nno' || language === 'nob') { // Nynorsk ja bokm\u00E5l\n return 'nor'; // Norwegian\n }\n return language;\n }\n\n}\n"],
5
- "mappings": "AAAA,OAAO,WAAW;AAClB,SAAQ,qBAAoB;AAQ5B,MAAM,cAAc;AAEpB,0BAA2B;AAEzB,SAAO,EAAC,aAAa,UAAU,IAAG;AAElC,WAAS,IAAI,QAAQ;AAEnB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAE9C,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AACnC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,wBAAoB,QAAQ;AAE5B,UAAM,OAAO,OAAO,IAAI,KAAK;AAC7B,SAAK,QAAQ,OAAK,YAAY,CAAC,CAAC;AAEhC,WAAO;AAAA,EACT;AAGA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,OAAO,KAAI;AAErC,qBAAiB,QAAQ,GAAG;AAE5B,UAAM,OAAO,OAAO,IAAI,KAAK;AAE7B,SAAK,QAAQ,OAAK,iBAAiB,GAAG,GAAG,CAAC;AAE1C,QAAI,QAAQ,EAAE,IAAI,QAAQ,UAAU;AACpC,WAAO;AAAA,EACT;AAEA,WAAS,iBAAiB,QAAQ,KAAK;AACrC,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AAEnC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,mBAAmB,wBAAwB,QAAQ;AACzD,UAAM,mBAAmB,oCAAoC,gBAAgB;AAC7E,QAAI,qBAAqB,kBAAkB;AACzC;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,sBAAsB,gBAAgB,SAAS,gBAAgB,GAAG;AACnF,QAAI,QAAQ;AAAA,EACd;AAGA,WAAS,+BAA+B,UAAU;AAChD,WAAO,mBAAmB,SAAS,SAAS,IAAI;AAAA,EAClD;AAGA,WAAS,iBAAiB,OAAO,KAAK;AAEpC,UAAM,cAAc,MAAM,KAAK;AAC/B,gBAAY,WAAW;AAEvB,UAAM,iBAAiB,cAAc,KAAK;AAC1C,UAAM,iBAAiB,cAAc,WAAW;AAEhD,QAAI,mBAAmB,gBAAgB;AACrC;AAAA,IACF;AACA,UAAM,MAAM,GAAG,cAAc,OAAO,cAAc;AAClD,QAAI,QAAQ,KAAK,GAAG;AAAA,EAEtB;AAGA,WAAS,oBAAoB,UAAU;AACrC,UAAM,mBAAmB,wBAAwB,QAAQ;AACzD,UAAM,mBAAmB,oCAAoC,gBAAgB;AAC7E,QAAI,qBAAqB,oBAAoB,iBAAiB,WAAW,GAAG;AAC1E,eAAS,QAAQ,GAAG,SAAS,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,gBAAgB,GAAG,SAAS,MAAM,UAAU,EAAE,CAAC;AACrG;AAAA,IACF;AAAA,EACF;AAEA,WAAS,YAAY,OAAO;AAC1B,QAAI,MAAM,UAAU,KAAK,QAAM,GAAG,SAAS,GAAG,GAAG;AAC/C;AAAA,IACF;AAEA,UAAM,UAAU,QAAQ,QAAM,oBAAoB,EAAE,CAAC;AAErD,aAAS,oBAAoB,UAAU;AACrC,UAAI,CAAC,+BAA+B,QAAQ,GAAG;AAC7C;AAAA,MACF;AACA,eAAS,QAAQ,oCAAoC,SAAS,KAAK;AAAA,IACrE;AAAA,EACF;AAEA,WAAS,wBAAwB,OAAO;AACtC,WAAO,MAAM,MAAM,UAAU,IAAI,EAAE;AAAA,EACrC;AAEA,WAAS,oCAAoC,UAAU;AACrD,QAAI,aAAa,SAAS,aAAa,OAAO;AAC5C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEF;",
4
+ "sourcesContent": ["import clone from 'clone';\nimport {fieldToString, nvdebug} from './utils.js';\nimport createDebugLogger from 'debug';\n\n// Fix language codes in 008/35-37 and 041 (does not sync them)\n//\n// Author(s): Nicholas Volk\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:fix-language-codes');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst description = 'Fix language codes';\n\n// eslint-disable-next-line max-lines-per-function\nexport default function () {\n\n return {description, validate, fix};\n\n function fix(record) {\n nvdebug(`FIX ME`, debugDev);\n const res = {message: [], fix: [], valid: true};\n\n const [field008] = record.get('008');\n if (!field008) {\n return res;\n }\n\n fixLanguageField008(field008);\n\n const f041 = record.get('041');\n f041.forEach(f => fixField041(f));\n\n return res;\n }\n\n\n function validate(record) {\n const res = {message: [], valid: true};\n\n validateField008(record, res);\n\n const f041 = record.get('041');\n\n f041.forEach(f => validateField041(f, res));\n\n res.valid = !(res.message.length >= 1);\n return res;\n }\n\n function validateField008(record, res) {\n const [field008] = record.get('008');\n\n if (!field008) {\n return;\n }\n\n const originalLanguage = getLanguageFromField008(field008);\n const modifiedLanguage = deprecatedLanguageToCurrentLanguage(originalLanguage);\n if (originalLanguage === modifiedLanguage) {\n return;\n }\n\n res.message.push(`Modify 008/35-37: '${originalLanguage}' => '${modifiedLanguage}'`);\n res.valid = false;\n }\n\n\n function isRelevantField041SubfieldCode(subfield) {\n return 'abdefghijkmnpqrt'.includes(subfield.code);\n }\n\n\n function validateField041(field, res) {\n\n const clonedField = clone(field);\n fixField041(clonedField);\n\n const originalString = fieldToString(field);\n const modifiedString = fieldToString(clonedField);\n\n if (originalString === modifiedString) {\n return;\n }\n const msg = `${originalString} => ${modifiedString}`;\n res.message.push(msg);\n\n }\n\n\n function fixLanguageField008(field008) {\n const originalLanguage = getLanguageFromField008(field008);\n const modifiedLanguage = deprecatedLanguageToCurrentLanguage(originalLanguage);\n if (originalLanguage !== modifiedLanguage && modifiedLanguage.length === 3) {\n field008.value = `${field008.value.substring(0, 35)}${modifiedLanguage}${field008.value.substring(38)}`;\n return;\n }\n }\n\n function fixField041(field) {\n if (field.subfields.some(sf => sf.code === '2')) {\n return;\n }\n\n field.subfields.forEach(sf => fixField041Subfield(sf));\n\n function fixField041Subfield(subfield) {\n if (!isRelevantField041SubfieldCode(subfield)) {\n return;\n }\n subfield.value = deprecatedLanguageToCurrentLanguage(subfield.value);\n }\n }\n\n function getLanguageFromField008(field) {\n return field.value.substring(35, 38); // return 008/35-37\n }\n\n function deprecatedLanguageToCurrentLanguage(language) {\n if (language === 'nno' || language === 'nob') { // Nynorsk ja bokm\u00E5l\n return 'nor'; // Norwegian\n }\n return language;\n }\n\n}\n"],
5
+ "mappings": "AAAA,OAAO,WAAW;AAClB,SAAQ,eAAe,eAAc;AACrC,OAAO,uBAAuB;AAM9B,MAAM,QAAQ,kBAAkB,6DAA6D;AAE7F,MAAM,WAAW,MAAM,OAAO,KAAK;AAEnC,MAAM,cAAc;AAGpB,0BAA2B;AAEzB,SAAO,EAAC,aAAa,UAAU,IAAG;AAElC,WAAS,IAAI,QAAQ;AACnB,YAAQ,UAAU,QAAQ;AAC1B,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAI;AAE9C,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AACnC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AAEA,wBAAoB,QAAQ;AAE5B,UAAM,OAAO,OAAO,IAAI,KAAK;AAC7B,SAAK,QAAQ,OAAK,YAAY,CAAC,CAAC;AAEhC,WAAO;AAAA,EACT;AAGA,WAAS,SAAS,QAAQ;AACxB,UAAM,MAAM,EAAC,SAAS,CAAC,GAAG,OAAO,KAAI;AAErC,qBAAiB,QAAQ,GAAG;AAE5B,UAAM,OAAO,OAAO,IAAI,KAAK;AAE7B,SAAK,QAAQ,OAAK,iBAAiB,GAAG,GAAG,CAAC;AAE1C,QAAI,QAAQ,EAAE,IAAI,QAAQ,UAAU;AACpC,WAAO;AAAA,EACT;AAEA,WAAS,iBAAiB,QAAQ,KAAK;AACrC,UAAM,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK;AAEnC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,mBAAmB,wBAAwB,QAAQ;AACzD,UAAM,mBAAmB,oCAAoC,gBAAgB;AAC7E,QAAI,qBAAqB,kBAAkB;AACzC;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,sBAAsB,gBAAgB,SAAS,gBAAgB,GAAG;AACnF,QAAI,QAAQ;AAAA,EACd;AAGA,WAAS,+BAA+B,UAAU;AAChD,WAAO,mBAAmB,SAAS,SAAS,IAAI;AAAA,EAClD;AAGA,WAAS,iBAAiB,OAAO,KAAK;AAEpC,UAAM,cAAc,MAAM,KAAK;AAC/B,gBAAY,WAAW;AAEvB,UAAM,iBAAiB,cAAc,KAAK;AAC1C,UAAM,iBAAiB,cAAc,WAAW;AAEhD,QAAI,mBAAmB,gBAAgB;AACrC;AAAA,IACF;AACA,UAAM,MAAM,GAAG,cAAc,OAAO,cAAc;AAClD,QAAI,QAAQ,KAAK,GAAG;AAAA,EAEtB;AAGA,WAAS,oBAAoB,UAAU;AACrC,UAAM,mBAAmB,wBAAwB,QAAQ;AACzD,UAAM,mBAAmB,oCAAoC,gBAAgB;AAC7E,QAAI,qBAAqB,oBAAoB,iBAAiB,WAAW,GAAG;AAC1E,eAAS,QAAQ,GAAG,SAAS,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,gBAAgB,GAAG,SAAS,MAAM,UAAU,EAAE,CAAC;AACrG;AAAA,IACF;AAAA,EACF;AAEA,WAAS,YAAY,OAAO;AAC1B,QAAI,MAAM,UAAU,KAAK,QAAM,GAAG,SAAS,GAAG,GAAG;AAC/C;AAAA,IACF;AAEA,UAAM,UAAU,QAAQ,QAAM,oBAAoB,EAAE,CAAC;AAErD,aAAS,oBAAoB,UAAU;AACrC,UAAI,CAAC,+BAA+B,QAAQ,GAAG;AAC7C;AAAA,MACF;AACA,eAAS,QAAQ,oCAAoC,SAAS,KAAK;AAAA,IACrE;AAAA,EACF;AAEA,WAAS,wBAAwB,OAAO;AACtC,WAAO,MAAM,MAAM,UAAU,IAAI,EAAE;AAAA,EACrC;AAEA,WAAS,oCAAoC,UAAU;AACrD,QAAI,aAAa,SAAS,aAAa,OAAO;AAC5C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,8 @@
1
1
  import createDebugLogger from "debug";
2
2
  import clone from "clone";
3
- import { fieldToString } from "./utils.js";
3
+ import { fieldToString, nvdebug } from "./utils.js";
4
4
  const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:fix-sami-041");
5
+ const debugDev = debug.extend("dev");
5
6
  export default function() {
6
7
  const samiLanguages = ["sma", "sme", "smj", "smn", "sms"];
7
8
  const subfieldCodesUsingSmi = ["a", "d"];
@@ -12,7 +13,7 @@ export default function() {
12
13
  };
13
14
  function getRelevantSubfieldCodes(record) {
14
15
  if (record && record.leader && record.leader[6]) {
15
- debug(` LDR/06 is '${record.leader[6]}'`);
16
+ nvdebug(` LDR/06 is '${record.leader[6]}'`, debugDev);
16
17
  if (["i", "j"].includes(record.leader[6])) {
17
18
  return ["d"];
18
19
  }
@@ -21,12 +22,12 @@ export default function() {
21
22
  return ["a", "d"];
22
23
  }
23
24
  function fix(record, validateMode = false) {
24
- debug(`Start ${validateMode ? "validator" : "fixer"}`);
25
+ nvdebug(`Start ${validateMode ? "validator" : "fixer"}`, debugDev);
25
26
  const relevantSubfieldCodes = getRelevantSubfieldCodes(record);
26
- debug(` Relevant subfield codes are '${relevantSubfieldCodes.join("', '")}'`);
27
+ nvdebug(` Relevant subfield codes are '${relevantSubfieldCodes.join("', '")}'`, debugDev);
27
28
  const relevantFields = record.fields.filter((f) => isRelevantField(f, relevantSubfieldCodes)).map((f) => validateMode ? clone(f) : f);
28
29
  if (relevantFields.length === 0) {
29
- debug(` No relevant f041 fields found`);
30
+ nvdebug(` No relevant f041 fields found`, debugDev);
30
31
  if (validateMode) {
31
32
  return { message: [], valid: true };
32
33
  }
@@ -43,22 +44,22 @@ export default function() {
43
44
  function updateAndReport008() {
44
45
  const [f008] = record.get("008").map((f) => validateMode ? clone(f) : f);
45
46
  if (!f008) {
46
- debug(" WARNING: no f008 found");
47
+ nvdebug(" WARNING: no f008 found"), debugDev;
47
48
  return [];
48
49
  }
49
50
  const currLang = f008.value.substr(35, 3);
50
51
  if (!samiLanguages.includes(currLang)) {
51
- debug(` Existing 008/35-37 '${currLang}' is not a sami language. No need to update 008/35-37`);
52
+ nvdebug(` Existing 008/35-37 '${currLang}' is not a sami language. No need to update 008/35-37`, debugDev);
52
53
  return [];
53
54
  }
54
55
  const origValue = f008.value;
55
56
  const firstRelevantSubfield = relevantFields[0].subfields.find((sf) => relevantSubfieldCodes.includes(sf.code));
56
57
  if (firstRelevantSubfield.value !== "smi") {
57
- debug(` First relevant subfield is '$${firstRelevantSubfield.code} ${firstRelevantSubfield.value}'. No need to update 008/35-37`);
58
+ nvdebug(` First relevant subfield is '$${firstRelevantSubfield.code} ${firstRelevantSubfield.value}'. No need to update 008/35-37`, debugDev);
58
59
  return [];
59
60
  }
60
61
  f008.value = `${f008.value.substr(0, 35)}smi${f008.value.substr(38)}`;
61
- debug(` Update 008/35-37: '${currLang}' => 'smi'`);
62
+ nvdebug(` Update 008/35-37: '${currLang}' => 'smi'`, debugDev);
62
63
  return createReport([origValue], [f008.value]);
63
64
  }
64
65
  function processField(f) {
@@ -76,7 +77,7 @@ export default function() {
76
77
  code: currSubfield.code,
77
78
  value: "smi"
78
79
  };
79
- debug(` f041: Add '$${currSubfield.code} smi' before '${currSubfield.value}'`);
80
+ nvdebug(` f041: Add '$${currSubfield.code} smi' before '${currSubfield.value}'`, debugDev);
80
81
  return processSubfields(otherSubfields, [...outgoingSubfields, smiSubfield, currSubfield]);
81
82
  }
82
83
  function isRelevantField(f) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/fix-sami-041.js"],
4
- "sourcesContent": ["// Author(s): Nicholas Volk\n\nimport createDebugLogger from 'debug';\nimport clone from 'clone';\n\nimport {fieldToString} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:fix-sami-041');\n\n\n\nexport default function () {\n /* 'sma': etel\u00E4saame, 'sme': pohjoissaame, 'smj': luulajansaame, 'smn': inarinsaame, 'sms': koltansaame */\n const samiLanguages = ['sma', 'sme', 'smj', 'smn', 'sms'];\n const subfieldCodesUsingSmi = ['a', 'd'];\n\n return {\n description: 'Add corresponding \\'smi\\' subfield before a specific sami language subfields and update 008/35-37, if needed',\n validate, fix\n };\n\n function getRelevantSubfieldCodes(record) { // Maybe this should be an exportable utility function...\n if (record && record.leader && record.leader[6]) {\n debug(` LDR/06 is '${record.leader[6]}'`);\n // We should test this properly...\n if (['i', 'j'].includes(record.leader[6])) { // Check type of record: sound recordings use 'd'\n return ['d'];\n }\n return ['a'];\n }\n\n return ['a', 'd']; // B\u00E5de-och\n }\n\n\n function fix(record, validateMode = false) {\n debug(`Start ${validateMode ? 'validator' : 'fixer'}`);\n const relevantSubfieldCodes = getRelevantSubfieldCodes(record);\n debug(` Relevant subfield codes are '${relevantSubfieldCodes.join(\"', '\")}'`);\n const relevantFields = record.fields.filter(f => isRelevantField(f, relevantSubfieldCodes)).map(f => validateMode ? clone(f) : f); // NV! relevant fields are cloned in validation mode!\n // Nothing to do:\n if (relevantFields.length === 0) {\n debug(` No relevant f041 fields found`);\n if (validateMode) {\n return {message: [], valid: true};\n }\n return {message: [], fix: [], valid: true};\n }\n\n const relevantFieldsAsStrings = relevantFields.map(f => fieldToString(f)); // get original values\n\n relevantFields.forEach(f => processField(f, relevantSubfieldCodes));\n const modFieldsAsStrings = relevantFields.map(f => fieldToString(f));\n const report = [...updateAndReport008(), ...createReport(relevantFieldsAsStrings, modFieldsAsStrings)];\n\n if (validateMode) {\n return {'message': report, 'valid': false};\n }\n\n return {message: [], fix: report, valid: true};\n\n function updateAndReport008() { // Update 008/35-37 if necessary + report it\n const [f008] = record.get('008').map(f => validateMode ? clone(f) : f);\n\n if (!f008) {\n debug(' WARNING: no f008 found');\n return [];\n }\n const currLang = f008.value.substr(35, 3);\n if (!samiLanguages.includes(currLang)) { // NB! If original 008/35-37 was not a sami language, we don't change anything!\n debug(` Existing 008/35-37 '${currLang}' is not a sami language. No need to update 008/35-37`);\n return [];\n }\n const origValue = f008.value;\n const firstRelevantSubfield = relevantFields[0].subfields.find(sf => relevantSubfieldCodes.includes(sf.code));\n if (firstRelevantSubfield.value !== 'smi') {\n debug(` First relevant subfield is '\\$${firstRelevantSubfield.code} ${firstRelevantSubfield.value}'. No need to update 008/35-37`);\n return [];\n }\n f008.value = `${f008.value.substr(0, 35)}smi${f008.value.substr(38)}`;\n debug(` Update 008/35-37: '${currLang}' => 'smi'`);\n return createReport([origValue], [f008.value]);\n }\n\n function processField(f) {\n f.subfields = processSubfields(f.subfields, []);\n }\n\n function processSubfields(incomingSubfields, outgoingSubfields = []) {\n const [currSubfield, ...otherSubfields] = incomingSubfields;\n if (!currSubfield) {\n return outgoingSubfields;\n }\n if (!isRelevantSamiSubfield(currSubfield, [...outgoingSubfields, ...otherSubfields])) {\n return processSubfields(otherSubfields, [...outgoingSubfields, currSubfield]);\n }\n\n const smiSubfield = {\n code: currSubfield.code,\n value: 'smi'\n };\n debug(` f041: Add '\\$${currSubfield.code} smi' before '${currSubfield.value}'`);\n\n return processSubfields(otherSubfields, [...outgoingSubfields, smiSubfield, currSubfield]);\n }\n\n function isRelevantField(f) {\n if (f.tag !== '041' || !f.subfields || f.subfields.some(sf => sf.code === '2')) {\n return false;\n }\n return f.subfields.some(sf => isRelevantSamiSubfield(sf, f.subfields)); // it's ok to pass sf in f.subfields also\n }\n\n function isRelevantSamiSubfield(sf, otherSubfields) {\n // NB! preceding 'smi' is added to all $a and $d fields, regardless of the LDR/06 value! (However, copying 041$a/d -> 008/35-37 depends on LDR/06)\n if (!subfieldCodesUsingSmi.includes(sf.code) || !samiLanguages.includes(sf.value)) {\n return false;\n }\n if (otherSubfields.some(sf2 => sf2.code === sf.code && sf2.value === 'smi')) { // fail if 'smi' already exists\n return false;\n }\n //debug(` '\\${sf.code} ${sf.value}' requires preceding 'smi'`);\n return true;\n }\n }\n\n function createReport(origArray, modArray) {\n return origArray.map((entry, index) => createEntry(entry, index));\n\n function createEntry(item, index) {\n return `'${item}' => '${modArray[index]}'`;\n }\n }\n\n function validate(record) {\n return fix(record, true);\n }\n\n\n\n\n\n\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Author(s): Nicholas Volk\n\nimport createDebugLogger from 'debug';\nimport clone from 'clone';\n\nimport {fieldToString, nvdebug} from './utils.js';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:fix-sami-041');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\n\n// eslint-disable-next-line max-lines-per-function\nexport default function () {\n /* 'sma': etel\u00E4saame, 'sme': pohjoissaame, 'smj': luulajansaame, 'smn': inarinsaame, 'sms': koltansaame */\n const samiLanguages = ['sma', 'sme', 'smj', 'smn', 'sms'];\n const subfieldCodesUsingSmi = ['a', 'd'];\n\n return {\n description: 'Add corresponding \\'smi\\' subfield before a specific sami language subfields and update 008/35-37, if needed',\n validate, fix\n };\n\n function getRelevantSubfieldCodes(record) { // Maybe this should be an exportable utility function...\n if (record && record.leader && record.leader[6]) {\n nvdebug(` LDR/06 is '${record.leader[6]}'`, debugDev);\n // We should test this properly...\n if (['i', 'j'].includes(record.leader[6])) { // Check type of record: sound recordings use 'd'\n return ['d'];\n }\n return ['a'];\n }\n\n return ['a', 'd']; // B\u00E5de-och\n }\n\n\n function fix(record, validateMode = false) {\n nvdebug(`Start ${validateMode ? 'validator' : 'fixer'}`, debugDev);\n const relevantSubfieldCodes = getRelevantSubfieldCodes(record);\n nvdebug(` Relevant subfield codes are '${relevantSubfieldCodes.join(\"', '\")}'`, debugDev);\n const relevantFields = record.fields.filter(f => isRelevantField(f, relevantSubfieldCodes)).map(f => validateMode ? clone(f) : f); // NV! relevant fields are cloned in validation mode!\n // Nothing to do:\n if (relevantFields.length === 0) {\n nvdebug(` No relevant f041 fields found`, debugDev);\n if (validateMode) {\n return {message: [], valid: true};\n }\n return {message: [], fix: [], valid: true};\n }\n\n const relevantFieldsAsStrings = relevantFields.map(f => fieldToString(f)); // get original values\n\n relevantFields.forEach(f => processField(f, relevantSubfieldCodes));\n const modFieldsAsStrings = relevantFields.map(f => fieldToString(f));\n const report = [...updateAndReport008(), ...createReport(relevantFieldsAsStrings, modFieldsAsStrings)];\n\n if (validateMode) {\n return {'message': report, 'valid': false};\n }\n\n return {message: [], fix: report, valid: true};\n\n function updateAndReport008() { // Update 008/35-37 if necessary + report it\n const [f008] = record.get('008').map(f => validateMode ? clone(f) : f);\n\n if (!f008) {\n nvdebug(' WARNING: no f008 found'), debugDev;\n return [];\n }\n const currLang = f008.value.substr(35, 3);\n if (!samiLanguages.includes(currLang)) { // NB! If original 008/35-37 was not a sami language, we don't change anything!\n nvdebug(` Existing 008/35-37 '${currLang}' is not a sami language. No need to update 008/35-37`, debugDev);\n return [];\n }\n const origValue = f008.value;\n const firstRelevantSubfield = relevantFields[0].subfields.find(sf => relevantSubfieldCodes.includes(sf.code));\n if (firstRelevantSubfield.value !== 'smi') {\n nvdebug(` First relevant subfield is '\\$${firstRelevantSubfield.code} ${firstRelevantSubfield.value}'. No need to update 008/35-37`, debugDev);\n return [];\n }\n f008.value = `${f008.value.substr(0, 35)}smi${f008.value.substr(38)}`;\n nvdebug(` Update 008/35-37: '${currLang}' => 'smi'`, debugDev);\n return createReport([origValue], [f008.value]);\n }\n\n function processField(f) {\n f.subfields = processSubfields(f.subfields, []);\n }\n\n function processSubfields(incomingSubfields, outgoingSubfields = []) {\n const [currSubfield, ...otherSubfields] = incomingSubfields;\n if (!currSubfield) {\n return outgoingSubfields;\n }\n if (!isRelevantSamiSubfield(currSubfield, [...outgoingSubfields, ...otherSubfields])) {\n return processSubfields(otherSubfields, [...outgoingSubfields, currSubfield]);\n }\n\n const smiSubfield = {\n code: currSubfield.code,\n value: 'smi'\n };\n nvdebug(` f041: Add '\\$${currSubfield.code} smi' before '${currSubfield.value}'`, debugDev);\n\n return processSubfields(otherSubfields, [...outgoingSubfields, smiSubfield, currSubfield]);\n }\n\n function isRelevantField(f) {\n if (f.tag !== '041' || !f.subfields || f.subfields.some(sf => sf.code === '2')) {\n return false;\n }\n return f.subfields.some(sf => isRelevantSamiSubfield(sf, f.subfields)); // it's ok to pass sf in f.subfields also\n }\n\n function isRelevantSamiSubfield(sf, otherSubfields) {\n // NB! preceding 'smi' is added to all $a and $d fields, regardless of the LDR/06 value! (However, copying 041$a/d -> 008/35-37 depends on LDR/06)\n if (!subfieldCodesUsingSmi.includes(sf.code) || !samiLanguages.includes(sf.value)) {\n return false;\n }\n if (otherSubfields.some(sf2 => sf2.code === sf.code && sf2.value === 'smi')) { // fail if 'smi' already exists\n return false;\n }\n //debug(` '\\${sf.code} ${sf.value}' requires preceding 'smi'`);\n return true;\n }\n }\n\n function createReport(origArray, modArray) {\n return origArray.map((entry, index) => createEntry(entry, index));\n\n function createEntry(item, index) {\n return `'${item}' => '${modArray[index]}'`;\n }\n }\n\n function validate(record) {\n return fix(record, true);\n }\n\n\n\n\n\n\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,7 @@
1
- import { fieldToString } from "./utils.js";
1
+ import createDebugLogger from "debug";
2
+ import { fieldToString, nvdebug } from "./utils.js";
3
+ const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:indicator-fixes");
4
+ const debugData = debug.extend("data");
2
5
  export default function() {
3
6
  return {
4
7
  description: "Normalizes indicator values",
@@ -17,6 +20,7 @@ export default function() {
17
20
  return res;
18
21
  }
19
22
  function validateRecord(record, res) {
23
+ nvdebug(record, debugData);
20
24
  const clonedFields = JSON.parse(JSON.stringify(record.fields));
21
25
  recordNormalizeIndicators(record);
22
26
  record.fields.forEach((field, index) => compareFields(field, index));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/indicator-fixes.js"],
4
- "sourcesContent": ["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n//import createDebugLogger from 'debug';\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:normalizeIdentifiers');\n\nimport {fieldToString} from './utils.js';\n\n\nexport default function () {\n\n return {\n description: 'Normalizes indicator values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n recordNormalizeIndicators(record);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n validateRecord(record, res);\n\n res.valid = res.message.length < 1;\n return res;\n }\n\n\n function validateRecord(record, res) {\n //nvdebug(record);\n const clonedFields = JSON.parse(JSON.stringify(record.fields));\n recordNormalizeIndicators(record);\n\n record.fields.forEach((field, index) => compareFields(field, index));\n\n function compareFields(field, index) {\n const origFieldAsString = fieldToString(clonedFields[index]);\n //const clonedFieldAsString = fieldToString(field);\n if (clonedFields[index].ind1 !== field.ind1) {\n //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);\n }\n if (clonedFields[index].ind2 !== field.ind2) {\n //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`);\n res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);\n }\n }\n // Validator should not change the original record:\n record.fields = clonedFields;\n return;\n }\n}\n\n\nconst ind1NonFilingChars = ['130', '630', '730', '740'];\nconst ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];\n\nfunction hasNonFilingIndicator1(field) {\n return ind1NonFilingChars.includes(field.tag);\n}\n\nfunction modifiableIndicatorValue(value) {\n // If field contains a legit-looking value, don't try to modify it here...\n return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);\n}\n\nfunction hasNonFilingIndicator2(field) {\n return ind2NonFilingChars.includes(field.tag);\n}\n\nfunction valueBeginsWithDeterminer(value, cands) {\n return cands.find(cand => value.substring(0, cand.length) === cand);\n}\n\nfunction determineNonFilingIndicatorValue(field, languages = undefined) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (!subfieldA) {\n // nvdebug(' Subfield $a miss!');\n return;\n }\n\n const name = subfieldA.value.toLowerCase();\n\n if (languages.includes('eng')) {\n const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('fre')) {\n const match = valueBeginsWithDeterminer(name, ['l\\'', 'le ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('ger')) {\n const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('swe')) {\n const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {\n return '4';\n }\n }\n\n // Fallback-ish: try to guess even without languages:\n const match = valueBeginsWithDeterminer(name, ['the ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) { // Skip \"a b c\", \"a la carte\"...\n return '2';\n }\n\n return '0';\n}\n\nfunction normalizeNonFilingIndicator1(field, languages = []) {\n if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {\n return;\n }\n\n field.ind1 = determineNonFilingIndicatorValue(field, languages);\n}\n\nfunction normalizeNonFilingIndicator2(field, languages = []) {\n if (!hasNonFilingIndicator2(field) || !modifiableIndicatorValue(field.ind2)) {\n return;\n }\n\n field.ind2 = determineNonFilingIndicatorValue(field, languages);\n}\n\nconst fiktiivisenAineistonLisaluokatFI = ['El\u00E4imet', 'Erotiikka', 'Er\u00E4', 'Fantasia', 'Historia', 'Huumori', 'J\u00E4nnitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];\n\nfunction containsFiktiivisenAineistonLisaluokka(field) {\n // Should we check Swedish versions as well?\n return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));\n}\n\nfunction normalize084Indicator1(field) {\n if (field.tag !== '084') {\n return;\n }\n\n // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka\n if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {\n field.ind1 = '9';\n return;\n }\n}\n\nfunction normalize245Indicator1(field, record) {\n if (field.tag !== '245') {\n return;\n }\n const field1XX = record.get('^1..$');\n field.ind1 = field1XX.length === 0 ? '0' : '1';\n}\n\nfunction noDisplayConstantGenerated520Indicator1(field) {\n if (field.tag !== '520') {\n return;\n }\n const as = field.subfields.filter(sf => sf.code === 'a');\n // Set ind1=8 \"no display constant generated\" fro certain values (part of MELKEHITYS-2579):\n if (as.length === 1 && ['Abstract.', 'Abstrakt.', 'Abstrakti.', 'Abstract.', 'English Summary.', 'Sammandrag.', 'Tiivistelm\u00E4.'].includes(field.subfields[0].value)) {\n field.ind1 = '8';\n }\n\n}\n\nfunction normalize776Indicator2(field) {\n if (field.tag !== '776') {\n return;\n }\n // If subfield $i exists, ind2 must me '8'\n if (field.subfields.some(sf => sf.code === 'i')) {\n field.ind2 = '8';\n return;\n }\n}\n\n\nfunction recordNormalize490(record) {\n const fields490 = record.get('^490$');\n const fields8XX = record.get('^(?:800|810|811|830)$');\n\n if (fields490.length === 0) {\n return;\n }\n if (fields490.length <= fields8XX.length) {\n // Trace found for each field 490:\n fields490.forEach(f => {\n f.ind1 = '1';\n });\n return;\n }\n if (fields8XX.length === 0) { // Fields 490 are always untraced (no traces found)\n fields490.forEach(f => {\n f.ind1 = '0';\n });\n return;\n }\n // For other combinations we just can't be sure, so leave them as they are.\n}\n\n\nfunction getLanguages(record) {\n const langFields = record.get('^041$');\n\n if (langFields.length === 0) {\n return [];\n }\n\n return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);\n\n function isRelevantSubfield(subfield) {\n if (!['a', 'd', 'h'].includes(subfield.code)) {\n return false;\n }\n if (subfield.value.length !== 3) {\n return false;\n }\n // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.\n return true;\n }\n\n}\n\nfunction translated041Indicator1(field){\n if (field.tag !== '041' || !field.subfields) {\n return;\n }\n if (field.ind1 !== '1' && field.subfields.some(sf => ['h', 'k', 'm', 'n'].includes(sf.code))) {\n field.ind1 = '1';\n return;\n }\n\n}\n\nfunction recordNormalizeIndicators(record) {\n recordNormalize490(record);\n\n // Language is used to handle non-filing indicators\n const languages = getLanguages(record);\n\n record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages));\n\n}\n\nfunction fieldNormalizeIndicators(field, record, languages) {\n translated041Indicator1(field);\n normalize084Indicator1(field);\n normalize245Indicator1(field, record);\n noDisplayConstantGenerated520Indicator1(field);\n normalizeNonFilingIndicator1(field, languages);\n normalizeNonFilingIndicator2(field, languages);\n normalize776Indicator2(field);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Relocated from melinda-marc-record-merge-reducers (and renamed)\n\nimport createDebugLogger from 'debug';\nimport {fieldToString, nvdebug} from './utils.js';\n\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:indicator-fixes');\nconst debugData = debug.extend('data');\n//const debugDev = debug.extend('dev');\n\nexport default function () {\n\n return {\n description: 'Normalizes indicator values',\n validate, fix\n };\n\n function fix(record) {\n const res = {message: [], fix: [], valid: true};\n\n recordNormalizeIndicators(record);\n\n return res;\n }\n\n function validate(record) {\n const res = {message: []};\n\n validateRecord(record, res);\n\n res.valid = res.message.length < 1;\n return res;\n }\n\n\n function validateRecord(record, res) {\n nvdebug(record, debugData);\n const clonedFields = JSON.parse(JSON.stringify(record.fields));\n recordNormalizeIndicators(record);\n\n record.fields.forEach((field, index) => compareFields(field, index));\n\n function compareFields(field, index) {\n const origFieldAsString = fieldToString(clonedFields[index]);\n //const clonedFieldAsString = fieldToString(field);\n if (clonedFields[index].ind1 !== field.ind1) {\n //nvdebug(`FIX IND1: '${clonedFields[index].ind1}' => '${field.ind1}': ${clonedFieldAsString}`, debugDev);\n res.message.push(`Expected IND1 for '${origFieldAsString}' is '${field.ind1}'`);\n }\n if (clonedFields[index].ind2 !== field.ind2) {\n //nvdebug(`FIX IND2: '${clonedFields[index].ind2}' => '${field.ind2}': ${clonedFieldAsString}`, debugDev);\n res.message.push(`Expected IND2 for '${origFieldAsString}' is '${field.ind2}'`);\n }\n }\n // Validator should not change the original record:\n record.fields = clonedFields;\n return;\n }\n}\n\n\nconst ind1NonFilingChars = ['130', '630', '730', '740'];\nconst ind2NonFilingChars = ['222', '240', '242', '243', '245', '830'];\n\nfunction hasNonFilingIndicator1(field) {\n return ind1NonFilingChars.includes(field.tag);\n}\n\nfunction modifiableIndicatorValue(value) {\n // If field contains a legit-looking value, don't try to modify it here...\n return !['9', '8', '7', '6', '5', '4', '3', '2', '1'].includes(value);\n}\n\nfunction hasNonFilingIndicator2(field) {\n return ind2NonFilingChars.includes(field.tag);\n}\n\nfunction valueBeginsWithDeterminer(value, cands) {\n return cands.find(cand => value.substring(0, cand.length) === cand);\n}\n\nfunction determineNonFilingIndicatorValue(field, languages = undefined) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (!subfieldA) {\n // nvdebug(' Subfield $a miss!', debugDev);\n return;\n }\n\n const name = subfieldA.value.toLowerCase();\n\n if (languages.includes('eng')) {\n const match = valueBeginsWithDeterminer(name, ['a ', 'an ', 'the ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('fre')) {\n const match = valueBeginsWithDeterminer(name, ['l\\'', 'le ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('ger')) {\n const match = valueBeginsWithDeterminer(name, ['das ', 'der ', 'die ']);\n if (match) {\n return `${match.length}`;\n }\n }\n\n if (languages.includes('swe')) {\n const match = valueBeginsWithDeterminer(name, ['en ', 'ett ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^de[nt] /u) && !name.match(/^de[nt] som /u)) {\n return '4';\n }\n }\n\n // Fallback-ish: try to guess even without languages:\n const match = valueBeginsWithDeterminer(name, ['the ']);\n if (match) {\n return `${match.length}`;\n }\n if (name.match(/^a /u) && !languages.includes('hun') && !name.match(/^a (?:b |la )/u)) { // Skip \"a b c\", \"a la carte\"...\n return '2';\n }\n\n return '0';\n}\n\nfunction normalizeNonFilingIndicator1(field, languages = []) {\n if (!hasNonFilingIndicator1(field) || !modifiableIndicatorValue(field.ind1)) {\n return;\n }\n\n field.ind1 = determineNonFilingIndicatorValue(field, languages);\n}\n\nfunction normalizeNonFilingIndicator2(field, languages = []) {\n if (!hasNonFilingIndicator2(field) || !modifiableIndicatorValue(field.ind2)) {\n return;\n }\n\n field.ind2 = determineNonFilingIndicatorValue(field, languages);\n}\n\nconst fiktiivisenAineistonLisaluokatFI = ['El\u00E4imet', 'Erotiikka', 'Er\u00E4', 'Fantasia', 'Historia', 'Huumori', 'J\u00E4nnitys', 'Kauhu', 'Novellit', 'Romantiikka', 'Scifi', 'Sota', 'Urheilu', 'Uskonto'];\n\nfunction containsFiktiivisenAineistonLisaluokka(field) {\n // Should we check Swedish versions as well?\n return field.subfields.some(sf => sf.code === 'a' && fiktiivisenAineistonLisaluokatFI.includes(sf.value));\n}\n\nfunction normalize084Indicator1(field) {\n if (field.tag !== '084') {\n return;\n }\n\n // https://marc21.kansalliskirjasto.fi/bib/05X-08X.htm#084 and https://finto.fi/ykl/fi/page/fiktioluokka\n if (field.ind1 !== '9' && containsFiktiivisenAineistonLisaluokka(field) && field.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')) {\n field.ind1 = '9';\n return;\n }\n}\n\nfunction normalize245Indicator1(field, record) {\n if (field.tag !== '245') {\n return;\n }\n const field1XX = record.get('^1..$');\n field.ind1 = field1XX.length === 0 ? '0' : '1';\n}\n\nfunction noDisplayConstantGenerated520Indicator1(field) {\n if (field.tag !== '520') {\n return;\n }\n const as = field.subfields.filter(sf => sf.code === 'a');\n // Set ind1=8 \"no display constant generated\" fro certain values (part of MELKEHITYS-2579):\n if (as.length === 1 && ['Abstract.', 'Abstrakt.', 'Abstrakti.', 'Abstract.', 'English Summary.', 'Sammandrag.', 'Tiivistelm\u00E4.'].includes(field.subfields[0].value)) {\n field.ind1 = '8';\n }\n\n}\n\nfunction normalize776Indicator2(field) {\n if (field.tag !== '776') {\n return;\n }\n // If subfield $i exists, ind2 must me '8'\n if (field.subfields.some(sf => sf.code === 'i')) {\n field.ind2 = '8';\n return;\n }\n}\n\n\nfunction recordNormalize490(record) {\n const fields490 = record.get('^490$');\n const fields8XX = record.get('^(?:800|810|811|830)$');\n\n if (fields490.length === 0) {\n return;\n }\n if (fields490.length <= fields8XX.length) {\n // Trace found for each field 490:\n fields490.forEach(f => {\n f.ind1 = '1';\n });\n return;\n }\n if (fields8XX.length === 0) { // Fields 490 are always untraced (no traces found)\n fields490.forEach(f => {\n f.ind1 = '0';\n });\n return;\n }\n // For other combinations we just can't be sure, so leave them as they are.\n}\n\n\nfunction getLanguages(record) {\n const langFields = record.get('^041$');\n\n if (langFields.length === 0) {\n return [];\n }\n\n return langFields[0].subfields.filter(sf => isRelevantSubfield(sf)).map(subfield => subfield.value);\n\n function isRelevantSubfield(subfield) {\n if (!['a', 'd', 'h'].includes(subfield.code)) {\n return false;\n }\n if (subfield.value.length !== 3) {\n return false;\n }\n // We could require /^[a-z][a-z][a-z]$/ etc as well, but it's not really that relevant.\n return true;\n }\n\n}\n\nfunction translated041Indicator1(field){\n if (field.tag !== '041' || !field.subfields) {\n return;\n }\n if (field.ind1 !== '1' && field.subfields.some(sf => ['h', 'k', 'm', 'n'].includes(sf.code))) {\n field.ind1 = '1';\n return;\n }\n\n}\n\nfunction recordNormalizeIndicators(record) {\n recordNormalize490(record);\n\n // Language is used to handle non-filing indicators\n const languages = getLanguages(record);\n\n record.fields.forEach(field => fieldNormalizeIndicators(field, record, languages));\n\n}\n\nfunction fieldNormalizeIndicators(field, record, languages) {\n translated041Indicator1(field);\n normalize084Indicator1(field);\n normalize245Indicator1(field, record);\n noDisplayConstantGenerated520Indicator1(field);\n normalizeNonFilingIndicator1(field, languages);\n normalizeNonFilingIndicator2(field, languages);\n normalize776Indicator2(field);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["match"]
7
7
  }
@@ -168,7 +168,7 @@ function getUnbalancedPairedSubfieldCode(field1, field2) {
168
168
  }
169
169
  const pairable = pairableIdentifier(field1, field2, "(FIN11)");
170
170
  const subfieldString = pairable ? removeNameRelatedSubfieldCodes(fullSubfieldString, field1.tag) : fullSubfieldString;
171
- debug(`CHECK ${pairable ? "PAIRABLE " : ""}${field1.tag} PAIRS: '${fullSubfieldString}' => '${subfieldString}'`);
171
+ nvdebug(`CHECK ${pairable ? "PAIRABLE " : ""}${field1.tag} PAIRS: '${fullSubfieldString}' => '${subfieldString}'`, debugDev);
172
172
  if (subfieldString === "") {
173
173
  return false;
174
174
  }
@@ -176,7 +176,7 @@ function getUnbalancedPairedSubfieldCode(field1, field2) {
176
176
  return subfieldArray.find((sfcode) => fieldHasNSubfields(field1, sfcode) !== fieldHasNSubfields(field2, sfcode));
177
177
  }
178
178
  function syntacticallyMergablePair(baseField, sourceField, config) {
179
- nvdebug("CHECK SYNTAX");
179
+ nvdebug("CHECK SYNTAX", debugDev);
180
180
  if (!mergableIndicator1(baseField, sourceField, config)) {
181
181
  nvdebug(`non-mergable (reason: indicator1): ${JSON.stringify(config)}`, debugDev);
182
182
  return false;
@@ -240,7 +240,7 @@ function removeNameRelatedSubfieldCodes(codestring, tag) {
240
240
  }
241
241
  function pairableIdentifier(field1, field2, prefix) {
242
242
  const normalizedPrefix = prefix;
243
- nvdebug(`PREF '${prefix}' => '${normalizedPrefix}'`);
243
+ nvdebug(`PREF '${prefix}' => '${normalizedPrefix}'`, debugDev);
244
244
  const prefixLength = normalizedPrefix.length;
245
245
  const identifiers1 = getIdentifiers(field1);
246
246
  if (identifiers1.length !== 1) {
@@ -287,8 +287,8 @@ function pairableValueInArray(tag, subfieldCode, val, arr) {
287
287
  return arr.some((val2) => pairableValue(tag, subfieldCode, val, val2));
288
288
  }
289
289
  function tightSubfieldMatch(field1, field2, subfieldCode, mustHave = false) {
290
- nvdebug(`${subfieldCode} F1: ${fieldToString(field1)}`);
291
- nvdebug(`${subfieldCode} F2: ${fieldToString(field2)}`);
290
+ nvdebug(`${subfieldCode} F1: ${fieldToString(field1)}`, debugDev);
291
+ nvdebug(`${subfieldCode} F2: ${fieldToString(field2)}`, debugDev);
292
292
  const values1 = getRelevantSubfieldValues(field1, subfieldCode);
293
293
  const values2 = getRelevantSubfieldValues(field2, subfieldCode);
294
294
  if (!mustHave) {
@@ -301,7 +301,7 @@ function tightSubfieldMatch(field1, field2, subfieldCode, mustHave = false) {
301
301
  }
302
302
  nvdebug(`Compare $${subfieldCode} contents:
303
303
  '${values1.join("'\n '")}' vs
304
- '${values2.join("'\n '")}'`);
304
+ '${values2.join("'\n '")}'`, debugDev);
305
305
  return values1.every((v) => pairableValueInArray(field1.tag, subfieldCode, v, values2)) && values2.every((v) => pairableValueInArray(field1.tag, subfieldCode, v, values1));
306
306
  }
307
307
  function looseSubfieldMatch(field1, field2, subfieldCode) {