const BIBLE_TOKEN_REGEX = /@bible:([^\s]+)/gi; const normalizeReference = (value = "") => { try { return decodeURIComponent(String(value || "")) .replace(/_/g, " ") .replace(/\s+/g, " ") .trim(); } catch (_error) { return String(value || "").replace(/_/g, " ").replace(/\s+/g, " ").trim(); } }; export const encodeBibleReference = (reference = "") => { return String(reference || "").replace(/\s+/g, "_").trim(); }; export const createBibleToken = (reference = "") => { const encoded = encodeBibleReference(reference); if (!encoded) return ""; return `@bible:${encoded}`; }; export const extractBibleReferences = (content = "") => { const seen = new Set(); const refs = []; if (!content || typeof content !== "string") return refs; let match; while ((match = BIBLE_TOKEN_REGEX.exec(content)) !== null) { const normalized = normalizeReference(match[1]); if (!normalized || seen.has(normalized)) continue; seen.add(normalized); refs.push(normalized); } return refs; }; export const stripBibleTokens = (content = "") => { if (!content || typeof content !== "string") return ""; return content .replace(BIBLE_TOKEN_REGEX, "") .replace(/[ \t]{2,}/g, " ") .replace(/[ \t]+\n/g, "\n") .trim(); }; export const fetchBiblePassage = async (reference = "") => { const safeReference = normalizeReference(reference); if (!safeReference) { throw new Error("Missing Bible reference"); } const response = await fetch(`https://bible-api.com/${encodeURIComponent(safeReference)}`); if (!response.ok) { throw new Error("Failed to load Bible passage"); } const payload = await response.json(); return { reference: payload?.reference || safeReference, text: (payload?.text || "").trim(), translation: payload?.translation_name || payload?.translation_id || "KJV", }; }; export const parseBibleReference = (reference = "") => { const normalized = normalizeReference(reference); const match = normalized.match(/^(.*)\s+(\d+)(?::(\d+)(?:-\d+)?)?$/); if (!match) { return { reference: normalized, book: normalized, chapter: 1, verse: 1, chapterReference: normalized, }; } const book = (match[1] || "").trim(); const chapter = Number(match[2] || "1"); const verse = Number(match[3] || "1"); return { reference: normalized, book, chapter, verse, chapterReference: `${book} ${chapter}`, }; }; export const BIBLE_BOOKS = [ "Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings", "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job", "Psalms", "Proverbs", "Ecclesiastes", "Song of Solomon", "Isaiah", "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai", "Zechariah", "Malachi", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation", ]; export const BIBLE_BOOK_CHAPTERS = { Genesis: 50, Exodus: 40, Leviticus: 27, Numbers: 36, Deuteronomy: 34, Joshua: 24, Judges: 21, Ruth: 4, "1 Samuel": 31, "2 Samuel": 24, "1 Kings": 22, "2 Kings": 25, "1 Chronicles": 29, "2 Chronicles": 36, Ezra: 10, Nehemiah: 13, Esther: 10, Job: 42, Psalms: 150, Proverbs: 31, Ecclesiastes: 12, "Song of Solomon": 8, Isaiah: 66, Jeremiah: 52, Lamentations: 5, Ezekiel: 48, Daniel: 12, Hosea: 14, Joel: 3, Amos: 9, Obadiah: 1, Jonah: 4, Micah: 7, Nahum: 3, Habakkuk: 3, Zephaniah: 3, Haggai: 2, Zechariah: 14, Malachi: 4, Matthew: 28, Mark: 16, Luke: 24, John: 21, Acts: 28, Romans: 16, "1 Corinthians": 16, "2 Corinthians": 13, Galatians: 6, Ephesians: 6, Philippians: 4, Colossians: 4, "1 Thessalonians": 5, "2 Thessalonians": 3, "1 Timothy": 6, "2 Timothy": 4, Titus: 3, Philemon: 1, Hebrews: 13, James: 5, "1 Peter": 5, "2 Peter": 3, "1 John": 5, "2 John": 1, "3 John": 1, Jude: 1, Revelation: 22, }; export const getBookChapterCount = (book = "") => { return BIBLE_BOOK_CHAPTERS[book] || 1; };