@natlibfi/marc-record-validators-melinda 11.6.7 → 12.0.0-alpha.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.
- package/.github/workflows/melinda-node-tests.yml +1 -1
- package/dist/access-rights.js +63 -91
- package/dist/access-rights.js.map +7 -1
- package/dist/access-rights.test.js +137 -0
- package/dist/access-rights.test.js.map +7 -0
- package/dist/addMissingField041.js +21 -53
- package/dist/addMissingField041.js.map +7 -1
- package/dist/addMissingField041.test.js +39 -0
- package/dist/addMissingField041.test.js.map +7 -0
- package/dist/addMissingField336.js +99 -191
- package/dist/addMissingField336.js.map +7 -1
- package/dist/addMissingField336.test.js +39 -0
- package/dist/addMissingField336.test.js.map +7 -0
- package/dist/addMissingField337.js +63 -132
- package/dist/addMissingField337.js.map +7 -1
- package/dist/addMissingField337.test.js +39 -0
- package/dist/addMissingField337.test.js.map +7 -0
- package/dist/addMissingField338.js +147 -253
- package/dist/addMissingField338.js.map +7 -1
- package/dist/addMissingField338.test.js +39 -0
- package/dist/addMissingField338.test.js.map +7 -0
- package/dist/cyrillux-usemarcon-replacement.js +119 -272
- package/dist/cyrillux-usemarcon-replacement.js.map +7 -1
- package/dist/cyrillux-usemarcon-replacement.test.js +46 -0
- package/dist/cyrillux-usemarcon-replacement.test.js.map +7 -0
- package/dist/cyrillux.js +119 -223
- package/dist/cyrillux.js.map +7 -1
- package/dist/cyrillux.test.js +39 -0
- package/dist/cyrillux.test.js.map +7 -0
- package/dist/disambiguateSeriesStatements.js +40 -81
- package/dist/disambiguateSeriesStatements.js.map +7 -1
- package/dist/disambiguateSeriesStatements.test.js +44 -0
- package/dist/disambiguateSeriesStatements.test.js.map +7 -0
- package/dist/double-commas.js +7 -14
- package/dist/double-commas.js.map +7 -1
- package/dist/double-commas.test.js +48 -0
- package/dist/double-commas.test.js.map +7 -0
- package/dist/duplicates-ind1.js +10 -31
- package/dist/duplicates-ind1.js.map +7 -1
- package/dist/duplicates-ind1.test.js +40 -0
- package/dist/duplicates-ind1.test.js.map +7 -0
- package/dist/empty-fields.js +10 -22
- package/dist/empty-fields.js.map +7 -1
- package/dist/empty-fields.test.js +129 -0
- package/dist/empty-fields.test.js.map +7 -0
- package/dist/ending-punctuation-conf.js +871 -769
- package/dist/ending-punctuation-conf.js.map +7 -1
- package/dist/ending-punctuation.js +84 -167
- package/dist/ending-punctuation.js.map +7 -1
- package/dist/ending-punctuation.test.js +2290 -0
- package/dist/ending-punctuation.test.js.map +7 -0
- package/dist/ending-whitespace.js +10 -35
- package/dist/ending-whitespace.js.map +7 -1
- package/dist/ending-whitespace.test.js +38 -0
- package/dist/ending-whitespace.test.js.map +7 -0
- package/dist/field-008-18-34-character-groups.js +40 -125
- package/dist/field-008-18-34-character-groups.js.map +7 -1
- package/dist/field-008-18-34-character-groups.test.js +45 -0
- package/dist/field-008-18-34-character-groups.test.js.map +7 -0
- package/dist/field-505-separators.js +19 -39
- package/dist/field-505-separators.js.map +7 -1
- package/dist/field-505-separators.test.js +45 -0
- package/dist/field-505-separators.test.js.map +7 -0
- package/dist/field-521-fix.js +19 -47
- package/dist/field-521-fix.js.map +7 -1
- package/dist/field-521-fix.test.js +44 -0
- package/dist/field-521-fix.test.js.map +7 -0
- package/dist/field-exclusion.js +37 -91
- package/dist/field-exclusion.js.map +7 -1
- package/dist/field-exclusion.test.js +821 -0
- package/dist/field-exclusion.test.js.map +7 -0
- package/dist/field-structure.js +52 -104
- package/dist/field-structure.js.map +7 -1
- package/dist/field-structure.test.js +587 -0
- package/dist/field-structure.test.js.map +7 -0
- package/dist/field33XUtils.js +119 -503
- package/dist/field33XUtils.js.map +7 -1
- package/dist/fields-present.js +11 -23
- package/dist/fields-present.js.map +7 -1
- package/dist/fields-present.test.js +95 -0
- package/dist/fields-present.test.js.map +7 -0
- package/dist/fix-33X.js +393 -431
- package/dist/fix-33X.js.map +7 -1
- package/dist/fix-33X.test.js +39 -0
- package/dist/fix-33X.test.js.map +7 -0
- package/dist/fix-country-codes.js +20 -50
- package/dist/fix-country-codes.js.map +7 -1
- package/dist/fix-country-codes.test.js +44 -0
- package/dist/fix-country-codes.test.js.map +7 -0
- package/dist/fix-language-codes.js +23 -53
- package/dist/fix-language-codes.js.map +7 -1
- package/dist/fix-language-codes.test.js +38 -0
- package/dist/fix-language-codes.test.js.map +7 -0
- package/dist/fixRelatorTerms.js +82 -209
- package/dist/fixRelatorTerms.js.map +7 -1
- package/dist/fixRelatorTerms.test.js +44 -0
- package/dist/fixRelatorTerms.test.js.map +7 -0
- package/dist/fixed-fields.js +21 -30
- package/dist/fixed-fields.js.map +7 -1
- package/dist/fixed-fields.test.js +87 -0
- package/dist/fixed-fields.test.js.map +7 -0
- package/dist/identical-fields.js +8 -24
- package/dist/identical-fields.js.map +7 -1
- package/dist/identical-fields.test.js +119 -0
- package/dist/identical-fields.test.js.map +7 -0
- package/dist/index.js +119 -413
- package/dist/index.js.map +7 -1
- package/dist/indicator-fixes.js +57 -95
- package/dist/indicator-fixes.js.map +7 -1
- package/dist/indicator-fixes.test.js +42 -0
- package/dist/indicator-fixes.test.js.map +7 -0
- package/dist/isbn-issn.js +66 -126
- package/dist/isbn-issn.js.map +7 -1
- package/dist/isbn-issn.test.js +398 -0
- package/dist/isbn-issn.test.js.map +7 -0
- package/dist/item-language.js +32 -65
- package/dist/item-language.js.map +7 -1
- package/dist/item-language.test.js +322 -0
- package/dist/item-language.test.js.map +7 -0
- package/dist/melindaCustomMergeFields.js +5182 -11233
- package/dist/melindaCustomMergeFields.js.map +7 -1
- package/dist/merge-fields/controlSubfields.js +75 -142
- package/dist/merge-fields/controlSubfields.js.map +7 -1
- package/dist/merge-fields/counterpartField.js +182 -379
- package/dist/merge-fields/counterpartField.js.map +7 -1
- package/dist/merge-fields/index.js +15 -49
- package/dist/merge-fields/index.js.map +7 -1
- package/dist/merge-fields/mergableIndicator.js +18 -51
- package/dist/merge-fields/mergableIndicator.js.map +7 -1
- package/dist/merge-fields/mergableTag.js +78 -30
- package/dist/merge-fields/mergableTag.js.map +7 -1
- package/dist/merge-fields/mergeConfig.js +66 -171
- package/dist/merge-fields/mergeConfig.js.map +7 -1
- package/dist/merge-fields/mergeConstraints.js +323 -1214
- package/dist/merge-fields/mergeConstraints.js.map +7 -1
- package/dist/merge-fields/mergeField.js +47 -111
- package/dist/merge-fields/mergeField.js.map +7 -1
- package/dist/merge-fields/mergeIndicator.js +64 -118
- package/dist/merge-fields/mergeIndicator.js.map +7 -1
- package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
- package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
- package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
- package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
- package/dist/merge-fields/mergeSubfield.js +47 -95
- package/dist/merge-fields/mergeSubfield.js.map +7 -1
- package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
- package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
- package/dist/merge-fields/worldKnowledge.js +15 -40
- package/dist/merge-fields/worldKnowledge.js.map +7 -1
- package/dist/merge-fields.test.js +44 -0
- package/dist/merge-fields.test.js.map +7 -0
- package/dist/mergeField500Lisapainokset.js +28 -57
- package/dist/mergeField500Lisapainokset.js.map +7 -1
- package/dist/mergeField500Lisapainokset.test.js +44 -0
- package/dist/mergeField500Lisapainokset.test.js.map +7 -0
- package/dist/mergeRelatorTermFields.js +33 -69
- package/dist/mergeRelatorTermFields.js.map +7 -1
- package/dist/mergeRelatorTermFields.test.js +44 -0
- package/dist/mergeRelatorTermFields.test.js.map +7 -0
- package/dist/modernize-502.js +23 -55
- package/dist/modernize-502.js.map +7 -1
- package/dist/modernize-502.test.js +38 -0
- package/dist/modernize-502.test.js.map +7 -0
- package/dist/multiple-subfield-0.js +23 -48
- package/dist/multiple-subfield-0.js.map +7 -1
- package/dist/multiple-subfield-0.test.js +44 -0
- package/dist/multiple-subfield-0.test.js.map +7 -0
- package/dist/non-breaking-space.js +11 -32
- package/dist/non-breaking-space.js.map +7 -1
- package/dist/non-breaking-space.test.js +38 -0
- package/dist/non-breaking-space.test.js.map +7 -0
- package/dist/normalize-dashes.js +18 -37
- package/dist/normalize-dashes.js.map +7 -1
- package/dist/normalize-dashes.test.js +44 -0
- package/dist/normalize-dashes.test.js.map +7 -0
- package/dist/normalize-identifiers.js +54 -140
- package/dist/normalize-identifiers.js.map +7 -1
- package/dist/normalize-identifiers.test.js +44 -0
- package/dist/normalize-identifiers.test.js.map +7 -0
- package/dist/normalize-qualifying-information.js +23 -48
- package/dist/normalize-qualifying-information.js.map +7 -1
- package/dist/normalize-qualifying-information.test.js +44 -0
- package/dist/normalize-qualifying-information.test.js.map +7 -0
- package/dist/normalize-utf8-diacritics.js +19 -105
- package/dist/normalize-utf8-diacritics.js.map +7 -1
- package/dist/normalize-utf8-diacritics.test.js +44 -0
- package/dist/normalize-utf8-diacritics.test.js.map +7 -0
- package/dist/normalizeFieldForComparison.js +67 -158
- package/dist/normalizeFieldForComparison.js.map +7 -1
- package/dist/normalizeSubfieldValueForComparison.js +37 -77
- package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
- package/dist/prepublicationUtils.js +58 -111
- package/dist/prepublicationUtils.js.map +7 -1
- package/dist/punctuation/index.js +56 -72
- package/dist/punctuation/index.js.map +7 -1
- package/dist/punctuation/rules/aut.js +372 -331
- package/dist/punctuation/rules/aut.js.map +7 -1
- package/dist/punctuation/rules/bib.js +420 -373
- package/dist/punctuation/rules/bib.js.map +7 -1
- package/dist/punctuation/rules/index.js +7 -21
- package/dist/punctuation/rules/index.js.map +7 -1
- package/dist/punctuation.test.js +44 -0
- package/dist/punctuation.test.js.map +7 -0
- package/dist/punctuation2.js +251 -800
- package/dist/punctuation2.js.map +7 -1
- package/dist/punctuation2.test.js +44 -0
- package/dist/punctuation2.test.js.map +7 -0
- package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
- package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
- package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
- package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
- package/dist/removeDuplicateDataFields.js +102 -202
- package/dist/removeDuplicateDataFields.js.map +7 -1
- package/dist/removeDuplicateDataFields.test.js +44 -0
- package/dist/removeDuplicateDataFields.test.js.map +7 -0
- package/dist/removeInferiorDataFields.js +103 -227
- package/dist/removeInferiorDataFields.js.map +7 -1
- package/dist/removeInferiorDataFields.test.js +44 -0
- package/dist/removeInferiorDataFields.test.js.map +7 -0
- package/dist/resolvable-ext-references-melinda.js +25 -60
- package/dist/resolvable-ext-references-melinda.js.map +7 -1
- package/dist/resolvable-ext-references-melinda.test.js +160 -0
- package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
- package/dist/resolveOrphanedSubfield6s.js +33 -64
- package/dist/resolveOrphanedSubfield6s.js.map +7 -1
- package/dist/resolveOrphanedSubfield6s.test.js +44 -0
- package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
- package/dist/sanitize-vocabulary-source-codes.js +27 -55
- package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
- package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
- package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
- package/dist/sort-tags.js +13 -25
- package/dist/sort-tags.js.map +7 -1
- package/dist/sort-tags.test.js +261 -0
- package/dist/sort-tags.test.js.map +7 -0
- package/dist/sortFields.js +152 -222
- package/dist/sortFields.js.map +7 -1
- package/dist/sortFields.test.js +44 -0
- package/dist/sortFields.test.js.map +7 -0
- package/dist/sortRelatorTerms.js +30 -68
- package/dist/sortRelatorTerms.js.map +7 -1
- package/dist/sortRelatorTerms.test.js +44 -0
- package/dist/sortRelatorTerms.test.js.map +7 -0
- package/dist/sortSubfields.js +102 -255
- package/dist/sortSubfields.js.map +7 -1
- package/dist/sortSubfields.test.js +44 -0
- package/dist/sortSubfields.test.js.map +7 -0
- package/dist/stripPunctuation.js +13 -36
- package/dist/stripPunctuation.js.map +7 -1
- package/dist/stripPunctuation.test.js +44 -0
- package/dist/stripPunctuation.test.js.map +7 -0
- package/dist/subfield-exclusion.js +28 -75
- package/dist/subfield-exclusion.js.map +7 -1
- package/dist/subfield-exclusion.test.js +471 -0
- package/dist/subfield-exclusion.test.js.map +7 -0
- package/dist/subfield6Utils.js +107 -269
- package/dist/subfield6Utils.js.map +7 -1
- package/dist/subfield8Utils.js +26 -50
- package/dist/subfield8Utils.js.map +7 -1
- package/dist/subfieldValueNormalizations.js +40 -74
- package/dist/subfieldValueNormalizations.js.map +7 -1
- package/dist/subfieldValueNormalizations.test.js +45 -0
- package/dist/subfieldValueNormalizations.test.js.map +7 -0
- package/dist/sync-007-and-300.js +22 -53
- package/dist/sync-007-and-300.js.map +7 -1
- package/dist/sync-007-and-300.test.js +44 -0
- package/dist/sync-007-and-300.test.js.map +7 -0
- package/dist/translate-terms.js +67 -155
- package/dist/translate-terms.js.map +7 -1
- package/dist/translate-terms.test.js +44 -0
- package/dist/translate-terms.test.js.map +7 -0
- package/dist/typeOfDate-008.js +10 -25
- package/dist/typeOfDate-008.js.map +7 -1
- package/dist/typeOfDate-008.test.js +40 -0
- package/dist/typeOfDate-008.test.js.map +7 -0
- package/dist/unicode-decomposition.js +94 -107
- package/dist/unicode-decomposition.js.map +7 -1
- package/dist/unicode-decomposition.test.js +94 -0
- package/dist/unicode-decomposition.test.js.map +7 -0
- package/dist/update-field-540.js +30 -75
- package/dist/update-field-540.js.map +7 -1
- package/dist/update-field-540.test.js +44 -0
- package/dist/update-field-540.test.js.map +7 -0
- package/dist/urn.js +55 -128
- package/dist/urn.js.map +7 -1
- package/dist/urn.test.js +44 -0
- package/dist/urn.test.js.map +7 -0
- package/dist/utils.js +72 -126
- package/dist/utils.js.map +7 -1
- package/eslint.config.mjs +1 -2
- package/package.json +21 -93
- package/src/access-rights.js +1 -1
- package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
- package/src/addMissingField041.js +1 -1
- package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
- package/src/addMissingField336.js +3 -3
- package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
- package/src/addMissingField337.js +2 -2
- package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
- package/src/addMissingField338.js +2 -2
- package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
- package/src/cyrillux-usemarcon-replacement.js +18 -18
- package/src/cyrillux-usemarcon-replacement.test.js +55 -0
- package/src/cyrillux.js +19 -12
- package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
- package/src/disambiguateSeriesStatements.js +2 -2
- package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
- package/src/double-commas.js +1 -1
- package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
- package/src/duplicates-ind1.js +1 -1
- package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
- package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
- package/src/ending-punctuation.js +1 -1
- package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +172 -173
- package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
- package/src/field-008-18-34-character-groups.js +2 -2
- package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
- package/src/field-505-separators.js +3 -3
- package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
- package/src/field-521-fix.js +2 -2
- package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
- package/src/field-exclusion.js +1 -1
- package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
- package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
- package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
- package/src/fix-33X.js +4 -4
- package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
- package/src/fix-country-codes.js +1 -1
- package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
- package/src/fix-language-codes.js +5 -5
- package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
- package/src/fixRelatorTerms.js +5 -5
- package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
- package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
- package/src/identical-fields.js +1 -1
- package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
- package/src/indicator-fixes.js +3 -3
- package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
- package/src/isbn-issn.js +1 -1
- package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
- package/src/{item-language.spec.js → item-language.test.js} +21 -22
- package/src/merge-fields/controlSubfields.js +1 -1
- package/src/merge-fields/counterpartField.js +8 -9
- package/src/merge-fields/index.js +1 -1
- package/src/merge-fields/mergableIndicator.js +1 -1
- package/src/merge-fields/mergeField.js +6 -6
- package/src/merge-fields/mergeIndicator.js +1 -1
- package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
- package/src/merge-fields/mergeOrAddSubfield.js +2 -2
- package/src/merge-fields/mergeSubfield.js +4 -4
- package/src/merge-fields/removeDuplicateSubfields.js +2 -2
- package/src/{merge-fields.spec.js → merge-fields.test.js} +12 -13
- package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
- package/src/mergeRelatorTermFields.js +5 -7
- package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
- package/src/modernize-502.js +1 -1
- package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
- package/src/multiple-subfield-0.js +3 -3
- package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
- package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
- package/src/normalize-dashes.js +2 -2
- package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
- package/src/normalize-identifiers.js +1 -1
- package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
- package/src/normalize-qualifying-information.js +2 -2
- package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
- package/src/normalize-utf8-diacritics.js +2 -2
- package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
- package/src/normalizeFieldForComparison.js +6 -6
- package/src/normalizeSubfieldValueForComparison.js +1 -1
- package/src/prepublicationUtils.js +4 -4
- package/src/punctuation/index.js +1 -1
- package/src/punctuation/rules/index.js +2 -2
- package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
- package/src/punctuation2.js +4 -4
- package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
- package/src/reindexSubfield6OccurenceNumbers.js +5 -7
- package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
- package/src/removeDuplicateDataFields.js +11 -19
- package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
- package/src/removeInferiorDataFields.js +11 -11
- package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
- package/src/resolvable-ext-references-melinda.js +1 -1
- package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
- package/src/resolveOrphanedSubfield6s.js +5 -5
- package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
- package/src/sanitize-vocabulary-source-codes.js +4 -4
- package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
- package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
- package/src/sortFields.js +4 -4
- package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
- package/src/sortRelatorTerms.js +3 -3
- package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
- package/src/sortSubfields.js +1 -1
- package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
- package/src/stripPunctuation.js +3 -3
- package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
- package/src/subfield-exclusion.js +1 -1
- package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
- package/src/subfield6Utils.js +6 -10
- package/src/subfield8Utils.js +4 -4
- package/src/subfieldValueNormalizations.js +3 -3
- package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
- package/src/sync-007-and-300.js +2 -2
- package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
- package/src/translate-terms.js +3 -3
- package/src/{translate-terms.spec.js → translate-terms.test.js} +13 -13
- package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
- package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
- package/src/update-field-540.js +2 -2
- package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
- package/src/urn.js +2 -2
- package/src/{urn.spec.js → urn.test.js} +12 -13
- package/src/utils.js +3 -3
- package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
- package/test-fixtures/field-505-separators/03/record.json +3 -0
- package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
- package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
- package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
- package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
- package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
- package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
- package/dist/access-rights.spec.js +0 -195
- package/dist/access-rights.spec.js.map +0 -1
- package/dist/addMissingField041.spec.js +0 -45
- package/dist/addMissingField041.spec.js.map +0 -1
- package/dist/addMissingField336.spec.js +0 -45
- package/dist/addMissingField336.spec.js.map +0 -1
- package/dist/addMissingField337.spec.js +0 -43
- package/dist/addMissingField337.spec.js.map +0 -1
- package/dist/addMissingField338.spec.js +0 -45
- package/dist/addMissingField338.spec.js.map +0 -1
- package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
- package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
- package/dist/cyrillux.spec.js +0 -46
- package/dist/cyrillux.spec.js.map +0 -1
- package/dist/disambiguateSeriesStatements.spec.js +0 -51
- package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
- package/dist/double-commas.spec.js +0 -73
- package/dist/double-commas.spec.js.map +0 -1
- package/dist/duplicates-ind1.spec.js +0 -45
- package/dist/duplicates-ind1.spec.js.map +0 -1
- package/dist/empty-fields.spec.js +0 -118
- package/dist/empty-fields.spec.js.map +0 -1
- package/dist/ending-punctuation.spec.js +0 -2654
- package/dist/ending-punctuation.spec.js.map +0 -1
- package/dist/ending-whitespace.spec.js +0 -42
- package/dist/ending-whitespace.spec.js.map +0 -1
- package/dist/field-008-18-34-character-groups.spec.js +0 -51
- package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
- package/dist/field-505-separators.spec.js +0 -51
- package/dist/field-505-separators.spec.js.map +0 -1
- package/dist/field-521-fix.spec.js +0 -51
- package/dist/field-521-fix.spec.js.map +0 -1
- package/dist/field-exclusion.spec.js +0 -1054
- package/dist/field-exclusion.spec.js.map +0 -1
- package/dist/field-structure.spec.js +0 -535
- package/dist/field-structure.spec.js.map +0 -1
- package/dist/fields-present.spec.js +0 -121
- package/dist/fields-present.spec.js.map +0 -1
- package/dist/fix-33X.spec.js +0 -45
- package/dist/fix-33X.spec.js.map +0 -1
- package/dist/fix-country-codes.spec.js +0 -51
- package/dist/fix-country-codes.spec.js.map +0 -1
- package/dist/fix-language-codes.spec.js +0 -44
- package/dist/fix-language-codes.spec.js.map +0 -1
- package/dist/fixRelatorTerms.spec.js +0 -51
- package/dist/fixRelatorTerms.spec.js.map +0 -1
- package/dist/fixed-fields.spec.js +0 -140
- package/dist/fixed-fields.spec.js.map +0 -1
- package/dist/identical-fields.spec.js +0 -99
- package/dist/identical-fields.spec.js.map +0 -1
- package/dist/indicator-fixes.spec.js +0 -51
- package/dist/indicator-fixes.spec.js.map +0 -1
- package/dist/isbn-issn.spec.js +0 -595
- package/dist/isbn-issn.spec.js.map +0 -1
- package/dist/item-language.spec.js +0 -306
- package/dist/item-language.spec.js.map +0 -1
- package/dist/melindaCustomMergeFields.json +0 -5120
- package/dist/merge-fields.spec.js +0 -51
- package/dist/merge-fields.spec.js.map +0 -1
- package/dist/mergeField500Lisapainokset.spec.js +0 -51
- package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
- package/dist/mergeRelatorTermFields.spec.js +0 -51
- package/dist/mergeRelatorTermFields.spec.js.map +0 -1
- package/dist/modernize-502.spec.js +0 -49
- package/dist/modernize-502.spec.js.map +0 -1
- package/dist/multiple-subfield-0.spec.js +0 -51
- package/dist/multiple-subfield-0.spec.js.map +0 -1
- package/dist/non-breaking-space.spec.js +0 -42
- package/dist/non-breaking-space.spec.js.map +0 -1
- package/dist/normalize-dashes.spec.js +0 -51
- package/dist/normalize-dashes.spec.js.map +0 -1
- package/dist/normalize-identifiers.spec.js +0 -51
- package/dist/normalize-identifiers.spec.js.map +0 -1
- package/dist/normalize-qualifying-information.spec.js +0 -51
- package/dist/normalize-qualifying-information.spec.js.map +0 -1
- package/dist/normalize-utf8-diacritics.spec.js +0 -51
- package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
- package/dist/punctuation.spec.js +0 -51
- package/dist/punctuation.spec.js.map +0 -1
- package/dist/punctuation2.spec.js +0 -51
- package/dist/punctuation2.spec.js.map +0 -1
- package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
- package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
- package/dist/removeDuplicateDataFields.spec.js +0 -51
- package/dist/removeDuplicateDataFields.spec.js.map +0 -1
- package/dist/removeInferiorDataFields.spec.js +0 -51
- package/dist/removeInferiorDataFields.spec.js.map +0 -1
- package/dist/resolvable-ext-references-melinda.spec.js +0 -166
- package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
- package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
- package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
- package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
- package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
- package/dist/sort-tags.spec.js +0 -207
- package/dist/sort-tags.spec.js.map +0 -1
- package/dist/sortFields.spec.js +0 -51
- package/dist/sortFields.spec.js.map +0 -1
- package/dist/sortRelatorTerms.spec.js +0 -51
- package/dist/sortRelatorTerms.spec.js.map +0 -1
- package/dist/sortSubfields.spec.js +0 -52
- package/dist/sortSubfields.spec.js.map +0 -1
- package/dist/stripPunctuation.spec.js +0 -51
- package/dist/stripPunctuation.spec.js.map +0 -1
- package/dist/subfield-exclusion.spec.js +0 -523
- package/dist/subfield-exclusion.spec.js.map +0 -1
- package/dist/subfieldValueNormalizations.spec.js +0 -51
- package/dist/subfieldValueNormalizations.spec.js.map +0 -1
- package/dist/sync-007-and-300.spec.js +0 -51
- package/dist/sync-007-and-300.spec.js.map +0 -1
- package/dist/translate-terms.spec.js +0 -51
- package/dist/translate-terms.spec.js.map +0 -1
- package/dist/typeOfDate-008.spec.js +0 -47
- package/dist/typeOfDate-008.spec.js.map +0 -1
- package/dist/unicode-decomposition.spec.js +0 -91
- package/dist/unicode-decomposition.spec.js.map +0 -1
- package/dist/update-field-540.spec.js +0 -51
- package/dist/update-field-540.spec.js.map +0 -1
- package/dist/urn.spec.js +0 -52
- package/dist/urn.spec.js.map +0 -1
- package/src/cyrillux-usemarcon-replacement.spec.js +0 -47
|
@@ -1,43 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var _worldKnowledge = require("./worldKnowledge");
|
|
10
|
-
var _utils = require("../utils");
|
|
11
|
-
var _normalizeFieldForComparison = require("../normalizeFieldForComparison.js");
|
|
12
|
-
var _counterpartField = require("./counterpartField");
|
|
13
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
-
const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');
|
|
15
|
-
//const debugData = debug.extend('data');
|
|
16
|
-
const debugDev = debug.extend('dev');
|
|
17
|
-
|
|
18
|
-
// NB! These are X00 specific. Should we somehow parametrize them?
|
|
1
|
+
import createDebugLogger from "debug";
|
|
2
|
+
import { partsAgree, subfieldContainsPartData } from "../normalizeSubfieldValueForComparison.js";
|
|
3
|
+
import { valueCarriesMeaning } from "./worldKnowledge.js";
|
|
4
|
+
import { nvdebug } from "../utils.js";
|
|
5
|
+
import { tagAndSubfieldCodeReferToIsbn } from "../normalizeFieldForComparison.js";
|
|
6
|
+
import { canContainOptionalQualifier, splitToNameAndQualifier } from "./counterpartField.js";
|
|
7
|
+
const debug = createDebugLogger("@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield");
|
|
8
|
+
const debugDev = debug.extend("dev");
|
|
19
9
|
const onlyBirthYear = /^[1-9][0-9]*-[,.]?$/u;
|
|
20
10
|
const onlyDeathYear = /^-[1-9][0-9]*[,.]?$/u;
|
|
21
11
|
const birthYearAndDeathYear = /^[1-9][0-9]*-[1-9][0-9]*[,.]?$/u;
|
|
22
12
|
function getDeathYear(str) {
|
|
23
|
-
return parseInt(str.substring(str.indexOf(
|
|
13
|
+
return parseInt(str.substring(str.indexOf("-") + 1), 10);
|
|
24
14
|
}
|
|
25
15
|
function isValidBirthYearAndDeathYear(str) {
|
|
26
16
|
if (!birthYearAndDeathYear.test(str)) {
|
|
27
17
|
return false;
|
|
28
18
|
}
|
|
29
|
-
// We have two years
|
|
30
19
|
const b = parseInt(str, 10);
|
|
31
20
|
const d = getDeathYear(str);
|
|
32
21
|
if (b > d) {
|
|
33
|
-
// died before birth! Rather unlikely.
|
|
34
22
|
return false;
|
|
35
23
|
}
|
|
36
24
|
if (d - b > 125) {
|
|
37
|
-
// Over 125 years old. Rather unlikely.
|
|
38
25
|
return false;
|
|
39
26
|
}
|
|
40
|
-
// Possible sanity check: Died after current year?
|
|
41
27
|
return true;
|
|
42
28
|
}
|
|
43
29
|
function anyYear(str) {
|
|
@@ -60,10 +46,7 @@ function replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfi
|
|
|
60
46
|
return false;
|
|
61
47
|
}
|
|
62
48
|
function replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) {
|
|
63
|
-
|
|
64
|
-
// This function treats only with X00$d subfields:
|
|
65
|
-
if (candSubfield.code !== 'd' || !/^[1678]00$/u.test(targetField.tag)) {
|
|
66
|
-
// njsscan-ignore: regex_dos
|
|
49
|
+
if (candSubfield.code !== "d" || !/^[1678]00$/u.test(targetField.tag)) {
|
|
67
50
|
return false;
|
|
68
51
|
}
|
|
69
52
|
if (!anyYear(relevantSubfields[0].value) && anyYear(candSubfield.value)) {
|
|
@@ -75,16 +58,14 @@ function replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfi
|
|
|
75
58
|
}
|
|
76
59
|
return false;
|
|
77
60
|
}
|
|
78
|
-
|
|
79
|
-
// use array.includes(value) for easy extendability (Swedish, other languages, abbrs, etc.()
|
|
80
61
|
function isKierreselka(value) {
|
|
81
|
-
return [
|
|
62
|
+
return ["kierreselk\xE4", "spiral bound", "spiral-bound", "spiralrygg"].includes(value);
|
|
82
63
|
}
|
|
83
64
|
function isKovakantinen(value) {
|
|
84
|
-
return [
|
|
65
|
+
return ["hardback", "hardcover", "h\xE5rda p\xE4rmar", "kovakantinen"].includes(value);
|
|
85
66
|
}
|
|
86
67
|
function isPehmeakantinen(value) {
|
|
87
|
-
return [
|
|
68
|
+
return ["mjuka p\xE4rmar", "paperback", "pehme\xE4kantinen", "softcover"].includes(value);
|
|
88
69
|
}
|
|
89
70
|
function isItsenainenJatkoOsa(value) {
|
|
90
71
|
if (value.match(/^Fristående fortsättning på verket[^a-z]*$/ui)) {
|
|
@@ -105,41 +86,38 @@ function isSisaltaaTeos(value) {
|
|
|
105
86
|
return false;
|
|
106
87
|
}
|
|
107
88
|
function relationInformationMatches(candSubfield, relevantSubfields) {
|
|
108
|
-
if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some(sf => isSisaltaaTeos(sf.value))) {
|
|
89
|
+
if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some((sf) => isSisaltaaTeos(sf.value))) {
|
|
109
90
|
return true;
|
|
110
91
|
}
|
|
111
|
-
if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some(sf => isItsenainenJatkoOsa(sf.value))) {
|
|
92
|
+
if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some((sf) => isItsenainenJatkoOsa(sf.value))) {
|
|
112
93
|
return true;
|
|
113
94
|
}
|
|
114
95
|
return false;
|
|
115
96
|
}
|
|
116
97
|
function coverTypesMatch(candSubfield, relevantSubfields) {
|
|
117
|
-
if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some(sf => isPehmeakantinen(sf.value))) {
|
|
98
|
+
if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some((sf) => isPehmeakantinen(sf.value))) {
|
|
118
99
|
return true;
|
|
119
100
|
}
|
|
120
|
-
if (isKovakantinen(candSubfield.value) && relevantSubfields.some(sf => isKovakantinen(sf.value))) {
|
|
101
|
+
if (isKovakantinen(candSubfield.value) && relevantSubfields.some((sf) => isKovakantinen(sf.value))) {
|
|
121
102
|
return true;
|
|
122
103
|
}
|
|
123
|
-
if (isKierreselka(candSubfield.value) && relevantSubfields.some(sf => isKierreselka(sf.value))) {
|
|
104
|
+
if (isKierreselka(candSubfield.value) && relevantSubfields.some((sf) => isKierreselka(sf.value))) {
|
|
124
105
|
return true;
|
|
125
106
|
}
|
|
126
107
|
return false;
|
|
127
108
|
}
|
|
128
109
|
function httpToHttps(val) {
|
|
129
|
-
return val.replace(/http:\/\//ug,
|
|
110
|
+
return val.replace(/http:\/\//ug, "https://");
|
|
130
111
|
}
|
|
131
112
|
function pairHttpAndHttps(candSubfield, relevantSubfields) {
|
|
132
113
|
const a = httpToHttps(candSubfield.value);
|
|
133
|
-
const bs = relevantSubfields.map(sf => httpToHttps(sf.value));
|
|
114
|
+
const bs = relevantSubfields.map((sf) => httpToHttps(sf.value));
|
|
134
115
|
return bs.includes(a);
|
|
135
116
|
}
|
|
136
117
|
function isSynonym(field, candSubfield, relevantSubfields) {
|
|
137
|
-
if (candSubfield.code ===
|
|
118
|
+
if (candSubfield.code === "q" && ["015", "020", "024", "028"].includes(field.tag)) {
|
|
138
119
|
return coverTypesMatch(candSubfield, relevantSubfields);
|
|
139
120
|
}
|
|
140
|
-
|
|
141
|
-
//nvdebug(`Looking for synonyms for '${subfieldToString(candSubfield)}'...`, debugDev);
|
|
142
|
-
|
|
143
121
|
if (relationInformationMatches(candSubfield, relevantSubfields)) {
|
|
144
122
|
return true;
|
|
145
123
|
}
|
|
@@ -149,16 +127,14 @@ function isSynonym(field, candSubfield, relevantSubfields) {
|
|
|
149
127
|
return false;
|
|
150
128
|
}
|
|
151
129
|
function preferHyphenatedISBN(field, candSubfield, relevantSubfields) {
|
|
152
|
-
if (!
|
|
130
|
+
if (!tagAndSubfieldCodeReferToIsbn(field.tag, candSubfield.code) || candSubfield.value.includes("-") === -1) {
|
|
153
131
|
return false;
|
|
154
132
|
}
|
|
155
|
-
|
|
156
|
-
// Must not already exist:
|
|
157
|
-
if (relevantSubfields.some(sf => sf.value === candSubfield.value)) {
|
|
133
|
+
if (relevantSubfields.some((sf) => sf.value === candSubfield.value)) {
|
|
158
134
|
return false;
|
|
159
135
|
}
|
|
160
|
-
const hyphenlessSubfields = relevantSubfields.filter(sf => sf.value.includes(
|
|
161
|
-
const pair = hyphenlessSubfields.find(sf => sf.value === candSubfield.value.replace(/-/gu,
|
|
136
|
+
const hyphenlessSubfields = relevantSubfields.filter((sf) => sf.value.includes("-") > -1);
|
|
137
|
+
const pair = hyphenlessSubfields.find((sf) => sf.value === candSubfield.value.replace(/-/gu, ""));
|
|
162
138
|
if (!pair) {
|
|
163
139
|
return false;
|
|
164
140
|
}
|
|
@@ -166,11 +142,11 @@ function preferHyphenatedISBN(field, candSubfield, relevantSubfields) {
|
|
|
166
142
|
return true;
|
|
167
143
|
}
|
|
168
144
|
function preferHttpsOverHttp(candSubfield, relevantSubfields) {
|
|
169
|
-
if (candSubfield.value.substring(0, 8) !==
|
|
145
|
+
if (candSubfield.value.substring(0, 8) !== "https://") {
|
|
170
146
|
return false;
|
|
171
147
|
}
|
|
172
148
|
const httpVersion = `http://${candSubfield.value.substring(8)}`;
|
|
173
|
-
const pair = relevantSubfields.find(sf => sf.value === httpVersion);
|
|
149
|
+
const pair = relevantSubfields.find((sf) => sf.value === httpVersion);
|
|
174
150
|
if (!pair) {
|
|
175
151
|
return false;
|
|
176
152
|
}
|
|
@@ -178,23 +154,21 @@ function preferHttpsOverHttp(candSubfield, relevantSubfields) {
|
|
|
178
154
|
return true;
|
|
179
155
|
}
|
|
180
156
|
function preferQualifierVersion(field, candSubfield, relevantSubfields) {
|
|
181
|
-
if (!
|
|
182
|
-
// currently only 300$a and 776$i can prefer source...
|
|
157
|
+
if (!canContainOptionalQualifier(field.tag, candSubfield.code)) {
|
|
183
158
|
return false;
|
|
184
159
|
}
|
|
185
|
-
const [name1, qualifier1] =
|
|
186
|
-
const pair = relevantSubfields.find(sf => subfieldQualifierCheck(sf, name1, qualifier1));
|
|
160
|
+
const [name1, qualifier1] = splitToNameAndQualifier(candSubfield.value);
|
|
161
|
+
const pair = relevantSubfields.find((sf) => subfieldQualifierCheck(sf, name1, qualifier1));
|
|
187
162
|
if (!pair) {
|
|
188
163
|
return false;
|
|
189
164
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return true; // True, but don't prefer the source value
|
|
165
|
+
if (field.tag === "300" && candSubfield.code === "a" && candSubfield.value.match(/(?:online|verkko)/iu)) {
|
|
166
|
+
return true;
|
|
193
167
|
}
|
|
194
168
|
pair.value = candSubfield.value;
|
|
195
169
|
return true;
|
|
196
170
|
function subfieldQualifierCheck(subfield, name, qualifier) {
|
|
197
|
-
const [name2, qualifier2] =
|
|
171
|
+
const [name2, qualifier2] = splitToNameAndQualifier(candSubfield.value);
|
|
198
172
|
if (name !== name2) {
|
|
199
173
|
return false;
|
|
200
174
|
}
|
|
@@ -205,10 +179,10 @@ function preferQualifierVersion(field, candSubfield, relevantSubfields) {
|
|
|
205
179
|
}
|
|
206
180
|
}
|
|
207
181
|
function preferSourceCorporateName(field, candSubfield, pair) {
|
|
208
|
-
if (candSubfield.code !==
|
|
182
|
+
if (candSubfield.code !== "a" || !["110", "610", "710", "810"].includes(field.tag)) {
|
|
209
183
|
return false;
|
|
210
184
|
}
|
|
211
|
-
|
|
185
|
+
nvdebug(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);
|
|
212
186
|
const prefer = actualPrefenceCheck();
|
|
213
187
|
if (prefer) {
|
|
214
188
|
pair.value = candSubfield.value;
|
|
@@ -222,56 +196,34 @@ function preferSourceCorporateName(field, candSubfield, pair) {
|
|
|
222
196
|
if (candSubfield.value.match(/^ntamo/u) && pair.value.match(/^N(?:tamo|TAMO)/u)) {
|
|
223
197
|
return true;
|
|
224
198
|
}
|
|
225
|
-
|
|
226
|
-
const [
|
|
227
|
-
|
|
228
|
-
if (sourceName === baseName && baseQualifier === undefined && sourceQualifier !== undefined) {
|
|
199
|
+
const [sourceName, sourceQualifier] = splitToNameAndQualifier(candSubfield.value);
|
|
200
|
+
const [baseName, baseQualifier] = splitToNameAndQualifier(pair.value);
|
|
201
|
+
if (sourceName === baseName && baseQualifier === void 0 && sourceQualifier !== void 0) {
|
|
229
202
|
return true;
|
|
230
203
|
}
|
|
231
|
-
// Not taking prefix and suffix into account here...
|
|
232
204
|
return false;
|
|
233
205
|
}
|
|
234
206
|
}
|
|
235
|
-
function mergeSubfield(targetField, candSubfield) {
|
|
236
|
-
|
|
237
|
-
// Currenty we only select the better X00$d.
|
|
238
|
-
// In future we might do more things here. Examples:
|
|
239
|
-
// - "FOO" gets replaced by "Foo" in certain fields.
|
|
240
|
-
// - "Etunimi Sukunimi" might lose to "Sukunimi, Etunimi" in X00 fields.
|
|
241
|
-
// - [put your ideas here]
|
|
242
|
-
// Return true, if replace is done.
|
|
243
|
-
// However, replacing/succeeding requires a sanity check, that the new value is a better one...
|
|
244
|
-
// Thus, typically this function fails...
|
|
245
|
-
|
|
246
|
-
const relevantSubfields = targetField.subfields.filter(subfield => subfield.code === candSubfield.code);
|
|
247
|
-
|
|
248
|
-
// There's nothing to replace the incoming subfield with. Thus abort:
|
|
207
|
+
export function mergeSubfield(targetField, candSubfield) {
|
|
208
|
+
const relevantSubfields = targetField.subfields.filter((subfield) => subfield.code === candSubfield.code);
|
|
249
209
|
if (relevantSubfields.length === 0) {
|
|
250
210
|
return false;
|
|
251
211
|
}
|
|
252
|
-
|
|
253
|
-
if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) || preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) || preferHttpsOverHttp(candSubfield, relevantSubfields) || preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) ||
|
|
254
|
-
// SF is non-repeat
|
|
212
|
+
nvdebug(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}\u2021${candSubfield.code}`, debugDev);
|
|
213
|
+
if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) || preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) || preferHttpsOverHttp(candSubfield, relevantSubfields) || preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) || // SF is non-repeat
|
|
255
214
|
preferQualifierVersion(targetField, candSubfield, relevantSubfields) || isSynonym(targetField, candSubfield, relevantSubfields)) {
|
|
256
215
|
return true;
|
|
257
216
|
}
|
|
258
|
-
|
|
259
|
-
// We found a crappy empty subfield: replace that with a meaningful one.
|
|
260
|
-
// 260 $a value "[S.l]" is the main type for this.
|
|
261
|
-
const meaninglessSubfields = relevantSubfields.filter(sf => !(0, _worldKnowledge.valueCarriesMeaning)(targetField.tag, sf.code, sf.value));
|
|
217
|
+
const meaninglessSubfields = relevantSubfields.filter((sf) => !valueCarriesMeaning(targetField.tag, sf.code, sf.value));
|
|
262
218
|
if (meaninglessSubfields.length > 0) {
|
|
263
219
|
meaninglessSubfields[0].value = candSubfield.value;
|
|
264
220
|
return true;
|
|
265
221
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// NB! Keeps the original value and drops the incoming value. (Just preventing it from going to add-part...)
|
|
269
|
-
// NB! We could improve this and choose the longer value later on.
|
|
270
|
-
if ((0, _normalizeSubfieldValueForComparison.subfieldContainsPartData)(targetField.tag, candSubfield.code)) {
|
|
271
|
-
if (relevantSubfields.some(sf => (0, _normalizeSubfieldValueForComparison.partsAgree)(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {
|
|
222
|
+
if (subfieldContainsPartData(targetField.tag, candSubfield.code)) {
|
|
223
|
+
if (relevantSubfields.some((sf) => partsAgree(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {
|
|
272
224
|
return true;
|
|
273
225
|
}
|
|
274
226
|
}
|
|
275
|
-
return false;
|
|
227
|
+
return false;
|
|
276
228
|
}
|
|
277
|
-
//# sourceMappingURL=mergeSubfield.js.map
|
|
229
|
+
//# sourceMappingURL=mergeSubfield.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{"version":3,"file":"mergeSubfield.js","names":["_debug","_interopRequireDefault","require","_normalizeSubfieldValueForComparison","_worldKnowledge","_utils","_normalizeFieldForComparison","_counterpartField","e","__esModule","default","debug","createDebugLogger","debugDev","extend","onlyBirthYear","onlyDeathYear","birthYearAndDeathYear","getDeathYear","str","parseInt","substring","indexOf","isValidBirthYearAndDeathYear","test","b","d","anyYear","replaceEntrysBirthAndDeathYear","targetField","candSubfield","relevantSubfields","value","replaceDatesAssociatedWithName","code","tag","isKierreselka","includes","isKovakantinen","isPehmeakantinen","isItsenainenJatkoOsa","match","isSisaltaaTeos","relationInformationMatches","some","sf","coverTypesMatch","httpToHttps","val","replace","pairHttpAndHttps","a","bs","map","isSynonym","field","preferHyphenatedISBN","tagAndSubfieldCodeReferToIsbn","hyphenlessSubfields","filter","pair","find","preferHttpsOverHttp","httpVersion","preferQualifierVersion","canContainOptionalQualifier","name1","qualifier1","splitToNameAndQualifier","subfieldQualifierCheck","subfield","name","qualifier","name2","qualifier2","preferSourceCorporateName","nvdebug","prefer","actualPrefenceCheck","sourceName","sourceQualifier","baseName","baseQualifier","undefined","mergeSubfield","subfields","length","meaninglessSubfields","valueCarriesMeaning","subfieldContainsPartData","partsAgree"],"sources":["../../src/merge-fields/mergeSubfield.js"],"sourcesContent":["import createDebugLogger from 'debug';\nimport {partsAgree, subfieldContainsPartData} from '../normalizeSubfieldValueForComparison';\nimport {valueCarriesMeaning} from './worldKnowledge';\nimport {nvdebug} from '../utils';\nimport {tagAndSubfieldCodeReferToIsbn} from '../normalizeFieldForComparison.js';\nimport {canContainOptionalQualifier, splitToNameAndQualifier} from './counterpartField';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\n// NB! These are X00 specific. Should we somehow parametrize them?\nconst onlyBirthYear = /^[1-9][0-9]*-[,.]?$/u;\nconst onlyDeathYear = /^-[1-9][0-9]*[,.]?$/u;\nconst birthYearAndDeathYear = /^[1-9][0-9]*-[1-9][0-9]*[,.]?$/u;\n\nfunction getDeathYear(str) {\n return parseInt(str.substring(str.indexOf('-') + 1), 10);\n}\n\nfunction isValidBirthYearAndDeathYear(str) {\n if (!birthYearAndDeathYear.test(str)) {\n return false;\n }\n // We have two years\n const b = parseInt(str, 10);\n const d = getDeathYear(str);\n if (b > d) { // died before birth! Rather unlikely.\n return false;\n }\n if (d - b > 125) { // Over 125 years old. Rather unlikely.\n return false;\n }\n // Possible sanity check: Died after current year?\n return true;\n}\n\nfunction anyYear(str) {\n if (onlyBirthYear.test(str) || onlyDeathYear.test(str) || isValidBirthYearAndDeathYear(str)) {\n return true;\n }\n return false;\n}\n\nfunction replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields) {\n if (birthYearAndDeathYear.test(candSubfield.value)) {\n if (onlyBirthYear.test(relevantSubfields[0].value) && parseInt(relevantSubfields[0].value, 10) === parseInt(candSubfield.value, 10)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (onlyDeathYear.test(relevantSubfields[0].value) && getDeathYear(relevantSubfields[0].value) === getDeathYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n }\n return false;\n}\n\nfunction replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) {\n // Add also the death year, if the original value only contains birth year.\n // This function treats only with X00$d subfields:\n if (candSubfield.code !== 'd' || !(/^[1678]00$/u).test(targetField.tag)) { // njsscan-ignore: regex_dos\n return false;\n }\n\n if (!anyYear(relevantSubfields[0].value) && anyYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n return false;\n}\n\n// use array.includes(value) for easy extendability (Swedish, other languages, abbrs, etc.()\nfunction isKierreselka(value) {\n return ['kierreselkä', 'spiral bound', 'spiral-bound', 'spiralrygg'].includes(value);\n}\n\nfunction isKovakantinen(value) {\n return ['hardback', 'hardcover', 'hårda pärmar', 'kovakantinen'].includes(value);\n}\n\nfunction isPehmeakantinen(value) {\n return ['mjuka pärmar', 'paperback', 'pehmeäkantinen', 'softcover'].includes(value);\n}\n\nfunction isItsenainenJatkoOsa(value) {\n if (value.match(/^Fristående fortsättning på verket[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Itsenäinen jatko-osa teokselle[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\n\nfunction isSisaltaaTeos(value) {\n if (value.match(/^Innehåller \\(verk\\)[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Sisältää \\(teos\\)[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\nfunction relationInformationMatches(candSubfield, relevantSubfields) {\n if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some(sf => isSisaltaaTeos(sf.value))) {\n return true;\n }\n if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some(sf => isItsenainenJatkoOsa(sf.value))) {\n return true;\n }\n\n return false;\n}\n\nfunction coverTypesMatch(candSubfield, relevantSubfields) {\n if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some(sf => isPehmeakantinen(sf.value))) {\n return true;\n }\n if (isKovakantinen(candSubfield.value) && relevantSubfields.some(sf => isKovakantinen(sf.value))) {\n return true;\n }\n if (isKierreselka(candSubfield.value) && relevantSubfields.some(sf => isKierreselka(sf.value))) {\n return true;\n }\n return false;\n}\n\nfunction httpToHttps(val) {\n return val.replace(/http:\\/\\//ug, 'https://');\n}\n\nfunction pairHttpAndHttps(candSubfield, relevantSubfields) {\n const a = httpToHttps(candSubfield.value);\n const bs = relevantSubfields.map(sf => httpToHttps(sf.value));\n return bs.includes(a);\n}\n\nfunction isSynonym(field, candSubfield, relevantSubfields) {\n if (candSubfield.code === 'q' && ['015', '020', '024', '028'].includes(field.tag)) {\n return coverTypesMatch(candSubfield, relevantSubfields);\n }\n\n //nvdebug(`Looking for synonyms for '${subfieldToString(candSubfield)}'...`, debugDev);\n\n if (relationInformationMatches(candSubfield, relevantSubfields)) {\n return true;\n }\n\n if (pairHttpAndHttps(candSubfield, relevantSubfields)) {\n return true;\n }\n\n return false;\n}\n\nfunction preferHyphenatedISBN(field, candSubfield, relevantSubfields) {\n if (!tagAndSubfieldCodeReferToIsbn(field.tag, candSubfield.code) || candSubfield.value.includes('-') === -1) {\n return false;\n }\n\n // Must not already exist:\n if (relevantSubfields.some(sf => sf.value === candSubfield.value)) {\n return false;\n }\n\n const hyphenlessSubfields = relevantSubfields.filter(sf => sf.value.includes('-') > -1);\n const pair = hyphenlessSubfields.find(sf => sf.value === candSubfield.value.replace(/-/gu, ''));\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\nfunction preferHttpsOverHttp(candSubfield, relevantSubfields) {\n if (candSubfield.value.substring(0, 8) !== 'https://') {\n return false;\n }\n\n const httpVersion = `http://${candSubfield.value.substring(8)}`;\n const pair = relevantSubfields.find(sf => sf.value === httpVersion);\n\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\n\nfunction preferQualifierVersion(field, candSubfield, relevantSubfields) {\n if (!canContainOptionalQualifier(field.tag, candSubfield.code)) { // currently only 300$a and 776$i can prefer source...\n return false;\n }\n\n const [name1, qualifier1] = splitToNameAndQualifier(candSubfield.value);\n const pair = relevantSubfields.find(sf => subfieldQualifierCheck(sf, name1, qualifier1));\n if (!pair) {\n return false;\n }\n // SN: \"Kuvailuohjeiden näkökulmasta epubille ei pitäisi koskaan merkitä sivumäärää\"\n if (field.tag === '300' && candSubfield.code === 'a' && candSubfield.value.match(/(?:online|verkko)/iu)) {\n return true; // True, but don't prefer the source value\n }\n\n pair.value = candSubfield.value;\n return true;\n\n function subfieldQualifierCheck(subfield, name, qualifier) {\n const [name2, qualifier2] = splitToNameAndQualifier(candSubfield.value);\n if (name !== name2) {\n return false;\n }\n if (!qualifier || !qualifier2 || qualifier === qualifier2) {\n return true;\n }\n return false;\n }\n\n}\n\nfunction preferSourceCorporateName(field, candSubfield, pair) {\n if (candSubfield.code !== 'a' || !['110', '610', '710', '810'].includes(field.tag)) {\n return false;\n }\n nvdebug(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);\n const prefer = actualPrefenceCheck();\n if (prefer) {\n pair.value = candSubfield.value;\n return true;\n }\n return false;\n\n function actualPrefenceCheck() {\n if (candSubfield.value.match(/^Werner Söderström/u) && pair.value.match(/^WSOY/ui)) {\n return true;\n }\n if (candSubfield.value.match(/^ntamo/u) && pair.value.match(/^N(?:tamo|TAMO)/u)) {\n return true;\n }\n // Prefer (qualifier):\n const [sourceName, sourceQualifier] = splitToNameAndQualifier(candSubfield.value);\n const [baseName, baseQualifier] = splitToNameAndQualifier(pair.value);\n if (sourceName === baseName && baseQualifier === undefined && sourceQualifier !== undefined) {\n return true;\n }\n // Not taking prefix and suffix into account here...\n return false;\n }\n\n}\n\nexport function mergeSubfield(targetField, candSubfield) {\n // Replace existing subfield with the incoming field. These replacements are by name rather hacky...\n // Currenty we only select the better X00$d.\n // In future we might do more things here. Examples:\n // - \"FOO\" gets replaced by \"Foo\" in certain fields.\n // - \"Etunimi Sukunimi\" might lose to \"Sukunimi, Etunimi\" in X00 fields.\n // - [put your ideas here]\n // Return true, if replace is done.\n // However, replacing/succeeding requires a sanity check, that the new value is a better one...\n // Thus, typically this function fails...\n\n const relevantSubfields = targetField.subfields.filter(subfield => subfield.code === candSubfield.code);\n\n // There's nothing to replace the incoming subfield with. Thus abort:\n if (relevantSubfields.length === 0) {\n return false;\n }\n\n nvdebug(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}‡${candSubfield.code}`, debugDev);\n\n\n if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) ||\n preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) ||\n preferHttpsOverHttp(candSubfield, relevantSubfields) ||\n preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) || // SF is non-repeat\n preferQualifierVersion(targetField, candSubfield, relevantSubfields) ||\n isSynonym(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n\n // We found a crappy empty subfield: replace that with a meaningful one.\n // 260 $a value \"[S.l]\" is the main type for this.\n const meaninglessSubfields = relevantSubfields.filter(sf => !valueCarriesMeaning(targetField.tag, sf.code, sf.value));\n if (meaninglessSubfields.length > 0) {\n meaninglessSubfields[0].value = candSubfield.value;\n return true;\n }\n\n // Mark 490$v \"osa 1\" vs \"1\" as merged (2nd part of MET-53).\n // NB! Keeps the original value and drops the incoming value. (Just preventing it from going to add-part...)\n // NB! We could improve this and choose the longer value later on.\n if (subfieldContainsPartData(targetField.tag, candSubfield.code)) {\n if (relevantSubfields.some(sf => partsAgree(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {\n return true;\n }\n }\n return false; // default to failure\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/merge-fields/mergeSubfield.js"],
|
|
4
|
+
"sourcesContent": ["import createDebugLogger from 'debug';\nimport {partsAgree, subfieldContainsPartData} from '../normalizeSubfieldValueForComparison.js';\nimport {valueCarriesMeaning} from './worldKnowledge.js';\nimport {nvdebug} from '../utils.js';\nimport {tagAndSubfieldCodeReferToIsbn} from '../normalizeFieldForComparison.js';\nimport {canContainOptionalQualifier, splitToNameAndQualifier} from './counterpartField.js';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:mergeSubfield');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\n// NB! These are X00 specific. Should we somehow parametrize them?\nconst onlyBirthYear = /^[1-9][0-9]*-[,.]?$/u;\nconst onlyDeathYear = /^-[1-9][0-9]*[,.]?$/u;\nconst birthYearAndDeathYear = /^[1-9][0-9]*-[1-9][0-9]*[,.]?$/u;\n\nfunction getDeathYear(str) {\n return parseInt(str.substring(str.indexOf('-') + 1), 10);\n}\n\nfunction isValidBirthYearAndDeathYear(str) {\n if (!birthYearAndDeathYear.test(str)) {\n return false;\n }\n // We have two years\n const b = parseInt(str, 10);\n const d = getDeathYear(str);\n if (b > d) { // died before birth! Rather unlikely.\n return false;\n }\n if (d - b > 125) { // Over 125 years old. Rather unlikely.\n return false;\n }\n // Possible sanity check: Died after current year?\n return true;\n}\n\nfunction anyYear(str) {\n if (onlyBirthYear.test(str) || onlyDeathYear.test(str) || isValidBirthYearAndDeathYear(str)) {\n return true;\n }\n return false;\n}\n\nfunction replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields) {\n if (birthYearAndDeathYear.test(candSubfield.value)) {\n if (onlyBirthYear.test(relevantSubfields[0].value) && parseInt(relevantSubfields[0].value, 10) === parseInt(candSubfield.value, 10)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (onlyDeathYear.test(relevantSubfields[0].value) && getDeathYear(relevantSubfields[0].value) === getDeathYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n }\n return false;\n}\n\nfunction replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) {\n // Add also the death year, if the original value only contains birth year.\n // This function treats only with X00$d subfields:\n if (candSubfield.code !== 'd' || !(/^[1678]00$/u).test(targetField.tag)) { // njsscan-ignore: regex_dos\n return false;\n }\n\n if (!anyYear(relevantSubfields[0].value) && anyYear(candSubfield.value)) {\n relevantSubfields[0].value = candSubfield.value;\n return true;\n }\n\n if (replaceEntrysBirthAndDeathYear(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n return false;\n}\n\n// use array.includes(value) for easy extendability (Swedish, other languages, abbrs, etc.()\nfunction isKierreselka(value) {\n return ['kierreselk\u00E4', 'spiral bound', 'spiral-bound', 'spiralrygg'].includes(value);\n}\n\nfunction isKovakantinen(value) {\n return ['hardback', 'hardcover', 'h\u00E5rda p\u00E4rmar', 'kovakantinen'].includes(value);\n}\n\nfunction isPehmeakantinen(value) {\n return ['mjuka p\u00E4rmar', 'paperback', 'pehme\u00E4kantinen', 'softcover'].includes(value);\n}\n\nfunction isItsenainenJatkoOsa(value) {\n if (value.match(/^Frist\u00E5ende forts\u00E4ttning p\u00E5 verket[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Itsen\u00E4inen jatko-osa teokselle[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\n\nfunction isSisaltaaTeos(value) {\n if (value.match(/^Inneh\u00E5ller \\(verk\\)[^a-z]*$/ui)) {\n return true;\n }\n if (value.match(/^Sis\u00E4lt\u00E4\u00E4 \\(teos\\)[^a-z]*$/ui)) {\n return true;\n }\n return false;\n}\nfunction relationInformationMatches(candSubfield, relevantSubfields) {\n if (isSisaltaaTeos(candSubfield.value) && relevantSubfields.some(sf => isSisaltaaTeos(sf.value))) {\n return true;\n }\n if (isItsenainenJatkoOsa(candSubfield.value) && relevantSubfields.some(sf => isItsenainenJatkoOsa(sf.value))) {\n return true;\n }\n\n return false;\n}\n\nfunction coverTypesMatch(candSubfield, relevantSubfields) {\n if (isPehmeakantinen(candSubfield.value) && relevantSubfields.some(sf => isPehmeakantinen(sf.value))) {\n return true;\n }\n if (isKovakantinen(candSubfield.value) && relevantSubfields.some(sf => isKovakantinen(sf.value))) {\n return true;\n }\n if (isKierreselka(candSubfield.value) && relevantSubfields.some(sf => isKierreselka(sf.value))) {\n return true;\n }\n return false;\n}\n\nfunction httpToHttps(val) {\n return val.replace(/http:\\/\\//ug, 'https://');\n}\n\nfunction pairHttpAndHttps(candSubfield, relevantSubfields) {\n const a = httpToHttps(candSubfield.value);\n const bs = relevantSubfields.map(sf => httpToHttps(sf.value));\n return bs.includes(a);\n}\n\nfunction isSynonym(field, candSubfield, relevantSubfields) {\n if (candSubfield.code === 'q' && ['015', '020', '024', '028'].includes(field.tag)) {\n return coverTypesMatch(candSubfield, relevantSubfields);\n }\n\n //nvdebug(`Looking for synonyms for '${subfieldToString(candSubfield)}'...`, debugDev);\n\n if (relationInformationMatches(candSubfield, relevantSubfields)) {\n return true;\n }\n\n if (pairHttpAndHttps(candSubfield, relevantSubfields)) {\n return true;\n }\n\n return false;\n}\n\nfunction preferHyphenatedISBN(field, candSubfield, relevantSubfields) {\n if (!tagAndSubfieldCodeReferToIsbn(field.tag, candSubfield.code) || candSubfield.value.includes('-') === -1) {\n return false;\n }\n\n // Must not already exist:\n if (relevantSubfields.some(sf => sf.value === candSubfield.value)) {\n return false;\n }\n\n const hyphenlessSubfields = relevantSubfields.filter(sf => sf.value.includes('-') > -1);\n const pair = hyphenlessSubfields.find(sf => sf.value === candSubfield.value.replace(/-/gu, ''));\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\nfunction preferHttpsOverHttp(candSubfield, relevantSubfields) {\n if (candSubfield.value.substring(0, 8) !== 'https://') {\n return false;\n }\n\n const httpVersion = `http://${candSubfield.value.substring(8)}`;\n const pair = relevantSubfields.find(sf => sf.value === httpVersion);\n\n if (!pair) {\n return false;\n }\n pair.value = candSubfield.value;\n return true;\n}\n\n\nfunction preferQualifierVersion(field, candSubfield, relevantSubfields) {\n if (!canContainOptionalQualifier(field.tag, candSubfield.code)) { // currently only 300$a and 776$i can prefer source...\n return false;\n }\n\n const [name1, qualifier1] = splitToNameAndQualifier(candSubfield.value);\n const pair = relevantSubfields.find(sf => subfieldQualifierCheck(sf, name1, qualifier1));\n if (!pair) {\n return false;\n }\n // SN: \"Kuvailuohjeiden n\u00E4k\u00F6kulmasta epubille ei pit\u00E4isi koskaan merkit\u00E4 sivum\u00E4\u00E4r\u00E4\u00E4\"\n if (field.tag === '300' && candSubfield.code === 'a' && candSubfield.value.match(/(?:online|verkko)/iu)) {\n return true; // True, but don't prefer the source value\n }\n\n pair.value = candSubfield.value;\n return true;\n\n function subfieldQualifierCheck(subfield, name, qualifier) {\n const [name2, qualifier2] = splitToNameAndQualifier(candSubfield.value);\n if (name !== name2) {\n return false;\n }\n if (!qualifier || !qualifier2 || qualifier === qualifier2) {\n return true;\n }\n return false;\n }\n\n}\n\nfunction preferSourceCorporateName(field, candSubfield, pair) {\n if (candSubfield.code !== 'a' || !['110', '610', '710', '810'].includes(field.tag)) {\n return false;\n }\n nvdebug(`CORP base '${pair.value}' vs '${candSubfield.value}'`, debugDev);\n const prefer = actualPrefenceCheck();\n if (prefer) {\n pair.value = candSubfield.value;\n return true;\n }\n return false;\n\n function actualPrefenceCheck() {\n if (candSubfield.value.match(/^Werner S\u00F6derstr\u00F6m/u) && pair.value.match(/^WSOY/ui)) {\n return true;\n }\n if (candSubfield.value.match(/^ntamo/u) && pair.value.match(/^N(?:tamo|TAMO)/u)) {\n return true;\n }\n // Prefer (qualifier):\n const [sourceName, sourceQualifier] = splitToNameAndQualifier(candSubfield.value);\n const [baseName, baseQualifier] = splitToNameAndQualifier(pair.value);\n if (sourceName === baseName && baseQualifier === undefined && sourceQualifier !== undefined) {\n return true;\n }\n // Not taking prefix and suffix into account here...\n return false;\n }\n\n}\n\nexport function mergeSubfield(targetField, candSubfield) {\n // Replace existing subfield with the incoming field. These replacements are by name rather hacky...\n // Currenty we only select the better X00$d.\n // In future we might do more things here. Examples:\n // - \"FOO\" gets replaced by \"Foo\" in certain fields.\n // - \"Etunimi Sukunimi\" might lose to \"Sukunimi, Etunimi\" in X00 fields.\n // - [put your ideas here]\n // Return true, if replace is done.\n // However, replacing/succeeding requires a sanity check, that the new value is a better one...\n // Thus, typically this function fails...\n\n const relevantSubfields = targetField.subfields.filter(subfield => subfield.code === candSubfield.code);\n\n // There's nothing to replace the incoming subfield with. Thus abort:\n if (relevantSubfields.length === 0) {\n return false;\n }\n\n nvdebug(`Got ${relevantSubfields.length} sf-cand(s) for field ${targetField.tag}\u2021${candSubfield.code}`, debugDev);\n\n\n if (replaceDatesAssociatedWithName(targetField, candSubfield, relevantSubfields) ||\n preferHyphenatedISBN(targetField, candSubfield, relevantSubfields) ||\n preferHttpsOverHttp(candSubfield, relevantSubfields) ||\n preferSourceCorporateName(targetField, candSubfield, relevantSubfields[0]) || // SF is non-repeat\n preferQualifierVersion(targetField, candSubfield, relevantSubfields) ||\n isSynonym(targetField, candSubfield, relevantSubfields)) {\n return true;\n }\n\n // We found a crappy empty subfield: replace that with a meaningful one.\n // 260 $a value \"[S.l]\" is the main type for this.\n const meaninglessSubfields = relevantSubfields.filter(sf => !valueCarriesMeaning(targetField.tag, sf.code, sf.value));\n if (meaninglessSubfields.length > 0) {\n meaninglessSubfields[0].value = candSubfield.value;\n return true;\n }\n\n // Mark 490$v \"osa 1\" vs \"1\" as merged (2nd part of MET-53).\n // NB! Keeps the original value and drops the incoming value. (Just preventing it from going to add-part...)\n // NB! We could improve this and choose the longer value later on.\n if (subfieldContainsPartData(targetField.tag, candSubfield.code)) {\n if (relevantSubfields.some(sf => partsAgree(sf.value, candSubfield.value, targetField.tag, candSubfield.code))) {\n return true;\n }\n }\n return false; // default to failure\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,47 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var _normalizeFieldForComparison = require("../normalizeFieldForComparison.js");
|
|
11
|
-
var _sortSubfields = require("../sortSubfields");
|
|
12
|
-
var _punctuation = require("../punctuation2");
|
|
13
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
-
// NB This should be moved and converted to a validator/fixer as well...
|
|
15
|
-
const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields');
|
|
16
|
-
//const debugData = debug.extend('data');
|
|
17
|
-
const debugDev = debug.extend('dev');
|
|
18
|
-
function recordRemoveDuplicateSubfieldsFromFields(record) {
|
|
19
|
-
record.fields.forEach(field => fieldRemoveDuplicateSubfields(field));
|
|
1
|
+
import { nvdebug, subfieldToString } from "../utils.js";
|
|
2
|
+
import createDebugLogger from "debug";
|
|
3
|
+
import { cloneAndRemovePunctuation } from "../normalizeFieldForComparison.js";
|
|
4
|
+
import { sortAdjacentSubfields } from "../sortSubfields.js";
|
|
5
|
+
import { fieldFixPunctuation } from "../punctuation2.js";
|
|
6
|
+
const debug = createDebugLogger("@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields");
|
|
7
|
+
const debugDev = debug.extend("dev");
|
|
8
|
+
export function recordRemoveDuplicateSubfieldsFromFields(record) {
|
|
9
|
+
record.fields.forEach((field) => fieldRemoveDuplicateSubfields(field));
|
|
20
10
|
}
|
|
21
|
-
function fieldRemoveDuplicateSubfields(field) {
|
|
22
|
-
|
|
23
|
-
if (!field.subfields || ['264', '300', '382', '505'].includes(field.tag)) {
|
|
11
|
+
export function fieldRemoveDuplicateSubfields(field) {
|
|
12
|
+
if (!field.subfields || ["264", "300", "382", "505"].includes(field.tag)) {
|
|
24
13
|
return;
|
|
25
14
|
}
|
|
26
|
-
const strippedField =
|
|
27
|
-
|
|
15
|
+
const strippedField = cloneAndRemovePunctuation(field);
|
|
28
16
|
let seen = {};
|
|
29
17
|
field.subfields = field.subfields.filter((sf, i) => notSeenBefore(sf, i));
|
|
30
18
|
if (field.collapsed) {
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
sortAdjacentSubfields(field);
|
|
20
|
+
fieldFixPunctuation(field);
|
|
33
21
|
delete field.collapsed;
|
|
34
22
|
}
|
|
35
23
|
function notSeenBefore(sf, index) {
|
|
36
|
-
const subfieldAsString =
|
|
24
|
+
const subfieldAsString = subfieldToString(strippedField.subfields[index]);
|
|
37
25
|
if (seen[subfieldAsString]) {
|
|
38
|
-
|
|
39
|
-
field.collapsed = 1;
|
|
26
|
+
nvdebug(`Remove field-internal duplicate subfield ${subfieldToString(sf)}`, debugDev);
|
|
27
|
+
field.collapsed = 1;
|
|
40
28
|
return false;
|
|
41
29
|
}
|
|
42
|
-
//nvdebug(`identical subfield removal: Add ${subfieldAsString} to seen[]`, debugDev);
|
|
43
30
|
seen[subfieldAsString] = subfieldAsString;
|
|
44
31
|
return true;
|
|
45
32
|
}
|
|
46
33
|
}
|
|
47
|
-
//# sourceMappingURL=removeDuplicateSubfields.js.map
|
|
34
|
+
//# sourceMappingURL=removeDuplicateSubfields.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/merge-fields/removeDuplicateSubfields.js"],
|
|
4
|
+
"sourcesContent": ["\nimport {nvdebug, subfieldToString} from '../utils.js';\nimport createDebugLogger from 'debug';\nimport {cloneAndRemovePunctuation} from '../normalizeFieldForComparison.js';\nimport {sortAdjacentSubfields} from '../sortSubfields.js';\nimport {fieldFixPunctuation} from '../punctuation2.js';\n\n\n// NB This should be moved and converted to a validator/fixer as well...\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:merge-fields:removeDuplicateSubfields');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function recordRemoveDuplicateSubfieldsFromFields(record) {\n record.fields.forEach(field => fieldRemoveDuplicateSubfields(field));\n}\n\nexport function fieldRemoveDuplicateSubfields(field) {\n // Skip bad (382, 505) and risky (264 ...) stuff: 382$n, 505$r, others...\n if (!field.subfields || ['264', '300', '382', '505'].includes(field.tag)) {\n return;\n }\n\n const strippedField = cloneAndRemovePunctuation(field); // make punctuation-less version\n\n let seen = {};\n\n field.subfields = field.subfields.filter((sf, i) => notSeenBefore(sf, i));\n\n if (field.collapsed) {\n sortAdjacentSubfields(field);\n fieldFixPunctuation(field);\n delete field.collapsed;\n }\n\n\n function notSeenBefore(sf, index) {\n const subfieldAsString = subfieldToString(strippedField.subfields[index]); // use normalized form\n if (seen[subfieldAsString]) {\n nvdebug(`Remove field-internal duplicate subfield ${subfieldToString(sf)}`, debugDev);\n field.collapsed = 1; // trigger punctuation reset\n return false;\n }\n //nvdebug(`identical subfield removal: Add ${subfieldAsString} to seen[]`, debugDev);\n seen[subfieldAsString] = subfieldAsString;\n return true;\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAQ,SAAS,wBAAuB;AACxC,OAAO,uBAAuB;AAC9B,SAAQ,iCAAgC;AACxC,SAAQ,6BAA4B;AACpC,SAAQ,2BAA0B;AAIlC,MAAM,QAAQ,kBAAkB,gFAAgF;AAEhH,MAAM,WAAW,MAAM,OAAO,KAAK;AAE5B,gBAAS,yCAAyC,QAAQ;AAC/D,SAAO,OAAO,QAAQ,WAAS,8BAA8B,KAAK,CAAC;AACrE;AAEO,gBAAS,8BAA8B,OAAO;AAEnD,MAAI,CAAC,MAAM,aAAa,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,MAAM,GAAG,GAAG;AACxE;AAAA,EACF;AAEA,QAAM,gBAAgB,0BAA0B,KAAK;AAErD,MAAI,OAAO,CAAC;AAEZ,QAAM,YAAY,MAAM,UAAU,OAAO,CAAC,IAAI,MAAM,cAAc,IAAI,CAAC,CAAC;AAExE,MAAI,MAAM,WAAW;AACnB,0BAAsB,KAAK;AAC3B,wBAAoB,KAAK;AACzB,WAAO,MAAM;AAAA,EACf;AAGA,WAAS,cAAc,IAAI,OAAO;AAChC,UAAM,mBAAmB,iBAAiB,cAAc,UAAU,KAAK,CAAC;AACxE,QAAI,KAAK,gBAAgB,GAAG;AAC1B,cAAQ,4CAA4C,iBAAiB,EAAE,CAAC,IAAI,QAAQ;AACpF,YAAM,YAAY;AAClB,aAAO;AAAA,IACT;AAEA,SAAK,gBAAgB,IAAI;AACzB,WAAO;AAAA,EACT;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.normalizeForSamenessCheck = normalizeForSamenessCheck;
|
|
7
|
-
exports.valueCarriesMeaning = valueCarriesMeaning;
|
|
8
|
-
//import {nvdebug} from '../utils';
|
|
9
|
-
|
|
10
|
-
function valueCarriesMeaning(tag, subfieldCode, value) {
|
|
11
|
-
// Some data is pretty meaningless and as meaningless is pretty close to nothing, this meaningless data should no prevent merge.
|
|
12
|
-
// The list below is incomples (swedish translations etc)
|
|
13
|
-
if (tag === '260' || tag === '264') {
|
|
14
|
-
// We drop these, instead of normalizing, as KV does not put this information in place...
|
|
15
|
-
if (subfieldCode === 'a') {
|
|
1
|
+
export function valueCarriesMeaning(tag, subfieldCode, value) {
|
|
2
|
+
if (tag === "260" || tag === "264") {
|
|
3
|
+
if (subfieldCode === "a") {
|
|
16
4
|
if (value.match(/^[^a-z]*(?:Kustannuspaikka tuntematon|S\.l)[^a-z]*$/ui)) {
|
|
17
5
|
return false;
|
|
18
6
|
}
|
|
19
7
|
}
|
|
20
|
-
if (subfieldCode ===
|
|
8
|
+
if (subfieldCode === "b") {
|
|
21
9
|
if (value.match(/^[^a-z]*(?:Kustantaja tuntematon|S\.n)[^a-z]*$/ui)) {
|
|
22
10
|
return false;
|
|
23
11
|
}
|
|
@@ -26,42 +14,33 @@ function valueCarriesMeaning(tag, subfieldCode, value) {
|
|
|
26
14
|
}
|
|
27
15
|
return true;
|
|
28
16
|
}
|
|
29
|
-
function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {
|
|
30
|
-
|
|
31
|
-
// Repeatable subfields are currently handled in mergeSubfields.js. Only non-repeatable subfields block field merge,
|
|
32
|
-
// (This split is suboptiomal... Minimum fix: make this disctinction cleaner...)
|
|
33
|
-
if (subfieldCode === 'a' && ['100', '600', '700', '800'].includes(tag)) {
|
|
17
|
+
export function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {
|
|
18
|
+
if (subfieldCode === "a" && ["100", "600", "700", "800"].includes(tag)) {
|
|
34
19
|
return normalizePersonalName(originalValue);
|
|
35
20
|
}
|
|
36
|
-
|
|
37
|
-
// NB! originalValue should already be lowercased, stripped on initial '[' chars and postpunctuation.
|
|
38
|
-
if (tag === '250' && subfieldCode === 'a') {
|
|
21
|
+
if (tag === "250" && subfieldCode === "a") {
|
|
39
22
|
return normalizeEditionStatement(originalValue);
|
|
40
23
|
}
|
|
41
|
-
|
|
42
|
-
// 506 - Restrictions on Access Note (R), $a - Terms governing access (NR)
|
|
43
|
-
if (tag === '506' && subfieldCode === 'a') {
|
|
24
|
+
if (tag === "506" && subfieldCode === "a") {
|
|
44
25
|
return normalize506a(originalValue);
|
|
45
26
|
}
|
|
46
|
-
if (tag ===
|
|
27
|
+
if (tag === "534" && subfieldCode === "p") {
|
|
47
28
|
return normalizeOriginalVersionNoteIntroductoryPhrase(originalValue);
|
|
48
29
|
}
|
|
49
30
|
return originalValue;
|
|
50
31
|
}
|
|
51
32
|
function normalizePersonalName(originalValue) {
|
|
52
|
-
|
|
53
|
-
return originalValue.replace(/^([^,]+), ([^,]+)$/u, '$2 $1');
|
|
33
|
+
return originalValue.replace(/^([^,]+), ([^,]+)$/u, "$2 $1");
|
|
54
34
|
}
|
|
55
|
-
const sallittu506a = [
|
|
35
|
+
const sallittu506a = ["sallittu kaikenik\xE4isille", "sallittu", "s"];
|
|
56
36
|
function normalize506a(originalValue) {
|
|
57
37
|
if (sallittu506a.includes(originalValue)) {
|
|
58
38
|
return sallittu506a[0];
|
|
59
39
|
}
|
|
60
40
|
return originalValue;
|
|
61
41
|
}
|
|
62
|
-
const introductoryPhrasesMeaning1 = [
|
|
42
|
+
const introductoryPhrasesMeaning1 = ["alkuper\xE4inen", "alkuper\xE4isen julkaisutiedot", "alun perin julkaistu", "alunperin julkaistu"];
|
|
63
43
|
function normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {
|
|
64
|
-
// MELKEHITYS-1935-ish:
|
|
65
44
|
if (introductoryPhrasesMeaning1.includes(originalValue)) {
|
|
66
45
|
return introductoryPhrasesMeaning1[0];
|
|
67
46
|
}
|
|
@@ -69,16 +48,12 @@ function normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {
|
|
|
69
48
|
}
|
|
70
49
|
function normalizeEditionStatement(originalValue) {
|
|
71
50
|
const value = originalValue;
|
|
72
|
-
|
|
73
|
-
// As normalization tries to translate things info Finnish, use this for similarity check only!
|
|
74
51
|
if (value.match(/^[1-9][0-9]*(?:\.|:a|nd|rd|st|th) (?:ed\.?|edition|p\.?|painos|uppl\.?|upplagan)[.\]]*$/ui)) {
|
|
75
|
-
const nth = value.replace(/[^0-9].*$/u,
|
|
52
|
+
const nth = value.replace(/[^0-9].*$/u, "");
|
|
76
53
|
return `${nth}. painos`;
|
|
77
54
|
}
|
|
78
|
-
|
|
79
|
-
// Quick and dirty fix for
|
|
80
55
|
if (value.match(/^[1-9][0-9]*(?:\.|:a|nd|rd|st|th)(?: förnyade|,? rev\.| uud\.| uudistettu) (?:ed\.?|edition|p\.?|painos|uppl\.?|upplagan)[.\]]*$/ui)) {
|
|
81
|
-
const nth = value.replace(/[^0-9].*$/u,
|
|
56
|
+
const nth = value.replace(/[^0-9].*$/u, "");
|
|
82
57
|
return `${nth}. uudistettu painos`;
|
|
83
58
|
}
|
|
84
59
|
if (value.match(/^(?:First|Första|Ensimmäinen) (?:ed\.?|edition|p\.?|painos|uppl\.?|upplagan)[.\]]*$/ui)) {
|
|
@@ -95,4 +70,4 @@ function normalizeEditionStatement(originalValue) {
|
|
|
95
70
|
}
|
|
96
71
|
return originalValue;
|
|
97
72
|
}
|
|
98
|
-
//# sourceMappingURL=worldKnowledge.js.map
|
|
73
|
+
//# sourceMappingURL=worldKnowledge.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/merge-fields/worldKnowledge.js"],
|
|
4
|
+
"sourcesContent": ["//import {nvdebug} from '../utils';\n\nexport function valueCarriesMeaning(tag, subfieldCode, value) {\n // Some data is pretty meaningless and as meaningless is pretty close to nothing, this meaningless data should no prevent merge.\n // The list below is incomples (swedish translations etc)\n if (tag === '260' || tag === '264') {\n // We drop these, instead of normalizing, as KV does not put this information in place...\n if (subfieldCode === 'a') {\n if (value.match(/^[^a-z]*(?:Kustannuspaikka tuntematon|S\\.l)[^a-z]*$/ui)) {\n return false;\n }\n }\n if (subfieldCode === 'b') {\n if (value.match(/^[^a-z]*(?:Kustantaja tuntematon|S\\.n)[^a-z]*$/ui)) {\n return false;\n }\n }\n return true;\n }\n return true;\n}\n\nexport function normalizeForSamenessCheck(tag, subfieldCode, originalValue) {\n // NB! These work only for non-repeatable subfields!\n // Repeatable subfields are currently handled in mergeSubfields.js. Only non-repeatable subfields block field merge,\n // (This split is suboptiomal... Minimum fix: make this disctinction cleaner...)\n if (subfieldCode === 'a' && ['100', '600', '700', '800'].includes(tag)) {\n return normalizePersonalName(originalValue);\n }\n\n // NB! originalValue should already be lowercased, stripped on initial '[' chars and postpunctuation.\n if (tag === '250' && subfieldCode === 'a') {\n return normalizeEditionStatement(originalValue);\n }\n\n // 506 - Restrictions on Access Note (R), $a - Terms governing access (NR)\n if (tag === '506' && subfieldCode === 'a') {\n return normalize506a(originalValue);\n }\n\n if (tag === '534' && subfieldCode === 'p') {\n return normalizeOriginalVersionNoteIntroductoryPhrase(originalValue);\n }\n\n return originalValue;\n}\n\n\nfunction normalizePersonalName(originalValue) {\n // Use more readable \"Forename Surname\" format in comparisons:\n return originalValue.replace(/^([^,]+), ([^,]+)$/u, '$2 $1');\n}\n\nconst sallittu506a = ['sallittu kaikenik\u00E4isille', 'sallittu', 's']; // downcased, without punctuation\nfunction normalize506a(originalValue) {\n if (sallittu506a.includes(originalValue)) {\n return sallittu506a[0];\n }\n return originalValue;\n}\n\nconst introductoryPhrasesMeaning1 = ['alkuper\u00E4inen', 'alkuper\u00E4isen julkaisutiedot', 'alun perin julkaistu', 'alunperin julkaistu'];\nfunction normalizeOriginalVersionNoteIntroductoryPhrase(originalValue) {\n // MELKEHITYS-1935-ish:\n if (introductoryPhrasesMeaning1.includes(originalValue)) {\n return introductoryPhrasesMeaning1[0];\n }\n\n return originalValue;\n}\n\nfunction normalizeEditionStatement(originalValue) {\n const value = originalValue;\n\n // As normalization tries to translate things info Finnish, use this for similarity check only!\n if (value.match(/^[1-9][0-9]*(?:\\.|:a|nd|rd|st|th) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n const nth = value.replace(/[^0-9].*$/u, '');\n return `${nth}. painos`;\n }\n\n // Quick and dirty fix for\n if (value.match(/^[1-9][0-9]*(?:\\.|:a|nd|rd|st|th)(?: f\u00F6rnyade|,? rev\\.| uud\\.| uudistettu) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n const nth = value.replace(/[^0-9].*$/u, '');\n return `${nth}. uudistettu painos`;\n }\n\n if (value.match(/^(?:First|F\u00F6rsta|Ensimm\u00E4inen) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `1. painos`;\n }\n\n if (value.match(/^(?:Andra|Second|Toinen) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `2. painos`;\n }\n\n if (value.match(/^(?:Kolmas|Third|Tredje) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `3. painos`;\n }\n\n if (value.match(/^(?:Fourth|Fj\u00E4rde|Nelj\u00E4s) (?:ed\\.?|edition|p\\.?|painos|uppl\\.?|upplagan)[.\\]]*$/ui)) {\n return `4. painos`;\n }\n\n return originalValue;\n}\n"],
|
|
5
|
+
"mappings": "AAEO,gBAAS,oBAAoB,KAAK,cAAc,OAAO;AAG5D,MAAI,QAAQ,SAAS,QAAQ,OAAO;AAElC,QAAI,iBAAiB,KAAK;AACxB,UAAI,MAAM,MAAM,uDAAuD,GAAG;AACxE,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,iBAAiB,KAAK;AACxB,UAAI,MAAM,MAAM,kDAAkD,GAAG;AACnE,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,gBAAS,0BAA0B,KAAK,cAAc,eAAe;AAI1E,MAAI,iBAAiB,OAAO,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AACtE,WAAO,sBAAsB,aAAa;AAAA,EAC5C;AAGA,MAAI,QAAQ,SAAS,iBAAiB,KAAK;AACzC,WAAO,0BAA0B,aAAa;AAAA,EAChD;AAGA,MAAI,QAAQ,SAAS,iBAAiB,KAAK;AACzC,WAAO,cAAc,aAAa;AAAA,EACpC;AAEA,MAAI,QAAQ,SAAS,iBAAiB,KAAK;AACzC,WAAO,+CAA+C,aAAa;AAAA,EACrE;AAEA,SAAO;AACT;AAGA,SAAS,sBAAsB,eAAe;AAE5C,SAAO,cAAc,QAAQ,uBAAuB,OAAO;AAC7D;AAEA,MAAM,eAAe,CAAC,+BAA4B,YAAY,GAAG;AACjE,SAAS,cAAc,eAAe;AACpC,MAAI,aAAa,SAAS,aAAa,GAAG;AACxC,WAAO,aAAa,CAAC;AAAA,EACvB;AACA,SAAO;AACT;AAEA,MAAM,8BAA8B,CAAC,mBAAgB,kCAA+B,wBAAwB,qBAAqB;AACjI,SAAS,+CAA+C,eAAe;AAErE,MAAI,4BAA4B,SAAS,aAAa,GAAG;AACvD,WAAO,4BAA4B,CAAC;AAAA,EACtC;AAEA,SAAO;AACT;AAEA,SAAS,0BAA0B,eAAe;AAChD,QAAM,QAAQ;AAGd,MAAI,MAAM,MAAM,2FAA2F,GAAG;AAC5G,UAAM,MAAM,MAAM,QAAQ,cAAc,EAAE;AAC1C,WAAO,GAAG,GAAG;AAAA,EACf;AAGA,MAAI,MAAM,MAAM,oIAAoI,GAAG;AACrJ,UAAM,MAAM,MAAM,QAAQ,cAAc,EAAE;AAC1C,WAAO,GAAG,GAAG;AAAA,EACf;AAEA,MAAI,MAAM,MAAM,uFAAuF,GAAG;AACxG,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM,kFAAkF,GAAG;AACnG,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM,kFAAkF,GAAG;AACnG,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM,mFAAmF,GAAG;AACpG,WAAO;AAAA,EACT;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|