@gracious.tech/fetch-client
Version:
Interact with a fetch(bible) collection in an API-like way
2,525 lines (2,509 loc) • 69.6 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
// src/index.ts
var src_exports = {};
__export(src_exports, {
BibleClient: () => BibleClient,
PassageReference: () => PassageReference,
book_abbrev_english: () => book_abbrev_english,
book_names_english: () => book_names_english,
books_ordered: () => books_ordered,
detect_references: () => detect_references,
english_abbrev_exclude: () => english_abbrev_exclude,
english_abbrev_include: () => english_abbrev_include,
get_chapters: () => get_chapters,
get_verses: () => get_verses,
last_verse: () => last_verse
});
module.exports = __toCommonJS(src_exports);
// ../references/dist/esm/utils.js
function parse_int(input, min, max) {
let int = parseInt(input, 10);
if (Number.isNaN(int)) {
return null;
}
if (min !== void 0) {
int = Math.max(int, min);
}
if (max !== void 0) {
int = Math.min(int, max);
}
return int;
}
// ../references/dist/esm/data.js
var books_ordered = Object.freeze([
"gen",
"exo",
"lev",
"num",
"deu",
"jos",
"jdg",
"rut",
"1sa",
"2sa",
"1ki",
"2ki",
"1ch",
"2ch",
"ezr",
"neh",
"est",
"job",
"psa",
"pro",
"ecc",
"sng",
"isa",
"jer",
"lam",
"ezk",
"dan",
"hos",
"jol",
"amo",
"oba",
"jon",
"mic",
"nam",
"hab",
"zep",
"hag",
"zec",
"mal",
"mat",
"mrk",
"luk",
"jhn",
"act",
"rom",
"1co",
"2co",
"gal",
"eph",
"php",
"col",
"1th",
"2th",
"1ti",
"2ti",
"tit",
"phm",
"heb",
"jas",
"1pe",
"2pe",
"1jn",
"2jn",
"3jn",
"jud",
"rev"
]);
var book_names_english = Object.freeze({
"gen": "Genesis",
"exo": "Exodus",
"lev": "Leviticus",
"num": "Numbers",
"deu": "Deuteronomy",
"jos": "Joshua",
"jdg": "Judges",
"rut": "Ruth",
"1sa": "1 Samuel",
"2sa": "2 Samuel",
"1ki": "1 Kings",
"2ki": "2 Kings",
"1ch": "1 Chronicles",
"2ch": "2 Chronicles",
"ezr": "Ezra",
"neh": "Nehemiah",
"est": "Esther",
"job": "Job",
"psa": "Psalms",
"pro": "Proverbs",
"ecc": "Ecclesiastes",
"sng": "Song of Songs",
"isa": "Isaiah",
"jer": "Jeremiah",
"lam": "Lamentations",
"ezk": "Ezekiel",
"dan": "Daniel",
"hos": "Hosea",
"jol": "Joel",
"amo": "Amos",
"oba": "Obadiah",
"jon": "Jonah",
"mic": "Micah",
"nam": "Nahum",
"hab": "Habakkuk",
"zep": "Zephaniah",
"hag": "Haggai",
"zec": "Zechariah",
"mal": "Malachi",
"mat": "Matthew",
"mrk": "Mark",
"luk": "Luke",
"jhn": "John",
"act": "Acts",
"rom": "Romans",
"1co": "1 Corinthians",
"2co": "2 Corinthians",
"gal": "Galatians",
"eph": "Ephesians",
"php": "Philippians",
"col": "Colossians",
"1th": "1 Thessalonians",
"2th": "2 Thessalonians",
"1ti": "1 Timothy",
"2ti": "2 Timothy",
"tit": "Titus",
"phm": "Philemon",
"heb": "Hebrews",
"jas": "James",
"1pe": "1 Peter",
"2pe": "2 Peter",
"1jn": "1 John",
"2jn": "2 John",
"3jn": "3 John",
"jud": "Jude",
"rev": "Revelation"
});
var book_abbrev_english = Object.freeze({
"gen": "Gen",
"exo": "Exo",
"lev": "Lev",
"num": "Num",
"deu": "Deut",
"jos": "Josh",
"jdg": "Judg",
"rut": "Ruth",
"1sa": "1 Sam",
"2sa": "2 Sam",
"1ki": "1 King",
"2ki": "2 King",
"1ch": "1 Chr",
"2ch": "2 Chr",
"ezr": "Ezra",
"neh": "Neh",
"est": "Est",
"job": "Job",
"psa": "Psalm",
"pro": "Prov",
"ecc": "Ecc",
"sng": "Song",
"isa": "Isa",
"jer": "Jer",
"lam": "Lam",
"ezk": "Ezek",
"dan": "Dan",
"hos": "Hos",
"jol": "Joel",
"amo": "Amos",
"oba": "Obad",
"jon": "Jonah",
"mic": "Micah",
"nam": "Nahum",
"hab": "Hab",
"zep": "Zeph",
"hag": "Hag",
"zec": "Zech",
"mal": "Mal",
"mat": "Matt",
"mrk": "Mark",
"luk": "Luke",
"jhn": "John",
"act": "Acts",
"rom": "Rom",
"1co": "1 Cor",
"2co": "2 Cor",
"gal": "Gal",
"eph": "Eph",
"php": "Phil",
"col": "Col",
"1th": "1 Thes",
"2th": "2 Thes",
"1ti": "1 Tim",
"2ti": "2 Tim",
"tit": "Titus",
"phm": "Phil",
"heb": "Heb",
"jas": "James",
"1pe": "1 Pet",
"2pe": "2 Pet",
"1jn": "1 John",
"2jn": "2 John",
"3jn": "3 John",
"jud": "Jude",
"rev": "Rev"
});
var english_abbrev_include = Object.freeze([
// [code, abbrev]
["num", "nm"],
["ezr", "ez"],
["mic", "mc"],
["hab", "hb"],
["jhn", "jn"],
["php", "phil"],
["phm", "pm"],
["jas", "jm"],
["jud", "jud"],
["jud", "jd"]
]);
var english_abbrev_exclude = Object.freeze(["is", "so", "at", "am", "me", "he", "hi"]);
// ../references/dist/esm/last_verse.js
var last_verse = Object.freeze({
"1ch": [
54,
55,
24,
43,
26,
81,
40,
40,
44,
14,
47,
40,
14,
17,
29,
43,
27,
17,
19,
8,
30,
19,
32,
31,
31,
32,
34,
21,
30
],
"1co": [
31,
16,
23,
21,
13,
20,
40,
13,
27,
33,
34,
31,
13,
40,
58,
24
],
"1jn": [
10,
29,
24,
21,
21
],
"1ki": [
53,
46,
28,
34,
18,
38,
51,
66,
28,
29,
43,
33,
34,
31,
34,
34,
24,
46,
21,
43,
29,
53
],
"1pe": [
25,
25,
22,
19,
14
],
"1sa": [
28,
36,
21,
22,
12,
21,
17,
22,
27,
27,
15,
25,
23,
52,
35,
23,
58,
30,
24,
42,
15,
23,
29,
22,
44,
25,
12,
25,
11,
31,
13
],
"1th": [
10,
20,
13,
18,
28
],
"1ti": [
20,
15,
16,
16,
25,
21
],
"2ch": [
17,
18,
17,
22,
14,
42,
22,
18,
31,
19,
23,
16,
22,
15,
19,
14,
19,
34,
11,
37,
20,
12,
21,
27,
28,
23,
9,
27,
36,
27,
21,
33,
25,
33,
27,
23
],
"2co": [
24,
17,
18,
18,
21,
18,
16,
24,
15,
18,
33,
21,
14
],
"2jn": [
13
],
"2ki": [
18,
25,
27,
44,
27,
33,
20,
29,
37,
36,
21,
21,
25,
29,
38,
20,
41,
37,
37,
21,
26,
20,
37,
20,
30
],
"2pe": [
21,
22,
18
],
"2sa": [
27,
32,
39,
12,
25,
23,
29,
18,
13,
19,
27,
31,
39,
33,
37,
23,
29,
33,
43,
26,
22,
51,
39,
25
],
"2th": [
12,
17,
18
],
"2ti": [
18,
26,
17,
22
],
"3jn": [
15
],
"act": [
26,
47,
26,
37,
42,
15,
60,
40,
43,
48,
30,
25,
52,
28,
41,
40,
34,
28,
41,
38,
40,
30,
35,
27,
27,
32,
44,
31
],
"amo": [
15,
16,
15,
13,
27,
14,
17,
14,
15
],
"col": [
29,
23,
25,
18
],
"dan": [
21,
49,
30,
37,
31,
28,
28,
27,
27,
21,
45,
13
],
"deu": [
46,
37,
29,
49,
33,
25,
26,
20,
29,
22,
32,
32,
18,
29,
23,
22,
20,
22,
21,
20,
23,
30,
25,
22,
19,
19,
26,
68,
29,
20,
30,
52,
29,
12
],
"ecc": [
18,
26,
22,
16,
20,
12,
29,
17,
18,
20,
10,
14
],
"eph": [
23,
22,
21,
32,
33,
24
],
"est": [
22,
23,
15,
17,
14,
14,
10,
17,
32,
3
],
"exo": [
22,
25,
22,
31,
23,
30,
25,
32,
35,
29,
10,
51,
22,
31,
27,
36,
16,
27,
25,
26,
36,
31,
33,
18,
40,
37,
21,
43,
46,
38,
18,
35,
23,
35,
35,
38,
29,
31,
43,
38
],
"ezk": [
28,
10,
27,
17,
17,
14,
27,
18,
11,
22,
25,
28,
23,
23,
8,
63,
24,
32,
14,
49,
32,
31,
49,
27,
17,
21,
36,
26,
21,
26,
18,
32,
33,
31,
15,
38,
28,
23,
29,
49,
26,
20,
27,
31,
25,
24,
23,
35
],
"ezr": [
11,
70,
13,
24,
17,
22,
28,
36,
15,
44
],
"gal": [
24,
21,
29,
31,
26,
18
],
"gen": [
31,
25,
24,
26,
32,
22,
24,
22,
29,
32,
32,
20,
18,
24,
21,
16,
27,
33,
38,
18,
34,
24,
20,
67,
34,
35,
46,
22,
35,
43,
55,
32,
20,
31,
29,
43,
36,
30,
23,
23,
57,
38,
34,
34,
28,
34,
31,
22,
33,
26
],
"hab": [
17,
20,
19
],
"hag": [
15,
23
],
"heb": [
14,
18,
19,
16,
14,
20,
28,
13,
28,
39,
40,
29,
25
],
"hos": [
11,
23,
5,
19,
15,
11,
16,
14,
17,
15,
12,
14,
16,
9
],
"isa": [
31,
22,
26,
6,
30,
13,
25,
22,
21,
34,
16,
6,
22,
32,
9,
14,
14,
7,
25,
6,
17,
25,
18,
23,
12,
21,
13,
29,
24,
33,
9,
20,
24,
17,
10,
22,
38,
22,
8,
31,
29,
25,
28,
28,
25,
13,
15,
22,
26,
11,
23,
15,
12,
17,
13,
12,
21,
14,
21,
22,
11,
12,
19,
12,
25,
24
],
"jas": [
27,
26,
18,
17,
20
],
"jdg": [
36,
23,
31,
24,
31,
40,
25,
35,
57,
18,
40,
15,
25,
20,
20,
31,
13,
31,
30,
48,
25
],
"jer": [
19,
37,
25,
31,
31,
30,
34,
22,
26,
25,
23,
17,
27,
22,
21,
21,
27,
23,
15,
18,
14,
30,
40,
10,
38,
24,
22,
17,
32,
24,
40,
44,
26,
22,
19,
32,
21,
28,
18,
16,
18,
22,
13,
30,
5,
28,
7,
47,
39,
46,
64,
34
],
"jhn": [
51,
25,
36,
54,
47,
71,
53,
59,
41,
42,
57,
50,
38,
31,
27,
33,
26,
40,
42,
31,
25
],
"job": [
22,
13,
26,
21,
27,
30,
21,
22,
35,
22,
20,
25,
28,
22,
35,
22,
16,
21,
29,
29,
34,
30,
17,
25,
6,
14,
23,
28,
25,
31,
40,
22,
33,
37,
16,
33,
24,
41,
30,
24,
34,
17
],
"jol": [
20,
32,
21
],
"jon": [
17,
10,
10,
11
],
"jos": [
18,
24,
17,
24,
15,
27,
26,
35,
27,
43,
23,
24,
33,
15,
63,
10,
18,
28,
51,
9,
45,
34,
16,
33
],
"jud": [
25
],
"lam": [
22,
22,
66,
22,
22
],
"lev": [
17,
16,
17,
35,
19,
30,
38,
36,
24,
20,
47,
8,
59,
57,
33,
34,
16,
30,
37,
27,
24,
33,
44,
23,
55,
46,
34
],
"luk": [
80,
52,
38,
44,
39,
49,
50,
56,
62,
42,
54,
59,
35,
35,
32,
31,
37,
43,
48,
47,
38,
71,
56,
53
],
"mal": [
14,
17,
18,
6
],
"mat": [
25,
23,
17,
25,
48,
34,
29,
34,
38,
42,
30,
50,
58,
36,
39,
28,
27,
35,
30,
34,
46,
46,
39,
51,
46,
75,
66,
20
],
"mic": [
16,
13,
12,
13,
15,
16,
20
],
"mrk": [
45,
28,
35,
41,
43,
56,
37,
38,
50,
52,
33,
44,
37,
72,
47,
// Mark's ending: 1-8 common, 9-20 long ending
// Some also add the alternate short ending to end of long ending with 21-22
// Not supporting 21-22 as whether ending abrupt/long/short it definitely wasn't both
20
],
"nam": [
15,
13,
19
],
"neh": [
11,
20,
32,
23,
19,
19,
73,
18,
38,
39,
36,
47,
31
],
"num": [
54,
34,
51,
49,
31,
27,
89,
26,
23,
36,
35,
16,
33,
45,
41,
50,
13,
32,
22,
29,
35,
41,
30,
25,
18,
65,
23,
31,
40,
16,
54,
42,
56,
29,
34,
13
],
"oba": [
21
],
"phm": [
25
],
"php": [
30,
30,
21,
23
],
"pro": [
33,
22,
35,
27,
23,
35,
27,
36,
18,
32,
31,
28,
25,
35,
33,
33,
28,
24,
29,
30,
31,
29,
35,
34,
28,
28,
27,
28,
27,
33,
31
],
"psa": [
6,
12,
8,
8,
12,
10,
17,
9,
20,
18,
7,
8,
6,
7,
5,
11,
15,
50,
14,
9,
13,
31,
6,
10,
22,
12,
14,
9,
11,
12,
24,
11,
22,
22,
28,
12,
40,
22,
13,
17,
13,
11,
5,
26,
17,
11,
9,
14,
20,
23,
19,
9,
6,
7,
23,
13,
11,
11,
17,
12,
8,
12,
11,
10,
13,
20,
7,
35,
36,
5,
24,
20,
28,
23,
10,
12,
20,
72,
13,
19,
16,
8,
18,
12,
13,
17,
7,
18,
52,
17,
16,
15,
5,
23,
11,
13,
12,
9,
9,
5,
8,
28,
22,
35,
45,
48,
43,
13,
31,
7,
10,
10,
9,
8,
18,
19,
2,
29,
176,
7,
8,
9,
4,
8,
5,
6,
5,
6,
8,
8,
3,
18,
3,
3,
21,
26,
9,
8,
24,
13,
10,
7,
12,
15,
21,
10,
20,
14,
9,
6
],
"rev": [
20,
29,
22,
11,
14,
17,
17,
13,
21,
11,
19,
18,
// 12:18 Many translations append 12:18 to 12:17 as the final verse
18,
20,
8,
21,
18,
24,
21,
15,
27,
21
],
"rom": [
32,
29,
31,
25,
21,
23,
25,
39,
33,
21,
36,
21,
14,
26,
33,
27
],
"rut": [
22,
23,
18,
22
],
"sng": [
17,
17,
11,
16,
16,
13,
13,
14
],
"tit": [
16,
15,
15
],
"zec": [
21,
13,
10,
14,
11,
15,
14,
23,
17,
12,
17,
14,
9,
21
],
"zep": [
18,
15,
20
]
});
// ../references/dist/esm/passage.js
var __defProp2 = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp2.call(b, prop))
__defNormalProp2(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp2(a, prop, b[prop]);
}
return a;
};
var __publicField2 = (obj, key, value) => {
__defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
function _verses_str_to_obj(ref) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
ref = ref.replace(/ /g, "").replace(/\./g, ":").replace(/:/gu, ":").replace(new RegExp("\\p{Dash}", "gu"), "-");
let start_chapter;
let start_verse;
let end_chapter;
let end_verse;
if (!ref.includes(":")) {
const parts = ref.split("-");
start_chapter = (_a = parse_int(parts[0])) != null ? _a : void 0;
end_chapter = (_c = parse_int((_b = parts[1]) != null ? _b : "")) != null ? _c : void 0;
} else {
const parts = ref.split("-");
const start_parts = parts[0].split(":");
start_chapter = (_d = parse_int(start_parts[0])) != null ? _d : void 0;
start_verse = (_f = parse_int((_e = start_parts[1]) != null ? _e : "")) != null ? _f : void 0;
if (parts[1]) {
const end_parts = parts[1].split(":");
if (end_parts.length > 1) {
end_chapter = (_g = parse_int(end_parts[0])) != null ? _g : void 0;
end_verse = (_h = parse_int(end_parts[1])) != null ? _h : void 0;
} else {
end_verse = (_i = parse_int(end_parts[0])) != null ? _i : void 0;
}
}
}
return { start_chapter, start_verse, end_chapter, end_verse };
}
function _detect_book(input, book_names, exclude_book_names = [], match_from_start = true) {
const clean = (string) => {
return string.trim().toLowerCase().replace(/^i /, "1").replace("1st ", "1").replace("first ", "1").replace(/^ii /, "2").replace("2nd ", "2").replace("second ", "2").replace(/^iii /, "3").replace("3rd ", "3").replace("third ", "3").replace(/[^\d\p{Letter}]/gui, "");
};
input = clean(input);
if (!input) {
return null;
}
exclude_book_names = exclude_book_names.map((name) => clean(name));
if (exclude_book_names.includes(input)) {
return null;
}
if (books_ordered.includes(input)) {
return input;
}
const normalised = book_names.map(([code, name]) => [code, clean(name)]).filter(([code, name]) => name);
const matches = [];
for (const [code, name] of normalised) {
if (input === name) {
return code;
} else if (name.startsWith(input)) {
matches.push([code, name]);
}
}
if (matches.length === 1) {
return matches[0][0];
} else if (matches.length) {
return null;
}
let input_regex_str = input.split("").join(".{0,4}");
if (match_from_start) {
if (["1", "2", "3"].includes(input[0])) {
input_regex_str = "^" + input[0] + input.slice(1).split("").join(".{0,4}");
} else {
input_regex_str = "^" + input_regex_str;
}
}
const input_regex = new RegExp(input_regex_str);
const fuzzy_matches = normalised.filter(([code, name]) => input_regex.test(name));
if (fuzzy_matches.length === 1) {
return fuzzy_matches[0][0];
}
return null;
}
var PassageReference = class _PassageReference {
constructor(book_or_obj, chapter, verse) {
__publicField2(this, "type");
__publicField2(this, "range");
__publicField2(this, "book");
__publicField2(this, "ot");
__publicField2(this, "nt");
__publicField2(this, "start_chapter");
__publicField2(this, "start_verse");
__publicField2(this, "end_chapter");
__publicField2(this, "end_verse");
__publicField2(this, "args_valid");
__publicField2(this, "_args");
var _a, _b, _c, _d, _e;
if (typeof book_or_obj !== "string") {
this._args = {
book: book_or_obj.book,
start_chapter: book_or_obj.start_chapter,
start_verse: book_or_obj.start_verse,
end_chapter: book_or_obj.end_chapter,
end_verse: book_or_obj.end_verse
};
} else {
this._args = {
book: book_or_obj,
start_chapter: chapter,
start_verse: verse
};
}
const chapters_given = typeof this._args.start_chapter === "number" || typeof this._args.end_chapter === "number";
const verses_given = typeof this._args.start_verse === "number" || typeof this._args.end_verse === "number";
this.book = this._args.book;
this.start_chapter = (_a = this._args.start_chapter) != null ? _a : 1;
this.start_verse = (_b = this._args.start_verse) != null ? _b : 1;
this.end_chapter = (_d = (_c = this._args.end_chapter) != null ? _c : this._args.start_chapter) != null ? _d : 1;
this.end_verse = (_e = this._args.end_verse) != null ? _e : this._args.end_chapter ? 999 : 1;
if (books_ordered.indexOf(this.book) === -1) {
this.book = "gen";
}
const last_verse_book = last_verse[this.book];
if (this.start_chapter < 1) {
this.start_chapter = 1;
this.start_verse = 1;
} else if (this.start_chapter > last_verse_book.length) {
this.start_chapter = last_verse_book.length;
this.start_verse = last_verse_book[last_verse_book.length - 1];
}
this.start_verse = Math.min(
Math.max(this.start_verse, 1),
last_verse_book[this.start_chapter - 1]
);
if (this.end_chapter < this.start_chapter || this.end_chapter === this.start_chapter && this.end_verse < this.start_verse) {
this.end_chapter = this.start_chapter;
this.end_verse = this.start_verse;
}
if (this.end_chapter > last_verse_book.length) {
this.end_chapter = last_verse_book.length;
this.end_verse = last_verse_book[last_verse_book.length - 1];
}
this.end_verse = Math.min(Math.max(this.end_verse, 1), last_verse_book[this.end_chapter - 1]);
const chapters_same = this.start_chapter === this.end_chapter;
const verses_same = this.start_verse === this.end_verse;
if (chapters_same && verses_same) {
this.type = chapters_given ? verses_given ? "verse" : "chapter" : "book";
} else {
this.type = chapters_same ? "range_verses" : verses_given ? "range_multi" : "range_chapters";
}
if (this.type === "range_multi" && this.start_verse === 1 && this.end_verse === last_verse_book[this.end_chapter - 1]) {
this.type = "range_chapters";
}
this.range = this.type.startsWith("range_");
this.ot = books_ordered.indexOf(this.book) < 39;
this.nt = !this.ot;
const determine_args_valid = () => {
if (this._args.book !== this.book) {
return false;
}
const props = ["start_chapter", "start_verse", "end_chapter", "end_verse"];
for (const prop of props) {
if (Number.isInteger(this._args[prop]) && this._args[prop] !== this[prop]) {
return false;
}
}
if (!this._args.start_chapter && (this._args.end_chapter || this._args.start_verse || this._args.end_verse)) {
return false;
}
if (this._args.end_verse && !this._args.start_verse) {
return false;
}
if (this._args.start_verse && this._args.end_chapter && !this._args.end_verse) {
return false;
}
return true;
};
this.args_valid = determine_args_valid();
}
// Parse passage reference string
// book_names can be a list if a single book has multiple names [["gen", "Genesis"], ...]
static from_string(reference, book_names, exclude_book_names, min_chars = 2, match_from_start = true) {
if (!book_names) {
book_names = [...Object.entries(book_names_english), ...english_abbrev_include];
if (!exclude_book_names) {
exclude_book_names = [...english_abbrev_exclude];
}
}
const book_names_list = Array.isArray(book_names) ? book_names : Object.entries(book_names);
reference = reference.trim();
let verses_start = reference.slice(1).search(/\d/) + 1;
if (verses_start === 0) {
verses_start = reference.length;
}
const book_str = reference.slice(0, verses_start).trim();
if (book_str.length < min_chars) {
return null;
}
const book_code = _detect_book(
book_str,
book_names_list,
exclude_book_names,
match_from_start
);
if (!book_code) {
return null;
}
const verses_str = reference.slice(verses_start);
let verses = _verses_str_to_obj(verses_str);
const single_chapter = ["2jn", "3jn", "jud", "oba", "phm"].includes(book_code);
if (single_chapter && verses.start_chapter && verses.start_verse === void 0 && verses.end_verse === void 0) {
verses = _verses_str_to_obj("1:" + verses_str);
}
return new _PassageReference(__spreadValues({ book: book_code }, verses));
}
// Return a new reference that extends from start of first ref to end of second ref
static from_refs(start, end) {
return new _PassageReference({
book: start.book,
start_chapter: start.start_chapter,
start_verse: start.start_verse,
end_chapter: end.end_chapter,
end_verse: end.end_verse
});
}
// Get name for book (defaults to English when book names not provided)
get_book_string(book_names = {}) {
return book_names[this.book] || book_names_english[this.book];
}
// Get string representation of verses
get_verses_string(verse_sep = ":", range_sep = "-") {
if (this.type === "book") {
return "";
} else if (this.type === "chapter") {
return `${this.start_chapter}`;
} else if (this.type === "range_chapters") {
return `${this.start_chapter}${range_sep}${this.end_chapter}`;
} else if (this.type === "verse") {
return `${this.start_chapter}${verse_sep}${this.start_verse}`;
}
let out = `${this.start_chapter}${verse_sep}${this.start_verse}${range_sep}`;
if (this.end_chapter !== this.start_chapter) {
out += `${this.end_chapter}${verse_sep}`;
}
return out + `${this.end_verse}`;
}
// Format passage reference to a readable string
toString(book_names = {}, verse_sep = ":", range_sep = "-") {
const out = this.get_book_string(book_names) + " " + this.get_verses_string(verse_sep, range_sep);
return out.trim();
}
// Whether this reference ends before the given chapter/verse or not
is_before(chapter, verse) {
return this.end_chapter < chapter || this.end_chapter === chapter && this.end_verse < verse;
}
// Whether this reference starts after the given chapter/verse or not
is_after(chapter, verse) {
return this.start_chapter > chapter || this.start_chapter === chapter && this.start_verse > verse;
}
// Whether this reference includes the given chapter/verse or not
includes(chapter, verse) {
return !this.is_before(chapter, verse) && !this.is_after(chapter, verse);
}
// Get a reference for just the start verse of this reference (no effect if single verse)
get_start() {
return new _PassageReference({
book: this.book,
start_chapter: this.start_chapter,
start_verse: this.start_verse
});
}
// Get a reference for just the end verse of this reference (no effect if single verse)
get_end() {
return new _PassageReference({
book: this.book,
start_chapter: this.end_chapter,
start_verse: this.end_verse
});
}
// Get a reference for the verse previous to this one (accounting for chapters)
// It can optionally be relative to the end verse, but a range is never returned (single verse)
get_prev_verse(prev_to_end = false) {
let chapter = prev_to_end ? this.end_chapter : this.start_chapter;
let verse = prev_to_end ? this.end_verse : this.start_verse;
if (chapter === 1 && verse === 1) {
return null;
}
if (verse === 1) {
chapter -= 1;
verse = last_verse[this.book][chapter - 1];
} else {
verse -= 1;
}
return new _PassageReference({
book: this.book,
start_chapter: chapter,
start_verse: verse
});
}
// Get a reference for the verse after this one (accounting for chapters)
// It can optionally be relative to the end verse, but a range is never returned (single verse)
get_next_verse(after_end = false) {
let chapter = after_end ? this.end_chapter : this.start_chapter;
let verse = after_end ? this.end_verse : this.start_verse;
const last_verse_book = last_verse[this.book];
if (chapter === last_verse_book.length && verse === last_verse_book[last_verse_book.length - 1]) {
return null;
}
if (verse === last_verse_book[chapter - 1]) {
chapter += 1;
verse = 1;
} else {
verse += 1;
}
return new _PassageReference({
book: this.book,
start_chapter: chapter,
start_verse: verse
});
}
};
// ../references/dist/esm/detect.js
var regex_verse_sep = "[:\uFF1A\\.]";
var regex_book_num_prefix = "(?:(?:[123]|I{1,3}) ? ?)?";
var regex_book_name_tmpl = "\\p{Letter}[\\p{Letter}\\p{Dash} ]{MIN_MID,16}END_LETTER\\.? ? ?";
var regex_integer_with_opt_sep = "\\d{1,3}[abc]?(?: ? ?" + regex_verse_sep + " ? ?\\d{1,3}[abc]?)?";
var regex_verse_range = regex_integer_with_opt_sep + "(?: ? ?\\p{Dash} ? ?" + regex_integer_with_opt_sep + ")?";
var regex_trailing = "(?![\\d\\p{Letter}@#$%])";
var regex_between_ranges = " ? ?[,;] ? ?";
var regex_additional_range = regex_between_ranges + "(" + regex_verse_range + ")" + regex_trailing;
function* detect_references(text, book_names, exclude_book_names, min_chars = 2, match_from_start = true) {
const from_string = (value) => {
return PassageReference.from_string(
value,
book_names,
exclude_book_names,
min_chars,
match_from_start
);
};
const regex_book_name = regex_book_name_tmpl.replace("MIN_MID", String(Math.max(0, min_chars - 2))).replace("END_LETTER", min_chars > 1 ? "\\p{Letter}" : "");
const regex_complete = regex_book_num_prefix + regex_book_name + regex_verse_range + regex_trailing;
const regex_book_check = regex_between_ranges + "(" + regex_book_num_prefix + regex_book_name + ")";
const regex = new RegExp(regex_complete, "uig");
let end_of_prev_match = 0;
while (true) {
const match = regex.exec(text);
if (!match) {
return null;
}
const ref = from_string(match[0]);
if (ref && ref.args_valid) {
yield {
ref,
text: match[0],
index: match.index,
index_from_prev_match: match.index - end_of_prev_match
};
end_of_prev_match = match.index + match[0].length;
const add_regex = new RegExp(regex_additional_range, "uiy");
add_regex.lastIndex = regex.lastIndex;
while (true) {
const book_look_ahead = new RegExp(regex_book_check, "uiy");
book_look_ahead.lastIndex = add_regex.lastIndex;
const possible_book = book_look_ahead.exec(text);
if (possible_book && from_string(possible_book[1])) {
break;
}
const add_match = add_regex.exec(text);
if (!add_match) {
break;
}
const add_match_real_index = add_match.index + add_match[0].indexOf(add_match[1]);
let prefix = ref.book;
const has_verse_sep = new RegExp(regex_verse_sep).test(add_match[1]);
if (!has_verse_sep && ["verse", "range_verses", "range_multi"].includes(ref.type)) {
prefix += `${ref.end_chapter}:`;
}
const add_ref = from_string(prefix + add_match[1]);
if (!add_ref || !add_ref.args_valid) {
break;
}
yield {
ref: add_ref,
text: add_match[1],
index: add_match_real_index,
index_from_prev_match: add_match_real_index - end_of_prev_match
};
end_of_prev_match = add_match_real_index + add_match[1].length;
if (add_regex.lastIndex > regex.lastIndex) {
regex.lastIndex = add_regex.lastIndex;
}
}
} else {
const chars_to_next_word = match[0].indexOf(" ", 1);
if (chars_to_next_word >= 1) {
regex.lastIndex -= match[0].length - chars_to_next_word - 1;
}
}
}
}
// ../references/dist/esm/stats.js
function get_chapters(book) {
return [...Array(last_verse[book].length).keys()].map((i) => i + 1);
}
function get_verses(book, chapter) {
return [...Array(last_verse[book][chapter - 1]).keys()].map((i) => i + 1);
}
// src/utils.ts
async function request(url) {
const resp = await fetch(url, { mode: "cors" });
if (resp.ok) {
return await resp.text();
}
throw new Error(`${resp.status} ${resp.statusText}: ${url}`);
}
function deep_copy(source) {
const copy = Array.isArray(source) ? [] : {};
for (const key in source) {
const value = source[key];
copy[key] = typeof value === "object" && value !== null ? deep_copy(value) : value;
}
return copy;
}
function rm_diacritics(string) {
return string.normalize("NFKD").replace(/\p{Diacritic}/gu, "");
}
function _fuzzy_match(input, candidate) {
if (!input || !candidate) {
return -Infinity;
}
let skipped = 0;
let input_i = 0;
for (let cand_i = 0; cand_i < candidate.length; cand_i++) {
if (candidate[cand_i] === input[input_i]) {
input_i++;
if (input_i >= input.length) {
return skipped * -1;
}
} else if (input_i === 0) {
return -Infinity;
} else {
skipped++;
if (skipped > 4) {
return -Infinity;
}
}
}
return -Infinity;
}
function fuzzy_search(input, candidates, cand_to_str) {
if (!input.trim()) {
return candidates.slice();
}
const input_words = rm_diacritics(input).toLowerCase().trim().split(" ");
const items = candidates.map((candidate) => {
const cand_words = rm_diacritics(cand_to_str(candidate)).toLowerCase().trim().split(" ");
const score = input_words.reduce((prev, item) => {
return prev + Math.max(...cand_words.map((cand) => _fuzzy_match(item, cand)));
}, 0);
return { candidate, score };
}).filter((item) => item.score > -4);
items.sort((a, b) => b.score - a.score);
return items.map((item) => item.candidate);
}
function escape_html(text) {
const escapes = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
};
return text.replace(/[&<>"']/g, (char) => escapes[char]);
}
function num_to_letters(num) {
if (num <= 0) {
return "";
}
const ascii_offset = 97;
return num_to_letters(Math.floor((num - 1) / 26)) + String.fromCharCode((num - 1) % 26 + ascii_offset);
}
// src/book.ts
function validate_ref(start_chapter, start_verse, end_chapter, end_verse) {
for (const arg of [start_chapter, start_verse, end_chapter, end_verse]) {
if (typeof arg !== "number") {
throw new Error("Chapter/verse arguments must all be numbers");
} else if (arg < 0) {
throw new Error("Chapter/verse arguments cannot be negative");
}
}
if (start_chapter > end_chapter || start_chapter === end_chapter && start_verse > end_verse) {
throw new Error("Passage end is less than passage start");
}
}
var BibleBookHtml = class {
// @internal
constructor(json, copyright) {
// @internal
__publicField(this, "_copyright");
// @internal
__publicField(this, "_html");
this._copyright = copyright;
this._html = JSON.parse(json);
}
// Get appropriate text for attribution (defaults to first license, optionally provide one)
get_attribution(license) {
if (!this._copyright) {
return "";
}
if (!license) {
license = this._copyright.licenses[0];
}
const url = this._copyright.attribution_url;
const owner = escape_html(this._copyright.attribution);
return `
<p class="fb-attribution">
<a href="${url}" target="_blank">${owner}</a>
(<a href="${license.url}" target="_blank">${license.name}</a>)
</p>
`;
}
// @internal
_attribution(license) {
if (license === false) {
return "";
}
return this.get_attribution(!license || license === true ? void 0 : license);
}
// Get the HTML for the entire book
get_whole({ attribute } = {}) {
return this._html.contents.flat().map((v) => v[1]).join("") + this._attribution(attribute);
}
// Get HTML for a specific passage
get_passage(start_chapter, start_verse, end_chapter, end_verse, options = {}) {
const chapters = this._get_list(start_chapter, start_verse, end_chapter, end_verse);
if (!chapters.length) {
return "";
}
let out = "";
for (const verses_for_ch of chapters) {
out += `<div class="fb-chapter" data-c="${verses_for_ch[0].chapter}">` + verses_for_ch[0].content[0] + verses_for_ch.map((v) => v.content[1]).join("") + verses_for_ch[verses_for_ch.length - 1].content[2] + "</div>";
}
return out + this._attribution(options.attribute);
}
// Get HTML for a specific passage specified by a PassageReference object
get_passage_from_ref(ref, options = {}) {
if (ref.type === "book") {
return this.get_whole(options);
}
if (ref.type === "chapter" || ref.type === "range_chapters") {
return this.get_chapters(ref.start_chapter, ref.end_chapter, options);
}
return this.get_passage(
ref.start_chapter,
ref.start_verse,
ref.end_chapter,
ref.end_verse,
options
);
}
// Get HTML for multiple chapters
get_chapters(first, last, options = {}) {
if (typeof first !== "number" || typeof last !== "number") {
throw new Error("First/last chapters must be numbers");
}
return this.get_passage(first, 1, last + 1, 0, options);
}
// Get HTML for a single chapter
get_chapter(chapter, options = {}) {
return this.get_chapters(chapter, chapter, options);
}
// Get HTML for a single verse
get_verse(chapter, verse, options = {}) {
return this.get_passage(chapter, verse, chapter, verse, options);
}
// @internal
_get_list(start_chapter = 1, start_verse = 1, end_chapter, end_verse) {
if (!end_chapter) {
end_chapter = this._html.contents.length;
end_verse = 0;
} else if (typeof end_verse !== "number") {
end_chapter += 1;
end_verse = 0;
}
validate_ref(start_chapter, start_verse, end_chapter, end_verse);
const get_verses_for_ch = (chapter, start, end) => {
var _a, _b;
const verses2 = (_b = (_a = this._html.contents[chapter]) == null ? void 0 : _a.slice(start, end && end + 1)) != null ? _b : [];
return verses2.map((verse, i) => {
const verse_num = start + i;
return {
// Calculate an id for the verse that is reproducible and sortable
// e.g. Psalm 119:176 = 119176 (cccvvv)
id: chapter * 1e3 + verse_num,
chapter,
verse: verse_num,
content: verse
};
});
};
const same_ch_end_verse = start_chapter === end_chapter ? end_verse : void 0;
const verses = [get_verses_for_ch(start_chapter, start_verse, same_ch_end_verse)];
for (let ch = start_chapter + 1; ch < end_chapter; ch++) {
verses.push(get_verses_for_ch(ch, 1));
}
if (end_chapter > start_chapter) {
verses.push(get_verses_for_ch(end_chapter, 1, end_verse));
}
return verses.filter((verses_for_ch) => verses_for_ch.length);
}
// Get HTML as an array of individual verses (each verse will be in its own paragraph)
get_list(start_chapter, start_verse, end_chapter, end_verse) {
return this._get_list(start_chapter, start_verse, end_chapter, end_verse).flat().map((verse) => {
return {
...verse,
content: verse.content.join("")
};
});
}
// Get HTML as an array of individual verses by passing a PassageReference object
get_list_from_ref(ref) {
let end_chapter = ref.end_chapter;
let end_verse = ref.end_verse;
if (ref.type === "book") {
end_chapter = void 0;
end_verse = void 0;
} else if (ref.type === "chapter") {
end_chapter += 1;
end_verse = 0;
}
return this.get_list(ref.start_chapter, ref.start_verse, end_chapter, end_verse);
}
};
var BibleBookUsx = class {
// @internal
constructor(usx, copyright) {
// @internal
__publicField(this, "_copyright");
// @internal
__publicField(this, "_usx");
this._copyright = copyright;
this._usx = usx;
}
// Get the USX for the entire book
get_whole() {
return this._usx;
}
};
var BibleBookUsfm = class {
// @internal
constructor(usfm, copyright) {
// @internal
__publicField(this, "_copyright");
// @internal
__publicField(this, "_usfm");
this._copyright = copyright;
this._usfm = usfm;
}
// Get the USFM for the entire book
get_whole() {
return this._usfm;
}
};
function txt_array_to_markdown(contents, headings = true, notes = true) {
const footnotes = [];
let result = contents.map((part) => {
if (typeof part === "string") {
return part;
} else if (part.type === "heading" && headings) {
return "\n" + "#".repeat(part.level) + " " + part.contents;
} else if (part.type === "note" && notes) {
footnotes.push(part.contents);
const note_letter = num_to_letters(footnotes.length);
return `[^${note_letter}]`;
}
return "";
}).join("");
if (footnotes.length) {
result += "\n\n\n\n";
result += footnotes.map((note, i) => `[^${num_to_letters(i + 1)}]: ${note}`).join("\n");
}
return result;
}
var BibleBookTxt = class {
// @internal
constructor(txt, copyright) {
// @internal
__publicField(this, "_copyright");
// @internal
__publicField(this, "_txt");
this._copyright = copyright;
this._txt = JSON.parse(txt);
}
// Get appropriate text for attribution (defaults to first license, optionally provide one)
get_attribution(license) {
if (!this._copyright) {
return "";
}
if (!license) {
license = this._copyright.licenses[0];
}
return `
[${license.name} - ${this._copyright.attribution}]`;
}
// @internal
_attribution(license) {
if (license === false) {
return "";
}
return this.get_attribution(!license || license === true ? void 0 : license);
}
// Get the contents of entire book
get_whole(options = {}) {
return this.get_passage(1, 1, this._txt.contents.length, 0, options);
}
// Get txt for a specific passage
get_passage(start_chapter, start_verse, end_chapter, end_verse, options = {}) {
validate_ref(start_chapter, start_verse, end_chapter, end_verse);
const get_verses_for_ch = (chapter, start, end) => {
var _a, _b;
const verses2 = (_b = (_a = this._txt.contents[chapter]) == null ? void 0 : _a.slice(start, end && end + 1)) != null ? _b : [];
if (!options.verse_nums) {
return verses2;
}
return verses2.map((verse, i) => {
let ref = "";
const verse_num = start + i;
if (verse_num === 1 || start > 1 && i === 0) {
ref += `${chapter}:`;
}
ref += verse_num;
ref = `[${ref}] `;
return [ref, ...verse];
});
};
const same_ch_end_verse = start_chapter === end_chapter ? end_verse : void 0;
const verses = get_verses_for_ch(start_chapter, start_verse, same_ch_end_verse);
for (let ch = start_chapter + 1; ch < end_chapter; ch++) {
verses.push(...get_verses_for_ch(ch, 1));
}
if (end_chapter > start_chapter) {
verses.push(...get_verses_for_ch(end_chapter, 1, end_verse));
}
const result = txt_array_to_markdown(verses.flat(), options.headings, options.notes);
return result + this._attribution(options.attribute);
}
// Get txt for multiple chapters
get_chapters(first, last, options = {}) {
if (typeof first !== "number" || typeof last !== "number") {
throw new Error("First/last chapters must be numbers");
}
return this.get_passage(first, 1, last + 1, 0, options);
}
// Get txt for a single chapter
get_chapter(chapter, options = {}) {
return this.get_chapters(chapter, chapter, options);
}
// Get txt for a single verse
get_verse(chapter, verse, options = {}) {
return this.get_passage(chapter, verse, chapter, verse, options);
}
};
// src/licenses.ts
function filter_licenses(licenses, usage) {
return licenses.filter((license) => {
const r = license.restrictions;
return (!usage.commercial || !r.forbid_commercial) && (!usage.attributionless || !r.forbid_attributionless) && (!usage.derivatives || !r.forbid_derivatives || usage.derivatives === "same-license" && r.forbid_derivatives === "same-license") && (!usage.limitless || !r.forbid_limitless);
});
}
// src/translation.ts
var TranslationExtra = class {
// @internal
constructor(extra) {
// @internal
__publicField(this, "_extra");
this._extra = extra;
}
// @internal
_ensure_book_exists(book) {
if (!books_ordered.includes(book)) {
throw new Error(`Book id "${book}" is not valid (should be 3 letters lowercase)`);
}
if (!(book in this._extra.book_names)) {
throw new Error(`Translation does not have book "${book}"`);
}
}
// Get local name data for a book.
// This will throw if the book doesn't exist or will contain empty strings if no data available.
// You should call `get_books()` on the collection instance for more intuitive access.
// It will automatically make use of local name data after fetching it.
get_book_name(book) {
this._ensure_book_exists(book);
return {
...this._extra.book_names[book]
};
}
// Get list of chapters for book which also includes a heading property for each
get_chapters(book) {
this._ensure_book_exists(book);
return this._extra.chapter_headings[book].map((heading, number) => ({ number, heading })).slice(1);
}
// Get the heading for a specific chapter
get_chapter_heading(book, chapter) {
this._ensure_book_exists(book);
return this._extra.chapter_headings[book][chapter];
}
// Get list of sections for a book which includes a heading for each and verse range
get_sections(book) {
this._ensure_book_exists(book);
return this._extra.sections[book].map((section) => {
var _a;
const heading = (_a = section.heading) != null ? _a : this._extra.chapter_headings[book][section.start_chapter];
return {
...section,
heading
};
});
}
};
// src/collection.ts
var BibleCollection = class {
// @internal
constructor(usage, remember_fetches, manifests) {
// @internal
__publicField(this, "_usage");
// @internal
__publicField(this, "_remember_fetches");
// @internal
__publicField(this, "_fetch_book_cache", {});
// @internal
__publicField(this, "_fetch_extras_cache", {});
// @internal
__publicField(this, "_local_book_names", {});
// @internal
__publicField(this, "_manifest");
// @internal
__publicField(this, "_endpoints", {});
// Map translation ids to endpoints
// @internal
__publicField(this, "_modern_year", (/* @__PURE__ */ new Date()).getFullYear() - 70);
this._usage = usage;
this._remember_fetches = remember_fetches;
this._manifest = {
licenses: manifests[0][1].licenses,
// Still useful even if resolved within transl.s
languages: {},
language2to3: {},
// NOTE If first manifest is sparse then may not include all possible codes
// But this is a non-essential array just used to slightly improve sorting
languages_most_spoken: manifests[0][1].languages_most_spoken,
translations: {}
};
const languages = /* @__PURE__ */ new Set();
for (const [endpoint, manifest] of manifests.reverse()) {
for (const [trans, trans_data] of Object.entries(manifest.translations)) {
let licenses = trans_data.copyright.licenses.map((item) => {
if (typeof item.license === "string") {
return {
id: item.license,
name: manifest.licenses[item.license].name,
restrictions: manifest.licenses[item.license].restrictions,
url: item.url
};
} else {
return {
id: null,
name: "Custom license",
restrictions: item.license,
url: item.url
};
}
});
licenses = filter_licenses(licenses, this._usage);
if (!licenses.length) {
continue;
}
languages.add(trans.slice(0, 3));
const ot = trans_data.books_ot === true ? books_ordered.slice(0, 39) : trans_data.books_ot;
const nt = trans_data.books_nt === true ? books_ordered.slice(39) : trans_data.books_nt;
this._manifest.translations[trans] = {
...trans_data,
books_ot_list: ot,
books_nt_list: nt,
copyright: {
...trans_data.copyright,
licenses
}
};
this._endpoints[trans] = endpoint;
}
for (const lang in manifest.languages) {
if (languages.has(lang)) {
this._manifest.languages[lang] = manifest.languages[lang];
}
}
for (const [lang2, lang3] of Object.entries(manifest.language2to3)) {
if (languages.has(lang3)) {
this._manifest.language2to3[lang2] = manifest.language2to3[lang2];