sedra-model
Version:
Sedra models and related utility functions
2,059 lines (2,007 loc) • 68.8 kB
JavaScript
/** @module sedraModel */
/**
* @file Sedra models and related utility functions
* @version 1.2.0
* @author Greg Borota
* @copyright (c) 2017 Greg Borota.
* @license MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// https://peshitta.github.io
// https://sedra.bethmardutho.org/about/fonts
// http://cal1.cn.huc.edu/searching/fullbrowser.html
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.sedraModel = {})));
}(this, (function (exports) { 'use strict';
/**
* Word Type enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordType = Object.freeze([
'Normal',
'Parenthesized',
'Bracketed',
'HighFrequency' // e.g. propositions
]);
/**
* Vowel enumeration
* @static
* @const
* @type { Array.<string> }
*/
var vowel = Object.freeze(['', 'a', 'o', 'e', 'i', 'u']);
/**
* Word Number enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordNumber = Object.freeze(['', 'Singular', 'Plural']);
/**
* Word Gender enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordGender = Object.freeze([
'',
'Common',
'Masculine',
'Feminine'
]);
/**
* Word Form enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordForm = Object.freeze([
'',
'Peal',
'Ethpeal',
'Pael',
'Ethpael',
'Aphel',
'Ettaphal',
'Shaphel',
'Eshtaphal',
'Saphel',
'Estaphal',
'Pauel',
'Ethpaual',
'Paiel',
'Ethpaial',
'Palpal',
'Ethpalpal',
'Palpel',
'Ethpalpal1',
'Pamel',
'Ethpamal',
'Parel',
'Ethparal',
'Pali',
'Ethpali',
'Pahli',
'Ethpahli',
'Taphel',
'Ethaphal'
]);
/**
* Root records, e.g. 0:2,"AB","ab |A",0
* Id is the position in the containing array so it is not stored
*
* @static
* @param { string } root e.g. "AB"
* @param { string } sort e.g. "ab |A"
* @param { number } attributes 16-bit map
* @returns { Root } Sedra Root row
*/
var makeRoot = function (root, sort, attributes) { return Object.freeze(
Object.create(null, {
root: { value: root, enumerable: true },
sort: { value: sort, enumerable: true },
attributes: { value: attributes, enumerable: true }
})
); };
/**
* Build Root Attribute object
* @static
* @param { boolean } seyame true if root has seyame
* @param { string } rootType word type enumeration
* @returns { RootAttribute } Root Attribute object
*/
var makeRootAttribute = function (seyame, rootType) { return Object.freeze(
Object.create(null, {
seyame: { value: seyame, enumerable: true },
rootType: { value: rootType, enumerable: true }
})
); };
/**
* Get Root Attribute object from root attribute bit map
* @static
* @param { number } attributes 16-bit map
* @returns { RootAttribute } Root Attribute object
*/
var getRootAttribute = function (attributes) { return makeRootAttribute(
!!(0x1 & attributes), // 0 SEYAME FLAG
wordType[(0x6 & attributes) >>> 1] // 1-2 ROOT TYPE
); };
/**
* Return flatten root object with parsed attribute values
* @static
* @param { number } id the id of current root object
* @param { Root } root root raw object
* @returns { FlatRoot } the flatten root model
*/
var getRoot = function (id, root) {
if (root) {
var attributes = getRootAttribute(root.attributes);
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
root: { value: root.root, enumerable: true },
sort: { value: root.sort, enumerable: true },
seyame: { value: attributes.seyame, enumerable: true },
rootType: { value: attributes.rootType, enumerable: true }
})
);
}
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
root: { value: null, enumerable: true },
sort: { value: null, enumerable: true },
seyame: { value: null, enumerable: true },
rootType: { value: null, enumerable: true }
})
);
};
/**
* Lexeme Grammatical Category enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemeGrammaticalCategory = Object.freeze([
'Verb',
'ParticipleAdjective',
'Denominative',
'Substantive',
'Noun',
'Pronoun',
'ProperNoun',
'Numeral',
'Adjective',
'Particle',
'Idiom',
'Adverb-)iTt',
'AdjectiveOfPlace',
'Adverb'
]);
/**
* Lexeme First Suffix enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemeFirstSuffix = Object.freeze([
'',
'to)',
'To)',
'no)',
'ono)',
'iTno)',
'wuno)',
'tono)',
'twuno)',
'wuso)',
'oro)',
'qono)',
'yin'
]);
/**
* Second Second Suffix enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemeSecondSuffix = Object.freeze(['', 'oTo)', 'iTto)']);
/**
* Lexeme Third Suffix enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemeThirdSuffix = Object.freeze(['', 'wuto)', 'o)iTt']);
/**
* Lexeme Prefix enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemePrefix = Object.freeze(['', 'm', 't', '$']);
/**
* Lexeme Radical Type enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemeRadicalType = Object.freeze([
'',
'Bi',
'Tri',
'FourRadical',
'FiveRadical',
'SixRadical',
'Compound'
]);
/**
* Lexeme Form enumeration
* @static
* @const
* @type { Array.<string> }
*/
var lexemeForm = Object.freeze([
'',
'Peal',
'Ethpeal',
'Pael',
'Ethpael',
'Aphel',
'Ettaphal',
'Shaphel',
'Eshtaphal',
'Saphel',
'Estaphal',
'P',
'Ethp',
'Palpel',
'Ethpalpal',
'Pamel' // ??? not documented
]);
/**
* Lexeme records, e.g. 1:2,0:2,"ABA",41960448,16
* Id is the position in the array so it is not stored
*
* @static
* @param { number } rootId Root Address, e.g. 2
* @param { string } lexeme e.g. "ABA"
* @param { number } morphologicalType 32-bit map
* @param { number } attributes 16-bit map
* @returns { Lexeme } Sedra Lexeme row
*/
var makeLexeme = function (rootId, lexeme, morphologicalType, attributes) { return Object.freeze(
Object.create(null, {
rootId: { value: rootId, enumerable: true },
lexeme: { value: lexeme, enumerable: true },
morphologicalType: { value: morphologicalType, enumerable: true },
attributes: { value: attributes, enumerable: true }
})
); };
/**
* Build Lexeme Attribute object
* @static
* @param { boolean } seyame true if lexeme has seyame
* @param { string } wordType word type enumeration
* @param { string } grammaticalCategory grammatical category enumeration
* @param { boolean } listing not clear yet what this is used for
* @returns { LexemeAttribute } Lexeme Attribute object
*/
var makeLexemeAttribute = function (
seyame,
wordType$$1,
grammaticalCategory,
listing
) { return Object.freeze(
Object.create(null, {
seyame: { value: seyame, enumerable: true },
wordType: { value: wordType$$1, enumerable: true },
grammaticalCategory: { value: grammaticalCategory, enumerable: true },
listing: { value: listing, enumerable: true } // TODO not documented, need to figure out
})
); };
/**
* Get Lexeme Attribute object from lexeme attribute bit map
* @static
* @param { number } attributes 16-bit map
* @returns { LexemeAttribute } Lexeme Attribute object
*/
var getLexemeAttribute = function (attributes) { return makeLexemeAttribute(
!!(0x1 & attributes), // 0 SEYAME FLAG
wordType[(0x2 & attributes) >>> 1], // 1 WORD TYPE
lexemeGrammaticalCategory[(0x3c & attributes) >>> 2], // 2-5 GRAMMATICAL CATEGORY
!!(0x40 & (attributes >>> 6)) // 6 ?
); };
/**
* Build Lexeme Morphological Type object
* @static
* @param { string } firstSuffix First suffix enumeration
* @param { string } secondSuffix Second suffix enumeration
* @param { string } thirdSuffix Third suffix enumeration
* @param { string } prefix M, T, ? enumeration
* @param { string } firstVowel First Vowel
* @param { string } secondVowel Second Vowel
* @param { string } thirdVowel Third Vowel
* @param { string } fourthVowel Forth Vowel
* @param { number } vowelCount Total no of vowels in lexeme
* @param { string } radicalType Radical type enumeration
* @param { string } form Word form enumeration
* @returns { LexemeMorphologicalType } Lexeme Morphological Type object
*/
var makeLexemeMorphologicalType = function (
firstSuffix,
secondSuffix,
thirdSuffix,
prefix,
firstVowel,
secondVowel,
thirdVowel,
fourthVowel,
vowelCount,
radicalType,
form
) { return Object.freeze(
Object.create(null, {
firstSuffix: { value: firstSuffix, enumerable: true },
secondSuffix: { value: secondSuffix, enumerable: true },
thirdSuffix: { value: thirdSuffix, enumerable: true },
prefix: { value: prefix, enumerable: true },
firstVowel: { value: firstVowel, enumerable: true },
secondVowel: { value: secondVowel, enumerable: true },
thirdVowel: { value: thirdVowel, enumerable: true },
fourthVowel: { value: fourthVowel, enumerable: true },
vowelCount: { value: vowelCount, enumerable: true },
radicalType: { value: radicalType, enumerable: true },
form: { value: form, enumerable: true }
})
); };
/**
* Get Lexeme Morphological Type object from lexeme bit map
* @static
* @param { number } morphologicalType Morphological Type 32-bit map
* @returns { LexemeMorphologicalType } Lexeme Morphological Type object
*/
var getLexemeMorphologicalType = function (morphologicalType) { return makeLexemeMorphologicalType(
lexemeFirstSuffix[0xf & morphologicalType], // 0-3 First SUFFIX
lexemeSecondSuffix[(0x30 & morphologicalType) >>> 4], // 4-5 SECOND SUFFIX
lexemeThirdSuffix[(0xc0 & morphologicalType) >>> 6], // 6-7 THIRD SUFFIX
lexemePrefix[(0x300 & morphologicalType) >>> 8], // 8-9 PREFIX
vowel[(0x1c00 & morphologicalType) >>> 10], // 10-12 FIRST VOWEL
vowel[(0xe000 & morphologicalType) >>> 13], // 13-15 SECOND VOWEL
vowel[(0x70000 & morphologicalType) >>> 16], // 16-18 THIRD VOWEL
vowel[(0x380000 & morphologicalType) >>> 19], // 19-21 FOURTH VOWEL
(0x1c00000 & morphologicalType) >>> 22, // 22-24 Total no of vowels in lexeme
lexemeRadicalType[(0xe000000 & morphologicalType) >>> 25], // 25-27 RADICAL TYPE
lexemeForm[(0xf0000000 & morphologicalType) >>> 28] // 28-31 FORM
); };
/**
* Return flatten lexeme object with parsed attribute and morphological values
* @static
* @param { number } id the id of current lexeme object
* @param { Lexeme } lexeme lexeme raw object
* @param { Array.<Root> } roots root list
* @returns { FlatLexeme } the flatten lexeme model
*/
var getLexeme = function (id, lexeme, roots) {
if (lexeme) {
var attributes = getLexemeAttribute(lexeme.attributes);
var morphologicalType = getLexemeMorphologicalType(
lexeme.morphologicalType
);
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
rootId: { value: lexeme.rootId, enumerable: true },
root: {
value:
roots && roots[lexeme.rootId] ? roots[lexeme.rootId].root : null,
enumerable: true
},
lexeme: { value: lexeme.lexeme, enumerable: true },
firstSuffix: { value: morphologicalType.firstSuffix, enumerable: true },
secondSuffix: {
value: morphologicalType.secondSuffix,
enumerable: true
},
thirdSuffix: { value: morphologicalType.thirdSuffix, enumerable: true },
prefix: { value: morphologicalType.prefix, enumerable: true },
firstVowel: { value: morphologicalType.firstVowel, enumerable: true },
secondVowel: { value: morphologicalType.secondVowel, enumerable: true },
thirdVowel: { value: morphologicalType.thirdVowel, enumerable: true },
fourthVowel: { value: morphologicalType.fourthVowel, enumerable: true },
vowelCount: { value: morphologicalType.vowelCount, enumerable: true },
radicalType: { value: morphologicalType.radicalType, enumerable: true },
form: { value: morphologicalType.form, enumerable: true },
seyame: { value: attributes.seyame, enumerable: true },
wordType: { value: attributes.wordType, enumerable: true },
grammaticalCategory: {
value: attributes.grammaticalCategory,
enumerable: true
},
listing: { value: attributes.listing, enumerable: true }
})
);
}
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
rootId: { value: null, enumerable: true },
root: { value: null, enumerable: true },
lexeme: { value: null, enumerable: true },
firstSuffix: { value: null, enumerable: true },
secondSuffix: { value: null, enumerable: true },
thirdSuffix: { value: null, enumerable: true },
prefix: { value: null, enumerable: true },
firstVowel: { value: null, enumerable: true },
secondVowel: { value: null, enumerable: true },
thirdVowel: { value: null, enumerable: true },
fourthVowel: { value: null, enumerable: true },
vowelCount: { value: null, enumerable: true },
radicalType: { value: null, enumerable: true },
form: { value: null, enumerable: true },
seyame: { value: null, enumerable: true },
wordType: { value: null, enumerable: true },
grammaticalCategory: { value: null, enumerable: true },
listing: { value: null, enumerable: true }
})
);
};
/**
* Word Suffix Gender enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordSuffixGender = Object.freeze([
'CommonOrNone',
'Masculine',
'Feminine'
]);
/**
* Word Suffix Person enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordSuffixPerson = Object.freeze(['', 'Third', 'Second', 'First']);
/**
* Word Suffix Number enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordSuffixNumber = Object.freeze(['SingularOrNone', 'Plural']);
/**
* Word Suffix Type enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordSuffixType = Object.freeze(['', 'Suffix', 'Contraction']);
/**
* Word Person enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordPerson = Object.freeze(['', 'Third', 'Second', 'First']);
/**
* Word State enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordState = Object.freeze([
'',
'Absolute',
'Construct',
'Emphatic'
]);
/**
* Word Tense enumeration
* @static
* @const
* @type { Array.<string> }
*/
var wordTense = Object.freeze([
'',
'Perfect',
'Imperfect',
'Imperative',
'Infinitive',
'ActiveParticiple',
'PassiveParticiple',
'Participles'
]);
/**
* Word records, e.g. 2:8,1:2,"ABHOH;","AaB,oHaOH_;",7405716,129
* Id is the position in the array so it is not stored
*
* @static
* @param { number } lexemeId Lexeme Address, e.g. 2
* @param { string } word Word, e.g. "ABHOH;"
* @param { string } vocalised Vocalised Word, e.g. "AaB,oHaOH_;"
* @param { number } morphologicalType 32-bit map
* @param { number } attributes 16-bit map
* @returns { Word } Sedra Word row
*/
var makeWord = function (
lexemeId,
word,
vocalised,
morphologicalType,
attributes
) { return Object.freeze(
Object.create(null, {
lexemeId: { value: lexemeId, enumerable: true },
word: { value: word, enumerable: true },
vocalised: { value: vocalised, enumerable: true },
morphologicalType: { value: morphologicalType, enumerable: true },
attributes: { value: attributes, enumerable: true }
})
); };
/**
* Build Word Attribute object
* @static
* @param { boolean } seyame true if word has seyame
* @param { number } listing Undocumented
* @param { boolean } enclitic true if word has enclitics
* @param { boolean } lexeme true if current word is lexeme
* @returns { WordAttribute } Word Attribute object
*/
var makeWordAttribute = function (seyame, listing, enclitic, lexeme) { return Object.freeze(
Object.create(null, {
seyame: { value: seyame, enumerable: true },
listing: { value: listing, enumerable: true }, // TODO not documented, need to figure out
enclitic: { value: enclitic, enumerable: true },
lexeme: { value: lexeme, enumerable: true }
})
); };
/**
* Get Word Attribute object from word attribute bit map
* @static
* @param { number } attributes 16-bit map
* @returns { WordAttribute } Word Attribute object
*/
var getWordAttribute = function (attributes) { return makeWordAttribute(
!!(0x1 & attributes), // 0 SEYAME FLAG
(0x1e & attributes) >>> 1, // 1-4 ignore
!!(0x20 & attributes), // 5 ENCLITIC FLAG
!!(0x40 & attributes) // 6 LEXEME FLAG
); };
/**
* Build Word Morphological Type object
* @static
* @param { string } suffixGender Word Suffix Gender enumeration
* @param { string } suffixPerson Word Suffix Person enumeration
* @param { string } suffixNumber Word Suffix Number enumeration
* @param { string } suffixType Word Suffix Type enumeration
* @param { number } prefixCode Word Prefix Code
* @param { string } gender Word Gender enumeration
* @param { string } person Word Person enumeration
* @param { string } number Word Number enumeration
* @param { string } state Word State enumeration
* @param { string } tense Word Tense enumeration
* @param { string } form Word Form enumeration
* @returns { WordMorphologicalType } Word Morphological Type object
*/
var makeWordMorphologicalType = function (
suffixGender,
suffixPerson,
suffixNumber,
suffixType,
prefixCode,
gender,
person,
number,
state,
tense,
form
) { return Object.freeze(
Object.create(null, {
suffixGender: { value: suffixGender, enumerable: true },
suffixPerson: { value: suffixPerson, enumerable: true },
suffixNumber: { value: suffixNumber, enumerable: true },
suffixType: { value: suffixType, enumerable: true },
prefixCode: { value: prefixCode, enumerable: true },
gender: { value: gender, enumerable: true },
person: { value: person, enumerable: true },
number: { value: number, enumerable: true },
state: { value: state, enumerable: true },
tense: { value: tense, enumerable: true },
form: { value: form, enumerable: true }
})
); };
/**
* Get Word Morphological Type object from word bit map
* @static
* @param { number } attributes Morphological Type 32-bit map
* @returns { WordMorphologicalType } Word Morphological Type object
*/
var getWordMorphologicalType = function (attributes) { return makeWordMorphologicalType(
// 0-1 <RESERVED>
wordSuffixGender[(0xc & attributes) >>> 2], // 2-3 SUFFIX GENDER
wordSuffixPerson[(0x30 & attributes) >>> 4], // 4-5 SUFFIX PERSON
wordSuffixNumber[(0x40 & attributes) >>> 6], // 6 SUFFIX NUMBER
wordSuffixType[(0x180 & attributes) >>> 7], // 7-8 SUFFIX/CONTRACTION
(0x7e00 & attributes) >>> 9, // 9-14 PREFIX CODE
wordGender[(0x18000 & attributes) >>> 15], // 15-16 GENDER
wordPerson[(0x60000 & attributes) >>> 17], // 17-18 PERSON
wordNumber[(0x180000 & attributes) >>> 19], // 19-20 NUMBER
wordState[(0x600000 & attributes) >>> 21], // 21-22 STATE
wordTense[(0x3800000 & attributes) >>> 23], // 23-25 TENSE
wordForm[(0xfc000000 & attributes) >>> 26] // 26-31 FORM
); };
/**
* Return flatten word object with parsed attribute and morphological values
* @static
* @param { number } id the id of current word object
* @param { Word } lexeme word raw object
* @param { Array.<Lexeme> } lexemes lexeme list
* @returns { FlatWord } the flatten word model
*/
var getWord = function (id, word, lexemes) {
if (word) {
var attributes = getWordAttribute(word.attributes);
var morphologicalType = getWordMorphologicalType(word.morphologicalType);
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
lexemeId: { value: word.lexemeId, enumerable: true },
lexeme: {
value:
lexemes && lexemes[word.lexemeId]
? lexemes[word.lexemeId].lexeme
: null,
enumerable: true
},
word: { value: word.word, enumerable: true },
vocalised: { value: word.vocalised, enumerable: true },
suffixGender: {
value: morphologicalType.suffixGender,
enumerable: true
},
suffixPerson: {
value: morphologicalType.suffixPerson,
enumerable: true
},
suffixNumber: {
value: morphologicalType.suffixNumber,
enumerable: true
},
suffixType: { value: morphologicalType.suffixType, enumerable: true },
prefixCode: { value: morphologicalType.prefixCode, enumerable: true },
gender: { value: morphologicalType.gender, enumerable: true },
person: { value: morphologicalType.person, enumerable: true },
number: { value: morphologicalType.number, enumerable: true },
state: { value: morphologicalType.state, enumerable: true },
tense: { value: morphologicalType.tense, enumerable: true },
form: { value: morphologicalType.form, enumerable: true },
seyame: { value: attributes.seyame, enumerable: true },
listing: { value: attributes.listing, enumerable: true },
enclitic: { value: attributes.enclitic, enumerable: true },
isLexeme: { value: attributes.lexeme, enumerable: true }
})
);
}
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
lexemeId: { value: null, enumerable: true },
lexeme: { value: null, enumerable: true },
word: { value: null, enumerable: true },
vocalised: { value: null, enumerable: true },
suffixGender: { value: null, enumerable: true },
suffixPerson: { value: null, enumerable: true },
suffixNumber: { value: null, enumerable: true },
suffixType: { value: null, enumerable: true },
prefixCode: { value: null, enumerable: true },
gender: { value: null, enumerable: true },
person: { value: null, enumerable: true },
number: { value: null, enumerable: true },
state: { value: null, enumerable: true },
tense: { value: null, enumerable: true },
form: { value: null, enumerable: true },
seyame: { value: null, enumerable: true },
listing: { value: null, enumerable: true },
enclitic: { value: null, enumerable: true },
isLexeme: { value: null, enumerable: true }
})
);
};
/**
* Text position enumeration
* @static
* @const
* @type { Array.<string> }
*/
var textPosition = Object.freeze(['BeforeWord', 'AfterWord']);
/**
* Font type enumeration
* @static
* @const
* @type { Array.<string> }
*/
var fontType = Object.freeze(['Normal', 'Italic']);
/**
* Verb type enumeration
* @const
* @static
* @type { Array.<string> }
*/
var verbType = Object.freeze(['None', 'Transitive', 'Intransitive']);
/**
* English meaning, e.g. 3:165,1:97,"cause","without","","",0,0
* Id is the position in the database array so it is not stored
*
* @static
* @param { number } lexemeId Lexeme address, e.g. 97
* @param { string } word Meaning, e.g. "cause"
* @param { string } before String before meaning, e.g. "without" (i.e. without cause)
* @param { number } after String after meaning, e.g. ""
* @param { number } comment Comment, e.g. ""
* @param { number } attributes 16-bit map
* @param { number } flag 1 bit flag
* @returns { English } Sedra English row
*/
var makeEnglish = function (
lexemeId,
word,
before,
after,
comment,
attributes,
flag
) { return Object.freeze(
Object.create(null, {
lexemeId: { value: lexemeId, enumerable: true },
word: { value: word, enumerable: true },
before: { value: before, enumerable: true },
after: { value: after, enumerable: true },
comment: { value: comment, enumerable: true },
attributes: { value: attributes, enumerable: true },
flag: { value: flag, enumerable: true }
})
); };
/**
* Build English Attribute object
* @static
* @param { string } commentPosition Comment before or after word meaning
* @param { string } commentFont Normal or Italic
* @param { string } stringBeforeFont Normal or Italic string before text font
* @param { string } stringAfterFont Normal or Italic string after text font
* @param { string } verb None, Transitive or Intransitive
* @param { string } number Word Number enumeration
* @param { string } gender Word Gender enumeration
* @param { string } form Word Form enumeration
* @returns { EnglishAttribute } English Attribute object
*/
var makeEnglishAttribute = function (
commentPosition,
commentFont,
stringBeforeFont,
stringAfterFont,
verb,
number,
gender,
form
) { return Object.freeze(
Object.create(null, {
commentPosition: { value: commentPosition, enumerable: true },
commentFont: { value: commentFont, enumerable: true },
stringBeforeFont: { value: stringBeforeFont, enumerable: true },
stringAfterFont: { value: stringAfterFont, enumerable: true },
verbType: { value: verb, enumerable: true },
number: { value: number, enumerable: true },
gender: { value: gender, enumerable: true },
form: { value: form, enumerable: true }
})
); };
/**
* Get English Attribute object from english attribute bit map
* @static
* @param { number } attributes 16-bit map
* @returns { EnglishAttribute } English Attribute object
*/
var getEnglishAttribute = function (attributes) { return makeEnglishAttribute(
// 0 <RESERVED>
textPosition[(0x2 & attributes) >>> 1], // 1 COMMENT POSITION
fontType[(0x4 & attributes) >>> 2], // 2 COMMENT FONT
fontType[(0x8 & attributes) >>> 3], // 3 STRING BEFORE FONT
fontType[(0x10 & attributes) >>> 4], // 4 STRING AFTER FONT
verbType[(0x60 & attributes) >>> 5], // 5-6 VERB TYPE
wordNumber[(0x180 & attributes) >>> 7], // 7-8 NUMBER
wordGender[(0x600 & attributes) >>> 9], // 9-10 GENDER
wordForm[(0xf800 & attributes) >>> 11] // 11-15 FORM
); };
/**
* Return flatten english object with parsed attribute values
* @static
* @param { number } id the id of current english object
* @param { English } english english raw object
* @param { Array.<Lexeme> } lexemes lexeme list
* @returns { FlatEnglish } the flatten english model
*/
var getEnglish = function (id, english, lexemes) {
if (english) {
var attributes = getEnglishAttribute(english.attributes);
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
lexemeId: { value: english.lexemeId, enumerable: true },
lexeme: {
value:
lexemes && lexemes[english.lexemeId]
? lexemes[english.lexemeId].lexeme
: null,
enumerable: true
},
word: { value: english.word, enumerable: true },
before: { value: english.before, enumerable: true },
after: { value: english.after, enumerable: true },
comment: { value: english.comment, enumerable: true },
commentPosition: {
value: attributes.commentPosition,
enumerable: true
},
commentFont: { value: attributes.commentFont, enumerable: true },
stringBeforeFont: {
value: attributes.stringBeforeFont,
enumerable: true
},
stringAfterFont: {
value: attributes.stringAfterFont,
enumerable: true
},
verbType: { value: attributes.verbType, enumerable: true },
number: { value: attributes.number, enumerable: true },
gender: { value: attributes.gender, enumerable: true },
form: { value: attributes.form, enumerable: true },
flag: { value: english.flag, enumerable: true }
})
);
}
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
lexemeId: { value: null, enumerable: true },
lexeme: { value: null, enumerable: true },
word: { value: null, enumerable: true },
before: { value: null, enumerable: true },
after: { value: null, enumerable: true },
comment: { value: null, enumerable: true },
commentPosition: { value: null, enumerable: true },
commentFont: { value: null, enumerable: true },
stringBeforeFont: { value: null, enumerable: true },
stringAfterFont: { value: null, enumerable: true },
verbType: { value: null, enumerable: true },
number: { value: null, enumerable: true },
gender: { value: null, enumerable: true },
form: { value: null, enumerable: true },
flag: { value: null, enumerable: true }
})
);
};
/**
* Etymology Language enumeration
* @static
* @const
* @type { Array.<string> }
*/
var etymologyLanguage = Object.freeze([
'Syriac',
'Akkadian',
'Aramaic',
'Arabic',
'Armenian',
'Greek',
'Hebrew',
'Latin',
'Persian',
'Sanskrit'
]);
/**
* Etymology records, e.g. 4:1,1:1,"a\255h\256r",5
* Id is the position in the array so it is not stored
*
* @static
* @param { number } lexemeId Lexeme address, e.g. 1
* @param { string } word Word Origin, e.g. "a\255h\256r"
* @param { number } attributes 16-bit map
* @returns { Etymology } Sedra Etymology row
*/
var makeEtymology = function (lexemeId, word, attributes) { return Object.freeze(
Object.create(null, {
lexemeId: { value: lexemeId, enumerable: true },
word: { value: word, enumerable: true },
attributes: { value: attributes, enumerable: true }
})
); };
/**
* Build Etymology Attribute object
* @static
* @param { string } language the source language
* @param { string } type word type enumeration
* @returns { EtymologyAttribute } Etymology Attribute object
*/
var makeEtymologyAttribute = function (language, type) { return Object.freeze(
Object.create(null, {
language: { value: language, enumerable: true },
wordType: { value: type, enumerable: true }
})
); };
/**
* Get Etymology Attribute object from etymology attribute bit map
* @static
* @param { number } attributes 16-bit map
* @returns { EtymologyAttribute } Etymology Attribute object
*/
var getEtymologyAttribute = function (attributes) { return makeEtymologyAttribute(
etymologyLanguage[0xf & attributes], // 0-3 LANGUAGE
wordType[(0x10 & attributes) >>> 4] // 4 TYPE
); };
/**
* Return flatten etymology object with parsed attribute values
* @static
* @param { number } id the id of current etymology object
* @param { Etymology } etymology etymology raw object
* @param { Array.<Lexeme> } lexemes lexeme list
* @returns { FlatEtymology } the flatten etymology model
*/
var getEtymology = function (id, etymology, lexemes) {
if (etymology) {
var attributes = getEtymologyAttribute(etymology.attributes);
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
lexemeId: { value: etymology.lexemeId, enumerable: true },
lexeme: {
value:
lexemes && lexemes[etymology.lexemeId]
? lexemes[etymology.lexemeId].lexeme
: null,
enumerable: true
},
word: { value: etymology.word, enumerable: true },
language: { value: attributes.language, enumerable: true },
wordType: { value: attributes.wordType, enumerable: true }
})
);
}
return Object.freeze(
Object.create(null, {
id: { value: id, enumerable: true },
lexemeId: { value: null, enumerable: true },
lexeme: { value: null, enumerable: true },
word: { value: null, enumerable: true },
language: { value: null, enumerable: true },
wordType: { value: null, enumerable: true }
})
);
};
var bookPrototype = Object.freeze(
Object.create(null, {
/**
* Get book full English name
* @alias module:sedraModel.Book#englishName
* @returns { string } English full name
*/
englishName: {
enumerable: true,
get: function get() {
return this.english[0];
}
},
/**
* Get book first abbreviated English name
* @alias module:sedraModel.Book#englishShortName
* @returns { string } English abbreviated name
*/
englishShortName: {
enumerable: true,
get: function get() {
return this.english[1];
}
}
})
);
/**
* Build a Book object
* @static
* @param { number } id Book Id
* @param { number } peshittaId Book Eastern Peshitta Id
* @param { string } name Book Aramaic name
* @param { string } vocalised Book vocalised Aramaic name
* @param { Array.<string> } english Book English names: full name followed by abbreviations
* @param { object } stats Book statistics { chapters, verses, words }
* @return { Book } Book object
*/
var makeBook = function (id, peshittaId, name, vocalised, english, stats) { return Object.freeze(
Object.create(bookPrototype, {
id: { value: id, enumerable: true },
peshittaId: { value: peshittaId, enumerable: true },
name: { value: name, enumerable: true },
vocalised: { value: vocalised, enumerable: true },
english: { value: english, enumerable: true },
stats: { value: stats, enumerable: true }
})
); };
var m = makeBook;
/**
* Peshitta books
* @static
* @const
* @type { Array.<string> }
*/
var books = [
m(0, 0, '', '', ['Old Testament', 'OT']),
m(1, 0, '', '', []),
m(2, 0, '', '', []),
m(3, 0, '', '', []),
m(4, 0, '', '', []),
m(5, 0, '', '', []),
m(6, 0, '', '', []),
m(7, 0, '', '', []),
m(8, 0, '', '', []),
m(9, 0, '', '', []),
m(10, 0, '', '', []),
m(11, 0, '', '', []),
m(12, 0, '', '', []),
m(13, 0, '', '', []),
m(14, 0, '', '', []),
m(15, 0, '', '', []),
m(16, 0, '', '', []),
m(17, 0, '', '', []),
m(18, 0, '', '', []),
m(19, 0, '', '', []),
m(20, 0, '', '', []),
m(21, 0, '', '', []),
m(22, 0, '', '', []),
m(23, 0, '', '', []),
m(24, 0, '', '', []),
m(25, 0, '', '', []),
m(26, 0, '', '', []),
m(27, 0, '', '', []),
m(28, 0, '', '', []),
m(29, 0, '', '', []),
m(30, 0, '', '', []),
m(31, 0, '', '', []),
m(32, 0, '', '', []),
m(33, 0, '', '', []),
m(34, 0, '', '', []),
m(35, 0, '', '', []),
m(36, 0, '', '', []),
m(37, 0, '', '', []),
m(38, 0, '', '', []),
m(39, 0, '', '', []),
m(40, 0, '', '', []),
m(41, 0, '', '', []),
m(42, 0, '', '', []),
m(43, 0, '', '', []),
m(44, 0, '', '', []),
m(45, 0, '', '', []),
m(46, 0, '', '', []),
m(47, 0, '', '', []),
m(48, 0, '', '', []),
m(49, 0, '', '', []),
m(50, 50, '', '', []),
m(51, 51, '', '', ['New Testament', 'NT'], {
books: 27,
chapters: 260,
verses: 7958,
words: 109654
}),
m(52, 52, 'mty', "mat'ay", ['Matthew', 'Mt', 'Matt', 'Mat'], {
chapters: 28,
verses: 1071,
words: 13980,
chapter: {
1: { verses: 25, words: 290 },
2: {
verses: 23,
words: 335
},
3: {
verses: 17,
words: 239
},
4: {
verses: 25,
words: 317
},
5: {
verses: 48,
words: 621
},
6: {
verses: 34,
words: 486
},
7: {
verses: 29,
words: 365
},
8: {
verses: 34,
words: 451
},
9: {
verses: 38,
words: 470
},
10: {
verses: 42,
words: 547
},
11: {
verses: 30,
words: 379
},
12: {
verses: 50,
words: 675
},
13: {
verses: 58,
words: 788
},
14: {
verses: 36,
words: 428
},
15: {
verses: 39,
words: 490
},
16: {
verses: 28,
words: 397
},
17: {
verses: 27,
words: 389
},
18: {
verses: 35,
words: 513
},
19: {
verses: 30,
words: 453
},
20: {
verses: 34,
words: 440
},
21: {
verses: 46,
words: 672
},
22: {
verses: 46,
words: 490
},
23: {
verses: 39,
words: 513
},
24: {
verses: 51,
words: 595
},
25: {
verses: 46,
words: 589
},
26: {
verses: 75,
words: 983
},
27: {
verses: 66,
words: 799
},
28: {
verses: 20,
words: 266
}
}
}),
m(53, 53, 'mrqws', 'marqwOs', ['Mark', 'Mk', 'Mrk', 'Mar', 'Mr'], {
chapters: 16,
verses: 678,
words: 8793,
chapter: {
1: {
verses: 45,
words: 511
},
2: {
verses: 28,
words: 400
},
3: {
verses: 35,
words: 380
},
4: {
verses: 41,
words: 517
},
5: {
verses: 43,
words: 531
},
6: {
verses: 56,
words: 766
},
7: {
verses: 37,
words: 476
},
8: {
verses: 38,
words: 494
},
9: {
verses: 50,
words: 695
},
10: {
verses: 52,
words: 702
},
11: {
verses: 33,
words: 467
},
12: {
verses: 44,
words: 628
},
13: {
verses: 37,
words: 485
},
14: {
verses: 72,
words: 945
},
15: {
verses: 47,
words: 546
},
16: {
verses: 20,
words: 250
}
}
}),
m(54, 54, 'lwq)', 'lwuqo)', ['Luke', 'Lk', 'Luk'], {
chapters: 24,
verses: 1151,
words: 15234,
chapter: {
1: {
verses: 80,
words: 831
},
2: {
verses: 52,
words: 625
},
3: {
verses: 38,
words: 494
},
4: {
verses: 44,
words: 582
},
5: {
verses: 39,
words: 567
},
6: {
verses: 49,
words: 703
},
7: {
verses: 50,
words: 716
},
8: {
verses: 56,
words: 866
},
9: {
verses: 62,
words: 877
},
10: {
verses: 42,
words: 606
},
11: {
verses: 54,
words: 797
},
12: {
verses: 59,
words: 825
},
13: {
verses: 35,
words: 510
},
14: {
verses: 35,
words: 484
},
15: {
verses: 32,
words: 424
},
16: {
verses: 31,
words: 477
},
17: {
verses: 37,
words: 460
},
18: {
verses: 43,
words: 579
},
19: {
verses: 48,
words: 600
},
20: {
verses: 47,
words: 563
},
21: {
verses: 38,
words: 452
},
22: {
verses: 71,
words: 853
},
23: {
verses: 56,
words: 714
},
24: {
verses: 53,
words: 629
}
}
}),
m(55, 55, 'ywxnn', 'ywuxanon', ['John', 'Jn', 'Joh', 'Jhn'], {
chapters: 21,
verses: 879,
words: 12409,
chapter: {
1: {
verses: 51,
words: 629
},
2: {
verses: 25,
words: 311
},
3: {
verses: 36,
words: 533
},
4: {
verses: 54,
words: 734
},
5: {
verses: 47,
words: 675
},
6: {
verses: 71,
words: 947
},
7: {
verses: 53,
words: 700
},
8: {
verses: 59,
words: 887
},
9: {
verses: 41,
words: 575
},
10: {
verses: 42,
words: 564
},
11: {
verses: 57,
words: 734
},
12: {
verses: 50,
words: 680
},
13: {
verses: 38,
words: 583
},
14: {
verses: 31,
words: 444
},
15: {
verses: 27,
words: 368
},
16: {
verses: 33,
words: 455
},
17: {
verses: 26,
words: 376
},
18: {
verses: 40,
words: 633
},
19: {
verses: 42,
words: 640
},
20: {
verses: 31,
words: 452
},
21: {
verses: 25,
words: 489
}
}
}),
m(56, 56, 'prksys', 'praksyis', ['Acts', 'Ac', 'Act'], {
chapters: 28,
verses: 1007,
words: 15385,
chapter: {
1: {
verses: 26,
words: 414
},
2: {
verses: 47,
words: 633
},
3: {
verses: 26,
words: 378
},
4: {
verses: 37,
words: 544
},
5: {
verses: 42,
words: 646
},
6: {
verses: 15,
words: 213
},
7: {
verses: 60,
words: 862
},
8: {
verses: 40,
words: 590
},
9: {
verses: 43,
words: 670
},
10: {
verses: 48,
words: 712
},
11: {
verses: 30,
words: 416
},
12: {
verses: 25,
words: 412
},
13: {
verses: 52,
words: 744
},
14: {
verses: 28,
words: 420
},
15: {
verses: 41,
words: 565
},
16: {
verses: 40,
words: 620
},
17: {
verses: 34,
words: 609
},
18: {
verses: 28,
words: 457
},
19: {
verses: 41,
words: 672
},
20: {
verses: 38,
words: 558
},
21: {
verses: 40,
words: 651
},
22: {
verses: 30,
words: 471
},
23: {
verses: 35,
words: 541
},
24: {
verses: 27,
words: 421
},
25: {
verses: 27,
words: 450
},
26: {
verses: 32,
words: 522
},
27: {
verses: 44,
words: 676
},
28: {
verses: 31,
words: 518
}
}
}),
m(57, 60, 'r*hwmy)', 'r*h_wumoye)', ['Romans', 'Ro', 'Rom', 'Rm'], {
chapters: 16,
verses: 433,
words: 5768,
chapter: {
1: {
verses: 32,
words: 424
},
2: {
verses: 29,
words: 407
},
3: {
verses: 31,
words: 324
},
4: {
verses: 25,
words: 326
},
5: {
verses: 21,
words: 317
},
6: {
verses: 23,
words: 293
},
7: {
verses: 25,
words: 390
},
8: {
verses: 39,
words: 518
},
9: {
verses: 33,
words: 432
},
10: {
verses: 21,
words: 260
},
11: {
verses: 36,
words: 501
},
12: {
verses: 21,
words: 271
},
13: {
verses: 14,
words: 234
},
14: {
verses: 23,
words: 336
},
15: {
verses: 33,
words: 412
},
16: {
verses: 27,
words: 323
}
}
}),
m(
58,
61,
'). qwr*ynty)',
'). qwOr*yint,oye)',
[
'1 Corinthians',
'1Co',
'1 Cor',
'1 Co',
'I Co',
'I Cor',
'I Corinthians',
'1Cor',
'1Corinthians',
'1st Corinthians',
'First Corinthians'
],
{
chapters: 16,
verses: 437,
words: 5987,
chapter: {
1: {
verses: 31,
words: 382
},
2: {
verses: 16,
words: 224
},
3: {
verses: 23,
words: 309
},
4: {
verses: 21,
words: 301
},
5: {
verses: 13,
words: 200
},
6: {
verses: 20,
words: 293
},
7: {
verses: 40,
words: 619
},
8: {
verses: 13,
words: 190
},
9: {
verses: 27,
words: 422
},
10: {
verses: 33,
words: 420
},
11: {
verses: 34,
words: 471
},
12: {
verses: 31,
words: 425
},
13: {
verses: 13,
words: 185
},
14: {
verses: 40,
words: 565
},
15: {
verses: 58,
words: 703
},
16: {
verses: 24,
words: 278
}
}
}
),
m(
59,
62,
'b. qwr*ynty)',
'b. qwOr*yint,oye)',
[
'2 Corinthians',
'2Co',
'2 Cor',
'2 Co',
'II Co',
'II Cor',
'II Corinthians',
'2Cor',
'2Corinthians',
'2nd Corinthians',
'Second Corinthians'
],
{
chapters: 13,
verses: 257,
words: 3737,
chapter: {
1: {
verses: 24,
words: 356
},
2: {
verses: 17,
words: 230
},
3: {
verses: 18,
words: 248
},
4: {
verses: 18,
words: 259
},
5: {
verses: 21,
words: 286
},
6: {
verses: 18,
words: 221
},
7: {
verses: 16,
words: 275
},
8: {
verses: 24,
words: 316
},
9: {
verses: 15,
words: 223
},
10: {
verses: 18,
words: 273
},
11: {
verses: 33,
words: 466
},
12: {
verses: 21,
words: 369
},
13: {
verses: 14,
words: 215
}
}
}
),
m(60, 63, 'glTy*)', 'goloToy*e)', ['Galatians', 'Ga', 'Gal'], {
chapters: 6,
verses: 149,
words: 1940,
chapter: {
1: {
verses: 24,
words: 301
},
2: {
verses: 21,
words: 348
},
3: {
verses: 29,
words: 401
},
4: {
verses: 31,
words: 376
},
5: {
verses: 26,
words: 297
},
6: {
verses: 18,
words: 217
}
}
}),
m(61, 64, ')psy*)', ')epEsy*e)', ['Ephesians', 'Ep', 'Eph', 'Ephes'], {
chapters: 6,
verses: 155,
words: 1774,
chapter: {
1: {
verses: 23,
words: 257
},
2: {
verses: 22,
words: 267
},
3: {
verses: 21,
words: 223
},
4: {
verses: 32,
words: 357
},
5: {
verses: 33,
words: 379
},
6: {
verses: 24,
words: 291
}
}
}),
m(
62,
65,
'pylypsy*)',
'pyilyipEsoy*e)',
['Philippians', 'Pp', 'Phil', 'Php'],
{
chapters: 4,
verses: 104,
words: 1326,
chapter: {
1: {
verses: 30,
words: 371
},
2: {
verses: 30,
words: 377
},
3: {
verses: 21,
words: 295
},
4: {
verses: 23,
words: 283
}
}
}
),
m(63, 66, 'qwl*sy)', 'qwl*sy)', ['Colossians', 'Co', 'Col'], {
chapters: 4,
verses: 95,
words: 1133,
chapter: {
1: {
verses: 29,
words: 356
},
2: {
verses: 23,
words: 283
},
3: {
verses: 25,
words: 284
},
4: {
verses: 18,
words: 210
}
}
}),
m(
64,
67,
'). tsl*wnyqy)',
"). t'esol*wOnyiqoye)",
[
'1 Thessalonians',
'1Th',
'1 Thess',
'1 Thes',
'1 Th',
'I Thess',
'I Thes',
'I Th',
'I Thessalonians',
'1Thess',
'1Thes',
'1Thessalonians',
'1st Thessalonians',
'1st Thess',
'First Thessalonians',
'First Thess'
],
{
chapters: 5,
verses: 89,
words: 1117,
chapter: {
1: {
verses: 10,
words: 139
},
2: {
verses: 20,
words: 299
},
3: {
verses: 13,
words: 171