From b046173740820fac1935e8acae9ba09937c8c7de Mon Sep 17 00:00:00 2001 From: samueljd Date: Thu, 29 Aug 2024 19:15:16 +0530 Subject: [PATCH] cache-file-working --- .gitignore | 2 + package.json | 6 +- .../EditorPage/LexicalEditor/cacheUtils.js | 142 + .../LexicalEditor/conversionUtils.js | 43 + .../EditorPage/LexicalEditor/updateAndSave.js | 14 + .../LexicalEditor/useUsfmGrammar.js | 72 + .../EditorPage/LexicalEditor/useUsjHook.js | 73 + .../Navigation/reference/SelectVerse.js | 4 +- .../EditorPage/TextEditor/EditorMenuBar.jsx | 3 +- .../EditorPage/TextEditor/Lexical.jsx | 120 + .../EditorPage/TextEditor/conversionUtils.js | 35 + .../EditorPage/TextEditor/hooks/saveToFile.js | 6 +- .../TextEditor/hooks/useReadUsfmFile.js | 26 +- .../EditorPage/TextEditor/index.jsx | 112 +- .../src/layouts/editor/SectionContainer.js | 16 + .../modules/editorsidebar/EditorSideBar.js | 7 +- styles/globals.css | 2429 ++++++++++++++++- yarn.lock | 160 +- 18 files changed, 3034 insertions(+), 236 deletions(-) create mode 100644 renderer/src/components/EditorPage/LexicalEditor/cacheUtils.js create mode 100644 renderer/src/components/EditorPage/LexicalEditor/conversionUtils.js create mode 100644 renderer/src/components/EditorPage/LexicalEditor/updateAndSave.js create mode 100644 renderer/src/components/EditorPage/LexicalEditor/useUsfmGrammar.js create mode 100644 renderer/src/components/EditorPage/LexicalEditor/useUsjHook.js create mode 100644 renderer/src/components/EditorPage/TextEditor/Lexical.jsx create mode 100644 renderer/src/components/EditorPage/TextEditor/conversionUtils.js diff --git a/.gitignore b/.gitignore index 91bdc8c22..b8ba0fc50 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,8 @@ Autogrpha-DB/ /app/**/*.map /.next .next +.yalc +yalc.lock # testing /coverage diff --git a/package.json b/package.json index b72a2de6e..9dd369b34 100644 --- a/package.json +++ b/package.json @@ -212,13 +212,14 @@ "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "5.0.1", + "sj-usfm-grammar": "^3.0.2", "styled-components": "^5.3.6", "tc-ui-toolkit": "5.3.3", "translation-helps-rcl": "3.5.12", "typescript": "^4.9.5", "use-deep-compare": "^1.1.0", "usfm-editor": "0.8.7", - "usfm-grammar": "^2.3.0", + "usfm-grammar": "3.0.0-alpha.4", "uuid": "^8.3.2", "wavesurfer.js": "^6.6.4", "webpack-node-externals": "^3.0.0", @@ -241,6 +242,7 @@ }, "optionalDependencies": { "bufferutil": "^4.0.6", + "react-icons": "4.10.1", "scripture-resources-rcl": "5.1.0", "utf-8-validate": "^5.0.9" }, @@ -252,4 +254,4 @@ "word-aligner": "$word-aligner", "@mui/lab": "$@mui/lab" } -} \ No newline at end of file +} diff --git a/renderer/src/components/EditorPage/LexicalEditor/cacheUtils.js b/renderer/src/components/EditorPage/LexicalEditor/cacheUtils.js new file mode 100644 index 000000000..62ef79b08 --- /dev/null +++ b/renderer/src/components/EditorPage/LexicalEditor/cacheUtils.js @@ -0,0 +1,142 @@ +import * as path from 'path'; +import * as crypto from 'crypto'; +import { convertUsfmToUsj } from './conversionUtils'; + +let fs; + +// Wrap the fs assignment in a function that checks if window is defined +function initFS() { + if (typeof window !== 'undefined' && window.require) { + fs = window.require('fs'); + } +} + +// Call initFS immediately +initFS(); + +// async function getWorkspaceFolderPath() { +// const userProfile = await localforage.getItem('userProfile'); +// const projectName = await localforage.getItem('currentProject'); +// const userName = userProfile?.username; +// const newpath = await localforage.getItem('userPath'); +// const CACHE_DIR = path.join(newpath, packageInfo.name, 'users', userName, 'project_cache', projectName); +// console.log({ CACHE_DIR }); +// return CACHE_DIR; +// } + +// const CACHE_DIR = await getWorkspaceFolderPath(); + +// const CACHE_FILE_NAME = 'fileCacheMap.json'; // File name to store the cache mapping +// // Ensure cache directory exists +// if (!fs.existsSync(CACHE_DIR)) { +// console.log('Creating cache directory:', CACHE_DIR); +// fs.mkdirSync(CACHE_DIR, { recursive: true }); +// } + +export function getMd5Hash(content) { + return crypto.createHash('md5').update(content).digest('hex'); +} + +export function getCacheFilePath(hash, projectCachePath) { + console.log({ hash, projectCachePath }); + return path.join(projectCachePath, `${hash}.json`); +} + +export function isCacheValid(hash, projectCachePath) { + if (!fs) { return false; } + const cacheFilePath = getCacheFilePath(hash, projectCachePath); + return fs.existsSync(cacheFilePath); +} + +export function readCache(hash, projectCachePath) { + if (!fs) { throw new Error('File system not available'); } + const cacheFilePath = path.join(projectCachePath, `${hash}.json`); + console.log(JSON.parse(fs.readFileSync(cacheFilePath, 'utf8'))); + return JSON.parse(fs.readFileSync(cacheFilePath, 'utf8')); +} + +export function writeCache(hash, data, projectCachePath) { + console.log({}); + if (!fs) { + console.error('File system not available'); + return; + } + const cacheFilePath = getCacheFilePath(hash, projectCachePath); + fs.writeFileSync(cacheFilePath, JSON.stringify(data), 'utf8'); +} + +export function deleteOldCacheFile(hash, projectCachePath) { + const cacheFilePath = getCacheFilePath(hash, projectCachePath); + if (fs.existsSync(cacheFilePath)) { + fs.unlinkSync(cacheFilePath); + } +} + +export function getCacheMapFromFile(fileCacheMapPath) { + if (fileCacheMapPath) { + try { + if (fs.existsSync(fileCacheMapPath)) { + const fileContent = fs.readFileSync(fileCacheMapPath, 'utf-8'); + return JSON.parse(fileContent); + } + } catch (error) { + console.error('Error reading cache file:', error); + } + } + + return {}; +} + +export function updateCacheMapToFile(fileCacheMapPath, filePath, hash) { + if (fileCacheMapPath) { + const cacheMap = getCacheMapFromFile(fileCacheMapPath); + cacheMap[filePath] = hash; + try { + fs.mkdirSync(path.dirname(fileCacheMapPath), { recursive: true }); + fs.writeFileSync(fileCacheMapPath, JSON.stringify(cacheMap)); + } catch (error) { + console.error('Error writing cache file:', error); + } + } +} + +export async function handleCache(filePath, usfmContent, projectCachePath, fileCacheMapPath) { + console.log({ usfmContent }); + const newHash = getMd5Hash(usfmContent); + const fileCacheMap = getCacheMapFromFile(fileCacheMapPath); + + const oldHash = fileCacheMap[filePath]; + if (oldHash && isCacheValid(oldHash, projectCachePath) && oldHash === newHash) { + console.log('Cache hit'); + return { usj: await readCache(oldHash, projectCachePath) }; + } + console.log('Cache miss or content changed'); + if (oldHash) { + deleteOldCacheFile(oldHash, projectCachePath); + } + const { usj, error } = await convertUsfmToUsj(usfmContent); + if (error) { + console.error('Error parsing USFM', error); + return { error }; + } + console.log({ newHash, usj }); + writeCache(newHash, usj, projectCachePath); + updateCacheMapToFile(fileCacheMapPath, filePath, newHash); + return { usj }; +} + +export async function updateCache(filePath, usj, usfm, fileCacheMapPath, projectCachePath) { + const newHash = getMd5Hash(usfm); + const fileCacheMap = getCacheMapFromFile(fileCacheMapPath); + const oldHash = fileCacheMap[filePath]; + + if (oldHash && isCacheValid(oldHash, projectCachePath) && oldHash === newHash) { + writeCache(oldHash, usj, projectCachePath); + } else { + if (oldHash) { + deleteOldCacheFile(oldHash, projectCachePath); + } + writeCache(newHash, usj, projectCachePath); + updateCacheMapToFile(fileCacheMapPath, filePath, newHash); + } +} diff --git a/renderer/src/components/EditorPage/LexicalEditor/conversionUtils.js b/renderer/src/components/EditorPage/LexicalEditor/conversionUtils.js new file mode 100644 index 000000000..ed292b060 --- /dev/null +++ b/renderer/src/components/EditorPage/LexicalEditor/conversionUtils.js @@ -0,0 +1,43 @@ +import USFMParser from 'sj-usfm-grammar'; + +let usfmParserInstance; +let usfmParserInitialized; + +export async function initializeParser() { + if (!usfmParserInstance) { + if (!usfmParserInitialized) { + usfmParserInitialized = await USFMParser.init(); + } + await usfmParserInitialized; + usfmParserInstance = new USFMParser(); + } + return usfmParserInstance; +} + +export async function convertUsfmToUsj(usfm) { + if (!usfmParserInstance) { + usfmParserInstance = await initializeParser(); + } + try { + const usj = usfmParserInstance.usfmToUsj(usfm); + return { usj }; + } catch (e) { + return { usj: { content: [] }, error: e }; + } +} + +export async function convertUsjToUsfm(usj) { + if (!usfmParserInstance) { + usfmParserInstance = await initializeParser(); + } + const usfm = usfmParserInstance.usjToUsfm(usj); + return usfm; +} + +initializeParser() + .then(() => { + console.log('USFM Parser initialized successfully'); + }) + .catch((err) => { + console.error('Error initializing USFM Parser:', err); + }); diff --git a/renderer/src/components/EditorPage/LexicalEditor/updateAndSave.js b/renderer/src/components/EditorPage/LexicalEditor/updateAndSave.js new file mode 100644 index 000000000..3c00c512b --- /dev/null +++ b/renderer/src/components/EditorPage/LexicalEditor/updateAndSave.js @@ -0,0 +1,14 @@ +import { getCachePaths } from '../TextEditor/hooks/useReadUsfmFile'; +import { convertUsjToUsfm } from './conversionUtils'; +import { updateCache } from './cacheUtils'; +import { saveToFile } from '../TextEditor/hooks/saveToFile'; + +export async function updateCacheNSaveFile(usj, bookId) { + const usfm = await convertUsjToUsfm(usj); + const { filePath, projectCachePath, fileCacheMapPath } = await getCachePaths(bookId); + updateCache(filePath, usj, usfm, fileCacheMapPath, projectCachePath); + if (usfm) { + await saveToFile(usfm, bookId); + console.log('file saved'); + } +} diff --git a/renderer/src/components/EditorPage/LexicalEditor/useUsfmGrammar.js b/renderer/src/components/EditorPage/LexicalEditor/useUsfmGrammar.js new file mode 100644 index 000000000..687211aa4 --- /dev/null +++ b/renderer/src/components/EditorPage/LexicalEditor/useUsfmGrammar.js @@ -0,0 +1,72 @@ +import { + useState, useEffect, useRef, useCallback, +} from 'react'; +import { USFMParser } from 'usfm-grammar'; + +// Hook to initialize the parser +export const useUSFMParser = () => { + const [usfmParser, setUsfmParser] = useState(); + + useEffect(() => { + const initParser = async () => { + await USFMParser.init(); + const usfmParser = new USFMParser(); + console.log({ usfmParser }); + setUsfmParser(usfmParser); + }; + initParser(); + }, []); + + return { USFMParser: usfmParser }; +}; + +// Hook for USFM to USJ conversion +export const useUsfmToUsj = () => { + const parserRef = useUSFMParser(); + console.log({ parserRef }); + const [usj, setUsj] = useState(null); + const [error, setError] = useState(null); + + const convert = useCallback((usfm) => { + console.log('inside the hook ======>', { usfm }); + if (parserRef.current) { + try { + const result = parserRef.current.usfmToUsj(usfm); + console.log({ result }); + setUsj(result); + setError(null); + } catch (err) { + setError(err.message); + setUsj(null); + } + } else { + setError('Parser not initialized'); + } + }, [parserRef]); + + return { usj, error, convert }; +}; + +// Hook for USJ to USFM conversion +export const useUsjToUsfm = () => { + const parserRef = useUSFMParser(); + const [usfm, setUsfm] = useState(null); + const [error, setError] = useState(null); + + const convert = useCallback((usj) => { + if (parserRef.current) { + try { + const result = parserRef.current.usjToUsfm(usj); + setUsfm(result); + setError(null); + } catch (err) { + setError(err.message); + setUsfm(null); + } + } else { + setError('Parser not initialized'); + } + }, [parserRef]); + + return { usfm, error, convert }; +}; diff --git a/renderer/src/components/EditorPage/LexicalEditor/useUsjHook.js b/renderer/src/components/EditorPage/LexicalEditor/useUsjHook.js new file mode 100644 index 000000000..97c34083a --- /dev/null +++ b/renderer/src/components/EditorPage/LexicalEditor/useUsjHook.js @@ -0,0 +1,73 @@ +// import { useState, useEffect, useRef } from 'react'; +// import { USFMParser } from 'usfm-grammar'; + +// export const useUSFMParser = () => { +// const [isReady, setIsReady] = useState(false); +// const parserRef = useRef(null); + +// useEffect(() => { +// const initializeParser = async () => { +// if (!parserRef.current) { +// await USFMParser.init(); +// parserRef.current = new USFMParser(); +// setIsReady(true); +// } +// }; + +// initializeParser(); +// }, []); + +// const usfmToUsj = (usfmString) => { +// if (!isReady) { +// throw new Error('USFM Parser is not initialized yet'); +// } +// return parserRef.current.usfmToUsj(usfmString); +// }; + +// const usjToUsfm = (usjObject) => { +// if (!isReady) { +// throw new Error('USFM Parser is not initialized yet'); +// } +// return parserRef.current.usjToUsfm(usjObject); +// }; + +// return { isReady, usfmToUsj, usjToUsfm }; +// }; + +// // export default useUSFMParser; + +import { useState, useEffect, useCallback } from 'react'; +import { USFMParser } from 'usfm-grammar'; + +export const useUSFMParser = () => { + const [parser, setParser] = useState(null); + + useEffect(() => { + const initializeParser = async () => { + if (!parser) { + await USFMParser.init(); + setParser(new USFMParser()); + } + }; + + initializeParser(); + }, [parser]); + + const usfmToUsj = useCallback((usfmString) => { + if (!parser) { + throw new Error('USFM Parser is not initialized yet'); + } + return parser.usfmToUsj(usfmString); + }, [parser]); + + const usjToUsfm = useCallback((usjObject) => { + if (!parser) { + throw new Error('USFM Parser is not initialized yet'); + } + return parser.usjToUsfm(usjObject); + }, [parser]); + + return { isReady: !!parser, usfmToUsj, usjToUsfm }; +}; + +export default useUSFMParser; diff --git a/renderer/src/components/EditorPage/Navigation/reference/SelectVerse.js b/renderer/src/components/EditorPage/Navigation/reference/SelectVerse.js index ba564b1ce..4cd805594 100644 --- a/renderer/src/components/EditorPage/Navigation/reference/SelectVerse.js +++ b/renderer/src/components/EditorPage/Navigation/reference/SelectVerse.js @@ -40,7 +40,7 @@ export default function SelectVerse({ window.location.href = `#ch-${chapterNum}`; if (chapterNum && setChapterNumber) { setChapterNumber(chapterNum); - document.getElementById('editor').querySelector(`#ch-${chapterNum}`)?.scrollIntoView(); + // document.getElementById('editor').querySelector(`#ch-${chapterNum}`)?.scrollIntoView(); } }; @@ -50,7 +50,7 @@ export default function SelectVerse({ closeBooks(); if (multiSelectVerse === false) { closeVerses(); } if (verseNum && setVerseNumber) { - document.getElementById('editor').querySelector(`#ch${chapter}v${verseNum}`)?.scrollIntoView(); + // document.getElementById('editor').querySelector(`#ch${chapter}v${verseNum}`)?.scrollIntoView(); setVerseNumber(verseNum); } }; diff --git a/renderer/src/components/EditorPage/TextEditor/EditorMenuBar.jsx b/renderer/src/components/EditorPage/TextEditor/EditorMenuBar.jsx index 9e48eda78..a9b13f3af 100644 --- a/renderer/src/components/EditorPage/TextEditor/EditorMenuBar.jsx +++ b/renderer/src/components/EditorPage/TextEditor/EditorMenuBar.jsx @@ -115,6 +115,7 @@ export default function EditorMenuBar(props) { aria-hidden="true" /> +
@@ -122,7 +123,7 @@ export default function EditorMenuBar(props) {
- +
diff --git a/renderer/src/components/EditorPage/TextEditor/Lexical.jsx b/renderer/src/components/EditorPage/TextEditor/Lexical.jsx new file mode 100644 index 000000000..81d6af51e --- /dev/null +++ b/renderer/src/components/EditorPage/TextEditor/Lexical.jsx @@ -0,0 +1,120 @@ +import { + useEffect, useState, useRef, useMemo, useContext, +} from 'react'; + +import { + Editor, getViewOptions, DEFAULT_VIEW_MODE, immutableNoteCallerNodeName, NoteEditor, +} from '@biblionexus-foundation/scribe-editor'; +import { ProjectContext } from '@/components/context/ProjectContext'; +import EditorSideBar from '@/modules/editorsidebar/EditorSideBar'; +// import '@biblionexus-foundation/scribe-editor/dist/style.css'; + +const defaultScrRef = { + /* PSA */ bookCode: 'PSA', + chapterNum: 1, + verseNum: 1, +}; + +export default function LexicalEditor({ usjInput, onUsjChange, setNavRef }) { + const [usj, setUsj] = useState(); + // const [initialRender, setInitialRender] = useState(true); + const [scrRef, setScrRef] = useState(defaultScrRef); + const editorRef = useRef(null); + const [stateX, setStateX] = useState(false); + const [text, setText] = useState(''); + const { + states: { openSideBar, scrollLock }, + actions: { setOpenSideBar, setSideBarTab }, + } = useContext(ProjectContext); + function closeSideBar(status) { + setOpenSideBar(status); + } + + const previousUsjRef = useRef(null); + + useEffect(() => { + const timeoutId = setTimeout(() => { + usj && editorRef.current?.setUsj(usj); + }, 0); + return () => clearTimeout(timeoutId); + }, [usj]); + useEffect(() => { + console.log('usjInput', usjInput); + if (usjInput) { + setUsj(usjInput); + } + }, [usjInput]); + + const [viewMode] = useState(DEFAULT_VIEW_MODE); + const nodeOptions = { + [immutableNoteCallerNodeName]: { + onClick: (e) => { + setStateX(true); + setText(e.currentTarget.getAttribute('data-caller-id')); + setOpenSideBar(!openSideBar); + }, + }, + }; + const viewOptions = useMemo(() => getViewOptions(viewMode), [viewMode]); + // const noteViewOptions = useMemo(() => getViewOptions(noteViepnpm i @types/lodash.debouncewMode), [noteViewMode]); + + const onChange = async (updatedUsj) => { + editorRef.current?.setUsj(updatedUsj); + // const usfm = await Usj2Usfm(updatedUsj); + onUsjChange(updatedUsj); + console.log(updatedUsj); + }; + + useEffect(() => { + setNavRef(scrRef); + }, [scrRef]); + + return ( +
+ +
+
+ +
+
+ + { + stateX && ( +
+
+ Note Editor + +
+
+ +
+
+ ) + } +
+ + ); +} diff --git a/renderer/src/components/EditorPage/TextEditor/conversionUtils.js b/renderer/src/components/EditorPage/TextEditor/conversionUtils.js new file mode 100644 index 000000000..b86c732d5 --- /dev/null +++ b/renderer/src/components/EditorPage/TextEditor/conversionUtils.js @@ -0,0 +1,35 @@ +import USFMParser from 'sj-usfm-grammar'; + +let usfmParserInstance; +let usfmParserInitialized; + +export async function initializeParser() { + if (!usfmParserInstance) { + if (!usfmParserInitialized) { + usfmParserInitialized = await USFMParser.init(); + } + await usfmParserInitialized; + usfmParserInstance = new USFMParser(); + } + return usfmParserInstance; +} + +export async function convertUsfmToUsj(usfm) { + if (!usfmParserInstance) { + usfmParserInstance = await initializeParser(); + } + try { + const usj = usfmParserInstance.usfmToUsj(usfm); + return { usj }; + } catch (e) { + return { usj: { content: [] }, error: e }; + } +} + +initializeParser() + .then(() => { + console.log('USFM Parser initialized successfully'); + }) + .catch((err) => { + console.error('Error initializing USFM Parser:', err); + }); diff --git a/renderer/src/components/EditorPage/TextEditor/hooks/saveToFile.js b/renderer/src/components/EditorPage/TextEditor/hooks/saveToFile.js index b5ef6c340..a4923347d 100644 --- a/renderer/src/components/EditorPage/TextEditor/hooks/saveToFile.js +++ b/renderer/src/components/EditorPage/TextEditor/hooks/saveToFile.js @@ -1,10 +1,8 @@ import localforage from 'localforage'; -// import { readRefMeta } from '../../../core/reference/readRefMeta'; import { isElectron } from '@/core/handleElectron'; import writeToFile from '@/core/editor/writeToFile'; import { readRefBurrito } from '@/core/reference/readRefBurrito'; import packageInfo from '../../../../../../package.json'; -import { newPath } from '../../../../../../supabase'; // function to save to file. export const saveToFile = async (usfmText, bookCode) => { @@ -14,12 +12,12 @@ export const saveToFile = async (usfmText, bookCode) => { const projectName = await localforage.getItem('currentProject'); const path = require('path'); const newpath = localStorage.getItem('userPath'); - const metaPath = isElectron() ? path.join(newpath, packageInfo.name, 'users', userName, 'projects', projectName, 'metadata.json') : `${newPath}/${userName}/projects/${projectName}/metadata.json`; + const metaPath = path.join(newpath, packageInfo.name, 'users', userName, 'projects', projectName, 'metadata.json'); const metaData = JSON.parse(await readRefBurrito({ metaPath })); Object.entries(metaData.ingredients).forEach(async ([key, _ingredients]) => { if (_ingredients.scope) { const _bookID = Object.entries(_ingredients.scope)[0][0]; - if (_bookID === bookCode) { + if (_bookID.toUpperCase() === bookCode.toUpperCase()) { await writeToFile({ username: userName, projectname: projectName, diff --git a/renderer/src/components/EditorPage/TextEditor/hooks/useReadUsfmFile.js b/renderer/src/components/EditorPage/TextEditor/hooks/useReadUsfmFile.js index 193486311..fcdc3dc11 100644 --- a/renderer/src/components/EditorPage/TextEditor/hooks/useReadUsfmFile.js +++ b/renderer/src/components/EditorPage/TextEditor/hooks/useReadUsfmFile.js @@ -4,10 +4,13 @@ import { ReferenceContext } from '@/components/context/ReferenceContext'; import { readRefBurrito } from '../../../../core/reference/readRefBurrito'; import { readFile } from '../../../../core/editor/readFile'; import packageInfo from '../../../../../../package.json'; +import { handleCache } from '../../LexicalEditor/cacheUtils'; // hook to fetch usfmfile from system drive export const useReadUsfmFile = () => { const [usfmData, setUsfmData] = useState([]); const [bookAvailable, setbookAvailable] = useState(false); + const [usfmString, setUsfmString] = useState(''); + const [cachedData, setCachedData] = useState({}); const { state: { bookId, @@ -32,8 +35,13 @@ export const useReadUsfmFile = () => { } }); const [currentBook] = _books.filter((bookObj) => bookObj.bookId === bookId?.toUpperCase()); + const projectCachePath = path.join(newpath, packageInfo.name, 'users', userName, 'project_cache', projectName); + const fileCacheMapPath = path.join(projectCachePath, 'fileCacheMap.json'); + const filePath = path.join(newpath, packageInfo.name, 'users', userName, 'projects', projectName, 'ingredients', `${bookId.toUpperCase()}.usfm`); + console.log('+++++++++++++>', { filePath }); if (currentBook) { const fileData = await readFile({ projectname: projectName, filename: currentBook.fileName, username: userName }); + const cachedData = await handleCache(filePath, fileData, projectCachePath, fileCacheMapPath); const books = [{ selectors: { org: 'unfoldingWord', lang: 'en', abbr: 'ult' }, bookCode: currentBook.bookId.toLowerCase(), @@ -41,6 +49,8 @@ export const useReadUsfmFile = () => { }]; setUsfmData(books); setbookAvailable(true); + setUsfmString(fileData); + setCachedData(cachedData); } else { setUsfmData([]); setbookAvailable(false); @@ -53,5 +63,19 @@ export const useReadUsfmFile = () => { } readLocalFile(); }, [bookId]); - return { usfmData, bookAvailable }; + return { + usfmData, bookAvailable, usfmString, bookId, cachedData, + }; }; + +export async function getCachePaths(bookId) { + const path = require('path'); + const userProfile = await localforage.getItem('userProfile'); + const projectName = await localforage.getItem('currentProject'); + const newPath = await localforage.getItem('userPath'); + const userName = userProfile?.username; + const projectCachePath = path.join(newPath, packageInfo.name, 'users', userName, 'project_cache', projectName); + const fileCacheMapPath = path.join(projectCachePath, 'fileCacheMap.json'); + const filePath = path.join(newPath, packageInfo.name, 'users', userName, 'projects', projectName, 'ingredients', `${bookId.toUpperCase()}.usfm`); + return { filePath, projectCachePath, fileCacheMapPath }; +} diff --git a/renderer/src/components/EditorPage/TextEditor/index.jsx b/renderer/src/components/EditorPage/TextEditor/index.jsx index 76734ba1e..1c61e1717 100644 --- a/renderer/src/components/EditorPage/TextEditor/index.jsx +++ b/renderer/src/components/EditorPage/TextEditor/index.jsx @@ -1,36 +1,53 @@ import React, { - useEffect, useState, useContext, Fragment, + useEffect, useState, useContext, Fragment, useMemo, } from 'react'; -import { useProskomma, useImport, useCatalog } from 'proskomma-react-hooks'; -import { useDeepCompareEffect } from 'use-deep-compare'; import { ScribexContext } from '@/components/context/ScribexContext'; import { ReferenceContext } from '@/components/context/ReferenceContext'; import { ProjectContext } from '@/components/context/ProjectContext'; import EditorSideBar from '@/modules/editorsidebar/EditorSideBar'; +import { debounce } from 'lodash'; import { useReadUsfmFile } from './hooks/useReadUsfmFile'; -import htmlMap from './hooks/htmlmap'; -import usePerf from './hooks/usePerf'; import EditorMenuBar from './EditorMenuBar'; -import Editor from './Editor'; +import LexicalEditor from './Lexical'; +import { updateCacheNSaveFile } from '../LexicalEditor/updateAndSave'; export default function TextEditor() { const { state, actions } = useContext(ScribexContext); - const { verbose } = state; - const [selectedBook, setSelectedBook] = useState(); const [bookChange, setBookChange] = useState(false); const [chapterNumber, setChapterNumber] = useState(1); const [verseNumber, setVerseNumber] = useState(1); const [triggerVerseInsert, setTriggerVerseInsert] = useState(false); - // const [newVerChapNumber, setInsertNumber] = useState(''); - // const [insertVerseRChapter, setInsertVerseRChapter] = useState(''); + const [usjInput, setUsjInput] = useState(); + // const [parser, setParser] = useState(); + const [navRef, setNavRef] = useState(); - const { usfmData, bookAvailable } = useReadUsfmFile(); + // const initializeParser = async () => { + // await USFMParser.init(); + // usfmParser = new USFMParser(); + // setParser(usfmParser); + // }; + // useEffect(() => { + // initializeParser(); + // }, []); const { - state: { bookId, selectedFont, editorFontSize }, - actions: { - handleSelectedFont, onChangeChapter, onChangeVerse, handleEditorFontSize, - }, + bookAvailable, bookId, cachedData, + } = useReadUsfmFile(); + useEffect(() => { + if (cachedData.error) { + console.error('Error parsing USFM', cachedData.error); + + return; + } + const { usj } = cachedData; + if (!usj && usj === {}) { return; } + console.log({ usj }); + setUsjInput(usj); + }, [bookId, cachedData]); + + const { + state: { selectedFont }, + actions: { handleSelectedFont, onChangeChapter, onChangeVerse }, } = useContext(ReferenceContext); const { @@ -38,69 +55,42 @@ export default function TextEditor() { actions: { setOpenSideBar }, } = useContext(ProjectContext); - let selectedDocument; - - const { proskomma, stateId, newStateId } = useProskomma({ verbose }); - const { done } = useImport({ - proskomma, - stateId, - newStateId, - documents: usfmData, - }); - function closeSideBar(status) { setOpenSideBar(status); } - useEffect(() => { - setSelectedBook(bookId.toUpperCase()); - setBookChange(true); - }, [bookId]); - useEffect(() => { onChangeChapter(chapterNumber, 1); onChangeVerse(verseNumber, 1); // eslint-disable-next-line react-hooks/exhaustive-deps }, [chapterNumber, verseNumber]); - const { catalog } = useCatalog({ proskomma, stateId, verbose }); - const { id: docSetId, documents } = (done && catalog.docSets[0]) || {}; - if (done) { - selectedDocument = documents?.find( - (doc) => doc.bookCode === selectedBook, - ); - } - - const { bookCode, h: bookName } = selectedDocument || {}; - const ready = (docSetId && bookCode) || false; - const isLoading = !done || !ready; - const { state: perfState, actions: perfActions } = usePerf({ - proskomma, - ready, - docSetId, - bookCode, - verbose, - htmlMap, - }); - const { htmlPerf } = perfState; - - useDeepCompareEffect(() => { - if (htmlPerf && htmlPerf.mainSequenceId !== state.sequenceIds[0]) { - actions.setSequenceIds([htmlPerf?.mainSequenceId]); + useEffect(() => { + if (navRef) { + const { chapterNum, verseNum } = navRef; + console.log(navRef); + setChapterNumber(chapterNum); + setVerseNumber(verseNum); } - }, [htmlPerf, state.sequenceIds, perfState]); + }, [navRef]); + + const handleUsjChange = useMemo( + () => debounce(async (updatedUsj) => { + updateCacheNSaveFile(updatedUsj, bookId); + }, 1000), + [bookId], + ); const _props = { ...state, - ...perfState, + // ...perfState, ...actions, - ...perfActions, - editorFontSize, + // ...perfActions, selectedFont, chapterNumber, verseNumber, - isLoading, - bookName, + // isLoading, + // bookName, bookChange, bookAvailable, handleEditorFontSize, @@ -120,7 +110,7 @@ export default function TextEditor() { />
- + {usjInput && }
); diff --git a/renderer/src/layouts/editor/SectionContainer.js b/renderer/src/layouts/editor/SectionContainer.js index 4e4415eb2..26436dfc0 100644 --- a/renderer/src/layouts/editor/SectionContainer.js +++ b/renderer/src/layouts/editor/SectionContainer.js @@ -28,6 +28,22 @@ const SectionContainer = () => { const data = fs.readFileSync(metaPath, 'utf-8'); const metadata = JSON.parse(data); setEditor(metadata.type.flavorType.flavor.name); + + if (metadata.type.flavorType.flavor.name === 'textTranslation') { + // Check for project_cache folder and create if it doesn't exist + const projectCachePath = path.join(newpath, packageInfo.name, 'users', username, 'project_cache', projectName); + if (!fs.existsSync(projectCachePath)) { + fs.mkdirSync(projectCachePath, { recursive: true }); + console.log('Created project_cache folder:', projectCachePath); + } + + // Check for fileCacheMap.json and create if it doesn't exist + const fileCacheMapPath = path.join(projectCachePath, 'fileCacheMap.json'); + if (!fs.existsSync(fileCacheMapPath)) { + fs.writeFileSync(fileCacheMapPath, JSON.stringify({}), 'utf-8'); + console.log('Created fileCacheMap.json:', fileCacheMapPath); + } + } }); }); }, [editor]); diff --git a/renderer/src/modules/editorsidebar/EditorSideBar.js b/renderer/src/modules/editorsidebar/EditorSideBar.js index 119689442..202d1fab4 100644 --- a/renderer/src/modules/editorsidebar/EditorSideBar.js +++ b/renderer/src/modules/editorsidebar/EditorSideBar.js @@ -18,6 +18,7 @@ import { BookmarkIcon, } from '@heroicons/react/24/outline'; +import { NoteEditor } from '@biblionexus-foundation/scribe-editor'; import PinIcon from '@/icons/basil/Outline/Status/Pin.svg'; import CrossReferenceIcon from '@/icons/crossreference.svg'; import FootNotesIcon from '@/icons/footnotes.svg'; @@ -193,9 +194,11 @@ export default function EditorSideBar(props) { {state.tabIndex === 0 && } {state.tabIndex === 1 - && } + // && } + && } {state.tabIndex === 2 - && } + && } + {/* && } */} {state.tabIndex === 3 && } {state.tabIndex === 4 diff --git a/styles/globals.css b/styles/globals.css index 956f6ff48..a4447008c 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -109,7 +109,7 @@ p.paragraph:has(.chapter) { } .ref-editor ::selection { - @apply bg-primary-50; + @apply bg-primary-50; } /* .perf .verse:after { @@ -271,37 +271,2420 @@ p.paragraph:has(.chapter) { margin: 0.1em; } */ .button { - @apply flex h-8 cursor-pointer items-center justify-center rounded-lg p-2 text-xs font-bold outline-none xl:px-4; + @apply flex h-8 cursor-pointer items-center justify-center rounded-lg p-2 text-xs font-bold outline-none xl:px-4; } -#sundesmosToolbar { - background-color: #E5E7EB; - border-color: white; +.editor-input { + text-align: start; } -.chunk-row:hover { - background-color: rgba(135, 206, 250, 0.3); +.editor-input > p { + direction: inherit; + margin-top: 0; + margin-bottom: 0; + line-height: 1.5; } -div.draggable { - border-color: #121212; - border-width: 1px; +/* USJ Nodes */ + +.leadingFloat { + float: start; +} +.clearFloat { + clear: both; +} +.align_start { + text-align: start; +} +.align_center { + text-align: center; +} +.align_end { + text-align: end; +} +@font-face { + font-family: 'Charis SIL'; + src: local('Charis SIL'), local('Charis SIL Bold'), + local('Charis SIL Bold Italic'), local('Charis SIL Italic'), + url('file:///C:/Windows/Fonts/CharisSIL-B.ttf'); + font-weight: normal; +} +@font-face { + font-family: 'Charis SIL'; + src: local('Charis SIL Bold'); + font-weight: bold; +} +@font-face { + font-family: 'Charis SIL'; + src: local('Charis SIL Italic'); + font-style: italic; +} +@font-face { + font-family: 'Charis SIL'; + src: local('Charis SIL Bold Italic'); + font-weight: bold; + font-style: italic; +} +.formatted-font .usfm { + font-family: 'Charis SIL'; + font-size: 12pt; +} + +/* BookNode */ + +.usfm_id { + display: none; +} +.formatted-font .usfm_id { + font-size: 100%; +} + +/* ChapterNode, ImmutableChapterNode */ + +.formatted-font .usfm_c { + @apply m-2 block break-before-column font-medium uppercase tracking-wider before:content-['Chapter_:_']; +} +.text-spacing[dir='ltr'] .usfm_c { + @apply pl-4 text-left; +} +.text-spacing[dir='rtl'] .usfm_c { + @apply pr-4 text-right; +} + +.formatted-font .usfm_ca { + color: #007306; + font-size: 133%; + font-style: italic; +} + +.formatted-font .usfm_cp { + font-weight: bold; + color: #003380; + font-size: 150%; +} +.text-spacing .usfm_cp { + margin-bottom: 4pt; + margin-top: 8pt; +} + +/* VerseNode, ImmutableVerseNode */ + +.formatted-font .usfm_v { + @apply align-top text-xs uppercase tracking-wider text-cyan-500; +} +.text-spacing[dir='ltr'] .usfm_v { + @apply text-left; +} +.text-spacing[dir='rtl'] .usfm_v { + @apply text-right; +} + +.formatted-font .usfm_va { + color: #007306; + font-size: 100%; + vertical-align: text-top; + font-size: 66%; +} + +.formatted-font .usfm_vp { + color: #003380; + font-size: 100%; + vertical-align: text-top; + font-size: 66%; +} + +/* ParaNode */ + +.formatted-font .usfm_usfm { + font-size: 100%; +} + +.formatted-font .usfm_ide { + font-size: 100%; + display: none; +} + +.formatted-font .usfm_h { + font-size: 100%; + display: none; +} + +.formatted-font .usfm_h1 { + font-size: 100%; +} + +.formatted-font .usfm_h2 { + font-size: 100%; +} + +.formatted-font .usfm_h3 { + font-size: 100%; +} + +.usfm_toc1 { + @apply hidden; +} +.formatted-font .usfm_toc1 { + @apply font-bold italic text-green-900; +} +.text-spacing[dir='ltr'] .usfm_toc1 { + @apply ml-2 text-left; +} +.text-spacing[dir='rtl'] .usfm_toc1 { + @apply mr-2 text-right; +} + +.usfm_toc2 { + @apply hidden; +} +.formatted-font .usfm_toc2 { + @apply italic text-green-900; +} +.text-spacing[dir='ltr'] .usfm_toc2 { + @apply ml-2 text-left; +} +.text-spacing[dir='rtl'] .usfm_toc2 { + @apply mr-2 text-right; +} + +.usfm_toc3 { + @apply hidden; +} +.formatted-font .usfm_toc3 { + @apply font-bold italic text-red-500; +} +.text-spacing[dir='ltr'] .usfm_toc3 { + @apply ml-2 text-left; +} +.text-spacing[dir='rtl'] .usfm_toc3 { + @apply mr-2 text-right; +} + +.formatted-font .usfm_toca1 { + color: #8c8c8c; + font-size: 83%; + font-style: italic; +} + +.formatted-font .usfm_toca2 { + color: #8c8c8c; + font-size: 83%; + font-style: italic; +} + +.formatted-font .usfm_toca3 { + color: #8c8c8c; + font-size: 83%; + font-style: italic; +} + +.formatted-font .usfm_rem { + color: #003380; + font-size: 100%; +} + +.formatted-font .usfm_sts { + color: #003380; + font-size: 100%; +} + +.formatted-font .usfm_restore { + color: #003380; + font-size: 100%; +} + +.formatted-font .usfm_imt { + font-weight: bold; + font-size: 116%; +} +.text-spacing .usfm_imt { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_imt1 { + font-weight: bold; + font-size: 116%; +} +.text-spacing .usfm_imt1 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_imt2 { + font-size: 108%; + font-style: italic; +} +.text-spacing .usfm_imt2 { + text-align: center; + margin-bottom: 3pt; + margin-top: 6pt; +} + +.formatted-font .usfm_imt3 { + font-weight: bold; + font-size: 100%; +} +.text-spacing .usfm_imt3 { + text-align: center; + margin-bottom: 2pt; + margin-top: 2pt; +} + +.formatted-font .usfm_imt4 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_imt4 { + text-align: center; + margin-bottom: 2pt; + margin-top: 2pt; +} + +.formatted-font .usfm_imte { + font-weight: bold; + font-size: 166%; +} +.text-spacing .usfm_imte { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_imte1 { + font-weight: bold; + font-size: 166%; +} +.text-spacing .usfm_imte1 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_imte2 { + font-size: 133%; + font-style: italic; +} +.text-spacing .usfm_imte2 { + text-align: center; + margin-bottom: 2pt; +} + +.formatted-font .usfm_is { + font-weight: bold; + font-size: 116%; +} +.text-spacing .usfm_is { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_is1 { + font-weight: bold; + font-size: 116%; +} +.text-spacing .usfm_is1 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_is2 { + font-weight: bold; + font-size: 100%; +} +.text-spacing .usfm_is2 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_iot { + font-weight: bold; + font-size: 100%; +} +.text-spacing .usfm_iot { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_io { + font-size: 100%; +} +.text-spacing[dir='ltr'] .usfm_io { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_io { + margin-right: 10vw; +} + +.formatted-font .usfm_io1 { + font-size: 100%; +} +.text-spacing[dir='ltr'] .usfm_io1 { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_io1 { + margin-right: 10vw; +} + +.formatted-font .usfm_io2 { + font-size: 100%; +} +.text-spacing[dir='ltr'] .usfm_io2 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_io2 { + margin-right: 15vw; +} + +.formatted-font .usfm_io3 { + font-size: 100%; +} +.text-spacing[dir='ltr'] .usfm_io3 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_io3 { + margin-right: 20vw; +} + +.formatted-font .usfm_io4 { + font-size: 100%; +} +.text-spacing[dir='ltr'] .usfm_io4 { + margin-left: 25vw; +} +.text-spacing[dir='rtl'] .usfm_io4 { + margin-right: 25vw; +} + +.formatted-font .usfm_ior { + font-size: 100%; +} + +.formatted-font .usfm_ip { + font-size: 100%; +} +.text-spacing .usfm_ip { + text-indent: 2.5vw; +} + +.formatted-font .usfm_im { + font-size: 100%; +} + +.formatted-font .usfm_ipi { + font-size: 100%; +} +.text-spacing .usfm_ipi { + text-indent: 2.5vw; + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_imi { + font-size: 100%; +} +.text-spacing .usfm_imi { + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_ili { + font-size: 100%; +} +.text-spacing .usfm_ili { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_ili { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_ili { + margin-right: 10vw; +} + +.formatted-font .usfm_ili1 { + font-size: 100%; +} +.text-spacing .usfm_ili1 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_ili1 { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_ili1 { + margin-right: 10vw; +} + +.formatted-font .usfm_ili2 { + font-size: 100%; +} +.text-spacing .usfm_ili2 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_ili2 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_ili2 { + margin-right: 15vw; +} + +.formatted-font .usfm_ipq { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_ipq { + text-indent: 2.5vw; + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_imq { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_imq { + margin-left: 5vw; + margin-right: 5vw; +} + +.usfm_ipr { + text-align: end; +} +.formatted-font .usfm_ipr { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_ipr { + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_ib { + font-size: 83%; +} + +.formatted-font .usfm_iq { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_iq { + text-indent: -15vw; +} +.text-spacing[dir='ltr'] .usfm_iq { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_iq { + margin-right: 20vw; +} + +.formatted-font .usfm_iq1 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_iq1 { + text-indent: -15vw; +} +.text-spacing[dir='ltr'] .usfm_iq1 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_iq1 { + margin-right: 20vw; +} + +.formatted-font .usfm_iq2 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_iq2 { + text-indent: -10vw; +} +.text-spacing[dir='ltr'] .usfm_iq2 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_iq2 { + margin-right: 20vw; +} + +.formatted-font .usfm_iq3 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_iq3 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_iq3 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_iq3 { + margin-right: 20vw; +} + +.formatted-font .usfm_iex { + font-size: 100%; +} +.text-spacing .usfm_iex { + text-indent: 2.5vw; + margin-bottom: 4pt; + margin-top: 4pt; +} + +.formatted-font .usfm_iqt { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_ie { + font-size: 83%; +} + +.formatted-font .usfm_cl { + font-weight: bold; + font-size: 150%; +} +.text-spacing .usfm_cl { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_cd { + font-size: 91%; +} +.text-spacing .usfm_cd { + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_p { + font-size: 100%; +} +.text-spacing .usfm_p { + text-indent: 2.5vw; +} + +.formatted-font .usfm_m { + font-size: 100%; +} + +.formatted-font .usfm_po { + font-size: 100%; +} +.text-spacing .usfm_po { + text-indent: 2.5vw; + margin-bottom: 4pt; + margin-top: 4pt; +} + +.usfm_pr { + text-align: end; +} +.formatted-font .usfm_pr { + font-size: 100%; +} + +.usfm_cls { + text-align: end; +} +.formatted-font .usfm_cls { + font-size: 100%; +} + +.formatted-font .usfm_pmo { + font-size: 100%; +} +.text-spacing .usfm_pmo { + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_pm { + font-size: 100%; +} +.text-spacing .usfm_pm { + text-indent: 2.5vw; + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_pmc { + font-size: 100%; +} +.text-spacing .usfm_pmc { + margin-left: 5vw; + margin-right: 5vw; +} + +.usfm_pmr { + text-align: end; +} +.formatted-font .usfm_pmr { + font-size: 100%; +} +.text-spacing .usfm_pmr { + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_pi { + font-size: 100%; +} +.text-spacing .usfm_pi { + text-indent: 2.5vw; + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_pi1 { + font-size: 100%; +} +.text-spacing .usfm_pi1 { + text-indent: 2.5vw; + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_pi2 { + font-size: 100%; +} +.text-spacing .usfm_pi2 { + text-indent: 2.5vw; +} +.text-spacing[dir='ltr'] .usfm_pi2 { + margin-left: 10vw; + margin-right: 5vw; +} +.text-spacing[dir='rtl'] .usfm_pi2 { + margin-left: 5vw; + margin-right: 10vw; +} + +.formatted-font .usfm_pi3 { + font-size: 100%; +} +.text-spacing .usfm_pi3 { + text-indent: 2.5vw; +} +.text-spacing[dir='ltr'] .usfm_pi3 { + margin-left: 15vw; + margin-right: 5vw; +} +.text-spacing[dir='rtl'] .usfm_pi3 { + margin-left: 5vw; + margin-right: 15vw; +} + +.formatted-font .usfm_pc { + font-size: 100%; +} +.text-spacing .usfm_pc { + text-align: center; +} + +.formatted-font .usfm_mi { + font-size: 100%; +} +.text-spacing .usfm_mi { + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_nb { + font-size: 100%; +} + +.formatted-font .usfm_q { + font-size: 100%; +} +.text-spacing .usfm_q { + text-indent: -10vw; +} +.text-spacing[dir='ltr'] .usfm_q { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_q { + margin-right: 15vw; +} + +.formatted-font .usfm_q1 { + font-size: 100%; +} +.text-spacing .usfm_q1 { + text-indent: -10vw; +} +.text-spacing[dir='ltr'] .usfm_q1 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_q1 { + margin-right: 15vw; +} + +.formatted-font .usfm_q2 { + font-size: 100%; +} +.text-spacing .usfm_q2 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_q2 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_q2 { + margin-right: 15vw; +} + +.formatted-font .usfm_q3 { + font-size: 100%; +} +.text-spacing .usfm_q3 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_q3 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_q3 { + margin-right: 15vw; +} + +.formatted-font .usfm_q4 { + font-size: 100%; +} +.text-spacing .usfm_q4 { + text-indent: -2.5vw; +} +.text-spacing[dir='ltr'] .usfm_q4 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_q4 { + margin-right: 15vw; +} + +.formatted-font .usfm_qc { + font-size: 100%; +} +.text-spacing .usfm_qc { + text-align: center; +} + +.usfm_qr { + text-align: end; +} +.formatted-font .usfm_qr { + font-size: 100%; +} + +.formatted-font .usfm_qa { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_qm { + font-size: 100%; +} +.text-spacing .usfm_qm { + text-indent: -15vw; +} +.text-spacing[dir='ltr'] .usfm_qm { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_qm { + margin-right: 20vw; +} + +.formatted-font .usfm_qm1 { + font-size: 100%; +} +.text-spacing .usfm_qm1 { + text-indent: -15vw; +} +.text-spacing[dir='ltr'] .usfm_qm1 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_qm1 { + margin-right: 20vw; +} + +.formatted-font .usfm_qm2 { + font-size: 100%; +} +.text-spacing .usfm_qm2 { + text-indent: -10vw; +} +.text-spacing[dir='ltr'] .usfm_qm2 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_qm2 { + margin-right: 20vw; +} + +.formatted-font .usfm_qm3 { + font-size: 100%; +} +.text-spacing .usfm_qm3 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_qm3 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_qm3 { + margin-right: 20vw; +} + +.formatted-font .usfm_qd { + font-size: 100%; + font-style: italic; +} +.text-spacing[dir='ltr'] .usfm_qd { + margin-left: 5vw; +} +.text-spacing[dir='rtl'] .usfm_qd { + margin-right: 5vw; +} + +.formatted-font .usfm_b { + font-size: 83%; +} + +.formatted-font .usfm_mt { + font-weight: bold; + font-size: 166%; +} +.text-spacing .usfm_mt { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_mt1 { + @apply text-2xl font-bold; +} +.text-spacing .usfm_mt1 { + @apply my-2 text-center; +} + +.formatted-font .usfm_mt2 { + font-size: 133%; + font-style: italic; +} +.text-spacing .usfm_mt2 { + text-align: center; + margin-bottom: 2pt; +} + +.formatted-font .usfm_mt3 { + font-weight: bold; + font-size: 133%; +} +.text-spacing .usfm_mt3 { + text-align: center; + margin-bottom: 2pt; + margin-top: 2pt; +} + +.formatted-font .usfm_mt4 { + font-size: 100%; +} +.text-spacing .usfm_mt4 { + text-align: center; + margin-bottom: 2pt; + margin-top: 2pt; +} + +.formatted-font .usfm_mte { + font-weight: bold; + font-size: 166%; +} +.text-spacing .usfm_mte { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_mte1 { + font-weight: bold; + font-size: 166%; +} +.text-spacing .usfm_mte1 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_mte2 { + font-size: 133%; + font-style: italic; +} +.text-spacing .usfm_mte2 { + text-align: center; + margin-bottom: 2pt; +} + +.formatted-font .usfm_ms { + font-weight: bold; + font-size: 116%; +} +.text-spacing .usfm_ms { + text-align: center; + margin-bottom: 4pt; + margin-top: 16pt; +} + +.formatted-font .usfm_ms1 { + @apply text-lg; +} +.text-spacing .usfm_ms1 { + @apply m-2 text-center; +} + +.formatted-font .usfm_ms2 { + font-weight: bold; + font-size: 116%; +} +.text-spacing .usfm_ms2 { + text-align: center; + margin-bottom: 4pt; + margin-top: 16pt; +} + +.formatted-font .usfm_ms3 { + font-size: 116%; + font-style: italic; +} +.text-spacing .usfm_ms3 { + text-align: center; + margin-bottom: 4pt; + margin-top: 16pt; +} + +.formatted-font .usfm_mr { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_mr { + text-align: center; + margin-bottom: 4pt; +} + +.formatted-font .usfm_s { + font-weight: bold; + font-size: 100%; +} +.text-spacing .usfm_s { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_s1 { + font-weight: bold; + font-size: 100%; +} +.text-spacing .usfm_s1 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_s2 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_s2 { + text-align: center; + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_s3 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_s3 { + margin-bottom: 3pt; + margin-top: 6pt; +} + +.formatted-font .usfm_s4 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_s4 { + margin-bottom: 3pt; + margin-top: 6pt; +} + +.formatted-font .usfm_sr { + font-weight: bold; + font-size: 100%; +} +.text-spacing .usfm_sr { + text-align: center; + margin-bottom: 4pt; +} + +.formatted-font .usfm_r { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_r { + text-align: center; + margin-bottom: 4pt; +} + +.formatted-font .usfm_sp { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_sp { + margin-bottom: 4pt; + margin-top: 8pt; +} + +.formatted-font .usfm_d { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_d { + text-align: center; + margin-bottom: 4pt; + margin-top: 4pt; +} + +.text-spacing .usfm_sd { + margin-bottom: 24pt; + margin-top: 24pt; +} + +.text-spacing .usfm_sd1 { + margin-bottom: 24pt; + margin-top: 24pt; +} + +.text-spacing .usfm_sd2 { + margin-bottom: 18pt; + margin-top: 18pt; +} + +.text-spacing .usfm_sd3 { + margin-bottom: 12pt; + margin-top: 12pt; +} + +.text-spacing .usfm_sd4 { + margin-bottom: 8pt; + margin-top: 8pt; +} + +.formatted-font .usfm_lh { + font-size: 100%; +} +.text-spacing .usfm_lh { + text-indent: 2.5vw; +} + +.formatted-font .usfm_li { + font-size: 100%; +} +.text-spacing .usfm_li { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_li { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_li { + margin-right: 10vw; +} + +.formatted-font .usfm_li1 { + font-size: 100%; +} +.text-spacing .usfm_li1 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_li1 { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_li1 { + margin-right: 10vw; +} + +.formatted-font .usfm_li2 { + font-size: 100%; +} +.text-spacing .usfm_li2 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_li2 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_li2 { + margin-right: 15vw; +} + +.formatted-font .usfm_li3 { + font-size: 100%; +} +.text-spacing .usfm_li3 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_li3 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_li3 { + margin-right: 20vw; +} + +.formatted-font .usfm_li4 { + font-size: 100%; +} +.text-spacing .usfm_li4 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_li4 { + margin-left: 25vw; +} +.text-spacing[dir='rtl'] .usfm_li4 { + margin-right: 25vw; +} + +.formatted-font .usfm_lf { + font-size: 100%; +} + +.formatted-font .usfm_lim { + font-size: 100%; +} +.text-spacing .usfm_lim { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_lim { + margin-left: 15vw; + margin-right: 5vw; +} +.text-spacing[dir='rtl'] .usfm_lim { + margin-left: 5vw; + margin-right: 15vw; +} + +.formatted-font .usfm_lim1 { + font-size: 100%; +} +.text-spacing .usfm_lim1 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_lim1 { + margin-left: 15vw; + margin-right: 5vw; +} +.text-spacing[dir='rtl'] .usfm_lim1 { + margin-left: 5vw; + margin-right: 15vw; +} + +.formatted-font .usfm_lim2 { + font-size: 100%; +} +.text-spacing .usfm_lim2 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_lim2 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_lim2 { + margin-right: 20vw; +} + +.formatted-font .usfm_lim3 { + font-size: 100%; +} +.text-spacing .usfm_lim3 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_lim3 { + margin-left: 25vw; +} +.text-spacing[dir='rtl'] .usfm_lim3 { + margin-right: 25vw; +} + +.formatted-font .usfm_lim4 { + font-size: 100%; +} +.text-spacing .usfm_lim4 { + text-indent: -7.5vw; +} +.text-spacing[dir='ltr'] .usfm_lim4 { + margin-left: 30vw; +} +.text-spacing[dir='rtl'] .usfm_lim4 { + margin-right: 30vw; +} + +.usfm_lit { + text-align: end; +} +.formatted-font .usfm_lit { + font-weight: bold; + font-size: 100%; +} + +.formatted-font .usfm_ph { + font-size: 100%; +} +.text-spacing .usfm_ph { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_ph { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_ph { + margin-right: 10vw; +} + +.formatted-font .usfm_ph1 { + font-size: 100%; +} +.text-spacing .usfm_ph1 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_ph1 { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_ph1 { + margin-right: 10vw; +} + +.formatted-font .usfm_ph2 { + font-size: 100%; +} +.text-spacing .usfm_ph2 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_ph2 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_ph2 { + margin-right: 15vw; +} + +.formatted-font .usfm_ph3 { + font-size: 100%; +} +.text-spacing .usfm_ph3 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_ph3 { + margin-left: 20vw; +} +.text-spacing[dir='rtl'] .usfm_ph3 { + margin-right: 20vw; +} + +/* CharNode */ + +.formatted-font .usfm_qs { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_qac { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_litl { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_lik { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_liv { + font-size: 100%; +} + +.formatted-font .usfm_liv1 { + font-size: 100%; +} + +.formatted-font .usfm_liv2 { + font-size: 100%; +} + +.formatted-font .usfm_liv3 { + font-size: 100%; +} + +.formatted-font .usfm_liv4 { + font-size: 100%; +} + +.formatted-font .usfm_liv5 { + font-size: 100%; +} + +.formatted-font .usfm_rq { + font-size: 83%; + font-style: italic; +} + +.formatted-font .usfm_qt { + font-weight: bold; + font-size: 100%; +} + +.formatted-font .usfm_nd { + font-size: 100%; + text-decoration: underline; +} + +.formatted-font .usfm_tl { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_dc { + font-style: italic; +} + +.formatted-font .usfm_bk { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_sig { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_pn { + font-weight: bold; + font-size: 100%; + text-decoration: underline; +} + +.formatted-font .usfm_png { + font-size: 100%; + text-decoration: underline; +} + +.formatted-font .usfm_addpn { + font-weight: bold; + font-size: 100%; + font-style: italic; + text-decoration: underline; +} + +.formatted-font .usfm_wj { + color: #d43128; + font-size: 100%; +} + +.formatted-font .usfm_k { + font-weight: bold; + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_sls { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_ord { + vertical-align: text-top; + font-size: 66%; +} + +.formatted-font .usfm_add { + font-weight: bold; + font-style: italic; +} + +.formatted-font .usfm_no { + font-size: 100%; +} + +.formatted-font .usfm_it { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_bd { + font-weight: bold; + font-size: 100%; +} + +.formatted-font .usfm_bdit { + font-weight: bold; + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_em { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_sc { + font-size: 100%; + font-variant: small-caps; +} + +.formatted-font .usfm_sup { + vertical-align: text-top; + font-size: 66%; +} + +.formatted-font .usfm_pb { + font-size: 100%; +} + +.formatted-font .usfm_fig { + font-size: 100%; +} + +.formatted-font .usfm_jmp { + color: #003380; + text-decoration: underline; +} + +.formatted-font .usfm_pro { + font-size: 83%; +} + +.formatted-font .usfm_rb { + font-size: 100%; +} + +.formatted-font .usfm_w { + font-size: 100%; +} + +.formatted-font .usfm_wh { + font-size: 100%; +} + +.formatted-font .usfm_wg { + font-size: 100%; +} + +.formatted-font .usfm_wa { + font-size: 100%; +} + +.formatted-font .usfm_ndx { + font-size: 100%; +} + +/* Footnote NoteNode */ + +.formatted-font .usfm_f { + font-size: 80%; + position: relative; + top: -0.5em; +} + +.formatted-font .usfm_fe { + font-size: 100%; +} + +/* Footnote CharNode */ + +.formatted-font .usfm_fr { + font-weight: bold; + font-size: 100%; +} + +.formatted-font .usfm_ft { + font-size: 100%; +} + +.formatted-font .usfm_fk { + font-weight: bold; + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_fq { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_fqa { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_fl { + font-weight: bold; + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_fw { + font-size: 100%; +} + +.formatted-font .usfm_fp { + font-size: 100%; +} + +.formatted-font .usfm_fv { + vertical-align: text-top; + font-size: 66%; +} + +.formatted-font .usfm_fdc { + font-size: 100%; +} + +.formatted-font .usfm_fm { + vertical-align: text-top; + font-size: 66%; +} + +/* Cross-reference NoteNode */ + +.formatted-font .usfm_x { + font-size: 100%; +} + +/* Cross-reference CharNode */ + +.formatted-font .usfm_xo { + font-weight: bold; + font-size: 100%; +} + +.formatted-font .usfm_xop { + font-size: 100%; +} + +.formatted-font .usfm_xt { + font-size: 100%; + unicode-bidi: embed; +} + +.formatted-font .usfm_xta { + font-size: 100%; +} + +.formatted-font .usfm_xk { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_xq { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_xot { + font-size: 100%; +} + +.formatted-font .usfm_xnt { + font-size: 100%; +} + +.formatted-font .usfm_xdc { + font-size: 100%; +} + +/* periph */ + +.formatted-font .usfm_periph { + font-weight: bold; + color: #e87217; + font-size: 116%; +} +.text-spacing .usfm_periph { + margin-bottom: 4pt; + margin-top: 16pt; +} + +.formatted-font .usfm_p1 { + font-size: 100%; +} +.text-spacing .usfm_p1 { + text-indent: 2.5vw; +} + +.formatted-font .usfm_p2 { + font-size: 100%; +} +.text-spacing .usfm_p2 { + text-indent: 2.5vw; +} +.text-spacing[dir='ltr'] .usfm_p2 { + margin-left: 2.5vw; +} +.text-spacing[dir='rtl'] .usfm_p2 { + margin-right: 2.5vw; +} + +.formatted-font .usfm_k1 { + font-size: 100%; +} + +.formatted-font .usfm_k2 { + font-size: 100%; +} + +.formatted-font .usfm_xtSee { + color: #003380; + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_xtSeeAlso { + color: #003380; + font-size: 100%; + font-style: italic; +} + +/* MilestoneNode */ + +.formatted-font .usfm_qt-s { + font-size: 100%; +} + +.formatted-font .usfm_qt-e { + font-size: 100%; +} + +.formatted-font .usfm_qt1-s { + font-size: 100%; +} + +.formatted-font .usfm_qt1-e { + font-size: 100%; +} + +.formatted-font .usfm_qt2-s { + font-size: 100%; +} + +.formatted-font .usfm_qt2-e { + font-size: 100%; +} + +.formatted-font .usfm_qt3-s { + font-size: 100%; +} + +.formatted-font .usfm_qt3-e { + font-size: 100%; +} + +.formatted-font .usfm_qt4-s { + font-size: 100%; +} + +.formatted-font .usfm_qt4-e { + font-size: 100%; +} + +.formatted-font .usfm_qt5-s { + font-size: 100%; +} + +.formatted-font .usfm_qt5-e { + font-size: 100%; +} + +.formatted-font .usfm_ts-s { + font-size: 100%; +} + +.formatted-font .usfm_ts-e { + font-size: 100%; +} + +/* table */ + +.formatted-font .usfm_tr { + font-size: 100%; +} +.text-spacing .usfm_tr { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_tr { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_tr { + margin-right: 10vw; +} + +.formatted-font .usfm_th1 { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_th2 { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_th3 { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_th4 { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_th5 { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_tc1 { + font-size: 100%; +} + +.formatted-font .usfm_tc2 { + font-size: 100%; +} + +.formatted-font .usfm_tc3 { + font-size: 100%; +} + +.formatted-font .usfm_tc4 { + font-size: 100%; +} + +.formatted-font .usfm_tc5 { + font-size: 100%; +} + +.formatted-font .usfm_thc1 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thc1 { + text-align: center; +} + +.formatted-font .usfm_thc2 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thc2 { + text-align: center; +} + +.formatted-font .usfm_thc3 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thc3 { + text-align: center; +} + +.formatted-font .usfm_thc4 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thc4 { + text-align: center; +} + +.formatted-font .usfm_thc5 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thc5 { + text-align: center; +} + +.formatted-font .usfm_tcc1 { + font-size: 100%; +} +.text-spacing .usfm_tcc1 { + text-align: center; +} + +.formatted-font .usfm_tcc2 { + font-size: 100%; +} +.text-spacing .usfm_tcc2 { + text-align: center; +} + +.formatted-font .usfm_tcc3 { + font-size: 100%; +} +.text-spacing .usfm_tcc3 { + text-align: center; +} + +.formatted-font .usfm_tcc4 { + font-size: 100%; +} +.text-spacing .usfm_tcc4 { + text-align: center; +} + +.formatted-font .usfm_tcc5 { + font-size: 100%; +} +.text-spacing .usfm_tcc5 { + text-align: center; +} + +.formatted-font .usfm_thr1 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thr1 { + text-align: end; +} + +.formatted-font .usfm_thr2 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thr2 { + text-align: end; +} + +.formatted-font .usfm_thr3 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thr3 { + text-align: end; +} + +.formatted-font .usfm_thr4 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thr4 { + text-align: end; +} + +.formatted-font .usfm_thr5 { + font-size: 100%; + font-style: italic; +} +.text-spacing .usfm_thr5 { + text-align: end; +} + +.formatted-font .usfm_tcr1 { + font-size: 100%; +} +.text-spacing .usfm_tcr1 { + text-align: end; +} + +.formatted-font .usfm_tcr2 { + font-size: 100%; +} +.text-spacing .usfm_tcr2 { + text-align: end; +} + +.formatted-font .usfm_tcr3 { + font-size: 100%; +} +.text-spacing .usfm_tcr3 { + text-align: end; +} + +.formatted-font .usfm_tcr4 { + font-size: 100%; +} +.text-spacing .usfm_tcr4 { + text-align: end; +} + +.formatted-font .usfm_tcr5 { + font-size: 100%; +} +.text-spacing .usfm_tcr5 { + text-align: end; +} + +/* table/unknown */ + +.formatted-font .usfm_tr1 { + font-size: 100%; +} +.text-spacing .usfm_tr1 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_tr1 { + margin-left: 10vw; +} +.text-spacing[dir='rtl'] .usfm_tr1 { + margin-right: 10vw; +} + +.formatted-font .usfm_tr2 { + font-size: 100%; +} +.text-spacing .usfm_tr2 { + text-indent: -5vw; +} +.text-spacing[dir='ltr'] .usfm_tr2 { + margin-left: 15vw; +} +.text-spacing[dir='rtl'] .usfm_tr2 { + margin-right: 15vw; +} + +.formatted-font .usfm_ps { + font-size: 100%; +} +.text-spacing .usfm_ps { + text-indent: 2.5vw; +} + +.formatted-font .usfm_psi { + font-size: 100%; +} +.text-spacing .usfm_psi { + text-indent: 2.5vw; + margin-left: 5vw; + margin-right: 5vw; +} + +.formatted-font .usfm_fs { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_wr { + font-size: 100%; + font-style: italic; +} + +.formatted-font .usfm_pub { + font-size: 83%; } -@media (prefers-color-scheme: dark) { - .source-text { - color: #ffffff; - } +.formatted-font .usfm_toc { + font-size: 83%; } -@media (prefers-color-scheme: light) { - .source-text { - color: #121212; - } +.formatted-font .usfm_pref { + font-size: 83%; } -.prevent-select { - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} \ No newline at end of file +.formatted-font .usfm_intro { + font-size: 83%; +} + +.formatted-font .usfm_conc { + font-size: 83%; +} + +.formatted-font .usfm_glo { + font-size: 83%; +} + +.formatted-font .usfm_idx { + font-size: 83%; +} + +.formatted-font .usfm_maps { + font-size: 83%; +} + +.formatted-font .usfm_cov { + font-size: 83%; +} + +.formatted-font .usfm_spine { + font-size: 83%; +} + +.formatted-font .usfm_pubinfo { + color: #003380; + font-size: 100%; +} + +.formatted-font .usfm_zpa-xb { + font-size: 100%; +} + +.formatted-font .usfm_zpa-xc { + font-weight: bold; + font-size: 100%; +} + +.formatted-font .usfm_zpa-xv { + font-size: 100%; +} + +.formatted-font .usfm_zpa-d { + font-size: 100%; +} + +body { + background-color: rgba(252, 252, 252, 1); + color: rgba(25, 25, 25, 1); +} + +.marker { + unicode-bidi: isolate; +} +.formatted-font .marker { + color: rgba(140, 140, 140, 1); + font-size: 0.7em; +} + +/* Used for unformatted displays */ +.markerplain { + unicode-bidi: isolate; +} + +.notetext { + unicode-bidi: embed; +} + +.attribute { + color: rgba(170, 170, 170, 1); +} + +.attribute:hover { + color: rgba(25, 25, 25, 1); +} + +.invalid { + color: rgba(204, 30, 20, 1); + font-weight: bold; +} + +/* NoteNode, ImmutableNoteCallerNode */ + +.immutable-note-caller > button, +/* Styles for Preview (and Ruby) views */ +.caller_preview, +.previewcallee { + color: rgba(18, 82, 179, 1); + font-weight: bold; + line-height: 1; + vertical-align: super; + font-size: 0.66em; +} + +.immutable-note-caller > button { + cursor: pointer; + text-decoration: none; + border: 0; + padding: 0; + background-color: inherit; +} + +.immutable-note-caller[data-caller='-'] { + display: none; +} + +.formatted-font .immutable-note-caller { + @apply text-xs text-blue-500; +} + +.caller_big { + unicode-bidi: normal; + color: rgba(18, 82, 179, 1); + font-weight: bold; + text-indent: 0pt; + vertical-align: text-top; + font-size: 0.66em; +} + +.caller_small { + unicode-bidi: normal; + color: rgba(18, 82, 179, 1); + font-family: Times New Roman; + vertical-align: text-top; + text-indent: 0pt; + font-size: 0.66em; +} + +.caller_highlight { + background-color: #ffffb5; + border-top: solid 1px #0000ff; + border-bottom: solid 1px #0000ff; +} + +.opennote { + color: #7777ff; +} + +rt { + cursor: pointer; +} + +/* Style statues */ +.status_unknown { + color: rgba(204, 30, 20, 1); + font-weight: bold; +} + +.status_invalid { + border-bottom: 1px solid rgba(204, 30, 20, 1); + color: rgba(204, 30, 20, 1); +} + +.caption { + text-align: center; + font-style: italic; + font-weight: bold; +} + +.figure { + text-align: center; +} + +.sidebar { + border: solid 1px rgba(18, 82, 179, 1); + margin-left: 10px; +} + +/* VerseNode, ImmutableVerseNode */ + +/* +.formatted-font .verse { + @apply text-cyan-500; + background-color: rgba(222, 222, 222, 1); + vertical-align: super; + font-size: 0.66em; +} +.text-spacing .verse { + margin: 0px 2px 0px 2px; + padding: 0px 1px 0px 1px; + text-indent: 0in; + white-space: nowrap; +} +*/ + +.annot_comment_todo { + border-bottom: 1px dashed #888888; +} +.annot_comment_todo { + border-bottom: 1px dashed #888888; +} +span.unread img { + background-color: #ffff99; + position: relative; + bottom: -1px; /* negative of border-width to align baseline */ + border-width: 1px; + border-style: solid; + border-color: #808080; +} +span.read img { + background-color: transparent; + position: relative; + bottom: 0px; + border-width: 0px; + border-style: none; +} + +.annot_comment_todo { + border-bottom: 1px dashed #888888; +} + +.annot_comment_done { + border-bottom: 1px dashed #888888; +} + +.annot_greencursor { + background-color: rgba(152, 235, 157, 1); +} +.annot_goldcursor { + background-color: rgba(255, 255, 163, 1); +} +.annot_bluecursor { + background-color: rgba(204, 224, 255, 1); +} +.annot_greycursor { + background-color: rgba(222, 222, 222, 1); +} +.annot_violetcursor { + background-color: rgba(233, 212, 255, 1); +} + +.annot_spellingerror { + background-repeat: repeat-x; + background-position: left bottom; + padding-bottom: 0px; + vertical-align: text-top; +} + +.annot_spellingunknown { + background-repeat: repeat-x; + background-position: left bottom; + padding-bottom: 0px; + vertical-align: text-top; +} + +.found_term { + background-color: rgba(222, 222, 222, 1); + text-indent: 0; + margin-left: 0; + display: inline-block; + border-bottom-style: solid; + border-bottom-width: medium medium thick medium; + border-bottom-color: rgba(252, 252, 252, 1); + text-decoration: inherit; +} +.guessed_term { + background-color: rgba(255, 191, 143, 1); + text-indent: 0; + margin-left: 0; + display: inline-block; + border-bottom-style: solid; + border-bottom-width: medium medium thick medium; + border-bottom-color: rgba(252, 252, 252, 1); + text-decoration: inherit; +} +.found_term.unselected_term { + background-color: rgba(222, 222, 222, 0.6); + text-indent: 0; + margin-left: 0; + display: inline-block; + border-bottom-style: solid; + border-bottom-width: medium medium thick medium; + border-bottom-color: rgba(252, 252, 252, 1); + text-decoration: inherit; +} +.guessed_term.unselected_term { + background-color: rgba(255, 191, 143, 0.3); + text-indent: 0; + margin-left: 0; + display: inline-block; + border-bottom-style: solid; + border-bottom-width: medium medium thick medium; + border-bottom-color: rgba(252, 252, 252, 1); + text-decoration: inherit; +} +.selected_term { + border-style: none none solid none; + text-indent: 0; + margin-left: 0; + display: inline-block; + border-bottom-style: solid; + border-bottom-width: medium medium thick medium; + border-bottom-color: rgba(252, 252, 252, 1); + text-decoration: inherit; +} +.annot_reference_link { + border-bottom: 1px solid #93c4ff; +} +.annot_invalid_reference { + border-bottom: 1px solid #ff8080; +} +.annot_checkError { + border-top: 1px solid #ff0000; + border-bottom: 1px solid #ff0000; + background-color: rgba(255, 204, 204, 0.5); +} + +/* ContextMenuPlugin */ + +.auto-embed-menu { + width: 150px; +} + +.typeahead-popover { + background: #fff; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3); + border-radius: 8px; +} + +.typeahead-popover ul { + padding: 0; + list-style: none; + margin: 0; + border-radius: 8px; + max-height: 200px; + overflow-y: scroll; + -ms-overflow-style: none; + scrollbar-width: none; +} + +.typeahead-popover ul::-webkit-scrollbar { + display: none; +} + +.typeahead-popover ul li { + margin: 0; + min-width: 180px; + font-size: 14px; + outline: none; + cursor: pointer; + border-radius: 8px; +} + +.typeahead-popover ul li.selected { + background: #eee; +} + +.typeahead-popover li { + margin: 0 8px 0 8px; + padding: 8px; + color: #050505; + cursor: pointer; + line-height: 16px; + font-size: 15px; + display: flex; + align-content: center; + flex-direction: row; + flex-shrink: 0; + background-color: #fff; + border-radius: 8px; + border: 0; +} + +.typeahead-popover li.active { + display: flex; + width: 20px; + height: 20px; + background-size: contain; +} + +.typeahead-popover li:first-child { + border-radius: 8px 8px 0px 0px; +} + +.typeahead-popover li:last-child { + border-radius: 0px 0px 8px 8px; +} + +.typeahead-popover li:hover { + background-color: #eee; +} + +.typeahead-popover li .text { + display: flex; + line-height: 20px; + flex-grow: 1; + min-width: 150px; +} + +.typeahead-popover li .icon { + display: flex; + width: 20px; + height: 20px; + user-select: none; + margin-right: 8px; + line-height: 16px; + background-size: contain; + background-repeat: no-repeat; + background-position: center; +} diff --git a/yarn.lock b/yarn.lock index 559bc4e8e..8948125f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5275,7 +5275,7 @@ adm-zip@^0.5.9: resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.12.tgz#87786328e91d54b37358d8a50f954c4cd73ba60b" integrity sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ== -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -5375,7 +5375,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.3.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -5517,7 +5517,7 @@ archiver@^5.0.0: tar-stream "^2.2.0" zip-stream "^4.1.0" -archy@^1.0.0, archy@~1.0.0: +archy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== @@ -5740,7 +5740,7 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== -asap@^2.0.0, asap@~2.0.3, asap@~2.0.6: +asap@~2.0.3, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== @@ -7100,13 +7100,6 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -cidr-regex@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-3.1.1.tgz#ba1972c57c66f61875f18fd7dd487469770b571d" - integrity sha512-RBqYd32aDwbCMFJRL6wHOlDNYJsPNTt8vC82ErHF5vKt8QQzxm1FrkW8s/R5pVrXMf17sba09Uoy91PKiddAsw== - dependencies: - ip-regex "^4.1.0" - cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -7246,11 +7239,6 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - clsx@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" @@ -8183,11 +8171,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw== - decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -8311,13 +8294,6 @@ default-require-extensions@^3.0.0: dependencies: strip-bom "^4.0.0" -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - defer-to-connect@^1.0.1: version "1.1.3" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" @@ -9044,11 +9020,6 @@ epitelete@^0.2.20, epitelete@^0.2.20-beta.1: pure-uuid "^1.6.3" rfdc "^1.3.0" -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -9975,11 +9946,6 @@ fast-unique-numbers@^9.0.4: "@babel/runtime" "^7.24.4" tslib "^2.6.2" -fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - fastq@^1.6.0: version "1.17.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" @@ -10365,7 +10331,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0, fs-minipass@^2.1.0: +fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -11502,11 +11468,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -13525,11 +13486,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json-stringify-nice@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" - integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw== - json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -15100,15 +15056,6 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -mkdirp-infer-owner@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316" - integrity sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw== - dependencies: - chownr "^2.0.0" - infer-owner "^1.0.4" - mkdirp "^1.0.3" - "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" @@ -15116,7 +15063,7 @@ mkdirp-infer-owner@^2.0.0: dependencies: minimist "^1.2.6" -mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -15164,7 +15111,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.2: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -15190,11 +15137,6 @@ murmurhash@^2.0.0: resolved "https://registry.yarnpkg.com/murmurhash/-/murmurhash-2.0.1.tgz#4097720e08cf978872194ad84ea5be2dec9b610f" integrity sha512-5vQEh3y+DG/lMPM0mCGPDnyV8chYg/g7rl6v3Gd8WMF9S429ox3Xk8qrk174kWhG767KQMqqxLD1WnGd77hiew== -mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - mz@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" @@ -16048,11 +15990,6 @@ open@^8.0.9, open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - optimist@~0.3.5: version "0.3.7" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" @@ -16151,13 +16088,6 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.0.0" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-pipe@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" @@ -17308,29 +17238,6 @@ progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise-all-reject-late@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2" - integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw== - -promise-call-limit@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.2.tgz#f64b8dd9ef7693c9c7613e7dfe8d6d24de3031ea" - integrity sha512-1vTUnfI2hzui8AEIixbdAJlFY4LFDXqQswy/2eOlThAscXCY4It8FdVuI0fMJGAB2aWGbdQf/gv0skKYXmdrHA== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -17353,13 +17260,6 @@ prompts@^2.0.1, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -promzard@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw== - dependencies: - read "1" - prop-types-extra@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" @@ -17624,11 +17524,6 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== -qrcode-terminal@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" - integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== - qs@6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -18259,16 +18154,6 @@ readdir-glob@^1.1.2: dependencies: minimatch "^5.1.0" -readdir-scoped-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -18690,11 +18575,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - retry@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" @@ -19278,6 +19158,13 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +sj-usfm-grammar@^3.0.0, sj-usfm-grammar@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/sj-usfm-grammar/-/sj-usfm-grammar-3.0.2.tgz#855ee3a439b582bfae93a71c3aa93cd9beb6bfdc" + integrity sha512-LBOx33vtU0gnUi/pAVxAqVMoGxD57c5itW650BaYGGD3Di2wweNHcQBD+XlQyGFXSoXoi3bn3gxfnNQG0oNGtg== + dependencies: + sj-usfm-grammar "^3.0.0" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -20319,7 +20206,7 @@ text-hex@1.0.x: resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== -text-table@^0.2.0, text-table@~0.2.0: +text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== @@ -21397,7 +21284,7 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" -validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: +validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -21508,11 +21395,6 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" -walk-up-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" - integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg== - walker@^1.0.7, walker@^1.0.8, walker@~1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" @@ -21562,12 +21444,10 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -wcwidth@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" +web-tree-sitter@^0.22.6: + version "0.22.6" + resolved "https://registry.yarnpkg.com/web-tree-sitter/-/web-tree-sitter-0.22.6.tgz#0f47fa798a5cbe0c2293b813f51c3ddebf94abbe" + integrity sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q== webidl-conversions@^3.0.0: version "3.0.1"