diff --git a/assets/localization/en.json b/assets/localization/en.json index 569d096fcc..4fd0c3cc01 100644 --- a/assets/localization/en.json +++ b/assets/localization/en.json @@ -1,49 +1,30 @@ { - "insertNote": "Insert Note", - "mainMenu_aboutPlatformBible": "About Platform.Bible", - "mainMenu_downloadSlashInstallResources": "Download/Install Resources", - "mainMenu_downloadSlashUpdateProject": "Download/Update Project", - "mainMenu_exit": "Exit", - "mainMenu_help": "Help", - "mainMenu_layout": "Layout", - "mainMenu_openHelloWorldProject": "Open Hello World Project", - "mainMenu_openProject": "Open Project", - "mainMenu_openPlatformScriptureEditor": "Open Scripture Editor", - "mainMenu_openPlatformResourceViewer": "Open Resource Viewer", - "mainMenu_openTextCollection": "Open Text Collection", - "mainMenu_openWordList": "Open Word List", - "mainMenu_openVerseImageGenerator": "Open Verse Image Generator", - "mainMenu_openVerseRefView": "Open Verse Ref View", - "mainMenu_project": "Project", - "mainMenu_settings": "Settings", - "mainMenu_visitSupportBible": "Visit Support.Bible", - "mainMenu_window": "Window", - "some_localization_key": "This is the English text for %some_localization_key%.", - "submitButton": "Submit", - "webView_edit": "Edit", - "webView_project": "Project", - "webView_projectAssignmentsAndProgress": "Assignments and Progress", - "webView_projectSendReceive": "Send/Receive this project", - "wordList": "Word List", - "webView_platformScriptureEditor_options": "Options", - "webView_platformScriptureEditor_info": "Info", - "webView_platformScriptureEditor_backgroundColor": "Background Color", - "webView_platformScriptureEditor_textColor": "Text Color", - "webView_platformScriptureEditor_thickBorders": "Thick Borders", - "webView_platformScriptureEditor_publisherInfo": "Publisher Info", - "webView_platformScriptureEditor_copyrightInfo": "Copyright Info", - "settings_platform_group1_label": "Platform Settings", - "settings_platform_group1_description": "Settings pertaining to the software overall", - "settings_platform_verseRef_label": "Current Verse Reference", - "settings_platform_interfaceLanguage_label": "Interface Language", - "settings_hello_world_group1_label": "Hello World Settings", - "settings_hello_world_personName_label": "Selected Person's Name on Hello World Web View", - "project_settings_platform_group1_label": "Platform Settings", - "project_settings_platform_group1_description": "Project settings pertaining to the software overall", - "project_settings_platform_fullName_label": "Project Full Name", - "project_settings_platform_language_label": "Project Primary Language", - "project_settings_platformScripture_booksPresent_label": "Scripture Books Present", - "project_settings_platformScripture_booksPresent_description": "Which books of the Bible are present in this Scripture project", - "project_settings_platformScripture_versification_label": "Scripture Versification", - "project_settings_platformScripture_versification_description": "Which versification scheme this Scripture project follows" + "%insertNote%": "Insert Note", + "%mainMenu_aboutPlatformBible%": "About Platform.Bible", + "%mainMenu_downloadSlashInstallResources%": "Download/Install Resources", + "%mainMenu_downloadSlashUpdateProject%": "Download/Update Project", + "%mainMenu_exit%": "Exit", + "%mainMenu_help%": "Help", + "%mainMenu_layout%": "Layout", + "%mainMenu_openHelloWorldProject%": "Open Hello World Project", + "%mainMenu_openProject%": "Open Project", + "%mainMenu_project%": "Project", + "%mainMenu_settings%": "Settings", + "%mainMenu_visitSupportBible%": "Visit Support.Bible", + "%mainMenu_window%": "Window", + "%some_localization_key%": "This is the English text for %some_localization_key%.", + "%submitButton%": "Submit", + "%webView_edit%": "Edit", + "%webView_project%": "Project", + "%webView_projectAssignmentsAndProgress%": "Assignments and Progress", + "%webView_projectSendReceive%": "Send/Receive this project", + "%wordList%": "Word List", + "%settings_platform_group1_label%": "Platform Settings", + "%settings_platform_group1_description%": "Settings pertaining to the software overall", + "%settings_platform_verseRef_label%": "Current Verse Reference", + "%settings_platform_interfaceLanguage_label%": "Interface Language", + "%project_settings_platform_group1_label%": "Platform Settings", + "%project_settings_platform_group1_description%": "Project settings pertaining to the software overall", + "%project_settings_platform_fullName_label%": "Project Full Name", + "%project_settings_platform_language_label%": "Project Primary Language" } diff --git a/assets/localization/fr.json b/assets/localization/fr.json index 1f5521736d..bd3147e528 100644 --- a/assets/localization/fr.json +++ b/assets/localization/fr.json @@ -1,5 +1,5 @@ { - "some_localization_key": "Ceci est le texte en français pour %some_localization_key%.", - "submitButton": "Soumettre", - "Book.Gen": "Genèse" + "%some_localization_key%": "Ceci est le texte en français pour %some_localization_key%.", + "%submitButton%": "Soumettre", + "%Book.Gen%": "Genèse" } diff --git a/assets/localization/km.json b/assets/localization/km.json index cf7bc2af4a..f3070478f8 100644 --- a/assets/localization/km.json +++ b/assets/localization/km.json @@ -1,90 +1,90 @@ { - "LocalizedId.BEL": "ព្រះបែល", - "LocalizedId.BLT": "BLT", - "LocalizedId.CNC": "CNC", - "LocalizedId.COL": "កូឡ", - "LocalizedId.DAG": "DAG", - "LocalizedId.DAN": "ដន", - "LocalizedId.DEU": "ទក", - "LocalizedId.DNT": "DNT", - "LocalizedId.ECC": "សស", - "LocalizedId.ENO": "ENO", - "LocalizedId.EPH": "អភ", - "LocalizedId.ESG": "ESG", - "LocalizedId.EST": "អធ", - "LocalizedId.EXO": "នក", - "LocalizedId.EZA": "EZA", - "LocalizedId.EZK": "អគ", - "LocalizedId.EZR": "អរ", - "LocalizedId.FRT": "FRT", - "LocalizedId.GAL": "កាឡ", - "LocalizedId.GEN": "លប", - "LocalizedId.GLO": "GLO", - "LocalizedId.HAB": "ហគ", - "LocalizedId.HAG": "ហក", - "LocalizedId.HEB": "ហប", - "LocalizedId.HOS": "ហស", - "LocalizedId.INT": "INT", - "LocalizedId.ISA": "អស", - "LocalizedId.JAS": "យក", - "LocalizedId.JDB": "JDB", - "LocalizedId.JDG": "ចហ", - "LocalizedId.JDT": "JDT", - "LocalizedId.JER": "យរ", - "LocalizedId.JHN": "យហ", - "LocalizedId.JOB": "យ៉ូប", - "LocalizedId.JOL": "យអ", - "LocalizedId.JON": "យណ", - "LocalizedId.JOS": "យស", - "LocalizedId.JSA": "JSA", - "LocalizedId.JUB": "JUB", - "LocalizedId.JUD": "យដ", - "LocalizedId.LAM": "បរ", - "LocalizedId.LAO": "LAO", - "LocalizedId.LBA": "LBA", - "LocalizedId.LEV": "លវ", - "LocalizedId.LJE": "LJE", - "LocalizedId.LUK": "លក", - "LocalizedId.MAL": "មគ", - "LocalizedId.MAN": "MAN", - "LocalizedId.MAT": "មថ", - "LocalizedId.MIC": "មីក", - "LocalizedId.MRK": "មក", - "LocalizedId.NAM": "ណហ", - "LocalizedId.NDX": "NDX", - "LocalizedId.NEH": "នហ", - "LocalizedId.NUM": "ជគ", - "LocalizedId.OBA": "អឌ", - "LocalizedId.ODA": "ODA", - "LocalizedId.OTH": "OTH", - "LocalizedId.PHM": "ភល", - "LocalizedId.PHP": "ភីល", - "LocalizedId.PRO": "សុភ", - "LocalizedId.PS2": "PS2", - "LocalizedId.PS3": "PS3", - "LocalizedId.PSA": "ទំន", - "LocalizedId.PSS": "PSS", - "LocalizedId.REP": "REP", - "LocalizedId.REV": "វវ", - "LocalizedId.ROM": "រ៉ូម", - "LocalizedId.RUT": "រស់", - "LocalizedId.S3Y": "S3Y", - "LocalizedId.SIR": "SIR", - "LocalizedId.SNG": "បច", - "LocalizedId.SST": "SST", - "LocalizedId.SUS": "SUS", - "LocalizedId.TBS": "TBS", - "LocalizedId.TDX": "TDX", - "LocalizedId.TIT": "ទត", - "LocalizedId.TOB": "TOB", - "LocalizedId.WIS": "WIS", - "LocalizedId.XXA": "XXA", - "LocalizedId.XXB": "XXB", - "LocalizedId.XXC": "XXC", - "LocalizedId.XXD": "XXD", - "LocalizedId.XXE": "XXE", - "LocalizedId.XXF": "XXF", - "LocalizedId.XXG": "XXG", - "LocalizedId.ZEC": "សក", - "LocalizedId.ZEP": "សផ" + "%LocalizedId.BEL%": "ព្រះបែល", + "%LocalizedId.BLT%": "BLT", + "%LocalizedId.CNC%": "CNC", + "%LocalizedId.COL%": "កូឡ", + "%LocalizedId.DAG%": "DAG", + "%LocalizedId.DAN%": "ដន", + "%LocalizedId.DEU%": "ទក", + "%LocalizedId.DNT%": "DNT", + "%LocalizedId.ECC%": "សស", + "%LocalizedId.ENO%": "ENO", + "%LocalizedId.EPH%": "អភ", + "%LocalizedId.ESG%": "ESG", + "%LocalizedId.EST%": "អធ", + "%LocalizedId.EXO%": "នក", + "%LocalizedId.EZA%": "EZA", + "%LocalizedId.EZK%": "អគ", + "%LocalizedId.EZR%": "អរ", + "%LocalizedId.FRT%": "FRT", + "%LocalizedId.GAL%": "កាឡ", + "%LocalizedId.GEN%": "លប", + "%LocalizedId.GLO%": "GLO", + "%LocalizedId.HAB%": "ហគ", + "%LocalizedId.HAG%": "ហក", + "%LocalizedId.HEB%": "ហប", + "%LocalizedId.HOS%": "ហស", + "%LocalizedId.INT%": "INT", + "%LocalizedId.ISA%": "អស", + "%LocalizedId.JAS%": "យក", + "%LocalizedId.JDB%": "JDB", + "%LocalizedId.JDG%": "ចហ", + "%LocalizedId.JDT%": "JDT", + "%LocalizedId.JER%": "យរ", + "%LocalizedId.JHN%": "យហ", + "%LocalizedId.JOB%": "យ៉ូប", + "%LocalizedId.JOL%": "យអ", + "%LocalizedId.JON%": "យណ", + "%LocalizedId.JOS%": "យស", + "%LocalizedId.JSA%": "JSA", + "%LocalizedId.JUB%": "JUB", + "%LocalizedId.JUD%": "យដ", + "%LocalizedId.LAM%": "បរ", + "%LocalizedId.LAO%": "LAO", + "%LocalizedId.LBA%": "LBA", + "%LocalizedId.LEV%": "លវ", + "%LocalizedId.LJE%": "LJE", + "%LocalizedId.LUK%": "លក", + "%LocalizedId.MAL%": "មគ", + "%LocalizedId.MAN%": "MAN", + "%LocalizedId.MAT%": "មថ", + "%LocalizedId.MIC%": "មីក", + "%LocalizedId.MRK%": "មក", + "%LocalizedId.NAM%": "ណហ", + "%LocalizedId.NDX%": "NDX", + "%LocalizedId.NEH%": "នហ", + "%LocalizedId.NUM%": "ជគ", + "%LocalizedId.OBA%": "អឌ", + "%LocalizedId.ODA%": "ODA", + "%LocalizedId.OTH%": "OTH", + "%LocalizedId.PHM%": "ភល", + "%LocalizedId.PHP%": "ភីល", + "%LocalizedId.PRO%": "សុភ", + "%LocalizedId.PS2%": "PS2", + "%LocalizedId.PS3%": "PS3", + "%LocalizedId.PSA%": "ទំន", + "%LocalizedId.PSS%": "PSS", + "%LocalizedId.REP%": "REP", + "%LocalizedId.REV%": "វវ", + "%LocalizedId.ROM%": "រ៉ូម", + "%LocalizedId.RUT%": "រស់", + "%LocalizedId.S3Y%": "S3Y", + "%LocalizedId.SIR%": "SIR", + "%LocalizedId.SNG%": "បច", + "%LocalizedId.SST%": "SST", + "%LocalizedId.SUS%": "SUS", + "%LocalizedId.TBS%": "TBS", + "%LocalizedId.TDX%": "TDX", + "%LocalizedId.TIT%": "ទត", + "%LocalizedId.TOB%": "TOB", + "%LocalizedId.WIS%": "WIS", + "%LocalizedId.XXA%": "XXA", + "%LocalizedId.XXB%": "XXB", + "%LocalizedId.XXC%": "XXC", + "%LocalizedId.XXD%": "XXD", + "%LocalizedId.XXE%": "XXE", + "%LocalizedId.XXF%": "XXF", + "%LocalizedId.XXG%": "XXG", + "%LocalizedId.ZEC%": "សក", + "%LocalizedId.ZEP%": "សផ" } diff --git a/assets/localization/zh-hans.json b/assets/localization/zh-hans.json index 460f61f9e8..de1b69ce10 100644 --- a/assets/localization/zh-hans.json +++ b/assets/localization/zh-hans.json @@ -1,127 +1,125 @@ { - "Book.GEN": "创", - "Book.EXO": "出", - "Book.LEV": "利", - "Book.NUM": "民", - "Book.DEU": "申", - "Book.JOS": "书", - "Book.JDG": "士", - "Book.RUT": "得", - "Book.1SA": "撒上", - "Book.2SA": "撒下", - "Book.1KI": "王上", - "Book.2KI": "王下", - "Book.1CH": "代上", - "Book.2CH": "代下", - "Book.EZR": "拉", - "Book.NEH": "尼", - "Book.EST": "斯", - "Book.JOB": "伯", - "Book.PSA": "诗", - "Book.PRO": "箴", - "Book.ECC": "传", - "Book.SNG": "歌", - "Book.ISA": "赛", - "Book.JER": "耶", - "Book.LAM": "哀", - "Book.EZK": "结", - "Book.DAN": "但", - "Book.HOS": "何", - "Book.JOL": "珥", - "Book.AMO": "摩", - "Book.OBA": "俄", - "Book.JON": "拿", - "Book.MIC": "弥", - "Book.NAM": "鸿", - "Book.HAB": "哈", - "Book.ZEP": "番", - "Book.HAG": "该", - "Book.ZEC": "亚", - "Book.MAL": "玛", - "Book.MAT": "太", - "Book.MRK": "可", - "Book.LUK": "路", - "Book.JHN": "约", - "Book.ACT": "徒", - "Book.ROM": "罗", - "Book.1CO": "林前", - "Book.2CO": "林后", - "Book.GAL": "加", - "Book.EPH": "弗", - "Book.PHP": "腓", - "Book.COL": "西", - "Book.1TH": "帖前", - "Book.2TH": "帖后", - "Book.1TI": "提前", - "Book.2TI": "提后", - "Book.TIT": "多", - "Book.PHM": "门", - "Book.HEB": "来", - "Book.JAS": "雅", - "Book.1PE": "彼前", - "Book.2PE": "彼后", - "Book.1JN": "约壹", - "Book.2JN": "约贰", - "Book.3JN": "约叁", - "Book.JUD": "犹", - "Book.REV": "启", - "Book.TOB": "多俾亚传", - "Book.JDT": "友弟德传", - "Book.ESG": "艾斯德尔传(希腊语)", - "Book.WIS": "智慧篇", - "Book.SIR": "德训篇", - "Book.BAR": "巴路克", - "Book.LJE": "耶肋米亚书信", - "Book.S3Y": "三童歌", - "Book.SUS": "苏珊拿传", - "Book.BEL": "彼勒与大龙", - "Book.1MA": "玛加伯上", - "Book.2MA": "玛加伯下", - "Book.3MA": "玛加伯三", - "Book.4MA": "玛加伯四", - "Book.1ES": "厄斯德拉一书(希腊语)", - "Book.2ES": "厄斯德拉二书(拉丁语)", - "Book.MAN": "玛拿西祷文", - "Book.PS2": "诗篇 151 篇", - "Book.ODA": "所罗门颂诗", - "Book.PSS": "所罗门诗篇", - "Book.JSA": "约书亚记 - 抄本 A 版本 *已不使用*", - "Book.JDB": "士师记 - 抄本 B 版本 *已不使用*", - "Book.TBS": "多俾亚传 - 抄本 S 版本 *已不使用*", - "Book.SST": "苏珊拿传 - Theodotian 版本 *已不使用*", - "Book.DNT": "但以理书 - Theodotian 版本 *已不使用*", - "Book.BLT": "彼勒与大龙 - Theodotian 版本 *已不使用*", - "Book.XXA": "附加 A", - "Book.XXB": "附加 B", - "Book.XXC": "附加 C", - "Book.XXD": "附加 D", - "Book.XXE": "附加 E", - "Book.XXF": "附加 F", - "Book.XXG": "附加 G", - "Book.FRT": "前页附属资料", - "Book.BAK": "书后附属资料", - "Book.OTH": "其他附属资料", - "Book.3ES": "厄斯德拉三书 *已不使用*", - "Book.EZA": "厄斯德拉启示录", - "Book.5EZ": "以斯拉五书(拉丁文序言)", - "Book.6EZ": "以斯拉六书(拉丁文后记)", - "Book.INT": "简介", - "Book.CNC": "汇编", - "Book.GLO": "词汇表", - "Book.TDX": "主题索引", - "Book.NDX": "名字索引", - "Book.DAG": "但以理书(希腊语)", - "Book.PS3": "诗篇 152-155 篇", - "Book.2BA": "巴路克二书(天启文学)", - "Book.LBA": "巴路克书信", - "Book.JUB": "禧年书", - "Book.ENO": "以诺书", - "Book.1MQ": "玛加伯上(埃塞俄比亚)", - "Book.2MQ": "玛加伯下(埃塞俄比亚)", - "Book.3MQ": "玛加伯三(埃塞俄比亚)", - "Book.REP": "Reproof(箴言 25-31)", - "Book.4BA": "巴路克四书(巴路克的其余部分)", - "Book.LAO": "老底嘉书", - "Paratext.Data.BookSetX.get_AllBooksMessage.\"All Books\"": "所有书卷", - "Paratext.Data.BookSetX.Summary.\"none\"": "无" + "%Book.GEN%": "创", + "%Book.EXO%": "出", + "%Book.LEV%": "利", + "%Book.NUM%": "民", + "%Book.DEU%": "申", + "%Book.JOS%": "书", + "%Book.JDG%": "士", + "%Book.RUT%": "得", + "%Book.1SA%": "撒上", + "%Book.2SA%": "撒下", + "%Book.1KI%": "王上", + "%Book.2KI%": "王下", + "%Book.1CH%": "代上", + "%Book.2CH%": "代下", + "%Book.EZR%": "拉", + "%Book.NEH%": "尼", + "%Book.EST%": "斯", + "%Book.JOB%": "伯", + "%Book.PSA%": "诗", + "%Book.PRO%": "箴", + "%Book.ECC%": "传", + "%Book.SNG%": "歌", + "%Book.ISA%": "赛", + "%Book.JER%": "耶", + "%Book.LAM%": "哀", + "%Book.EZK%": "结", + "%Book.DAN%": "但", + "%Book.HOS%": "何", + "%Book.JOL%": "珥", + "%Book.AMO%": "摩", + "%Book.OBA%": "俄", + "%Book.JON%": "拿", + "%Book.MIC%": "弥", + "%Book.NAM%": "鸿", + "%Book.HAB%": "哈", + "%Book.ZEP%": "番", + "%Book.HAG%": "该", + "%Book.ZEC%": "亚", + "%Book.MAL%": "玛", + "%Book.MAT%": "太", + "%Book.MRK%": "可", + "%Book.LUK%": "路", + "%Book.JHN%": "约", + "%Book.ACT%": "徒", + "%Book.ROM%": "罗", + "%Book.1CO%": "林前", + "%Book.2CO%": "林后", + "%Book.GAL%": "加", + "%Book.EPH%": "弗", + "%Book.PHP%": "腓", + "%Book.COL%": "西", + "%Book.1TH%": "帖前", + "%Book.2TH%": "帖后", + "%Book.1TI%": "提前", + "%Book.2TI%": "提后", + "%Book.TIT%": "多", + "%Book.PHM%": "门", + "%Book.HEB%": "来", + "%Book.JAS%": "雅", + "%Book.1PE%": "彼前", + "%Book.2PE%": "彼后", + "%Book.1JN%": "约壹", + "%Book.2JN%": "约贰", + "%Book.3JN%": "约叁", + "%Book.JUD%": "犹", + "%Book.REV%": "启", + "%Book.TOB%": "多俾亚传", + "%Book.JDT%": "友弟德传", + "%Book.ESG%": "艾斯德尔传(希腊语)", + "%Book.WIS%": "智慧篇", + "%Book.SIR%": "德训篇", + "%Book.BAR%": "巴路克", + "%Book.LJE%": "耶肋米亚书信", + "%Book.S3Y%": "三童歌", + "%Book.SUS%": "苏珊拿传", + "%Book.BEL%": "彼勒与大龙", + "%Book.1MA%": "玛加伯上", + "%Book.2MA%": "玛加伯下", + "%Book.3MA%": "玛加伯三", + "%Book.4MA%": "玛加伯四", + "%Book.1ES%": "厄斯德拉一书(希腊语)", + "%Book.2ES%": "厄斯德拉二书(拉丁语)", + "%Book.MAN%": "玛拿西祷文", + "%Book.PS2%": "诗篇 151 篇", + "%Book.ODA%": "所罗门颂诗", + "%Book.PSS%": "所罗门诗篇", + "%Book.JSA%": "约书亚记 - 抄本 A 版本 *已不使用*", + "%Book.JDB%": "士师记 - 抄本 B 版本 *已不使用*", + "%Book.TBS%": "多俾亚传 - 抄本 S 版本 *已不使用*", + "%Book.SST%": "苏珊拿传 - Theodotian 版本 *已不使用*", + "%Book.DNT%": "但以理书 - Theodotian 版本 *已不使用*", + "%Book.BLT%": "彼勒与大龙 - Theodotian 版本 *已不使用*", + "%Book.XXA%": "附加 A", + "%Book.XXB%": "附加 B", + "%Book.XXC%": "附加 C", + "%Book.XXD%": "附加 D", + "%Book.XXE%": "附加 E", + "%Book.XXF%": "附加 F", + "%Book.XXG%": "附加 G", + "%Book.FRT%": "前页附属资料", + "%Book.BAK%": "书后附属资料", + "%Book.OTH%": "其他附属资料", + "%Book.3ES%": "厄斯德拉三书 *已不使用*", + "%Book.EZA%": "厄斯德拉启示录", + "%Book.5EZ%": "以斯拉五书(拉丁文序言)", + "%Book.6EZ%": "以斯拉六书(拉丁文后记)", + "%Book.INT%": "简介", + "%Book.CNC%": "汇编", + "%Book.GLO%": "词汇表", + "%Book.TDX%": "主题索引", + "%Book.NDX%": "名字索引", + "%Book.DAG%": "但以理书(希腊语)", + "%Book.PS3%": "诗篇 152-155 篇", + "%Book.2BA%": "巴路克二书(天启文学)", + "%Book.LBA%": "巴路克书信", + "%Book.JUB%": "禧年书", + "%Book.ENO%": "以诺书", + "%Book.1MQ%": "玛加伯上(埃塞俄比亚)", + "%Book.2MQ%": "玛加伯下(埃塞俄比亚)", + "%Book.3MQ%": "玛加伯三(埃塞俄比亚)", + "%Book.REP%": "Reproof(箴言 25-31)", + "%Book.4BA%": "巴路克四书(巴路克的其余部分)", + "%Book.LAO%": "老底嘉书" } diff --git a/assets/localization/zh-hant.json b/assets/localization/zh-hant.json index 87cf1fa95f..6a9522f936 100644 --- a/assets/localization/zh-hant.json +++ b/assets/localization/zh-hant.json @@ -1,127 +1,125 @@ { - "Book.GEN": "創", - "Book.EXO": "出", - "Book.LEV": "利", - "Book.NUM": "民", - "Book.DEU": "申", - "Book.JOS": "書", - "Book.JDG": "士", - "Book.RUT": "得", - "Book.1SA": "撒上", - "Book.2SA": "撒下", - "Book.1KI": "王上", - "Book.2KI": "王下", - "Book.1CH": "代上", - "Book.2CH": "代下", - "Book.EZR": "拉", - "Book.NEH": "尼", - "Book.EST": "斯", - "Book.JOB": "伯", - "Book.PSA": "詩", - "Book.PRO": "箴", - "Book.ECC": "傳", - "Book.SNG": "歌", - "Book.ISA": "賽", - "Book.JER": "耶", - "Book.LAM": "哀", - "Book.EZK": "結", - "Book.DAN": "但", - "Book.HOS": "何", - "Book.JOL": "珥", - "Book.AMO": "摩", - "Book.OBA": "俄", - "Book.JON": "拿", - "Book.MIC": "彌", - "Book.NAM": "鴻", - "Book.HAB": "哈", - "Book.ZEP": "番", - "Book.HAG": "該", - "Book.ZEC": "亞", - "Book.MAL": "瑪", - "Book.MAT": "太", - "Book.MRK": "可", - "Book.LUK": "路", - "Book.JHN": "約", - "Book.ACT": "徒", - "Book.ROM": "羅", - "Book.1CO": "林前", - "Book.2CO": "林後", - "Book.GAL": "加", - "Book.EPH": "弗", - "Book.PHP": "腓", - "Book.COL": "西", - "Book.1TH": "帖前", - "Book.2TH": "帖後", - "Book.1TI": "提前", - "Book.2TI": "提後", - "Book.TIT": "多", - "Book.PHM": "門", - "Book.HEB": "來", - "Book.JAS": "雅", - "Book.1PE": "彼前", - "Book.2PE": "彼後", - "Book.1JN": "約壹", - "Book.2JN": "約貳", - "Book.3JN": "約叄", - "Book.JUD": "猶", - "Book.REV": "啟", - "Book.TOB": "多比傳", - "Book.JDT": "猶滴傳", - "Book.ESG": "以斯帖記(希臘語)", - "Book.WIS": "所羅門智訓篇", - "Book.SIR": "便西拉智訓", - "Book.BAR": "巴錄書", - "Book.LJE": "耶利米書信", - "Book.S3Y": "三童歌", - "Book.SUS": "蘇撒拿傳", - "Book.BEL": "彼勒與大龍", - "Book.1MA": "馬加比一書", - "Book.2MA": "馬加比二書", - "Book.3MA": "馬加比三書", - "Book.4MA": "馬加比四書", - "Book.1ES": "以斯拉一書(希臘語)", - "Book.2ES": "以斯拉二書(拉丁語)", - "Book.MAN": "瑪拿西禱文", - "Book.PS2": "詩篇 151 篇", - "Book.ODA": "所羅門頌詩", - "Book.PSS": "所羅門詩篇", - "Book.JSA": "約書亞記 - 抄本 A 版本 *已不使用*", - "Book.JDB": "士師記 - 抄本 B 版本 *已不使用*", - "Book.TBS": "多比傳 - 抄本 S 版本 *已不使用*", - "Book.SST": "蘇撒拿傳 - Theodotian 版本 *已不使用*", - "Book.DNT": "但以理書 - Theodotian 版本 *已不使用*", - "Book.BLT": "彼勒與大龍 - Theodotian 版本 *已不使用*", - "Book.XXA": "附加 A", - "Book.XXB": "附加 B", - "Book.XXC": "附加 C", - "Book.XXD": "附加 D", - "Book.XXE": "附加 E", - "Book.XXF": "附加 F", - "Book.XXG": "附加 G", - "Book.FRT": "前頁附屬資料", - "Book.BAK": "書後附屬資料", - "Book.OTH": "其他附屬資料", - "Book.3ES": "以斯拉三書 *已不使用*", - "Book.EZA": "以斯拉啟示錄", - "Book.5EZ": "以斯拉五書(拉丁文序言)", - "Book.6EZ": "以斯拉六書(拉丁文後記)", - "Book.INT": "簡介", - "Book.CNC": "彙編", - "Book.GLO": "詞彙表", - "Book.TDX": "主題索引", - "Book.NDX": "名字索引", - "Book.DAG": "但以理書(希臘語)", - "Book.PS3": "詩篇 152-155 篇", - "Book.2BA": "巴錄二書(天啟文學)", - "Book.LBA": "巴錄書信", - "Book.JUB": "禧年書", - "Book.ENO": "以諾書", - "Book.1MQ": "馬加比一書(埃塞俄比亞)", - "Book.2MQ": "馬加比二書(埃塞俄比亞)", - "Book.3MQ": "馬加比三書(埃塞俄比亞)", - "Book.REP": "Reproof(箴言 25-31)", - "Book.4BA": "巴錄四書(巴錄書其餘的部分)", - "Book.LAO": "老底嘉書", - "Paratext.Data.BookSetX.get_AllBooksMessage.\"All Books\"": "所有書卷", - "Paratext.Data.BookSetX.Summary.\"none\"": "無" + "%Book.GEN%": "創", + "%Book.EXO%": "出", + "%Book.LEV%": "利", + "%Book.NUM%": "民", + "%Book.DEU%": "申", + "%Book.JOS%": "書", + "%Book.JDG%": "士", + "%Book.RUT%": "得", + "%Book.1SA%": "撒上", + "%Book.2SA%": "撒下", + "%Book.1KI%": "王上", + "%Book.2KI%": "王下", + "%Book.1CH%": "代上", + "%Book.2CH%": "代下", + "%Book.EZR%": "拉", + "%Book.NEH%": "尼", + "%Book.EST%": "斯", + "%Book.JOB%": "伯", + "%Book.PSA%": "詩", + "%Book.PRO%": "箴", + "%Book.ECC%": "傳", + "%Book.SNG%": "歌", + "%Book.ISA%": "賽", + "%Book.JER%": "耶", + "%Book.LAM%": "哀", + "%Book.EZK%": "結", + "%Book.DAN%": "但", + "%Book.HOS%": "何", + "%Book.JOL%": "珥", + "%Book.AMO%": "摩", + "%Book.OBA%": "俄", + "%Book.JON%": "拿", + "%Book.MIC%": "彌", + "%Book.NAM%": "鴻", + "%Book.HAB%": "哈", + "%Book.ZEP%": "番", + "%Book.HAG%": "該", + "%Book.ZEC%": "亞", + "%Book.MAL%": "瑪", + "%Book.MAT%": "太", + "%Book.MRK%": "可", + "%Book.LUK%": "路", + "%Book.JHN%": "約", + "%Book.ACT%": "徒", + "%Book.ROM%": "羅", + "%Book.1CO%": "林前", + "%Book.2CO%": "林後", + "%Book.GAL%": "加", + "%Book.EPH%": "弗", + "%Book.PHP%": "腓", + "%Book.COL%": "西", + "%Book.1TH%": "帖前", + "%Book.2TH%": "帖後", + "%Book.1TI%": "提前", + "%Book.2TI%": "提後", + "%Book.TIT%": "多", + "%Book.PHM%": "門", + "%Book.HEB%": "來", + "%Book.JAS%": "雅", + "%Book.1PE%": "彼前", + "%Book.2PE%": "彼後", + "%Book.1JN%": "約壹", + "%Book.2JN%": "約貳", + "%Book.3JN%": "約叄", + "%Book.JUD%": "猶", + "%Book.REV%": "啟", + "%Book.TOB%": "多比傳", + "%Book.JDT%": "猶滴傳", + "%Book.ESG%": "以斯帖記(希臘語)", + "%Book.WIS%": "所羅門智訓篇", + "%Book.SIR%": "便西拉智訓", + "%Book.BAR%": "巴錄書", + "%Book.LJE%": "耶利米書信", + "%Book.S3Y%": "三童歌", + "%Book.SUS%": "蘇撒拿傳", + "%Book.BEL%": "彼勒與大龍", + "%Book.1MA%": "馬加比一書", + "%Book.2MA%": "馬加比二書", + "%Book.3MA%": "馬加比三書", + "%Book.4MA%": "馬加比四書", + "%Book.1ES%": "以斯拉一書(希臘語)", + "%Book.2ES%": "以斯拉二書(拉丁語)", + "%Book.MAN%": "瑪拿西禱文", + "%Book.PS2%": "詩篇 151 篇", + "%Book.ODA%": "所羅門頌詩", + "%Book.PSS%": "所羅門詩篇", + "%Book.JSA%": "約書亞記 - 抄本 A 版本 *已不使用*", + "%Book.JDB%": "士師記 - 抄本 B 版本 *已不使用*", + "%Book.TBS%": "多比傳 - 抄本 S 版本 *已不使用*", + "%Book.SST%": "蘇撒拿傳 - Theodotian 版本 *已不使用*", + "%Book.DNT%": "但以理書 - Theodotian 版本 *已不使用*", + "%Book.BLT%": "彼勒與大龍 - Theodotian 版本 *已不使用*", + "%Book.XXA%": "附加 A", + "%Book.XXB%": "附加 B", + "%Book.XXC%": "附加 C", + "%Book.XXD%": "附加 D", + "%Book.XXE%": "附加 E", + "%Book.XXF%": "附加 F", + "%Book.XXG%": "附加 G", + "%Book.FRT%": "前頁附屬資料", + "%Book.BAK%": "書後附屬資料", + "%Book.OTH%": "其他附屬資料", + "%Book.3ES%": "以斯拉三書 *已不使用*", + "%Book.EZA%": "以斯拉啟示錄", + "%Book.5EZ%": "以斯拉五書(拉丁文序言)", + "%Book.6EZ%": "以斯拉六書(拉丁文後記)", + "%Book.INT%": "簡介", + "%Book.CNC%": "彙編", + "%Book.GLO%": "詞彙表", + "%Book.TDX%": "主題索引", + "%Book.NDX%": "名字索引", + "%Book.DAG%": "但以理書(希臘語)", + "%Book.PS3%": "詩篇 152-155 篇", + "%Book.2BA%": "巴錄二書(天啟文學)", + "%Book.LBA%": "巴錄書信", + "%Book.JUB%": "禧年書", + "%Book.ENO%": "以諾書", + "%Book.1MQ%": "馬加比一書(埃塞俄比亞)", + "%Book.2MQ%": "馬加比二書(埃塞俄比亞)", + "%Book.3MQ%": "馬加比三書(埃塞俄比亞)", + "%Book.REP%": "Reproof(箴言 25-31)", + "%Book.4BA%": "巴錄四書(巴錄書其餘的部分)", + "%Book.LAO%": "老底嘉書" } diff --git a/extensions/lib/git.util.ts b/extensions/lib/git.util.ts index 144933a2ca..116667ddfc 100644 --- a/extensions/lib/git.util.ts +++ b/extensions/lib/git.util.ts @@ -146,6 +146,9 @@ const replaceInFileIgnoreGlobs = [ '**/.eslintcache', '**/dist/**/*', '**/release/**/*', + // With npm workspaces, child workspace package-lock.json files are not used. Let's not format + // them so they can stay the same as how they were in the template to avoid merge conflicts + '**/package-lock.json', ]; /** diff --git a/extensions/src/hello-someone/contributions/localizedStrings.json b/extensions/src/hello-someone/contributions/localizedStrings.json new file mode 100644 index 0000000000..56de66efd0 --- /dev/null +++ b/extensions/src/hello-someone/contributions/localizedStrings.json @@ -0,0 +1,6 @@ +{ + "metadata": {}, + "localizedStrings": { + "en": {} + } +} diff --git a/extensions/src/hello-someone/manifest.json b/extensions/src/hello-someone/manifest.json index 3bb73e6a5f..c2506b3ac2 100644 --- a/extensions/src/hello-someone/manifest.json +++ b/extensions/src/hello-someone/manifest.json @@ -9,6 +9,7 @@ "menus": "contributions/menus.json", "settings": "contributions/settings.json", "projectSettings": "contributions/projectSettings.json", + "localizedStrings": "contributions/localizedStrings.json", "activationEvents": [ "onCommand:helloSomeone.helloSomeone", "onCommand:helloSomeone.echoSomeoneRenderer" diff --git a/extensions/src/hello-world/contributions/localizedStrings.json b/extensions/src/hello-world/contributions/localizedStrings.json new file mode 100644 index 0000000000..47076d384e --- /dev/null +++ b/extensions/src/hello-world/contributions/localizedStrings.json @@ -0,0 +1,9 @@ +{ + "metadata": {}, + "localizedStrings": { + "en": { + "%settings_hello_world_group1_label%": "Hello World Settings", + "%settings_hello_world_personName_label%": "Selected Person's Name on Hello World Web View" + } + } +} diff --git a/extensions/src/hello-world/manifest.json b/extensions/src/hello-world/manifest.json index 8f7bf6a78b..525db0110f 100644 --- a/extensions/src/hello-world/manifest.json +++ b/extensions/src/hello-world/manifest.json @@ -9,5 +9,6 @@ "menus": "contributions/menus.json", "settings": "contributions/settings.json", "projectSettings": "contributions/projectSettings.json", + "localizedStrings": "contributions/localizedStrings.json", "activationEvents": ["onCommand:helloWorld.helloWorld", "onCommand:helloWorld.helloException"] } diff --git a/extensions/src/platform-scripture-editor/contributions/localizedStrings.json b/extensions/src/platform-scripture-editor/contributions/localizedStrings.json new file mode 100644 index 0000000000..87832dc8bf --- /dev/null +++ b/extensions/src/platform-scripture-editor/contributions/localizedStrings.json @@ -0,0 +1,16 @@ +{ + "metadata": {}, + "localizedStrings": { + "en": { + "%mainMenu_openPlatformScriptureEditor%": "Open Scripture Editor", + "%mainMenu_openPlatformResourceViewer%": "Open Resource Viewer", + "%webView_platformScriptureEditor_options%": "Options", + "%webView_platformScriptureEditor_info%": "Info", + "%webView_platformScriptureEditor_backgroundColor%": "Background Color", + "%webView_platformScriptureEditor_textColor%": "Text Color", + "%webView_platformScriptureEditor_thickBorders%": "Thick Borders", + "%webView_platformScriptureEditor_publisherInfo%": "Publisher Info", + "%webView_platformScriptureEditor_copyrightInfo%": "Copyright Info" + } + } +} diff --git a/extensions/src/platform-scripture-editor/contributions/menus.json b/extensions/src/platform-scripture-editor/contributions/menus.json index d96640f9f2..8bfbb2b89c 100644 --- a/extensions/src/platform-scripture-editor/contributions/menus.json +++ b/extensions/src/platform-scripture-editor/contributions/menus.json @@ -14,7 +14,7 @@ "label": "%mainMenu_openPlatformResourceViewer%", "localizeNotes": "Application main menu > Project > Open Resource Viewer", "group": "platform.projectResources", - "order": -100, + "order": -99, "command": "platformScriptureEditor.openResourceViewer" } ] diff --git a/extensions/src/platform-scripture-editor/manifest.json b/extensions/src/platform-scripture-editor/manifest.json index a7f4673652..d5672d7ed9 100644 --- a/extensions/src/platform-scripture-editor/manifest.json +++ b/extensions/src/platform-scripture-editor/manifest.json @@ -9,5 +9,6 @@ "menus": "contributions/menus.json", "settings": "contributions/settings.json", "projectSettings": "contributions/projectSettings.json", + "localizedStrings": "contributions/localizedStrings.json", "activationEvents": [] } diff --git a/extensions/src/platform-scripture-editor/src/main.ts b/extensions/src/platform-scripture-editor/src/main.ts index f247e3342c..159fa08413 100644 --- a/extensions/src/platform-scripture-editor/src/main.ts +++ b/extensions/src/platform-scripture-editor/src/main.ts @@ -74,10 +74,11 @@ const scriptureEditorWebViewProvider: IWebViewProvider = { (savedWebView.state?.projectId as string) || undefined; const isReadOnly = getWebViewOptions.isReadOnly || savedWebView.state?.isReadOnly; - let title = isReadOnly ? 'Resource Viewer' : 'Scripture Editor'; + let title = ''; if (projectId) { - title += `: ${(await papi.projectLookup.getMetadataForProject(projectId)).name ?? projectId}`; - } + title = `${(await papi.projectLookup.getMetadataForProject(projectId)).name ?? projectId}${isReadOnly ? '' : ' (Editable)'}`; + } else title = isReadOnly ? 'Resource Viewer' : 'Scripture Editor'; + return { title, ...savedWebView, diff --git a/extensions/src/platform-scripture/contributions/localizedStrings.json b/extensions/src/platform-scripture/contributions/localizedStrings.json new file mode 100644 index 0000000000..66afcf9fbc --- /dev/null +++ b/extensions/src/platform-scripture/contributions/localizedStrings.json @@ -0,0 +1,11 @@ +{ + "metadata": {}, + "localizedStrings": { + "en": { + "%project_settings_platformScripture_booksPresent_label%": "Scripture Books Present", + "%project_settings_platformScripture_booksPresent_description%": "Which books of the Bible are present in this Scripture project", + "%project_settings_platformScripture_versification_label%": "Scripture Versification", + "%project_settings_platformScripture_versification_description%": "Which versification scheme this Scripture project follows" + } + } +} diff --git a/extensions/src/platform-scripture/manifest.json b/extensions/src/platform-scripture/manifest.json index 9e75cb4893..c2e6528f96 100644 --- a/extensions/src/platform-scripture/manifest.json +++ b/extensions/src/platform-scripture/manifest.json @@ -9,5 +9,6 @@ "menus": "contributions/menus.json", "settings": "contributions/settings.json", "projectSettings": "contributions/projectSettings.json", + "localizedStrings": "contributions/localizedStrings.json", "activationEvents": [] } diff --git a/extensions/src/quick-verse/contributions/localizedStrings.json b/extensions/src/quick-verse/contributions/localizedStrings.json new file mode 100644 index 0000000000..56de66efd0 --- /dev/null +++ b/extensions/src/quick-verse/contributions/localizedStrings.json @@ -0,0 +1,6 @@ +{ + "metadata": {}, + "localizedStrings": { + "en": {} + } +} diff --git a/extensions/src/quick-verse/manifest.json b/extensions/src/quick-verse/manifest.json index 0f60f4815a..a0ef6c44ab 100644 --- a/extensions/src/quick-verse/manifest.json +++ b/extensions/src/quick-verse/manifest.json @@ -9,5 +9,6 @@ "menus": "contributions/menus.json", "settings": "contributions/settings.json", "projectSettings": "contributions/projectSettings.json", + "localizedStrings": "contributions/localizedStrings.json", "activationEvents": [] } diff --git a/extensions/webpack/webpack.util.ts b/extensions/webpack/webpack.util.ts index d06b510406..e7c5502295 100644 --- a/extensions/webpack/webpack.util.ts +++ b/extensions/webpack/webpack.util.ts @@ -141,6 +141,8 @@ const staticFiles: { { from: '', noErrorOnMissing: true }, // Copy the project settings JSON file into the output folder based on its listing in `manifest.projectSettings` { from: '', noErrorOnMissing: true }, + // Copy the localized strings JSON file into the output folder based on its listing in `manifest.localizedStrings` + { from: '', noErrorOnMissing: true }, ]; /** Get the actual static file name from the template static file name */ @@ -149,8 +151,9 @@ function getStaticFileName(staticFile: string, extensionInfo: ExtensionInfo) { .replace(//g, extensionInfo.name) .replace(//g, extensionInfo.types ?? '') .replace(//g, extensionInfo.menus ?? '') - .replace(//g, extensionInfo.menus ?? '') - .replace(//g, extensionInfo.menus ?? ''); + .replace(//g, extensionInfo.settings ?? '') + .replace(//g, extensionInfo.projectSettings ?? '') + .replace(//g, extensionInfo.localizedStrings ?? ''); } /** Get CopyFile plugin patterns for copying static files for an extension */ @@ -296,6 +299,8 @@ type ExtensionManifest = { settings?: string; /** Path to the JSON file that defines the project settings this extension is adding. */ projectSettings?: string; + /** Path to the JSON file that defines the localized strings this extension is adding. */ + localizedStrings?: string; activationEvents: string[]; }; diff --git a/lib/papi-dts/papi.d.ts b/lib/papi-dts/papi.d.ts index 2f13bdc4a5..6b549c9203 100644 --- a/lib/papi-dts/papi.d.ts +++ b/lib/papi-dts/papi.d.ts @@ -4772,23 +4772,14 @@ declare module 'shared/services/localization.service-model' { DataProviderDataType, DataProviderUpdateInstructions, } from 'shared/models/data-provider.model'; - import { OnDidDispose } from 'platform-bible-utils'; - export type LocalizationMetadata = { - notes: string; - fallbackKey: string; - }; - export type LocalizedStringMetadata = { - [localizedStringKey: string]: LocalizationMetadata; - }; - export type LocalizationData = { - [localizeKey: string]: string; - }; + import { LanguageStrings, LocalizeKey, OnDidDispose } from 'platform-bible-utils'; + export type LocalizationData = LanguageStrings; export type LocalizationSelector = { - localizeKey: string; + localizeKey: LocalizeKey; locales?: string[]; }; export type LocalizationSelectors = { - localizeKeys: string[]; + localizeKeys: LocalizeKey[]; locales?: string[]; }; /** @@ -4807,13 +4798,7 @@ declare module 'shared/services/localization.service-model' { }>; export type LocalizationDataDataTypes = { LocalizedString: DataProviderDataType; - LocalizedStrings: DataProviderDataType< - LocalizationSelectors, - { - [localizeKey: string]: string; - }, - never - >; + LocalizedStrings: DataProviderDataType; }; module 'papi-shared-types' { interface DataProviders { @@ -5591,6 +5576,8 @@ declare module 'extension-host/extension-types/extension-manifest.model' { settings?: string; /** Path to the JSON file that defines the project settings this extension is adding. */ projectSettings?: string; + /** Path to the JSON file that defines the localized strings this extension is adding. */ + localizedStrings?: string; /** * List of events that occur that should cause this extension to be activated. Not yet * implemented. diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 6dd04ee16d..74d6d9e588 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var we=Object.defineProperty;var Ee=(t,e,r)=>e in t?we(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var d=(t,e,r)=>(Ee(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Oe=require("async-mutex");class je{constructor(e,r=1e4){d(this,"variableName");d(this,"promiseToValue");d(this,"resolver");d(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,i)=>{this.resolver=s,this.rejecter=i}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}class H{constructor(){d(this,"subscribe",this.event);d(this,"subscriptions");d(this,"lazyEvent");d(this,"isDisposed",!1);d(this,"dispose",()=>this.disposeFn());d(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}function Se(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function W(t){return typeof t=="string"||t instanceof String}function v(t){return JSON.parse(JSON.stringify(t))}function Ae(t,e=300){if(W(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function Pe(t,e,r){const s=new Map;return t.forEach(i=>{const n=e(i),o=s.get(n),a=r?r(i,n):i;o?o.push(a):s.set(n,[a])}),s}function Ce(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function qe(t){if(Ce(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Me(t){return qe(t).message}function L(t){return new Promise(e=>setTimeout(e,t))}function Te(t,e){const r=L(e).then(()=>{});return Promise.any([r,t()])}function De(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(i=>{try{typeof t[i]=="function"&&r.add(i)}catch(n){console.debug(`Skipping ${i} on ${e} due to error: ${n}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(i=>{try{typeof t[i]=="function"&&r.add(i)}catch(n){console.debug(`Skipping ${i} on ${e}'s prototype due to error: ${n}`)}}),s=Object.getPrototypeOf(s);return r}function xe(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...i)=>(await t())[s](...i)}})}class Z{constructor(e,r){d(this,"baseDocument");d(this,"contributions",new Map);d(this,"latestOutput");d(this,"options");d(this,"onDidRebuildEmitter",new H);d(this,"onDidRebuild",this.onDidRebuildEmitter.subscribe);this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateBaseDocument(e),this.baseDocument=this.options.copyDocuments?v(e):e,this.baseDocument=this.transformBaseDocumentAfterValidation(this.baseDocument),this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e);let i=this.options.copyDocuments&&r?v(r):r;i=this.transformContributionAfterValidation(e,i),this.contributions.set(e,i);try{return this.rebuild()}catch(n){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${n}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error(`${e} does not exist`);this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}deleteAllContributions(){if(this.contributions.size<=0)return this.latestOutput;const e=[...this.contributions.entries()];e.forEach(([r])=>this.contributions.delete(r));try{return this.rebuild()}catch(r){throw e.forEach(([s,i])=>this.contributions.set(s,i)),new Error(`Error when deleting all contributions: ${r}`)}}rebuild(){if(this.contributions.size===0){let r=v(this.baseDocument);return r=this.transformFinalOutputBeforeValidation(r),this.validateOutput(r),this.latestOutput=r,this.onDidRebuildEmitter.emit(void 0),this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=Re(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutputBeforeValidation(e),this.validateOutput(e),this.latestOutput=e,this.onDidRebuildEmitter.emit(void 0),this.latestOutput}transformBaseDocumentAfterValidation(e){return e}transformContributionAfterValidation(e,r){return r}validateBaseDocument(e){}validateContribution(e,r){}validateOutput(e){}transformFinalOutputBeforeValidation(e){return e}}function R(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function I(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function Re(t,e,r){const s=v(t);return e?X(s,v(e),r):s}function X(t,e,r){if(!e)return t;if(R(t,e)){const s=t,i=e;Object.keys(i).forEach(n=>{if(Object.hasOwn(s,n)){if(R(s[n],i[n]))s[n]=X(s[n],i[n],r);else if(I(s[n],i[n]))s[n]=s[n].concat(i[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=i[n]})}else I(t,e)&&t.push(...e);return t}class Ie extends Z{constructor(e,r){super(e,r)}get output(){return this.latestOutput}}class Be{constructor(e="Anonymous"){d(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,i)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${i} failed!`),s))}}class Q extends Oe.Mutex{}class ze{constructor(){d(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new Q,this.mutexesByID.set(e,r),r)}}const Y=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],ee=1,te=Y.length-1,re=1,se=1,ie=t=>{var e;return((e=Y[t])==null?void 0:e.chapters)??-1},_e=(t,e)=>({bookNum:Math.max(ee,Math.min(t.bookNum+e,te)),chapterNum:1,verseNum:1}),Ge=(t,e)=>({...t,chapterNum:Math.min(Math.max(re,t.chapterNum+e),ie(t.bookNum)),verseNum:1}),Ve=(t,e)=>({...t,verseNum:Math.max(se,t.verseNum+e)}),Je=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),Ke=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var B=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},y={},Ue=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",i="\\u1ab0-\\u1aff",n="\\u1dc0-\\u1dff",o=e+r+s+i+n,a="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",p=`[${t}]`,u=`[${o}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,g=`[^${t}]`,m="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",$="[\\ud800-\\udbff][\\udc00-\\udfff]",P="\\u200d",be="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ye=`[${c}]`,D=`${f}?`,x=`[${a}]?`,ve=`(?:${P}(?:${[g,m,$].join("|")})${x+D})*`,Ne=x+D+ve,$e=`(?:${[`${g}${u}?`,u,m,$,p,ye].join("|")})`;return new RegExp(`${be}|${l}(?=${l})|${$e+Ne}`,"g")},Fe=B&&B.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(y,"__esModule",{value:!0});var j=Fe(Ue);function C(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(j.default())||[]}var ke=y.toArray=C;function M(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(j.default());return e===null?0:e.length}var He=y.length=M;function ne(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(j.default());return s?s.slice(e,r).join(""):""}var We=y.substring=ne;function Le(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=M(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var i;typeof r>"u"?i=s:(typeof r!="number"&&(r=parseInt(r,10)),i=r>=0?r+e:e);var n=t.match(j.default());return n?n.slice(e,i).join(""):""}var Ze=y.substr=Le;function Xe(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var i=M(t);if(i>e)return ne(t,0,e);if(i=s.length)return e===""?s.length:-1;if(e==="")return r;var i=C(e),n=!1,o;for(o=r;oh(t)||e<-h(t)))return A(t,e,1)}function tt(t,e){return e<0||e>h(t)-1?"":A(t,e,1)}function rt(t,e){if(!(e<0||e>h(t)-1))return A(t,e,1).codePointAt(0)}function st(t,e,r=h(t)){const s=ue(t,e);return!(s===-1||s+h(e)!==r)}function ae(t,e,r=0){const s=E(t,r);return S(s,e)!==-1}function S(t,e,r=0){return Ye(t,e,r)}function ue(t,e,r){let s=r===void 0?h(t):r;s<0?s=0:s>=h(t)&&(s=h(t)-1);for(let i=s;i>=0;i--)if(A(t,i,h(e))===e)return i;return-1}function h(t){return He(t)}function it(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function nt(t,e,r=" "){return e<=h(t)?t:oe(t,e,r,"right")}function ot(t,e,r=" "){return e<=h(t)?t:oe(t,e,r,"left")}function z(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function at(t,e,r){const s=h(t);if(e>s||r&&(e>r&&!(e>=0&&e-s)||r<-s))return"";const i=z(s,e),n=r?z(s,r):void 0;return E(t,i,n)}function ut(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return le(t).slice(0,r);let i=e;(typeof e=="string"||e instanceof RegExp&&!ae(e.flags,"g"))&&(i=new RegExp(e,"g"));const n=t.match(i);let o=0;if(!n)return[t];for(let a=0;a<(r?r-1:n.length);a++){const c=S(t,n[a],o),p=h(n[a]);if(s.push(E(t,o,c)),o=c+p,r!==void 0&&s.length===r)break}return s.push(E(t,o)),s}function lt(t,e,r=0){return S(t,e,r)===r}function A(t,e=0,r=h(t)-e){return Ze(t,e,r)}function E(t,e,r=h(t)){return We(t,e,r)}function le(t){return ke(t)}var ct=Object.getOwnPropertyNames,ft=Object.getOwnPropertySymbols,pt=Object.prototype.hasOwnProperty;function _(t,e){return function(s,i,n){return t(s,i,n)&&e(s,i,n)}}function O(t){return function(r,s,i){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,i);var n=i.cache,o=n.get(r),a=n.get(s);if(o&&a)return o===s&&a===r;n.set(r,s),n.set(s,r);var c=t(r,s,i);return n.delete(r),n.delete(s),c}}function G(t){return ct(t).concat(ft(t))}var ce=Object.hasOwn||function(t,e){return pt.call(t,e)};function N(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var fe="_owner",V=Object.getOwnPropertyDescriptor,J=Object.keys;function dt(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ht(t,e){return N(t.getTime(),e.getTime())}function K(t,e,r){if(t.size!==e.size)return!1;for(var s={},i=t.entries(),n=0,o,a;(o=i.next())&&!o.done;){for(var c=e.entries(),p=!1,u=0;(a=c.next())&&!a.done;){var l=o.value,f=l[0],g=l[1],m=a.value,$=m[0],P=m[1];!p&&!s[u]&&(p=r.equals(f,$,n,u,t,e,r)&&r.equals(g,P,f,$,t,e,r))&&(s[u]=!0),u++}if(!p)return!1;n++}return!0}function mt(t,e,r){var s=J(t),i=s.length;if(J(e).length!==i)return!1;for(var n;i-- >0;)if(n=s[i],n===fe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ce(e,n)||!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function w(t,e,r){var s=G(t),i=s.length;if(G(e).length!==i)return!1;for(var n,o,a;i-- >0;)if(n=s[i],n===fe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ce(e,n)||!r.equals(t[n],e[n],n,n,t,e,r)||(o=V(t,n),a=V(e,n),(o||a)&&(!o||!a||o.configurable!==a.configurable||o.enumerable!==a.enumerable||o.writable!==a.writable)))return!1;return!0}function gt(t,e){return N(t.valueOf(),e.valueOf())}function bt(t,e){return t.source===e.source&&t.flags===e.flags}function U(t,e,r){if(t.size!==e.size)return!1;for(var s={},i=t.values(),n,o;(n=i.next())&&!n.done;){for(var a=e.values(),c=!1,p=0;(o=a.next())&&!o.done;)!c&&!s[p]&&(c=r.equals(n.value,o.value,n.value,o.value,t,e,r))&&(s[p]=!0),p++;if(!c)return!1}return!0}function yt(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var vt="[object Arguments]",Nt="[object Boolean]",$t="[object Date]",wt="[object Map]",Et="[object Number]",Ot="[object Object]",jt="[object RegExp]",St="[object Set]",At="[object String]",Pt=Array.isArray,F=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,k=Object.assign,Ct=Object.prototype.toString.call.bind(Object.prototype.toString);function qt(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,i=t.areObjectsEqual,n=t.arePrimitiveWrappersEqual,o=t.areRegExpsEqual,a=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var g=u.constructor;if(g!==l.constructor)return!1;if(g===Object)return i(u,l,f);if(Pt(u))return e(u,l,f);if(F!=null&&F(u))return c(u,l,f);if(g===Date)return r(u,l,f);if(g===RegExp)return o(u,l,f);if(g===Map)return s(u,l,f);if(g===Set)return a(u,l,f);var m=Ct(u);return m===$t?r(u,l,f):m===jt?o(u,l,f):m===wt?s(u,l,f):m===St?a(u,l,f):m===Ot?typeof u.then!="function"&&typeof l.then!="function"&&i(u,l,f):m===vt?i(u,l,f):m===Nt||m===Et||m===At?n(u,l,f):!1}}function Mt(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,i={areArraysEqual:s?w:dt,areDatesEqual:ht,areMapsEqual:s?_(K,w):K,areObjectsEqual:s?w:mt,arePrimitiveWrappersEqual:gt,areRegExpsEqual:bt,areSetsEqual:s?_(U,w):U,areTypedArraysEqual:s?w:yt};if(r&&(i=k({},i,r(i))),e){var n=O(i.areArraysEqual),o=O(i.areMapsEqual),a=O(i.areObjectsEqual),c=O(i.areSetsEqual);i=k({},i,{areArraysEqual:n,areMapsEqual:o,areObjectsEqual:a,areSetsEqual:c})}return i}function Tt(t){return function(e,r,s,i,n,o,a){return t(e,r,a)}}function Dt(t){var e=t.circular,r=t.comparator,s=t.createState,i=t.equals,n=t.strict;if(s)return function(c,p){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,g=u.meta;return r(c,p,{cache:f,equals:i,meta:g,strict:n})};if(e)return function(c,p){return r(c,p,{cache:new WeakMap,equals:i,meta:void 0,strict:n})};var o={cache:void 0,equals:i,meta:void 0,strict:n};return function(c,p){return r(c,p,o)}}var xt=b();b({strict:!0});b({circular:!0});b({circular:!0,strict:!0});b({createInternalComparator:function(){return N}});b({strict:!0,createInternalComparator:function(){return N}});b({circular:!0,createInternalComparator:function(){return N}});b({circular:!0,createInternalComparator:function(){return N},strict:!0});function b(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,i=t.createState,n=t.strict,o=n===void 0?!1:n,a=Mt(t),c=qt(a),p=s?s(c):Tt(c);return Dt({circular:r,comparator:c,createState:i,equals:p,strict:o})}function Rt(t,e){return xt(t,e)}function q(t,e,r){return JSON.stringify(t,(i,n)=>{let o=n;return e&&(o=e(i,o)),o===void 0&&(o=null),o},r)}function pe(t,e){function r(i){return Object.keys(i).forEach(n=>{i[n]===null?i[n]=void 0:typeof i[n]=="object"&&(i[n]=r(i[n]))}),i}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function It(t){try{const e=q(t);return e===q(pe(e))}catch{return!1}}const Bt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),de={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(de);const T={projectSettingsContribution:{description:"The data an extension provides to inform Platform.Bible of the project settings it provides",anyOf:[{$ref:"#/$defs/projectSettingsGroup"},{type:"array",items:{$ref:"#/$defs/projectSettingsGroup"}}]},projectSettingsGroup:{description:"Group of related settings definitions",type:"object",properties:{label:{description:"localizeKey that displays in the project settings dialog as the group name",$ref:"#/$defs/localizeKey"},description:{description:"localizeKey that displays in the project settings dialog to describe the group",$ref:"#/$defs/localizeKey"},properties:{$ref:"#/$defs/projectSettingProperties"}},required:["label","properties"]},projectSettingProperties:{description:"Object whose keys are setting IDs and whose values are settings objects",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/projectSetting"}},additionalProperties:!1},projectSetting:{description:"A description of an extension's setting entry",anyOf:[{$ref:"#/$defs/extensionControlledProjectSetting"}]},extensionControlledProjectSetting:{description:"Setting definition that is validated by the extension.",allOf:[{$ref:"#/$defs/projectSettingBase"},{$ref:"#/$defs/modifierExtensionControlled"}]},projectSettingBase:{description:"Base information needed to describe a project setting entry",allOf:[{$ref:"#/$defs/settingBase"},{$ref:"#/$defs/modifierProject"}]},modifierProject:{description:"Modifies setting type to be project setting",type:"object",properties:{includeProjectTypes:{description:"`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog",anyOf:[{type:"null"},{type:"string"},{type:"array",items:{type:"string"}}]},excludeProjectTypes:{description:"`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`",anyOf:[{type:"null"},{type:"string"},{type:"array",items:{type:"string"}}]}}},settingsContribution:{description:"The data an extension provides to inform Platform.Bible of the settings it provides",anyOf:[{$ref:"#/$defs/settingsGroup"},{type:"array",items:{$ref:"#/$defs/settingsGroup"}}]},settingsGroup:{description:"Group of related settings definitions",type:"object",properties:{label:{description:"localizeKey that displays in the settings dialog as the group name",$ref:"#/$defs/localizeKey"},description:{description:"localizeKey that displays in the settings dialog to describe the group",$ref:"#/$defs/localizeKey"},properties:{$ref:"#/$defs/settingProperties"}},required:["label","properties"]},settingProperties:{description:"Object whose keys are setting IDs and whose values are settings objects",type:"object",patternProperties:{"^[\\w-]+\\.[\\w-]+$":{$ref:"#/$defs/setting"}},additionalProperties:!1},setting:{description:"A description of an extension's setting entry",anyOf:[{$ref:"#/$defs/extensionControlledSetting"}]},extensionControlledSetting:{description:"Setting definition that is validated by the extension.",allOf:[{$ref:"#/$defs/settingBase"},{$ref:"#/$defs/modifierExtensionControlled"}]},settingBase:{description:"Base information needed to describe a setting entry",allOf:[{$ref:"#/$defs/stateBase"},{type:"object",properties:{label:{description:"localizeKey that displays in the settings dialog as the setting name",$ref:"#/$defs/localizeKey"},description:{description:"localizeKey that displays in the settings dialog to describe the setting",$ref:"#/$defs/localizeKey"}},required:["label"]}]},projectStateContribution:{description:"The data an extension provides to inform Platform.Bible of the project state it provides",$ref:"#/$defs/userStateProperties"},userStateContribution:{description:"The data an extension provides to inform Platform.Bible of the user state it provides",$ref:"#/$defs/userStateProperties"},userStateProperties:{description:"Object whose keys are state IDs and whose values are state objects",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/userState"}},additionalProperties:!1},userState:{description:"A description of an extension's user state entry",anyOf:[{$ref:"#/$defs/extensionControlledState"}]},extensionControlledState:{description:"State definition that is validated by the extension.",allOf:[{$ref:"#/$defs/stateBase"},{$ref:"#/$defs/modifierExtensionControlled"}]},modifierExtensionControlled:{description:'Modifies state/setting type to be extension-controlled. "Extension-controlled" means the extension provides the component and the validator for the state/setting, so the state/setting is controlled by the extension.',not:{anyOf:[{type:"object",required:["platformType"]},{type:"object",required:["type"]}]}},stateBase:{description:"Base information needed to describe a state entry",type:"object",properties:{default:{description:"default value for the state/setting",type:"any"},derivesFrom:{description:"a state/setting ID whose value to set to this state/setting's starting value the first time this state/setting is loaded",$ref:"#/$defs/id"}},required:["default"]},localizeKey:{description:"Identifier for a string that will be localized based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$",tsType:"LocalizeKey"},id:{description:"",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$",tsType:"Id"}};function he(t){t&&Object.values(t).forEach(e=>{if(e.type){if("tsType"in e&&delete e.tsType,e.type==="any"){delete e.type;return}e.type==="object"&&he(e.properties)}})}he(T);const me={$schema:"https://json-schema.org/draft/2020-12/schema",title:"Project Settings Contribution",description:"The data an extension provides to inform Platform.Bible of the project settings it provides",anyOf:[{$ref:"#/$defs/projectSettingsGroup"},{type:"array",items:{$ref:"#/$defs/projectSettingsGroup"}}],$defs:T};Object.freeze(me);const ge={$schema:"https://json-schema.org/draft/2020-12/schema",title:"Settings Contribution",description:"The data an extension provides to inform Platform.Bible of the settings it provides",anyOf:[{$ref:"#/$defs/settingsGroup"},{type:"array",items:{$ref:"#/$defs/settingsGroup"}}],$defs:T};Object.freeze(ge);exports.AsyncVariable=je;exports.DocumentCombiner=Z;exports.FIRST_SCR_BOOK_NUM=ee;exports.FIRST_SCR_CHAPTER_NUM=re;exports.FIRST_SCR_VERSE_NUM=se;exports.LAST_SCR_BOOK_NUM=te;exports.Mutex=Q;exports.MutexMap=ze;exports.NonValidatingDocumentCombiner=Ie;exports.PlatformEventEmitter=H;exports.UnsubscriberAsyncList=Be;exports.aggregateUnsubscriberAsyncs=Ke;exports.aggregateUnsubscribers=Je;exports.at=et;exports.charAt=tt;exports.codePointAt=rt;exports.createSyncProxyForAsyncObject=xe;exports.debounce=Ae;exports.deepClone=v;exports.deepEqual=Rt;exports.deserialize=pe;exports.endsWith=st;exports.getAllObjectFunctionNames=De;exports.getChaptersForBook=ie;exports.getErrorMessage=Me;exports.groupBy=Pe;exports.htmlEncode=Bt;exports.includes=ae;exports.indexOf=S;exports.isSerializable=It;exports.isString=W;exports.lastIndexOf=ue;exports.menuDocumentSchema=de;exports.newGuid=Se;exports.normalize=it;exports.offsetBook=_e;exports.offsetChapter=Ge;exports.offsetVerse=Ve;exports.padEnd=nt;exports.padStart=ot;exports.projectSettingsDocumentSchema=me;exports.serialize=q;exports.settingsDocumentSchema=ge;exports.slice=at;exports.split=ut;exports.startsWith=lt;exports.stringLength=h;exports.substring=E;exports.toArray=le;exports.wait=L;exports.waitForDuration=Te; +"use strict";var Ue=Object.defineProperty;var Le=(t,e,r)=>e in t?Ue(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var m=(t,e,r)=>(Le(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Fe=require("async-mutex");class We{constructor(e,r=1e4){m(this,"variableName");m(this,"promiseToValue");m(this,"resolver");m(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,i)=>{this.resolver=s,this.rejecter=i}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}class ce{constructor(){m(this,"subscribe",this.event);m(this,"subscriptions");m(this,"lazyEvent");m(this,"isDisposed",!1);m(this,"dispose",()=>this.disposeFn());m(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}function Ze(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function fe(t){return typeof t=="string"||t instanceof String}function j(t){return JSON.parse(JSON.stringify(t))}function Qe(t,e=300){if(fe(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function Ye(t,e,r){const s=new Map;return t.forEach(i=>{const n=e(i),o=s.get(n),a=r?r(i,n):i;o?o.push(a):s.set(n,[a])}),s}function et(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function tt(t){if(et(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function rt(t){return tt(t).message}function he(t){return new Promise(e=>setTimeout(e,t))}function st(t,e){const r=he(e).then(()=>{});return Promise.any([r,t()])}function it(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(i=>{try{typeof t[i]=="function"&&r.add(i)}catch(n){console.debug(`Skipping ${i} on ${e} due to error: ${n}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(i=>{try{typeof t[i]=="function"&&r.add(i)}catch(n){console.debug(`Skipping ${i} on ${e}'s prototype due to error: ${n}`)}}),s=Object.getPrototypeOf(s);return r}function nt(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...i)=>(await t())[s](...i)}})}class pe{constructor(e,r){m(this,"baseDocument");m(this,"contributions",new Map);m(this,"latestOutput");m(this,"options");m(this,"onDidRebuildEmitter",new ce);m(this,"onDidRebuild",this.onDidRebuildEmitter.subscribe);this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateBaseDocument(e),this.baseDocument=this.options.copyDocuments?j(e):e,this.baseDocument=this.transformBaseDocumentAfterValidation(this.baseDocument),this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e);let i=this.options.copyDocuments&&r?j(r):r;i=this.transformContributionAfterValidation(e,i),this.contributions.set(e,i);try{return this.rebuild()}catch(n){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${n}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error(`${e} does not exist`);this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}deleteAllContributions(){if(this.contributions.size<=0)return this.latestOutput;const e=[...this.contributions.entries()];e.forEach(([r])=>this.contributions.delete(r));try{return this.rebuild()}catch(r){throw e.forEach(([s,i])=>this.contributions.set(s,i)),new Error(`Error when deleting all contributions: ${r}`)}}rebuild(){if(this.contributions.size===0){let r=j(this.baseDocument);return r=this.transformFinalOutputBeforeValidation(r),this.validateOutput(r),this.latestOutput=r,this.onDidRebuildEmitter.emit(void 0),this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=ot(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutputBeforeValidation(e),this.validateOutput(e),this.latestOutput=e,this.onDidRebuildEmitter.emit(void 0),this.latestOutput}transformBaseDocumentAfterValidation(e){return e}transformContributionAfterValidation(e,r){return r}validateBaseDocument(e){}validateContribution(e,r){}validateOutput(e){}transformFinalOutputBeforeValidation(e){return e}}function W(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function Z(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function ot(t,e,r){const s=j(t);return e?de(s,j(e),r):s}function de(t,e,r){if(!e)return t;if(W(t,e)){const s=t,i=e;Object.keys(i).forEach(n=>{if(Object.hasOwn(s,n)){if(W(s[n],i[n]))s[n]=de(s[n],i[n],r);else if(Z(s[n],i[n]))s[n]=s[n].concat(i[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=i[n]})}else Z(t,e)&&t.push(...e);return t}class at extends pe{constructor(e,r){super(e,r)}get output(){return this.latestOutput}}class ut{constructor(e="Anonymous"){m(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,i)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${i} failed!`),s))}}class me extends Fe.Mutex{}class lt{constructor(){m(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new me,this.mutexesByID.set(e,r),r)}}var ct=Object.defineProperty,ft=(t,e,r)=>e in t?ct(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,l=(t,e,r)=>(ft(t,typeof e!="symbol"?e+"":e,r),r);const $=["GEN","EXO","LEV","NUM","DEU","JOS","JDG","RUT","1SA","2SA","1KI","2KI","1CH","2CH","EZR","NEH","EST","JOB","PSA","PRO","ECC","SNG","ISA","JER","LAM","EZK","DAN","HOS","JOL","AMO","OBA","JON","MIC","NAM","HAB","ZEP","HAG","ZEC","MAL","MAT","MRK","LUK","JHN","ACT","ROM","1CO","2CO","GAL","EPH","PHP","COL","1TH","2TH","1TI","2TI","TIT","PHM","HEB","JAS","1PE","2PE","1JN","2JN","3JN","JUD","REV","TOB","JDT","ESG","WIS","SIR","BAR","LJE","S3Y","SUS","BEL","1MA","2MA","3MA","4MA","1ES","2ES","MAN","PS2","ODA","PSS","JSA","JDB","TBS","SST","DNT","BLT","XXA","XXB","XXC","XXD","XXE","XXF","XXG","FRT","BAK","OTH","3ES","EZA","5EZ","6EZ","INT","CNC","GLO","TDX","NDX","DAG","PS3","2BA","LBA","JUB","ENO","1MQ","2MQ","3MQ","REP","4BA","LAO"],J=["XXA","XXB","XXC","XXD","XXE","XXF","XXG","FRT","BAK","OTH","INT","CNC","GLO","TDX","NDX"],ge=["Genesis","Exodus","Leviticus","Numbers","Deuteronomy","Joshua","Judges","Ruth","1 Samuel","2 Samuel","1 Kings","2 Kings","1 Chronicles","2 Chronicles","Ezra","Nehemiah","Esther (Hebrew)","Job","Psalms","Proverbs","Ecclesiastes","Song of Songs","Isaiah","Jeremiah","Lamentations","Ezekiel","Daniel (Hebrew)","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","Tobit","Judith","Esther Greek","Wisdom of Solomon","Sirach (Ecclesiasticus)","Baruch","Letter of Jeremiah","Song of 3 Young Men","Susanna","Bel and the Dragon","1 Maccabees","2 Maccabees","3 Maccabees","4 Maccabees","1 Esdras (Greek)","2 Esdras (Latin)","Prayer of Manasseh","Psalm 151","Odes","Psalms of Solomon","Joshua A. *obsolete*","Judges B. *obsolete*","Tobit S. *obsolete*","Susanna Th. *obsolete*","Daniel Th. *obsolete*","Bel Th. *obsolete*","Extra A","Extra B","Extra C","Extra D","Extra E","Extra F","Extra G","Front Matter","Back Matter","Other Matter","3 Ezra *obsolete*","Apocalypse of Ezra","5 Ezra (Latin Prologue)","6 Ezra (Latin Epilogue)","Introduction","Concordance ","Glossary ","Topical Index","Names Index","Daniel Greek","Psalms 152-155","2 Baruch (Apocalypse)","Letter of Baruch","Jubilees","Enoch","1 Meqabyan","2 Meqabyan","3 Meqabyan","Reproof (Proverbs 25-31)","4 Baruch (Rest of Baruch)","Laodiceans"],Q=Et();function A(t,e=!0){return e&&(t=t.toUpperCase()),t in Q?Q[t]:0}function G(t){return A(t)>0}function ht(t){const e=typeof t=="string"?A(t):t;return e>=40&&e<=66}function pt(t){return(typeof t=="string"?A(t):t)<=39}function be(t){return t<=66}function dt(t){const e=typeof t=="string"?A(t):t;return Ne(e)&&!be(e)}function*mt(){for(let t=1;t<=$.length;t++)yield t}const gt=1,ye=$.length;function bt(){return["XXA","XXB","XXC","XXD","XXE","XXF","XXG"]}function X(t,e="***"){const r=t-1;return r<0||r>=$.length?e:$[r]}function ve(t){return t<=0||t>ye?"******":ge[t-1]}function yt(t){return ve(A(t))}function Ne(t){const e=typeof t=="number"?X(t):t;return G(e)&&!J.includes(e)}function vt(t){const e=typeof t=="number"?X(t):t;return G(e)&&J.includes(e)}function Nt(t){return ge[t-1].includes("*obsolete*")}function Et(){const t={};for(let e=0;e<$.length;e++)t[$[e]]=e+1;return t}const E={allBookIds:$,nonCanonicalIds:J,bookIdToNumber:A,isBookIdValid:G,isBookNT:ht,isBookOT:pt,isBookOTNT:be,isBookDC:dt,allBookNumbers:mt,firstBook:gt,lastBook:ye,extraBooks:bt,bookNumberToId:X,bookNumberToEnglishName:ve,bookIdToEnglishName:yt,isCanonical:Ne,isExtraMaterial:vt,isObsolete:Nt};var w=(t=>(t[t.Unknown=0]="Unknown",t[t.Original=1]="Original",t[t.Septuagint=2]="Septuagint",t[t.Vulgate=3]="Vulgate",t[t.English=4]="English",t[t.RussianProtestant=5]="RussianProtestant",t[t.RussianOrthodox=6]="RussianOrthodox",t))(w||{});const N=class{constructor(e){if(l(this,"name"),l(this,"fullPath"),l(this,"isPresent"),l(this,"hasVerseSegments"),l(this,"isCustomized"),l(this,"baseVersification"),l(this,"scriptureBooks"),l(this,"_type"),e!=null)typeof e=="string"?this.name=e:this._type=e;else throw new Error("Argument null")}get type(){return this._type}equals(e){return!e.type||!this.type?!1:e.type===this.type}};l(N,"Original",new N(w.Original)),l(N,"Septuagint",new N(w.Septuagint)),l(N,"Vulgate",new N(w.Vulgate)),l(N,"English",new N(w.English)),l(N,"RussianProtestant",new N(w.RussianProtestant)),l(N,"RussianOrthodox",new N(w.RussianOrthodox));let C=N;function Y(t,e){const r=e[0];for(let s=1;s(t[t.Valid=0]="Valid",t[t.UnknownVersification=1]="UnknownVersification",t[t.OutOfRange=2]="OutOfRange",t[t.VerseOutOfOrder=3]="VerseOutOfOrder",t[t.VerseRepeated=4]="VerseRepeated",t))(Ee||{});const y=class f{constructor(e,r,s,i){if(l(this,"firstChapter"),l(this,"lastChapter"),l(this,"lastVerse"),l(this,"hasSegmentsDefined"),l(this,"text"),l(this,"BBBCCCVVVS"),l(this,"longHashCode"),l(this,"versification"),l(this,"rtlMark","‏"),l(this,"_bookNum",0),l(this,"_chapterNum",0),l(this,"_verseNum",0),l(this,"_verse"),s==null&&i==null)if(e!=null&&typeof e=="string"){const n=e,o=r!=null&&r instanceof C?r:void 0;this.setEmpty(o),this.parse(n)}else if(e!=null&&typeof e=="number"){const n=r!=null&&r instanceof C?r:void 0;this.setEmpty(n),this._verseNum=e%f.chapterDigitShifter,this._chapterNum=Math.floor(e%f.bookDigitShifter/f.chapterDigitShifter),this._bookNum=Math.floor(e/f.bookDigitShifter)}else if(r==null)if(e!=null&&e instanceof f){const n=e;this._bookNum=n.bookNum,this._chapterNum=n.chapterNum,this._verseNum=n.verseNum,this._verse=n.verse,this.versification=n.versification}else{if(e==null)return;const n=e instanceof C?e:f.defaultVersification;this.setEmpty(n)}else throw new Error("VerseRef constructor not supported.");else if(e!=null&&r!=null&&s!=null)if(typeof e=="string"&&typeof r=="string"&&typeof s=="string")this.setEmpty(i),this.updateInternal(e,r,s);else if(typeof e=="number"&&typeof r=="number"&&typeof s=="number")this._bookNum=e,this._chapterNum=r,this._verseNum=s,this.versification=i??f.defaultVersification;else throw new Error("VerseRef constructor not supported.");else throw new Error("VerseRef constructor not supported.")}static parse(e,r=f.defaultVersification){const s=new f(r);return s.parse(e),s}static isVerseParseable(e){return e.length>0&&"0123456789".includes(e[0])&&!e.endsWith(this.verseRangeSeparator)&&!e.endsWith(this.verseSequenceIndicator)}static tryParse(e){let r;try{return r=f.parse(e),{success:!0,verseRef:r}}catch(s){if(s instanceof M)return r=new f,{success:!1,verseRef:r};throw s}}static getBBBCCCVVV(e,r,s){return e%f.bcvMaxValue*f.bookDigitShifter+(r>=0?r%f.bcvMaxValue*f.chapterDigitShifter:0)+(s>=0?s%f.bcvMaxValue:0)}static tryGetVerseNum(e){let r;if(!e)return r=-1,{success:!0,vNum:r};r=0;let s;for(let i=0;i"9")return i===0&&(r=-1),{success:!1,vNum:r};if(r=r*10+ +s-+"0",r>f.bcvMaxValue)return r=-1,{success:!1,vNum:r}}return{success:!0,vNum:r}}get isDefault(){return this.bookNum===0&&this.chapterNum===0&&this.verseNum===0&&this.versification==null}get hasMultiple(){return this._verse!=null&&(this._verse.includes(f.verseRangeSeparator)||this._verse.includes(f.verseSequenceIndicator))}get book(){return E.bookNumberToId(this.bookNum,"")}set book(e){this.bookNum=E.bookIdToNumber(e)}get chapter(){return this.isDefault||this._chapterNum<0?"":this._chapterNum.toString()}set chapter(e){const r=+e;this._chapterNum=Number.isInteger(r)?r:-1}get verse(){return this._verse!=null?this._verse:this.isDefault||this._verseNum<0?"":this._verseNum.toString()}set verse(e){const{success:r,vNum:s}=f.tryGetVerseNum(e);this._verse=r?void 0:e.replace(this.rtlMark,""),this._verseNum=s,!(this._verseNum>=0)&&({vNum:this._verseNum}=f.tryGetVerseNum(this._verse))}get bookNum(){return this._bookNum}set bookNum(e){if(e<=0||e>E.lastBook)throw new M("BookNum must be greater than zero and less than or equal to last book");this._bookNum=e}get chapterNum(){return this._chapterNum}set chapterNum(e){this.chapterNum=e}get verseNum(){return this._verseNum}set verseNum(e){this._verseNum=e}get versificationStr(){var e;return(e=this.versification)==null?void 0:e.name}set versificationStr(e){this.versification=this.versification!=null?new C(e):void 0}get valid(){return this.validStatus===0}get validStatus(){return this.validateVerse(f.verseRangeSeparators,f.verseSequenceIndicators)}get BBBCCC(){return f.getBBBCCCVVV(this._bookNum,this._chapterNum,0)}get BBBCCCVVV(){return f.getBBBCCCVVV(this._bookNum,this._chapterNum,this._verseNum)}get isExcluded(){return!1}parse(e){if(e=e.replace(this.rtlMark,""),e.includes("/")){const n=e.split("/");if(e=n[0],n.length>1)try{const o=+n[1].trim();this.versification=new C(w[o])}catch{throw new M("Invalid reference : "+e)}}const r=e.trim().split(" ");if(r.length!==2)throw new M("Invalid reference : "+e);const s=r[1].split(":"),i=+s[0];if(s.length!==2||E.bookIdToNumber(r[0])===0||!Number.isInteger(i)||i<0||!f.isVerseParseable(s[1]))throw new M("Invalid reference : "+e);this.updateInternal(r[0],s[0],s[1])}simplify(){this._verse=void 0}clone(){return new f(this)}toString(){const e=this.book;return e===""?"":`${e} ${this.chapter}:${this.verse}`}equals(e){return e instanceof f?e._bookNum===this._bookNum&&e._chapterNum===this._chapterNum&&e._verseNum===this._verseNum&&e.verse===this.verse&&e.versification!=null&&this.versification!=null&&e.versification.equals(this.versification):!1}allVerses(e=!1,r=f.verseRangeSeparators,s=f.verseSequenceIndicators){if(this._verse==null||this.chapterNum<=0)return[this.clone()];const i=[],n=Y(this._verse,s);for(const o of n.map(a=>Y(a,r))){const a=this.clone();a.verse=o[0];const h=a.verseNum;if(i.push(a),o.length>1){const p=this.clone();if(p.verse=o[1],!e)for(let u=h+1;uo)return 3;if(s===o)return 4;s=o}return 0}get internalValid(){return this.versification==null?1:this._bookNum<=0||this._bookNum>E.lastBook?2:(E.isCanonical(this._bookNum),0)}setEmpty(e=f.defaultVersification){this._bookNum=0,this._chapterNum=-1,this._verse=void 0,this.versification=e}updateInternal(e,r,s){this.bookNum=E.bookIdToNumber(e),this.chapter=r,this.verse=s}};l(y,"defaultVersification",C.English),l(y,"verseRangeSeparator","-"),l(y,"verseSequenceIndicator",","),l(y,"verseRangeSeparators",[y.verseRangeSeparator]),l(y,"verseSequenceIndicators",[y.verseSequenceIndicator]),l(y,"chapterDigitShifter",1e3),l(y,"bookDigitShifter",y.chapterDigitShifter*y.chapterDigitShifter),l(y,"bcvMaxValue",y.chapterDigitShifter-1),l(y,"ValidStatusType",Ee);class M extends Error{}var ee=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},O={},wt=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",i="\\u1ab0-\\u1aff",n="\\u1dc0-\\u1dff",o=e+r+s+i+n,a="\\ufe0e\\ufe0f",h="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",p=`[${t}]`,u=`[${o}]`,c="\\ud83c[\\udffb-\\udfff]",d=`(?:${u}|${c})`,v=`[^${t}]`,b="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",T="[\\ud800-\\udbff][\\udc00-\\udfff]",V="\\u200d",Je="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",Ge=`[${h}]`,L=`${d}?`,F=`[${a}]?`,Xe=`(?:${V}(?:${[v,b,T].join("|")})${F+L})*`,Ke=F+L+Xe,He=`(?:${[`${v}${u}?`,u,b,T,p,Ge].join("|")})`;return new RegExp(`${Je}|${c}(?=${c})|${He+Ke}`,"g")},St=ee&&ee.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(O,"__esModule",{value:!0});var I=St(wt);function q(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(I.default())||[]}var $t=O.toArray=q;function K(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(I.default());return e===null?0:e.length}var Ot=O.length=K;function we(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(I.default());return s?s.slice(e,r).join(""):""}var Ct=O.substring=we;function jt(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=K(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var i;typeof r>"u"?i=s:(typeof r!="number"&&(r=parseInt(r,10)),i=r>=0?r+e:e);var n=t.match(I.default());return n?n.slice(e,i).join(""):""}var At=O.substr=jt;function Pt(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var i=K(t);if(i>e)return we(t,0,e);if(i=s.length)return e===""?s.length:-1;if(e==="")return r;var i=q(e),n=!1,o;for(o=r;og(t)||e<-g(t)))return x(t,e,1)}function Bt(t,e){return e<0||e>g(t)-1?"":x(t,e,1)}function Rt(t,e){if(!(e<0||e>g(t)-1))return x(t,e,1).codePointAt(0)}function It(t,e,r=g(t)){const s=Oe(t,e);return!(s===-1||s+g(e)!==r)}function $e(t,e,r=0){const s=B(t,r);return k(s,e)!==-1}function k(t,e,r=0){return Mt(t,e,r)}function Oe(t,e,r){let s=r===void 0?g(t):r;s<0?s=0:s>=g(t)&&(s=g(t)-1);for(let i=s;i>=0;i--)if(x(t,i,g(e))===e)return i;return-1}function g(t){return Ot(t)}function kt(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function xt(t,e,r=" "){return e<=g(t)?t:Se(t,e,r,"right")}function Vt(t,e,r=" "){return e<=g(t)?t:Se(t,e,r,"left")}function te(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function qt(t,e,r){const s=g(t);if(e>s||r&&(e>r&&!(e>=0&&e-s)||r<-s))return"";const i=te(s,e),n=r?te(s,r):void 0;return B(t,i,n)}function z(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return je(t).slice(0,r);let i=e;(typeof e=="string"||e instanceof RegExp&&!$e(e.flags,"g"))&&(i=new RegExp(e,"g"));const n=t.match(i);let o=0;if(!n)return[t];for(let a=0;a<(r?r-1:n.length);a++){const h=k(t,n[a],o),p=g(n[a]);if(s.push(B(t,o,h)),o=h+p,r!==void 0&&s.length===r)break}return s.push(B(t,o)),s}function Ce(t,e,r=0){return k(t,e,r)===r}function x(t,e=0,r=g(t)-e){return At(t,e,r)}function B(t,e,r=g(t)){return Ct(t,e,r)}function je(t){return $t(t)}const Ae=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],Pe=1,Te=Ae.length-1,Me=1,De=1,Be=t=>{var e;return((e=Ae[t])==null?void 0:e.chapters)??-1},zt=(t,e)=>({bookNum:Math.max(Pe,Math.min(t.bookNum+e,Te)),chapterNum:1,verseNum:1}),_t=(t,e)=>({...t,chapterNum:Math.min(Math.max(Me,t.chapterNum+e),Be(t.bookNum)),verseNum:1}),Jt=(t,e)=>({...t,verseNum:Math.max(De,t.verseNum+e)});async function Gt(t,e,r){const s=E.bookNumberToId(t);if(!Ce(Intl.getCanonicalLocales(e)[0],"zh"))return r({localizeKey:`LocalizedId.${s}`,languagesToSearch:[e]});const i=await r({localizeKey:`Book.${s}`,languagesToSearch:[e]}),n=z(i,"-");return z(n[0],"ÿ08")[0].trim()}const Xt=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),Kt=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var Ht=Object.getOwnPropertyNames,Ut=Object.getOwnPropertySymbols,Lt=Object.prototype.hasOwnProperty;function re(t,e){return function(s,i,n){return t(s,i,n)&&e(s,i,n)}}function R(t){return function(r,s,i){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,i);var n=i.cache,o=n.get(r),a=n.get(s);if(o&&a)return o===s&&a===r;n.set(r,s),n.set(s,r);var h=t(r,s,i);return n.delete(r),n.delete(s),h}}function se(t){return Ht(t).concat(Ut(t))}var Re=Object.hasOwn||function(t,e){return Lt.call(t,e)};function P(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var Ie="_owner",ie=Object.getOwnPropertyDescriptor,ne=Object.keys;function Ft(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function Wt(t,e){return P(t.getTime(),e.getTime())}function oe(t,e,r){if(t.size!==e.size)return!1;for(var s={},i=t.entries(),n=0,o,a;(o=i.next())&&!o.done;){for(var h=e.entries(),p=!1,u=0;(a=h.next())&&!a.done;){var c=o.value,d=c[0],v=c[1],b=a.value,T=b[0],V=b[1];!p&&!s[u]&&(p=r.equals(d,T,n,u,t,e,r)&&r.equals(v,V,d,T,t,e,r))&&(s[u]=!0),u++}if(!p)return!1;n++}return!0}function Zt(t,e,r){var s=ne(t),i=s.length;if(ne(e).length!==i)return!1;for(var n;i-- >0;)if(n=s[i],n===Ie&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!Re(e,n)||!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function D(t,e,r){var s=se(t),i=s.length;if(se(e).length!==i)return!1;for(var n,o,a;i-- >0;)if(n=s[i],n===Ie&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!Re(e,n)||!r.equals(t[n],e[n],n,n,t,e,r)||(o=ie(t,n),a=ie(e,n),(o||a)&&(!o||!a||o.configurable!==a.configurable||o.enumerable!==a.enumerable||o.writable!==a.writable)))return!1;return!0}function Qt(t,e){return P(t.valueOf(),e.valueOf())}function Yt(t,e){return t.source===e.source&&t.flags===e.flags}function ae(t,e,r){if(t.size!==e.size)return!1;for(var s={},i=t.values(),n,o;(n=i.next())&&!n.done;){for(var a=e.values(),h=!1,p=0;(o=a.next())&&!o.done;)!h&&!s[p]&&(h=r.equals(n.value,o.value,n.value,o.value,t,e,r))&&(s[p]=!0),p++;if(!h)return!1}return!0}function er(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var tr="[object Arguments]",rr="[object Boolean]",sr="[object Date]",ir="[object Map]",nr="[object Number]",or="[object Object]",ar="[object RegExp]",ur="[object Set]",lr="[object String]",cr=Array.isArray,ue=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,le=Object.assign,fr=Object.prototype.toString.call.bind(Object.prototype.toString);function hr(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,i=t.areObjectsEqual,n=t.arePrimitiveWrappersEqual,o=t.areRegExpsEqual,a=t.areSetsEqual,h=t.areTypedArraysEqual;return function(u,c,d){if(u===c)return!0;if(u==null||c==null||typeof u!="object"||typeof c!="object")return u!==u&&c!==c;var v=u.constructor;if(v!==c.constructor)return!1;if(v===Object)return i(u,c,d);if(cr(u))return e(u,c,d);if(ue!=null&&ue(u))return h(u,c,d);if(v===Date)return r(u,c,d);if(v===RegExp)return o(u,c,d);if(v===Map)return s(u,c,d);if(v===Set)return a(u,c,d);var b=fr(u);return b===sr?r(u,c,d):b===ar?o(u,c,d):b===ir?s(u,c,d):b===ur?a(u,c,d):b===or?typeof u.then!="function"&&typeof c.then!="function"&&i(u,c,d):b===tr?i(u,c,d):b===rr||b===nr||b===lr?n(u,c,d):!1}}function pr(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,i={areArraysEqual:s?D:Ft,areDatesEqual:Wt,areMapsEqual:s?re(oe,D):oe,areObjectsEqual:s?D:Zt,arePrimitiveWrappersEqual:Qt,areRegExpsEqual:Yt,areSetsEqual:s?re(ae,D):ae,areTypedArraysEqual:s?D:er};if(r&&(i=le({},i,r(i))),e){var n=R(i.areArraysEqual),o=R(i.areMapsEqual),a=R(i.areObjectsEqual),h=R(i.areSetsEqual);i=le({},i,{areArraysEqual:n,areMapsEqual:o,areObjectsEqual:a,areSetsEqual:h})}return i}function dr(t){return function(e,r,s,i,n,o,a){return t(e,r,a)}}function mr(t){var e=t.circular,r=t.comparator,s=t.createState,i=t.equals,n=t.strict;if(s)return function(h,p){var u=s(),c=u.cache,d=c===void 0?e?new WeakMap:void 0:c,v=u.meta;return r(h,p,{cache:d,equals:i,meta:v,strict:n})};if(e)return function(h,p){return r(h,p,{cache:new WeakMap,equals:i,meta:void 0,strict:n})};var o={cache:void 0,equals:i,meta:void 0,strict:n};return function(h,p){return r(h,p,o)}}var gr=S();S({strict:!0});S({circular:!0});S({circular:!0,strict:!0});S({createInternalComparator:function(){return P}});S({strict:!0,createInternalComparator:function(){return P}});S({circular:!0,createInternalComparator:function(){return P}});S({circular:!0,createInternalComparator:function(){return P},strict:!0});function S(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,i=t.createState,n=t.strict,o=n===void 0?!1:n,a=pr(t),h=hr(a),p=s?s(h):dr(h);return mr({circular:r,comparator:h,createState:i,equals:p,strict:o})}function br(t,e){return gr(t,e)}function _(t,e,r){return JSON.stringify(t,(i,n)=>{let o=n;return e&&(o=e(i,o)),o===void 0&&(o=null),o},r)}function ke(t,e){function r(i){return Object.keys(i).forEach(n=>{i[n]===null?i[n]=void 0:typeof i[n]=="object"&&(i[n]=r(i[n]))}),i}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function yr(t){try{const e=_(t);return e===_(ke(e))}catch{return!1}}const vr=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),H={projectSettingsContribution:{description:"The data an extension provides to inform Platform.Bible of the project settings it provides",anyOf:[{$ref:"#/$defs/projectSettingsGroup"},{type:"array",items:{$ref:"#/$defs/projectSettingsGroup"}}]},projectSettingsGroup:{description:"Group of related settings definitions",type:"object",properties:{label:{description:"localizeKey that displays in the project settings dialog as the group name",$ref:"#/$defs/localizeKey"},description:{description:"localizeKey that displays in the project settings dialog to describe the group",$ref:"#/$defs/localizeKey"},properties:{$ref:"#/$defs/projectSettingProperties"}},required:["label","properties"]},projectSettingProperties:{description:"Object whose keys are setting IDs and whose values are settings objects",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/projectSetting"}},additionalProperties:!1},projectSetting:{description:"A description of an extension's setting entry",anyOf:[{$ref:"#/$defs/extensionControlledProjectSetting"}]},extensionControlledProjectSetting:{description:"Setting definition that is validated by the extension.",allOf:[{$ref:"#/$defs/projectSettingBase"},{$ref:"#/$defs/modifierExtensionControlled"}]},projectSettingBase:{description:"Base information needed to describe a project setting entry",allOf:[{$ref:"#/$defs/settingBase"},{$ref:"#/$defs/modifierProject"}]},modifierProject:{description:"Modifies setting type to be project setting",type:"object",properties:{includeProjectTypes:{description:"`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog",anyOf:[{type:"null"},{type:"string"},{type:"array",items:{type:"string"}}]},excludeProjectTypes:{description:"`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`",anyOf:[{type:"null"},{type:"string"},{type:"array",items:{type:"string"}}]}}},settingsContribution:{description:"The data an extension provides to inform Platform.Bible of the settings it provides",anyOf:[{$ref:"#/$defs/settingsGroup"},{type:"array",items:{$ref:"#/$defs/settingsGroup"}}]},settingsGroup:{description:"Group of related settings definitions",type:"object",properties:{label:{description:"localizeKey that displays in the settings dialog as the group name",$ref:"#/$defs/localizeKey"},description:{description:"localizeKey that displays in the settings dialog to describe the group",$ref:"#/$defs/localizeKey"},properties:{$ref:"#/$defs/settingProperties"}},required:["label","properties"]},settingProperties:{description:"Object whose keys are setting IDs and whose values are settings objects",type:"object",patternProperties:{"^[\\w-]+\\.[\\w-]+$":{$ref:"#/$defs/setting"}},additionalProperties:!1},setting:{description:"A description of an extension's setting entry",anyOf:[{$ref:"#/$defs/extensionControlledSetting"}]},extensionControlledSetting:{description:"Setting definition that is validated by the extension.",allOf:[{$ref:"#/$defs/settingBase"},{$ref:"#/$defs/modifierExtensionControlled"}]},settingBase:{description:"Base information needed to describe a setting entry",allOf:[{$ref:"#/$defs/stateBase"},{type:"object",properties:{label:{description:"localizeKey that displays in the settings dialog as the setting name",$ref:"#/$defs/localizeKey"},description:{description:"localizeKey that displays in the settings dialog to describe the setting",$ref:"#/$defs/localizeKey"}},required:["label"]}]},projectStateContribution:{description:"The data an extension provides to inform Platform.Bible of the project state it provides",$ref:"#/$defs/userStateProperties"},userStateContribution:{description:"The data an extension provides to inform Platform.Bible of the user state it provides",$ref:"#/$defs/userStateProperties"},userStateProperties:{description:"Object whose keys are state IDs and whose values are state objects",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/userState"}},additionalProperties:!1},userState:{description:"A description of an extension's user state entry",anyOf:[{$ref:"#/$defs/extensionControlledState"}]},extensionControlledState:{description:"State definition that is validated by the extension.",allOf:[{$ref:"#/$defs/stateBase"},{$ref:"#/$defs/modifierExtensionControlled"}]},modifierExtensionControlled:{description:'Modifies state/setting type to be extension-controlled. "Extension-controlled" means the extension provides the component and the validator for the state/setting, so the state/setting is controlled by the extension.',not:{anyOf:[{type:"object",required:["platformType"]},{type:"object",required:["type"]}]}},stateBase:{description:"Base information needed to describe a state entry",type:"object",properties:{default:{description:"default value for the state/setting",type:"any"},derivesFrom:{description:"a state/setting ID whose value to set to this state/setting's starting value the first time this state/setting is loaded",$ref:"#/$defs/id"}},required:["default"]},localizeKey:{description:"Identifier for a string that will be localized based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$",tsType:"LocalizeKey"},id:{description:"",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$",tsType:"Id"}};function U(t){t&&Object.values(t).forEach(e=>{if(e.type){if("tsType"in e&&delete e.tsType,e.type==="any"){delete e.type;return}e.type==="object"&&U(e.properties)}})}U(H);const xe={$schema:"https://json-schema.org/draft/2020-12/schema",title:"Project Settings Contribution",description:"The data an extension provides to inform Platform.Bible of the project settings it provides",anyOf:[{$ref:"#/$defs/projectSettingsGroup"},{type:"array",items:{$ref:"#/$defs/projectSettingsGroup"}}],$defs:H};Object.freeze(xe);const Ve={$schema:"https://json-schema.org/draft/2020-12/schema",title:"Settings Contribution",description:"The data an extension provides to inform Platform.Bible of the settings it provides",anyOf:[{$ref:"#/$defs/settingsGroup"},{type:"array",items:{$ref:"#/$defs/settingsGroup"}}],$defs:H};Object.freeze(Ve);const qe={languageStrings:{description:"Map whose keys are localized string keys and whose values provide information about how to localize strings for the localized string key",type:"object",patternProperties:{"^%[\\w\\-\\.]+%$":{$ref:"#/$defs/localizedStringValue"}},additionalProperties:!1},localizedStringValue:{description:"Localized string value associated with this key",type:"string"},stringsMetadata:{description:"Map whose keys are localized string keys and whose values provide additional non-locale-specific information about the localized string key",type:"object",patternProperties:{"^%[\\w\\-\\.]+%$":{$ref:"#/$defs/stringMetadata"}},additionalProperties:!1},stringMetadata:{description:"Additional non-locale-specific information about a localized string key",type:"object",properties:{fallbackKey:{description:"Localized string key from which to get this value if one does not exist in the specified language. If a new key/value pair needs to be made to replace an existing one, this could help smooth over the transition if the meanings are close enough",$ref:"#/$defs/localizeKey"},notes:{description:"Additional information provided by developers in English to help the translator to know how to translate this localized string accurately",type:"string"}}},localizeKey:{description:"Identifier for a string that will be localized based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$",tsType:"LocalizeKey"}};U(qe);const ze={$schema:"https://json-schema.org/draft/2020-12/schema",title:"Localized String Data Contribution",description:"The data an extension provides to inform Platform.Bible of the localized strings it provides.",type:"object",properties:{metadata:{$ref:"#/$defs/stringsMetadata"},localizedStrings:{type:"object",additionalProperties:{$ref:"#/$defs/languageStrings"}}},$defs:qe};Object.freeze(ze);const _e={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(_e);exports.AsyncVariable=We;exports.DocumentCombiner=pe;exports.FIRST_SCR_BOOK_NUM=Pe;exports.FIRST_SCR_CHAPTER_NUM=Me;exports.FIRST_SCR_VERSE_NUM=De;exports.LAST_SCR_BOOK_NUM=Te;exports.Mutex=me;exports.MutexMap=lt;exports.NonValidatingDocumentCombiner=at;exports.PlatformEventEmitter=ce;exports.UnsubscriberAsyncList=ut;exports.aggregateUnsubscriberAsyncs=Kt;exports.aggregateUnsubscribers=Xt;exports.at=Dt;exports.charAt=Bt;exports.codePointAt=Rt;exports.createSyncProxyForAsyncObject=nt;exports.debounce=Qe;exports.deepClone=j;exports.deepEqual=br;exports.deserialize=ke;exports.endsWith=It;exports.getAllObjectFunctionNames=it;exports.getChaptersForBook=Be;exports.getErrorMessage=rt;exports.getLocalizedIdFromBookNumber=Gt;exports.groupBy=Ye;exports.htmlEncode=vr;exports.includes=$e;exports.indexOf=k;exports.isSerializable=yr;exports.isString=fe;exports.lastIndexOf=Oe;exports.localizedStringsDocumentSchema=ze;exports.menuDocumentSchema=_e;exports.newGuid=Ze;exports.normalize=kt;exports.offsetBook=zt;exports.offsetChapter=_t;exports.offsetVerse=Jt;exports.padEnd=xt;exports.padStart=Vt;exports.projectSettingsDocumentSchema=xe;exports.serialize=_;exports.settingsDocumentSchema=Ve;exports.slice=qt;exports.split=z;exports.startsWith=Ce;exports.stringLength=g;exports.substring=B;exports.toArray=je;exports.wait=he;exports.waitForDuration=st; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index 032827ab6e..e52fc48ca9 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/platform-event-emitter.model.ts","../src/util.ts","../src/document-combiner.ts","../src/non-validating-document-combiner.ts","../src/unsubscriber-async-list.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../../../node_modules/char-regex/index.js","../../../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts","../src/settings.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n\n/** Within type T, recursively change all properties to be optional */\nexport type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;\n\n/** Within type T, recursively change properties that were of type A to be of type B */\nexport type ReplaceType = T extends A\n ? B\n : T extends object\n ? { [K in keyof T]: ReplaceType }\n : T;\n","import PlatformEventEmitter from './platform-event-emitter.model';\nimport { deepClone } from './util';\n\ntype JsonObjectLike = { [key: string]: unknown };\ntype JsonArrayLike = unknown[];\n\nexport type JsonDocumentLike = JsonObjectLike | JsonArrayLike;\n\n/**\n * Options for DocumentCombiner objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (primarily in the form of JS objects\n * or arrays) together into a single output document.\n */\nexport default class DocumentCombiner {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n private readonly onDidRebuildEmitter = new PlatformEventEmitter();\n /** Event that emits to announce that the document has been rebuilt and the output has been updated */\n // Need `onDidRebuildEmitter` to be instantiated before this line\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly onDidRebuild = this.onDidRebuildEmitter.subscribe;\n\n /**\n * Create a DocumentCombiner instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateBaseDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n this.baseDocument = this.transformBaseDocumentAfterValidation(this.baseDocument);\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * Note: the order in which contribution documents are added can be considered to be indeterminate\n * as it is currently ordered by however `Map.forEach` provides the contributions. The order\n * matters when merging two arrays into one. Also, when `options.ignoreDuplicateProperties` is\n * `true`, the order also matters when adding the same property to an object that is already\n * provided previously. Please let us know if you have trouble because of indeterminate\n * contribution ordering.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n let documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n documentToSet = this.transformContributionAfterValidation(documentName, documentToSet);\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): JsonDocumentLike | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`${documentName} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete all present contribution documents for the composition process and return to the base\n * document\n *\n * @returns Recalculated output document consisting only of the base document\n */\n deleteAllContributions(): JsonDocumentLike | undefined {\n if (this.contributions.size <= 0) return this.latestOutput;\n\n // Save out all contributions\n const contributions = [...this.contributions.entries()];\n\n // Delete all contributions\n contributions.forEach(([contributionName]) => this.contributions.delete(contributionName));\n\n // Rebuild with no contributions\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting all contributions, put them back and rethrow\n contributions.forEach(([contributionName, document]) =>\n this.contributions.set(contributionName, document),\n );\n throw new Error(`Error when deleting all contributions: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutputBeforeValidation(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutputBeforeValidation(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n /**\n * Transform the starting document that is given to the combiner. This transformation occurs after\n * validating the base document and before combining any contributions.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the `baseDocument` passed in.\n *\n * @param baseDocument Initial input document. Already validated via `validateBaseDocument`\n * @returns Transformed base document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformBaseDocumentAfterValidation(baseDocument: JsonDocumentLike): JsonDocumentLike {\n return baseDocument;\n }\n\n /**\n * Transform the contributed document associated with `documentName`. This transformation occurs\n * after validating the contributed document and before combining with other documents.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the contributed `document` passed in.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine. Already validated via\n * `validateContribution`\n * @returns Transformed contributed document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformContributionAfterValidation(\n // @ts-expect-error this parameter is unused but may be used in child classes\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike {\n return document;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateBaseDocument(baseDocument: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateContribution(documentName: string, document: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateOutput(output: JsonDocumentLike): void {}\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation via `validateOutput`\n * before `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n // no-op intended to be overridden by child classes. Can't be static\n // eslint-disable-next-line class-methods-use-this\n protected transformFinalOutputBeforeValidation(finalOutput: JsonDocumentLike): JsonDocumentLike {\n return finalOutput;\n }\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Deep clone and recursively merge the properties of one object (copyFrom) into another\n * (startingPoint). Throws if copyFrom would overwrite values already existing in startingPoint.\n *\n * Does not modify the objects passed in.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n\n if (!copyFrom) return retVal;\n\n return mergeObjectsInternal(retVal, deepClone(copyFrom), ignoreDuplicateProperties);\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * WARNING: Modifies the argument objects in some way. Recommended to use `mergeObjects`\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjectsInternal(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n if (!copyFrom) return startingPoint;\n\n if (areNonArrayObjects(startingPoint, copyFrom)) {\n // Merge properties since they are both objects\n\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n const startingPointObj = startingPoint as JsonObjectLike;\n const copyFromObj = copyFrom as JsonObjectLike;\n /* eslint-enable no-type-assertion/no-type-assertion */\n Object.keys(copyFromObj).forEach((key: string | number) => {\n if (Object.hasOwn(startingPointObj, key)) {\n if (areNonArrayObjects(startingPointObj[key], copyFromObj[key])) {\n startingPointObj[key] = mergeObjectsInternal(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] as JsonObjectLike,\n copyFromObj[key] as JsonObjectLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPointObj[key], copyFromObj[key])) {\n // Concat the arrays since they are both arrays\n\n // We know these are arrays from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] = (startingPointObj[key] as JsonArrayLike).concat(\n copyFromObj[key] as JsonArrayLike,\n );\n /* eslint-enable no-type-assertion/no-type-assertion */\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n // Note that the first non-object non-array value that gets placed in a property stays.\n // New values do not override existing ones\n } else {\n startingPointObj[key] = copyFromObj[key];\n }\n });\n } else if (areArrayObjects(startingPoint, copyFrom)) {\n // Concat the arrays since they are both arrays\n\n // Push the contents of copyFrom into startingPoint since it is a const and was already deep cloned\n // We know these are objects from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n (startingPoint as JsonArrayLike).push(...(copyFrom as JsonArrayLike));\n /* eslint-enable no-type-assertion/no-type-assertion */\n }\n\n // Note that nothing happens if `startingPoint` is not an object or an array or if `startingPoint`\n // and `copyFrom` are not both object or both arrays. Should we throw? Should we push `copyFrom`'s\n // values into the array? Other? Maybe one day we can add some options to decide what to do in\n // this situation, but YAGNI for now\n\n return startingPoint;\n}\n\n// #endregion\n","import DocumentCombiner, { DocumentCombinerOptions, JsonDocumentLike } from './document-combiner';\n\nexport default class NonValidatingDocumentCombiner extends DocumentCombiner {\n // Making the protected base constructor public\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n super(baseDocument, options);\n }\n\n get output(): JsonDocumentLike | undefined {\n return this.latestOutput;\n }\n}\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * This function mirrors the `at` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Finds the Unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified offset,\n * undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > stringLength(string) || index < -stringLength(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `charAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a new string consisting of the single unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified offset, empty\n * string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > stringLength(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the character at the given\n * index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > stringLength(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * This function mirrors the `endsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether a string ends with the characters of this string.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be found. Default is\n * `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = stringLength(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * This function mirrors the `includes` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Performs a case-sensitive search to determine if searchString is found in string.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString. Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * This function mirrors the `indexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the index of the first occurrence of a given string.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Searches this string and returns the index of the last occurrence of the specified substring.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(string: string, searchString: string, position?: number): number {\n let validatedPosition = position === undefined ? stringLength(string) : position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= stringLength(string)) {\n validatedPosition = stringLength(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, stringLength(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * This function mirrors the `length` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes. Since `length` appears to be a\n * reserved keyword, the function was renamed to `stringLength`\n *\n * Returns the length of a string.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function stringLength(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * This function mirrors the `normalize` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * This function mirrors the `padEnd` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * This function mirrors the `padStart` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\n// This is a helper function that performs a correction on the slice index to make sure it\n// cannot go out of bounds\nfunction correctSliceIndex(length: number, index: number) {\n if (index > length) return length;\n if (index < -length) return 0;\n if (index < 0) return index + length;\n return index;\n}\n\n/**\n * This function mirrors the `slice` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const length: number = stringLength(string);\n if (\n indexStart > length ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(indexStart >= 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) ||\n indexEnd < -length))\n )\n return '';\n\n const newStart = correctSliceIndex(length, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * This function mirrors the `split` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits the\n * string at each occurrence of specified separator, but stops when limit entries have been placed\n * in the array.\n * @returns An array of strings, split at each point where separator occurs in the starting string.\n * Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = stringLength(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * This function mirrors the `startsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found (the index of\n * searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string, including when\n * searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * This function mirrors the `substr` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and length. This function is not exported because it is\n * considered deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String length minus start parameter`. Default is `String\n * length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(\n string: string,\n begin: number = 0,\n len: number = stringLength(string) - begin,\n): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * This function mirrors the `substring` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and end position.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = stringLength(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * This function mirrors the `toArray` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Converts a string to an array of string characters.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { ReplaceType } from './util';\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single context menu/submenu.\n * Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInSingleColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: OrderedExtensibleContainer | MenuGroupDetailsInSubMenu;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu within a\n * multi-column menu. Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInMultiColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: GroupsInSingleColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n /** Groups that belong in this menu */\n groups: GroupsInMultiColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus before they are localized */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n/**\n * Type that converts any menu type before it is localized to what it is after it is localized. This\n * can be applied to any menu type as needed.\n */\nexport type Localized = ReplaceType, ReferencedItem, string>;\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { LocalizeKey, ReferencedItem } from 'menus.model';\n\n/** The data an extension provides to inform Platform.Bible of the settings it provides */\nexport type SettingsContribution = SettingsGroup | SettingsGroup[];\n/** A description of an extension's setting entry */\nexport type Setting = ExtensionControlledSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledSetting = SettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a setting entry */\nexport type SettingBase = StateBase & {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the setting name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the setting */\n description?: LocalizeKey;\n};\n/** The data an extension provides to inform Platform.Bible of the project settings it provides */\nexport type ProjectSettingsContribution = ProjectSettingsGroup | ProjectSettingsGroup[];\n/** A description of an extension's setting entry */\nexport type ProjectSetting = ExtensionControlledProjectSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledProjectSetting = ProjectSettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a project setting entry */\nexport type ProjectSettingBase = SettingBase & ModifierProject;\n/** A description of an extension's user state entry */\nexport type UserState = ExtensionControlledState;\n/** State definition that is validated by the extension. */\nexport type ExtensionControlledState = StateBase & ModifierExtensionControlled;\n/** Group of related settings definitions */\nexport interface SettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the group */\n description?: LocalizeKey;\n properties: SettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface SettingProperties {\n [k: ReferencedItem]: Setting;\n}\n/** Base information needed to describe a state entry */\nexport interface StateBase {\n [k: string]: unknown;\n /** Default value for the state/setting */\n default: unknown;\n /**\n * A state/setting ID whose value to set to this state/setting's starting value the first time\n * this state/setting is loaded\n */\n derivesFrom?: ReferencedItem;\n}\n/**\n * Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the\n * extension provides the component and the validator for the state/setting, so the state/setting is\n * controlled by the extension.\n */\nexport interface ModifierExtensionControlled {\n [k: string]: unknown;\n platformType?: undefined;\n type?: undefined;\n}\n/** Group of related settings definitions */\nexport interface ProjectSettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the project settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the project settings dialog to describe the group */\n description?: LocalizeKey;\n properties: ProjectSettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface ProjectSettingProperties {\n [k: ReferencedItem]: ProjectSetting;\n}\n/** Modifies setting type to be project setting */\nexport interface ModifierProject {\n [k: string]: unknown;\n /**\n * `RegExp` pattern(s) to match against `projectType` (using the\n * [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)\n * function) to determine whether this project setting should be displayed in the Project Settings\n * Dialog of that `projectType`. null means do not show on any Project Settings dialog\n */\n includeProjectTypes?: undefined | string | string[];\n /**\n * `RegExp` pattern to match against `projectType` to determine if this project setting should\n * absolutely not be displayed in the Project Settings dialog of that `projectType` even if it\n * matches with `includeProjectTypes`\n */\n excludeProjectTypes?: undefined | string | string[];\n}\n/** The data an extension provides to inform Platform.Bible of the user state it provides */\nexport interface UserStateContribution {\n [k: ReferencedItem]: UserState;\n}\n/** The data an extension provides to inform Platform.Bible of the project state it provides */\nexport interface ProjectStateContribution {\n [k: ReferencedItem]: UserState;\n}\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\nconst settingsDefs = {\n projectSettingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n },\n projectSettingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the project settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description:\n 'localizeKey that displays in the project settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/projectSettingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n projectSettingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/projectSetting',\n },\n },\n additionalProperties: false,\n },\n projectSetting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledProjectSetting',\n },\n ],\n },\n extensionControlledProjectSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/projectSettingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n projectSettingBase: {\n description: 'Base information needed to describe a project setting entry',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierProject',\n },\n ],\n },\n modifierProject: {\n description: 'Modifies setting type to be project setting',\n type: 'object',\n properties: {\n includeProjectTypes: {\n description:\n '`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n excludeProjectTypes: {\n description:\n '`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n },\n },\n settingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n },\n settingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/settingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n settingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w-]+\\\\.[\\\\w-]+$': {\n $ref: '#/$defs/setting',\n },\n },\n additionalProperties: false,\n },\n setting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledSetting',\n },\n ],\n },\n extensionControlledSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n settingBase: {\n description: 'Base information needed to describe a setting entry',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the setting name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the setting',\n $ref: '#/$defs/localizeKey',\n },\n },\n required: ['label'],\n },\n ],\n },\n projectStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the user state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateProperties: {\n description: 'Object whose keys are state IDs and whose values are state objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/userState',\n },\n },\n additionalProperties: false,\n },\n userState: {\n description: \"A description of an extension's user state entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledState',\n },\n ],\n },\n extensionControlledState: {\n description: 'State definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n modifierExtensionControlled: {\n description:\n 'Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the extension provides the component and the validator for the state/setting, so the state/setting is controlled by the extension.',\n not: {\n anyOf: [\n {\n type: 'object',\n required: ['platformType'],\n },\n {\n type: 'object',\n required: ['type'],\n },\n ],\n },\n },\n stateBase: {\n description: 'Base information needed to describe a state entry',\n type: 'object',\n properties: {\n default: {\n description: 'default value for the state/setting',\n type: 'any',\n },\n derivesFrom: {\n description:\n \"a state/setting ID whose value to set to this state/setting's starting value the first time this state/setting is loaded\",\n $ref: '#/$defs/id',\n },\n },\n required: ['default'],\n },\n localizeKey: {\n description: \"Identifier for a string that will be localized based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n tsType: 'LocalizeKey',\n },\n id: {\n description: '',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n tsType: 'Id',\n },\n};\n\n/**\n * Json-schema-to-typescript has some added stuff that isn't actually compatible with JSON schema,\n * so we remove them here\n *\n * @param defs The `$defs` property of a JSON schema (will be modified in place)\n */\n// JSON schema types are weird, so we'll just be careful\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction removeJsonToTypeScriptTypesStuff(defs: any) {\n if (!defs) return;\n\n // JSON schema types are weird, so we'll just be careful\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.values(defs).forEach((def: any) => {\n if (!def.type) return;\n\n if ('tsType' in def) delete def.tsType;\n\n if (def.type === 'any') {\n delete def.type;\n return;\n }\n\n if (def.type === 'object') {\n removeJsonToTypeScriptTypesStuff(def.properties);\n }\n });\n}\n\nremoveJsonToTypeScriptTypesStuff(settingsDefs);\n\n/** JSON schema object that aligns with the ProjectSettingsContribution type */\nexport const projectSettingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Project Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(projectSettingsDocumentSchema);\n\n/** JSON schema object that aligns with the {@link SettingsContribution} type */\nexport const settingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(settingsDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","PlatformEventEmitter","event","callback","callbackIndex","_a","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombiner","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","contributions","contributionName","potentialOutput","outputIteration","contribution","mergeObjects","output","finalOutput","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","mergeObjectsInternal","startingPointObj","copyFromObj","NonValidatingDocumentCombiner","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","stringLength","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema","settingsDefs","removeJsonToTypeScriptTypesStuff","defs","def","projectSettingsDocumentSchema","settingsDocumentSchema"],"mappings":"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B,QAAQ,KAAM,MAAM,EACpB,QAAQ,KAAM,QAAQ,EACtB,QAAQ,KAAM,QAAQ,EACtB,QAAQ,MAAO,QAAQ,EC8BfqK,GAAqB,CAChC,MAAO,uBACP,KAAM,SACN,WAAY,CACV,SAAU,CACR,YAAa,qCACb,KAAM,yBACR,EACA,sBAAuB,CACrB,YAAa,8DACb,KAAM,yBACR,EACA,0BAA2B,CACzB,YAAa,kEACb,KAAM,0BACR,EACA,aAAc,CACZ,YAAa,mDACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,4BACR,CACF,EACA,qBAAsB,EACxB,CACF,EACA,SAAU,CAAC,WAAY,wBAAyB,4BAA6B,cAAc,EAC3F,qBAAsB,GACtB,MAAO,CACL,YAAa,CACX,YACE,2FACF,KAAM,SACN,QAAS,kBACX,EACA,eAAgB,CACd,YACE,oGACF,KAAM,SACN,QAAS,yBACX,EACA,mBAAoB,CAClB,YACE,uFACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,qCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6CACb,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YACE,6EACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,8EACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,QAAS,OAAO,EAC3B,qBAAsB,EACxB,CACF,EACA,WAAY,CACV,aAAc,CACZ,YACE,qFACF,KAAM,SACR,CACF,CACF,EACA,WAAY,CACV,YACE,uJACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,wCACb,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB,ECrThC,MAAMC,EAAe,CACnB,4BAA6B,CAC3B,YACE,8FACF,MAAO,CACL,CACE,KAAM,8BACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,8BACR,CACF,CACF,CACF,EACA,qBAAsB,CACpB,YAAa,wCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6EACb,KAAM,qBACR,EACA,YAAa,CACX,YACE,iFACF,KAAM,qBACR,EACA,WAAY,CACV,KAAM,kCACR,CACF,EACA,SAAU,CAAC,QAAS,YAAY,CAClC,EACA,yBAA0B,CACxB,YAAa,0EACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,wBACR,CACF,EACA,qBAAsB,EACxB,EACA,eAAgB,CACd,YAAa,gDACb,MAAO,CACL,CACE,KAAM,2CACR,CACF,CACF,EACA,kCAAmC,CACjC,YAAa,yDACb,MAAO,CACL,CACE,KAAM,4BACR,EACA,CACE,KAAM,qCACR,CACF,CACF,EACA,mBAAoB,CAClB,YAAa,8DACb,MAAO,CACL,CACE,KAAM,qBACR,EACA,CACE,KAAM,yBACR,CACF,CACF,EACA,gBAAiB,CACf,YAAa,8CACb,KAAM,SACN,WAAY,CACV,oBAAqB,CACnB,YACE,2VACF,MAAO,CACL,CACE,KAAM,MACR,EACA,CACE,KAAM,QACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,QACR,CACF,CACF,CACF,EACA,oBAAqB,CACnB,YACE,6NACF,MAAO,CACL,CACE,KAAM,MACR,EACA,CACE,KAAM,QACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,QACR,CACF,CACF,CACF,CACF,CACF,EACA,qBAAsB,CACpB,YACE,sFACF,MAAO,CACL,CACE,KAAM,uBACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,uBACR,CACF,CACF,CACF,EACA,cAAe,CACb,YAAa,wCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,qEACb,KAAM,qBACR,EACA,YAAa,CACX,YAAa,yEACb,KAAM,qBACR,EACA,WAAY,CACV,KAAM,2BACR,CACF,EACA,SAAU,CAAC,QAAS,YAAY,CAClC,EACA,kBAAmB,CACjB,YAAa,0EACb,KAAM,SACN,kBAAmB,CACjB,sBAAuB,CACrB,KAAM,iBACR,CACF,EACA,qBAAsB,EACxB,EACA,QAAS,CACP,YAAa,gDACb,MAAO,CACL,CACE,KAAM,oCACR,CACF,CACF,EACA,2BAA4B,CAC1B,YAAa,yDACb,MAAO,CACL,CACE,KAAM,qBACR,EACA,CACE,KAAM,qCACR,CACF,CACF,EACA,YAAa,CACX,YAAa,sDACb,MAAO,CACL,CACE,KAAM,mBACR,EACA,CACE,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,uEACb,KAAM,qBACR,EACA,YAAa,CACX,YAAa,2EACb,KAAM,qBACR,CACF,EACA,SAAU,CAAC,OAAO,CACpB,CACF,CACF,EACA,yBAA0B,CACxB,YACE,2FACF,KAAM,6BACR,EACA,sBAAuB,CACrB,YACE,wFACF,KAAM,6BACR,EACA,oBAAqB,CACnB,YAAa,qEACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,mBACR,CACF,EACA,qBAAsB,EACxB,EACA,UAAW,CACT,YAAa,mDACb,MAAO,CACL,CACE,KAAM,kCACR,CACF,CACF,EACA,yBAA0B,CACxB,YAAa,uDACb,MAAO,CACL,CACE,KAAM,mBACR,EACA,CACE,KAAM,qCACR,CACF,CACF,EACA,4BAA6B,CAC3B,YACE,0NACF,IAAK,CACH,MAAO,CACL,CACE,KAAM,SACN,SAAU,CAAC,cAAc,CAC3B,EACA,CACE,KAAM,SACN,SAAU,CAAC,MAAM,CACnB,CACF,CACF,CACF,EACA,UAAW,CACT,YAAa,oDACb,KAAM,SACN,WAAY,CACV,QAAS,CACP,YAAa,sCACb,KAAM,KACR,EACA,YAAa,CACX,YACE,2HACF,KAAM,YACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,EACA,YAAa,CACX,YAAa,iFACb,KAAM,SACN,QAAS,mBACT,OAAQ,aACV,EACA,GAAI,CACF,YAAa,GACb,KAAM,SACN,QAAS,0BACT,OAAQ,IACV,CACF,EAUA,SAASC,GAAiCC,EAAW,CAC9CA,GAIL,OAAO,OAAOA,CAAI,EAAE,QAASC,GAAa,CACxC,GAAKA,EAAI,KAIL,IAFA,WAAYA,GAAK,OAAOA,EAAI,OAE5BA,EAAI,OAAS,MAAO,CACtB,OAAOA,EAAI,KACX,MACF,CAEIA,EAAI,OAAS,UACfF,GAAiCE,EAAI,UAAU,EACjD,CACD,CACH,CAEAF,GAAiCD,CAAY,EAGtC,MAAMI,GAAgC,CAC3C,QAAS,+CACT,MAAO,gCACP,YACE,8FACF,MAAO,CACL,CACE,KAAM,8BACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,8BACR,CACF,CACF,EAEA,MAAOJ,CACT,EAEA,OAAO,OAAOI,EAA6B,EAGpC,MAAMC,GAAyB,CACpC,QAAS,+CACT,MAAO,wBACP,YACE,sFACF,MAAO,CACL,CACE,KAAM,uBACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,uBACR,CACF,CACF,EAEA,MAAOL,CACT,EAEA,OAAO,OAAOK,EAAsB","x_google_ignoreList":[10,11,13]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/platform-event-emitter.model.ts","../src/util.ts","../src/document-combiner.ts","../src/non-validating-document-combiner.ts","../src/unsubscriber-async-list.ts","../src/mutex.ts","../src/mutex-map.ts","../../../node_modules/@sillsdev/scripture/dist/index.es.js","../../../node_modules/char-regex/index.js","../../../node_modules/stringz/dist/index.js","../src/string-util.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/settings.model.ts","../src/localized-strings.model.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n\n/** Within type T, recursively change all properties to be optional */\nexport type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;\n\n/** Within type T, recursively change properties that were of type A to be of type B */\nexport type ReplaceType = T extends A\n ? B\n : T extends object\n ? { [K in keyof T]: ReplaceType }\n : T;\n","import PlatformEventEmitter from './platform-event-emitter.model';\nimport { deepClone } from './util';\n\ntype JsonObjectLike = { [key: string]: unknown };\ntype JsonArrayLike = unknown[];\n\nexport type JsonDocumentLike = JsonObjectLike | JsonArrayLike;\n\n/**\n * Options for DocumentCombiner objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (primarily in the form of JS objects\n * or arrays) together into a single output document.\n */\nexport default class DocumentCombiner {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n private readonly onDidRebuildEmitter = new PlatformEventEmitter();\n /** Event that emits to announce that the document has been rebuilt and the output has been updated */\n // Need `onDidRebuildEmitter` to be instantiated before this line\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly onDidRebuild = this.onDidRebuildEmitter.subscribe;\n\n /**\n * Create a DocumentCombiner instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateBaseDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n this.baseDocument = this.transformBaseDocumentAfterValidation(this.baseDocument);\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * Note: the order in which contribution documents are added can be considered to be indeterminate\n * as it is currently ordered by however `Map.forEach` provides the contributions. The order\n * matters when merging two arrays into one. Also, when `options.ignoreDuplicateProperties` is\n * `true`, the order also matters when adding the same property to an object that is already\n * provided previously. Please let us know if you have trouble because of indeterminate\n * contribution ordering.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n let documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n documentToSet = this.transformContributionAfterValidation(documentName, documentToSet);\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): JsonDocumentLike | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`${documentName} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete all present contribution documents for the composition process and return to the base\n * document\n *\n * @returns Recalculated output document consisting only of the base document\n */\n deleteAllContributions(): JsonDocumentLike | undefined {\n if (this.contributions.size <= 0) return this.latestOutput;\n\n // Save out all contributions\n const contributions = [...this.contributions.entries()];\n\n // Delete all contributions\n contributions.forEach(([contributionName]) => this.contributions.delete(contributionName));\n\n // Rebuild with no contributions\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting all contributions, put them back and rethrow\n contributions.forEach(([contributionName, document]) =>\n this.contributions.set(contributionName, document),\n );\n throw new Error(`Error when deleting all contributions: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutputBeforeValidation(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutputBeforeValidation(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n /**\n * Transform the starting document that is given to the combiner. This transformation occurs after\n * validating the base document and before combining any contributions.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the `baseDocument` passed in.\n *\n * @param baseDocument Initial input document. Already validated via `validateBaseDocument`\n * @returns Transformed base document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformBaseDocumentAfterValidation(baseDocument: JsonDocumentLike): JsonDocumentLike {\n return baseDocument;\n }\n\n /**\n * Transform the contributed document associated with `documentName`. This transformation occurs\n * after validating the contributed document and before combining with other documents.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the contributed `document` passed in.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine. Already validated via\n * `validateContribution`\n * @returns Transformed contributed document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformContributionAfterValidation(\n // @ts-expect-error this parameter is unused but may be used in child classes\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike {\n return document;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateBaseDocument(baseDocument: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateContribution(documentName: string, document: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateOutput(output: JsonDocumentLike): void {}\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation via `validateOutput`\n * before `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n // no-op intended to be overridden by child classes. Can't be static\n // eslint-disable-next-line class-methods-use-this\n protected transformFinalOutputBeforeValidation(finalOutput: JsonDocumentLike): JsonDocumentLike {\n return finalOutput;\n }\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Deep clone and recursively merge the properties of one object (copyFrom) into another\n * (startingPoint). Throws if copyFrom would overwrite values already existing in startingPoint.\n *\n * Does not modify the objects passed in.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n\n if (!copyFrom) return retVal;\n\n return mergeObjectsInternal(retVal, deepClone(copyFrom), ignoreDuplicateProperties);\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * WARNING: Modifies the argument objects in some way. Recommended to use `mergeObjects`\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjectsInternal(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n if (!copyFrom) return startingPoint;\n\n if (areNonArrayObjects(startingPoint, copyFrom)) {\n // Merge properties since they are both objects\n\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n const startingPointObj = startingPoint as JsonObjectLike;\n const copyFromObj = copyFrom as JsonObjectLike;\n /* eslint-enable no-type-assertion/no-type-assertion */\n Object.keys(copyFromObj).forEach((key: string | number) => {\n if (Object.hasOwn(startingPointObj, key)) {\n if (areNonArrayObjects(startingPointObj[key], copyFromObj[key])) {\n startingPointObj[key] = mergeObjectsInternal(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] as JsonObjectLike,\n copyFromObj[key] as JsonObjectLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPointObj[key], copyFromObj[key])) {\n // Concat the arrays since they are both arrays\n\n // We know these are arrays from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] = (startingPointObj[key] as JsonArrayLike).concat(\n copyFromObj[key] as JsonArrayLike,\n );\n /* eslint-enable no-type-assertion/no-type-assertion */\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n // Note that the first non-object non-array value that gets placed in a property stays.\n // New values do not override existing ones\n } else {\n startingPointObj[key] = copyFromObj[key];\n }\n });\n } else if (areArrayObjects(startingPoint, copyFrom)) {\n // Concat the arrays since they are both arrays\n\n // Push the contents of copyFrom into startingPoint since it is a const and was already deep cloned\n // We know these are objects from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n (startingPoint as JsonArrayLike).push(...(copyFrom as JsonArrayLike));\n /* eslint-enable no-type-assertion/no-type-assertion */\n }\n\n // Note that nothing happens if `startingPoint` is not an object or an array or if `startingPoint`\n // and `copyFrom` are not both object or both arrays. Should we throw? Should we push `copyFrom`'s\n // values into the array? Other? Maybe one day we can add some options to decide what to do in\n // this situation, but YAGNI for now\n\n return startingPoint;\n}\n\n// #endregion\n","import DocumentCombiner, { DocumentCombinerOptions, JsonDocumentLike } from './document-combiner';\n\nexport default class NonValidatingDocumentCombiner extends DocumentCombiner {\n // Making the protected base constructor public\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n super(baseDocument, options);\n }\n\n get output(): JsonDocumentLike | undefined {\n return this.latestOutput;\n }\n}\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","var P = Object.defineProperty;\nvar R = (t, e, s) => e in t ? P(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;\nvar n = (t, e, s) => (R(t, typeof e != \"symbol\" ? e + \"\" : e, s), s);\nclass z {\n constructor() {\n n(this, \"books\");\n n(this, \"firstSelectedBookNum\");\n n(this, \"lastSelectedBookNum\");\n n(this, \"count\");\n n(this, \"selectedBookNumbers\");\n n(this, \"selectedBookIds\");\n }\n}\nconst m = [\n \"GEN\",\n \"EXO\",\n \"LEV\",\n \"NUM\",\n \"DEU\",\n \"JOS\",\n \"JDG\",\n \"RUT\",\n \"1SA\",\n \"2SA\",\n // 10\n \"1KI\",\n \"2KI\",\n \"1CH\",\n \"2CH\",\n \"EZR\",\n \"NEH\",\n \"EST\",\n \"JOB\",\n \"PSA\",\n \"PRO\",\n // 20\n \"ECC\",\n \"SNG\",\n \"ISA\",\n \"JER\",\n \"LAM\",\n \"EZK\",\n \"DAN\",\n \"HOS\",\n \"JOL\",\n \"AMO\",\n // 30\n \"OBA\",\n \"JON\",\n \"MIC\",\n \"NAM\",\n \"HAB\",\n \"ZEP\",\n \"HAG\",\n \"ZEC\",\n \"MAL\",\n \"MAT\",\n // 40\n \"MRK\",\n \"LUK\",\n \"JHN\",\n \"ACT\",\n \"ROM\",\n \"1CO\",\n \"2CO\",\n \"GAL\",\n \"EPH\",\n \"PHP\",\n // 50\n \"COL\",\n \"1TH\",\n \"2TH\",\n \"1TI\",\n \"2TI\",\n \"TIT\",\n \"PHM\",\n \"HEB\",\n \"JAS\",\n \"1PE\",\n // 60\n \"2PE\",\n \"1JN\",\n \"2JN\",\n \"3JN\",\n \"JUD\",\n \"REV\",\n \"TOB\",\n \"JDT\",\n \"ESG\",\n \"WIS\",\n // 70\n \"SIR\",\n \"BAR\",\n \"LJE\",\n \"S3Y\",\n \"SUS\",\n \"BEL\",\n \"1MA\",\n \"2MA\",\n \"3MA\",\n \"4MA\",\n // 80\n \"1ES\",\n \"2ES\",\n \"MAN\",\n \"PS2\",\n \"ODA\",\n \"PSS\",\n \"JSA\",\n // actual variant text for JOS, now in LXA text\n \"JDB\",\n // actual variant text for JDG, now in LXA text\n \"TBS\",\n // actual variant text for TOB, now in LXA text\n \"SST\",\n // actual variant text for SUS, now in LXA text // 90\n \"DNT\",\n // actual variant text for DAN, now in LXA text\n \"BLT\",\n // actual variant text for BEL, now in LXA text\n \"XXA\",\n \"XXB\",\n \"XXC\",\n \"XXD\",\n \"XXE\",\n \"XXF\",\n \"XXG\",\n \"FRT\",\n // 100\n \"BAK\",\n \"OTH\",\n \"3ES\",\n // Used previously but really should be 2ES\n \"EZA\",\n // Used to be called 4ES, but not actually in any known project\n \"5EZ\",\n // Used to be called 5ES, but not actually in any known project\n \"6EZ\",\n // Used to be called 6ES, but not actually in any known project\n \"INT\",\n \"CNC\",\n \"GLO\",\n \"TDX\",\n // 110\n \"NDX\",\n \"DAG\",\n \"PS3\",\n \"2BA\",\n \"LBA\",\n \"JUB\",\n \"ENO\",\n \"1MQ\",\n \"2MQ\",\n \"3MQ\",\n // 120\n \"REP\",\n \"4BA\",\n \"LAO\"\n], v = [\n \"XXA\",\n \"XXB\",\n \"XXC\",\n \"XXD\",\n \"XXE\",\n \"XXF\",\n \"XXG\",\n \"FRT\",\n \"BAK\",\n \"OTH\",\n \"INT\",\n \"CNC\",\n \"GLO\",\n \"TDX\",\n \"NDX\"\n], X = [\n \"Genesis\",\n \"Exodus\",\n \"Leviticus\",\n \"Numbers\",\n \"Deuteronomy\",\n \"Joshua\",\n \"Judges\",\n \"Ruth\",\n \"1 Samuel\",\n \"2 Samuel\",\n \"1 Kings\",\n \"2 Kings\",\n \"1 Chronicles\",\n \"2 Chronicles\",\n \"Ezra\",\n \"Nehemiah\",\n \"Esther (Hebrew)\",\n \"Job\",\n \"Psalms\",\n \"Proverbs\",\n \"Ecclesiastes\",\n \"Song of Songs\",\n \"Isaiah\",\n \"Jeremiah\",\n \"Lamentations\",\n \"Ezekiel\",\n \"Daniel (Hebrew)\",\n \"Hosea\",\n \"Joel\",\n \"Amos\",\n \"Obadiah\",\n \"Jonah\",\n \"Micah\",\n \"Nahum\",\n \"Habakkuk\",\n \"Zephaniah\",\n \"Haggai\",\n \"Zechariah\",\n \"Malachi\",\n \"Matthew\",\n \"Mark\",\n \"Luke\",\n \"John\",\n \"Acts\",\n \"Romans\",\n \"1 Corinthians\",\n \"2 Corinthians\",\n \"Galatians\",\n \"Ephesians\",\n \"Philippians\",\n \"Colossians\",\n \"1 Thessalonians\",\n \"2 Thessalonians\",\n \"1 Timothy\",\n \"2 Timothy\",\n \"Titus\",\n \"Philemon\",\n \"Hebrews\",\n \"James\",\n \"1 Peter\",\n \"2 Peter\",\n \"1 John\",\n \"2 John\",\n \"3 John\",\n \"Jude\",\n \"Revelation\",\n \"Tobit\",\n \"Judith\",\n \"Esther Greek\",\n \"Wisdom of Solomon\",\n \"Sirach (Ecclesiasticus)\",\n \"Baruch\",\n \"Letter of Jeremiah\",\n \"Song of 3 Young Men\",\n \"Susanna\",\n \"Bel and the Dragon\",\n \"1 Maccabees\",\n \"2 Maccabees\",\n \"3 Maccabees\",\n \"4 Maccabees\",\n \"1 Esdras (Greek)\",\n \"2 Esdras (Latin)\",\n \"Prayer of Manasseh\",\n \"Psalm 151\",\n \"Odes\",\n \"Psalms of Solomon\",\n // WARNING, if you change the spelling of the *obsolete* tag be sure to update\n // IsObsolete routine\n \"Joshua A. *obsolete*\",\n \"Judges B. *obsolete*\",\n \"Tobit S. *obsolete*\",\n \"Susanna Th. *obsolete*\",\n \"Daniel Th. *obsolete*\",\n \"Bel Th. *obsolete*\",\n \"Extra A\",\n \"Extra B\",\n \"Extra C\",\n \"Extra D\",\n \"Extra E\",\n \"Extra F\",\n \"Extra G\",\n \"Front Matter\",\n \"Back Matter\",\n \"Other Matter\",\n \"3 Ezra *obsolete*\",\n \"Apocalypse of Ezra\",\n \"5 Ezra (Latin Prologue)\",\n \"6 Ezra (Latin Epilogue)\",\n \"Introduction\",\n \"Concordance \",\n \"Glossary \",\n \"Topical Index\",\n \"Names Index\",\n \"Daniel Greek\",\n \"Psalms 152-155\",\n \"2 Baruch (Apocalypse)\",\n \"Letter of Baruch\",\n \"Jubilees\",\n \"Enoch\",\n \"1 Meqabyan\",\n \"2 Meqabyan\",\n \"3 Meqabyan\",\n \"Reproof (Proverbs 25-31)\",\n \"4 Baruch (Rest of Baruch)\",\n \"Laodiceans\"\n], C = K();\nfunction N(t, e = !0) {\n return e && (t = t.toUpperCase()), t in C ? C[t] : 0;\n}\nfunction B(t) {\n return N(t) > 0;\n}\nfunction x(t) {\n const e = typeof t == \"string\" ? N(t) : t;\n return e >= 40 && e <= 66;\n}\nfunction T(t) {\n return (typeof t == \"string\" ? N(t) : t) <= 39;\n}\nfunction O(t) {\n return t <= 66;\n}\nfunction V(t) {\n const e = typeof t == \"string\" ? N(t) : t;\n return I(e) && !O(e);\n}\nfunction* L() {\n for (let t = 1; t <= m.length; t++)\n yield t;\n}\nconst G = 1, S = m.length;\nfunction H() {\n return [\"XXA\", \"XXB\", \"XXC\", \"XXD\", \"XXE\", \"XXF\", \"XXG\"];\n}\nfunction k(t, e = \"***\") {\n const s = t - 1;\n return s < 0 || s >= m.length ? e : m[s];\n}\nfunction A(t) {\n return t <= 0 || t > S ? \"******\" : X[t - 1];\n}\nfunction y(t) {\n return A(N(t));\n}\nfunction I(t) {\n const e = typeof t == \"number\" ? k(t) : t;\n return B(e) && !v.includes(e);\n}\nfunction q(t) {\n const e = typeof t == \"number\" ? k(t) : t;\n return B(e) && v.includes(e);\n}\nfunction U(t) {\n return X[t - 1].includes(\"*obsolete*\");\n}\nfunction K() {\n const t = {};\n for (let e = 0; e < m.length; e++)\n t[m[e]] = e + 1;\n return t;\n}\nconst f = {\n allBookIds: m,\n nonCanonicalIds: v,\n bookIdToNumber: N,\n isBookIdValid: B,\n isBookNT: x,\n isBookOT: T,\n isBookOTNT: O,\n isBookDC: V,\n allBookNumbers: L,\n firstBook: G,\n lastBook: S,\n extraBooks: H,\n bookNumberToId: k,\n bookNumberToEnglishName: A,\n bookIdToEnglishName: y,\n isCanonical: I,\n isExtraMaterial: q,\n isObsolete: U\n};\nvar l = /* @__PURE__ */ ((t) => (t[t.Unknown = 0] = \"Unknown\", t[t.Original = 1] = \"Original\", t[t.Septuagint = 2] = \"Septuagint\", t[t.Vulgate = 3] = \"Vulgate\", t[t.English = 4] = \"English\", t[t.RussianProtestant = 5] = \"RussianProtestant\", t[t.RussianOrthodox = 6] = \"RussianOrthodox\", t))(l || {});\nconst u = class u {\n // private versInfo: Versification;\n constructor(e) {\n n(this, \"name\");\n n(this, \"fullPath\");\n n(this, \"isPresent\");\n n(this, \"hasVerseSegments\");\n n(this, \"isCustomized\");\n n(this, \"baseVersification\");\n n(this, \"scriptureBooks\");\n n(this, \"_type\");\n if (e != null)\n typeof e == \"string\" ? this.name = e : this._type = e;\n else\n throw new Error(\"Argument null\");\n }\n get type() {\n return this._type;\n }\n equals(e) {\n return !e.type || !this.type ? !1 : e.type === this.type;\n }\n};\nn(u, \"Original\", new u(l.Original)), n(u, \"Septuagint\", new u(l.Septuagint)), n(u, \"Vulgate\", new u(l.Vulgate)), n(u, \"English\", new u(l.English)), n(u, \"RussianProtestant\", new u(l.RussianProtestant)), n(u, \"RussianOrthodox\", new u(l.RussianOrthodox));\nlet c = u;\nfunction E(t, e) {\n const s = e[0];\n for (let r = 1; r < e.length; r++)\n t = t.split(e[r]).join(s);\n return t.split(s);\n}\nvar D = /* @__PURE__ */ ((t) => (t[t.Valid = 0] = \"Valid\", t[t.UnknownVersification = 1] = \"UnknownVersification\", t[t.OutOfRange = 2] = \"OutOfRange\", t[t.VerseOutOfOrder = 3] = \"VerseOutOfOrder\", t[t.VerseRepeated = 4] = \"VerseRepeated\", t))(D || {});\nconst i = class i {\n constructor(e, s, r, o) {\n /** Not yet implemented. */\n n(this, \"firstChapter\");\n /** Not yet implemented. */\n n(this, \"lastChapter\");\n /** Not yet implemented. */\n n(this, \"lastVerse\");\n /** Not yet implemented. */\n n(this, \"hasSegmentsDefined\");\n /** Not yet implemented. */\n n(this, \"text\");\n /** Not yet implemented. */\n n(this, \"BBBCCCVVVS\");\n /** Not yet implemented. */\n n(this, \"longHashCode\");\n /** The versification of the reference. */\n n(this, \"versification\");\n n(this, \"rtlMark\", \"‏\");\n n(this, \"_bookNum\", 0);\n n(this, \"_chapterNum\", 0);\n n(this, \"_verseNum\", 0);\n n(this, \"_verse\");\n if (r == null && o == null)\n if (e != null && typeof e == \"string\") {\n const a = e, h = s != null && s instanceof c ? s : void 0;\n this.setEmpty(h), this.parse(a);\n } else if (e != null && typeof e == \"number\") {\n const a = s != null && s instanceof c ? s : void 0;\n this.setEmpty(a), this._verseNum = e % i.chapterDigitShifter, this._chapterNum = Math.floor(\n e % i.bookDigitShifter / i.chapterDigitShifter\n ), this._bookNum = Math.floor(e / i.bookDigitShifter);\n } else if (s == null)\n if (e != null && e instanceof i) {\n const a = e;\n this._bookNum = a.bookNum, this._chapterNum = a.chapterNum, this._verseNum = a.verseNum, this._verse = a.verse, this.versification = a.versification;\n } else {\n if (e == null)\n return;\n const a = e instanceof c ? e : i.defaultVersification;\n this.setEmpty(a);\n }\n else\n throw new Error(\"VerseRef constructor not supported.\");\n else if (e != null && s != null && r != null)\n if (typeof e == \"string\" && typeof s == \"string\" && typeof r == \"string\")\n this.setEmpty(o), this.updateInternal(e, s, r);\n else if (typeof e == \"number\" && typeof s == \"number\" && typeof r == \"number\")\n this._bookNum = e, this._chapterNum = s, this._verseNum = r, this.versification = o ?? i.defaultVersification;\n else\n throw new Error(\"VerseRef constructor not supported.\");\n else\n throw new Error(\"VerseRef constructor not supported.\");\n }\n /**\n * @deprecated Will be removed in v2. Replace `VerseRef.parse('...')` with `new VerseRef('...')`\n * or refactor to use `VerseRef.tryParse('...')` which has a different return type.\n */\n static parse(e, s = i.defaultVersification) {\n const r = new i(s);\n return r.parse(e), r;\n }\n /**\n * Determines if the verse string is in a valid format (does not consider versification).\n */\n static isVerseParseable(e) {\n return e.length > 0 && \"0123456789\".includes(e[0]) && !e.endsWith(this.verseRangeSeparator) && !e.endsWith(this.verseSequenceIndicator);\n }\n /**\n * Tries to parse the specified string into a verse reference.\n * @param str - The string to attempt to parse.\n * @returns success: `true` if the specified string was successfully parsed, `false` otherwise.\n * @returns verseRef: The result of the parse if successful, or empty VerseRef if it failed\n */\n static tryParse(e) {\n let s;\n try {\n return s = i.parse(e), { success: !0, verseRef: s };\n } catch (r) {\n if (r instanceof d)\n return s = new i(), { success: !1, verseRef: s };\n throw r;\n }\n }\n /**\n * Gets the reference as a comparable integer where the book, chapter, and verse each occupy 3\n * digits.\n * @param bookNum - Book number (this is 1-based, not an index).\n * @param chapterNum - Chapter number.\n * @param verseNum - Verse number.\n * @returns The reference as a comparable integer where the book, chapter, and verse each occupy 3\n * digits.\n */\n static getBBBCCCVVV(e, s, r) {\n return e % i.bcvMaxValue * i.bookDigitShifter + (s >= 0 ? s % i.bcvMaxValue * i.chapterDigitShifter : 0) + (r >= 0 ? r % i.bcvMaxValue : 0);\n }\n /**\n * Parses a verse string and gets the leading numeric portion as a number.\n * @param verseStr - verse string to parse\n * @returns true if the entire string could be parsed as a single, simple verse number (1-999);\n * false if the verse string represented a verse bridge, contained segment letters, or was invalid\n */\n static tryGetVerseNum(e) {\n let s;\n if (!e)\n return s = -1, { success: !0, vNum: s };\n s = 0;\n let r;\n for (let o = 0; o < e.length; o++) {\n if (r = e[o], r < \"0\" || r > \"9\")\n return o === 0 && (s = -1), { success: !1, vNum: s };\n if (s = s * 10 + +r - +\"0\", s > i.bcvMaxValue)\n return s = -1, { success: !1, vNum: s };\n }\n return { success: !0, vNum: s };\n }\n /**\n * Checks to see if a VerseRef hasn't been set - all values are the default.\n */\n get isDefault() {\n return this.bookNum === 0 && this.chapterNum === 0 && this.verseNum === 0 && this.versification == null;\n }\n /**\n * Gets whether the verse contains multiple verses.\n */\n get hasMultiple() {\n return this._verse != null && (this._verse.includes(i.verseRangeSeparator) || this._verse.includes(i.verseSequenceIndicator));\n }\n /**\n * Gets or sets the book of the reference. Book is the 3-letter abbreviation in capital letters,\n * e.g. `'MAT'`.\n */\n get book() {\n return f.bookNumberToId(this.bookNum, \"\");\n }\n set book(e) {\n this.bookNum = f.bookIdToNumber(e);\n }\n /**\n * Gets or sets the chapter of the reference,. e.g. `'3'`.\n */\n get chapter() {\n return this.isDefault || this._chapterNum < 0 ? \"\" : this._chapterNum.toString();\n }\n set chapter(e) {\n const s = +e;\n this._chapterNum = Number.isInteger(s) ? s : -1;\n }\n /**\n * Gets or sets the verse of the reference, including range, segments, and sequences, e.g. `'4'`,\n * or `'4b-5a, 7'`.\n */\n get verse() {\n return this._verse != null ? this._verse : this.isDefault || this._verseNum < 0 ? \"\" : this._verseNum.toString();\n }\n set verse(e) {\n const { success: s, vNum: r } = i.tryGetVerseNum(e);\n this._verse = s ? void 0 : e.replace(this.rtlMark, \"\"), this._verseNum = r, !(this._verseNum >= 0) && ({ vNum: this._verseNum } = i.tryGetVerseNum(this._verse));\n }\n /**\n * Get or set Book based on book number, e.g. `42`.\n */\n get bookNum() {\n return this._bookNum;\n }\n set bookNum(e) {\n if (e <= 0 || e > f.lastBook)\n throw new d(\n \"BookNum must be greater than zero and less than or equal to last book\"\n );\n this._bookNum = e;\n }\n /**\n * Gets or sets the chapter number, e.g. `3`. `-1` if not valid.\n */\n get chapterNum() {\n return this._chapterNum;\n }\n set chapterNum(e) {\n this.chapterNum = e;\n }\n /**\n * Gets or sets verse start number, e.g. `4`. `-1` if not valid.\n */\n get verseNum() {\n return this._verseNum;\n }\n set verseNum(e) {\n this._verseNum = e;\n }\n /**\n * String representing the versification (should ONLY be used for serialization/deserialization).\n *\n * @remarks This is for backwards compatibility when ScrVers was an enumeration.\n */\n get versificationStr() {\n var e;\n return (e = this.versification) == null ? void 0 : e.name;\n }\n set versificationStr(e) {\n this.versification = this.versification != null ? new c(e) : void 0;\n }\n /**\n * Determines if the reference is valid.\n */\n get valid() {\n return this.validStatus === 0;\n }\n /**\n * Get the valid status for this reference.\n */\n get validStatus() {\n return this.validateVerse(i.verseRangeSeparators, i.verseSequenceIndicators);\n }\n /**\n * Gets the reference as a comparable integer where the book,\n * chapter, and verse each occupy three digits and the verse is 0.\n */\n get BBBCCC() {\n return i.getBBBCCCVVV(this._bookNum, this._chapterNum, 0);\n }\n /**\n * Gets the reference as a comparable integer where the book,\n * chapter, and verse each occupy three digits. If verse is not null\n * (i.e., this reference represents a complex reference with verse\n * segments or bridge) this cannot be used for an exact comparison.\n */\n get BBBCCCVVV() {\n return i.getBBBCCCVVV(this._bookNum, this._chapterNum, this._verseNum);\n }\n /**\n * Gets whether the verse is defined as an excluded verse in the versification.\n * Does not handle verse ranges.\n */\n // eslint-disable-next-line @typescript-eslint/class-literal-property-style\n get isExcluded() {\n return !1;\n }\n /**\n * Parses the reference in the specified string.\n * Optionally versification can follow reference as in GEN 3:11/4\n * Throw an exception if\n * - invalid book name\n * - chapter number is missing or not a number\n * - verse number is missing or does not start with a number\n * - versification is invalid\n * @param verseStr - string to parse e.g. 'MAT 3:11'\n */\n parse(e) {\n if (e = e.replace(this.rtlMark, \"\"), e.includes(\"/\")) {\n const a = e.split(\"/\");\n if (e = a[0], a.length > 1)\n try {\n const h = +a[1].trim();\n this.versification = new c(l[h]);\n } catch {\n throw new d(\"Invalid reference : \" + e);\n }\n }\n const s = e.trim().split(\" \");\n if (s.length !== 2)\n throw new d(\"Invalid reference : \" + e);\n const r = s[1].split(\":\"), o = +r[0];\n if (r.length !== 2 || f.bookIdToNumber(s[0]) === 0 || !Number.isInteger(o) || o < 0 || !i.isVerseParseable(r[1]))\n throw new d(\"Invalid reference : \" + e);\n this.updateInternal(s[0], r[0], r[1]);\n }\n /**\n * Simplifies this verse ref so that it has no bridging of verses or\n * verse segments like `'1a'`.\n */\n simplify() {\n this._verse = void 0;\n }\n /**\n * Makes a clone of the reference.\n *\n * @returns The cloned VerseRef.\n */\n clone() {\n return new i(this);\n }\n toString() {\n const e = this.book;\n return e === \"\" ? \"\" : `${e} ${this.chapter}:${this.verse}`;\n }\n /**\n * Compares this `VerseRef` with supplied one.\n * @param verseRef - object to compare this one to.\n * @returns `true` if this `VerseRef` is equal to the supplied on, `false` otherwise.\n */\n equals(e) {\n return e instanceof i ? e._bookNum === this._bookNum && e._chapterNum === this._chapterNum && e._verseNum === this._verseNum && e.verse === this.verse && e.versification != null && this.versification != null && e.versification.equals(this.versification) : !1;\n }\n /**\n * Enumerate all individual verses contained in a VerseRef.\n * Verse ranges are indicated by \"-\" and consecutive verses by \",\"s.\n * Examples:\n * GEN 1:2 returns GEN 1:2\n * GEN 1:1a-3b,5 returns GEN 1:1a, GEN 1:2, GEN 1:3b, GEN 1:5\n * GEN 1:2a-2c returns //! ??????\n *\n * @param specifiedVersesOnly - if set to true return only verses that are\n * explicitly specified only, not verses within a range. Defaults to `false`.\n * @param verseRangeSeparators - Verse range separators.\n * Defaults to `VerseRef.verseRangeSeparators`.\n * @param verseSequenceSeparators - Verse sequence separators.\n * Defaults to `VerseRef.verseSequenceIndicators`.\n * @returns An array of all single verse references in this VerseRef.\n */\n allVerses(e = !1, s = i.verseRangeSeparators, r = i.verseSequenceIndicators) {\n if (this._verse == null || this.chapterNum <= 0)\n return [this.clone()];\n const o = [], a = E(this._verse, r);\n for (const h of a.map((g) => E(g, s))) {\n const g = this.clone();\n g.verse = h[0];\n const w = g.verseNum;\n if (o.push(g), h.length > 1) {\n const p = this.clone();\n if (p.verse = h[1], !e)\n for (let b = w + 1; b < p.verseNum; b++) {\n const J = new i(\n this._bookNum,\n this._chapterNum,\n b,\n this.versification\n );\n this.isExcluded || o.push(J);\n }\n o.push(p);\n }\n }\n return o;\n }\n /**\n * Validates a verse number using the supplied separators rather than the defaults.\n */\n validateVerse(e, s) {\n if (!this.verse)\n return this.internalValid;\n let r = 0;\n for (const o of this.allVerses(!0, e, s)) {\n const a = o.internalValid;\n if (a !== 0)\n return a;\n const h = o.BBBCCCVVV;\n if (r > h)\n return 3;\n if (r === h)\n return 4;\n r = h;\n }\n return 0;\n }\n /**\n * Gets whether a single verse reference is valid.\n */\n get internalValid() {\n return this.versification == null ? 1 : this._bookNum <= 0 || this._bookNum > f.lastBook ? 2 : (f.isCanonical(this._bookNum), 0);\n }\n setEmpty(e = i.defaultVersification) {\n this._bookNum = 0, this._chapterNum = -1, this._verse = void 0, this.versification = e;\n }\n updateInternal(e, s, r) {\n this.bookNum = f.bookIdToNumber(e), this.chapter = s, this.verse = r;\n }\n};\nn(i, \"defaultVersification\", c.English), n(i, \"verseRangeSeparator\", \"-\"), n(i, \"verseSequenceIndicator\", \",\"), n(i, \"verseRangeSeparators\", [i.verseRangeSeparator]), n(i, \"verseSequenceIndicators\", [i.verseSequenceIndicator]), n(i, \"chapterDigitShifter\", 1e3), n(i, \"bookDigitShifter\", i.chapterDigitShifter * i.chapterDigitShifter), n(i, \"bcvMaxValue\", i.chapterDigitShifter - 1), /**\n * The valid status of the VerseRef.\n */\nn(i, \"ValidStatusType\", D);\nlet M = i;\nclass d extends Error {\n}\nexport {\n z as BookSet,\n f as Canon,\n c as ScrVers,\n l as ScrVersType,\n M as VerseRef,\n d as VerseRefException\n};\n//# sourceMappingURL=index.es.js.map\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * This function mirrors the `at` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Finds the Unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified offset,\n * undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > stringLength(string) || index < -stringLength(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `charAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a new string consisting of the single unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified offset, empty\n * string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > stringLength(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the character at the given\n * index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > stringLength(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * This function mirrors the `endsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether a string ends with the characters of this string.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be found. Default is\n * `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = stringLength(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * This function mirrors the `includes` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Performs a case-sensitive search to determine if searchString is found in string.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString. Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * This function mirrors the `indexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the index of the first occurrence of a given string.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Searches this string and returns the index of the last occurrence of the specified substring.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(string: string, searchString: string, position?: number): number {\n let validatedPosition = position === undefined ? stringLength(string) : position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= stringLength(string)) {\n validatedPosition = stringLength(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, stringLength(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * This function mirrors the `length` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes. Since `length` appears to be a\n * reserved keyword, the function was renamed to `stringLength`\n *\n * Returns the length of a string.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function stringLength(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * This function mirrors the `normalize` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * This function mirrors the `padEnd` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * This function mirrors the `padStart` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\n// This is a helper function that performs a correction on the slice index to make sure it\n// cannot go out of bounds\nfunction correctSliceIndex(length: number, index: number) {\n if (index > length) return length;\n if (index < -length) return 0;\n if (index < 0) return index + length;\n return index;\n}\n\n/**\n * This function mirrors the `slice` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const length: number = stringLength(string);\n if (\n indexStart > length ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(indexStart >= 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) ||\n indexEnd < -length))\n )\n return '';\n\n const newStart = correctSliceIndex(length, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * This function mirrors the `split` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits the\n * string at each occurrence of specified separator, but stops when limit entries have been placed\n * in the array.\n * @returns An array of strings, split at each point where separator occurs in the starting string.\n * Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = stringLength(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * This function mirrors the `startsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found (the index of\n * searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string, including when\n * searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * This function mirrors the `substr` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and length. This function is not exported because it is\n * considered deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String length minus start parameter`. Default is `String\n * length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(\n string: string,\n begin: number = 0,\n len: number = stringLength(string) - begin,\n): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * This function mirrors the `substring` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and end position.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = stringLength(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * This function mirrors the `toArray` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Converts a string to an array of string characters.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","import { Canon } from '@sillsdev/scripture';\nimport { BookInfo, ScriptureReference } from './scripture.model';\nimport { split, startsWith } from './string-util';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n\n/**\n * https://github.com/ubsicap/Paratext/blob/master/ParatextData/SILScriptureExtensions.cs#L72\n *\n * Convert book number to a localized Id (a short description of the book). This should be used\n * whenever a book ID (short code) is shown to the user. It is primarily needed for people who do\n * not read Roman script well and need to have books identified in a alternate script (e.g.\n * Chinese or Russian)\n *\n * @param bookNumber\n * @param localizationLanguage in BCP 47 format\n * @param getLocalizedString function that provides the localized versions of the book ids and names\n * asynchronously.\n * @returns\n */\nexport async function getLocalizedIdFromBookNumber(\n bookNumber: number,\n localizationLanguage: string,\n getLocalizedString: (item: {\n localizeKey: string;\n languagesToSearch?: string[];\n }) => Promise,\n) {\n const id = Canon.bookNumberToId(bookNumber);\n\n if (!startsWith(Intl.getCanonicalLocales(localizationLanguage)[0], 'zh'))\n return getLocalizedString({\n localizeKey: `LocalizedId.${id}`,\n languagesToSearch: [localizationLanguage],\n });\n\n // For Chinese the normal book name is already fairly short.\n const bookName = await getLocalizedString({\n localizeKey: `Book.${id}`,\n languagesToSearch: [localizationLanguage],\n });\n const parts = split(bookName, '-');\n // some entries had a second name inside ideographic parenthesis\n const parts2 = split(parts[0], '\\xff08')\n const retVal = parts2[0].trim();\n return retVal;\n}\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { LocalizeKey, ReferencedItem } from 'menus.model';\n\n/** The data an extension provides to inform Platform.Bible of the settings it provides */\nexport type SettingsContribution = SettingsGroup | SettingsGroup[];\n/** A description of an extension's setting entry */\nexport type Setting = ExtensionControlledSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledSetting = SettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a setting entry */\nexport type SettingBase = StateBase & {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the setting name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the setting */\n description?: LocalizeKey;\n};\n/** The data an extension provides to inform Platform.Bible of the project settings it provides */\nexport type ProjectSettingsContribution = ProjectSettingsGroup | ProjectSettingsGroup[];\n/** A description of an extension's setting entry */\nexport type ProjectSetting = ExtensionControlledProjectSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledProjectSetting = ProjectSettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a project setting entry */\nexport type ProjectSettingBase = SettingBase & ModifierProject;\n/** A description of an extension's user state entry */\nexport type UserState = ExtensionControlledState;\n/** State definition that is validated by the extension. */\nexport type ExtensionControlledState = StateBase & ModifierExtensionControlled;\n/** Group of related settings definitions */\nexport interface SettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the group */\n description?: LocalizeKey;\n properties: SettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface SettingProperties {\n [k: ReferencedItem]: Setting;\n}\n/** Base information needed to describe a state entry */\nexport interface StateBase {\n [k: string]: unknown;\n /** Default value for the state/setting */\n default: unknown;\n /**\n * A state/setting ID whose value to set to this state/setting's starting value the first time\n * this state/setting is loaded\n */\n derivesFrom?: ReferencedItem;\n}\n/**\n * Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the\n * extension provides the component and the validator for the state/setting, so the state/setting is\n * controlled by the extension.\n */\nexport interface ModifierExtensionControlled {\n [k: string]: unknown;\n platformType?: undefined;\n type?: undefined;\n}\n/** Group of related settings definitions */\nexport interface ProjectSettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the project settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the project settings dialog to describe the group */\n description?: LocalizeKey;\n properties: ProjectSettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface ProjectSettingProperties {\n [k: ReferencedItem]: ProjectSetting;\n}\n/** Modifies setting type to be project setting */\nexport interface ModifierProject {\n [k: string]: unknown;\n /**\n * `RegExp` pattern(s) to match against `projectType` (using the\n * [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)\n * function) to determine whether this project setting should be displayed in the Project Settings\n * Dialog of that `projectType`. null means do not show on any Project Settings dialog\n */\n includeProjectTypes?: undefined | string | string[];\n /**\n * `RegExp` pattern to match against `projectType` to determine if this project setting should\n * absolutely not be displayed in the Project Settings dialog of that `projectType` even if it\n * matches with `includeProjectTypes`\n */\n excludeProjectTypes?: undefined | string | string[];\n}\n/** The data an extension provides to inform Platform.Bible of the user state it provides */\nexport interface UserStateContribution {\n [k: ReferencedItem]: UserState;\n}\n/** The data an extension provides to inform Platform.Bible of the project state it provides */\nexport interface ProjectStateContribution {\n [k: ReferencedItem]: UserState;\n}\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\nconst settingsDefs = {\n projectSettingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n },\n projectSettingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the project settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description:\n 'localizeKey that displays in the project settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/projectSettingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n projectSettingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/projectSetting',\n },\n },\n additionalProperties: false,\n },\n projectSetting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledProjectSetting',\n },\n ],\n },\n extensionControlledProjectSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/projectSettingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n projectSettingBase: {\n description: 'Base information needed to describe a project setting entry',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierProject',\n },\n ],\n },\n modifierProject: {\n description: 'Modifies setting type to be project setting',\n type: 'object',\n properties: {\n includeProjectTypes: {\n description:\n '`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n excludeProjectTypes: {\n description:\n '`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n },\n },\n settingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n },\n settingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/settingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n settingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w-]+\\\\.[\\\\w-]+$': {\n $ref: '#/$defs/setting',\n },\n },\n additionalProperties: false,\n },\n setting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledSetting',\n },\n ],\n },\n extensionControlledSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n settingBase: {\n description: 'Base information needed to describe a setting entry',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the setting name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the setting',\n $ref: '#/$defs/localizeKey',\n },\n },\n required: ['label'],\n },\n ],\n },\n projectStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the user state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateProperties: {\n description: 'Object whose keys are state IDs and whose values are state objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/userState',\n },\n },\n additionalProperties: false,\n },\n userState: {\n description: \"A description of an extension's user state entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledState',\n },\n ],\n },\n extensionControlledState: {\n description: 'State definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n modifierExtensionControlled: {\n description:\n 'Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the extension provides the component and the validator for the state/setting, so the state/setting is controlled by the extension.',\n not: {\n anyOf: [\n {\n type: 'object',\n required: ['platformType'],\n },\n {\n type: 'object',\n required: ['type'],\n },\n ],\n },\n },\n stateBase: {\n description: 'Base information needed to describe a state entry',\n type: 'object',\n properties: {\n default: {\n description: 'default value for the state/setting',\n type: 'any',\n },\n derivesFrom: {\n description:\n \"a state/setting ID whose value to set to this state/setting's starting value the first time this state/setting is loaded\",\n $ref: '#/$defs/id',\n },\n },\n required: ['default'],\n },\n localizeKey: {\n description: \"Identifier for a string that will be localized based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n tsType: 'LocalizeKey',\n },\n id: {\n description: '',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n tsType: 'Id',\n },\n};\n\n/**\n * Json-schema-to-typescript has some added stuff that isn't actually compatible with JSON schema,\n * so we remove them here\n *\n * @param defs The `$defs` property of a JSON schema (will be modified in place)\n */\n// JSON schema types are weird, so we'll just be careful\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function removeJsonToTypeScriptTypesStuff(defs: any) {\n if (!defs) return;\n\n // JSON schema types are weird, so we'll just be careful\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.values(defs).forEach((def: any) => {\n if (!def.type) return;\n\n if ('tsType' in def) delete def.tsType;\n\n if (def.type === 'any') {\n delete def.type;\n return;\n }\n\n if (def.type === 'object') {\n removeJsonToTypeScriptTypesStuff(def.properties);\n }\n });\n}\n\nremoveJsonToTypeScriptTypesStuff(settingsDefs);\n\n/** JSON schema object that aligns with the ProjectSettingsContribution type */\nexport const projectSettingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Project Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(projectSettingsDocumentSchema);\n\n/** JSON schema object that aligns with the {@link SettingsContribution} type */\nexport const settingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(settingsDocumentSchema);\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { LocalizeKey } from 'menus.model';\nimport { removeJsonToTypeScriptTypesStuff } from './settings.model';\n\n/** Localized string value associated with this key */\nexport type LocalizedStringValue = string;\n\n/** The data an extension provides to inform Platform.Bible of the localized strings it provides. */\nexport interface LocalizedStringDataContribution {\n [k: string]: unknown;\n metadata?: StringsMetadata;\n localizedStrings?: {\n [k: string]: LanguageStrings;\n };\n}\n/**\n * Map whose keys are localized string keys and whose values provide additional non-locale-specific\n * information about the localized string key\n */\nexport interface StringsMetadata {\n [k: LocalizeKey]: StringMetadata;\n}\n/** Additional non-locale-specific information about a localized string key */\nexport interface StringMetadata {\n [k: string]: unknown;\n /**\n * Localized string key from which to get this value if one does not exist in the specified\n * language. If a new key/value pair needs to be made to replace an existing one, this could help\n * smooth over the transition if the meanings are close enough\n */\n fallbackKey?: LocalizeKey;\n /**\n * Additional information provided by developers in English to help the translator to know how to\n * translate this localized string accurately\n */\n notes?: string;\n}\n/**\n * Map whose keys are localized string keys and whose values provide information about how to\n * localize strings for the localized string key\n */\nexport interface LanguageStrings {\n [k: LocalizeKey]: LocalizedStringValue;\n}\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n\nconst localizedStringsDefs = {\n languageStrings: {\n description:\n 'Map whose keys are localized string keys and whose values provide information about how to localize strings for the localized string key',\n type: 'object',\n patternProperties: {\n '^%[\\\\w\\\\-\\\\.]+%$': {\n $ref: '#/$defs/localizedStringValue',\n },\n },\n additionalProperties: false,\n },\n localizedStringValue: {\n description: 'Localized string value associated with this key',\n type: 'string',\n },\n stringsMetadata: {\n description:\n 'Map whose keys are localized string keys and whose values provide additional non-locale-specific information about the localized string key',\n type: 'object',\n patternProperties: {\n '^%[\\\\w\\\\-\\\\.]+%$': {\n $ref: '#/$defs/stringMetadata',\n },\n },\n additionalProperties: false,\n },\n stringMetadata: {\n description: 'Additional non-locale-specific information about a localized string key',\n type: 'object',\n properties: {\n fallbackKey: {\n description:\n 'Localized string key from which to get this value if one does not exist in the specified language. If a new key/value pair needs to be made to replace an existing one, this could help smooth over the transition if the meanings are close enough',\n $ref: '#/$defs/localizeKey',\n },\n notes: {\n description:\n 'Additional information provided by developers in English to help the translator to know how to translate this localized string accurately',\n type: 'string',\n },\n },\n },\n localizeKey: {\n description: \"Identifier for a string that will be localized based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n tsType: 'LocalizeKey',\n },\n};\n\nremoveJsonToTypeScriptTypesStuff(localizedStringsDefs);\n\n/** JSON schema object that aligns with the LocalizedStringDataContribution type */\nexport const localizedStringsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Localized String Data Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the localized strings it provides.',\n type: 'object',\n properties: {\n metadata: {\n $ref: '#/$defs/stringsMetadata',\n },\n localizedStrings: {\n type: 'object',\n additionalProperties: {\n $ref: '#/$defs/languageStrings',\n },\n },\n },\n $defs: localizedStringsDefs,\n};\n\nObject.freeze(localizedStringsDocumentSchema);\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { ReplaceType } from './util';\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single context menu/submenu.\n * Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInSingleColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: OrderedExtensibleContainer | MenuGroupDetailsInSubMenu;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu within a\n * multi-column menu. Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInMultiColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: GroupsInSingleColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n /** Groups that belong in this menu */\n groups: GroupsInMultiColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus before they are localized */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n/**\n * Type that converts any menu type before it is localized to what it is after it is localized. This\n * can be applied to any menu type as needed.\n */\nexport type Localized = ReplaceType, ReferencedItem, string>;\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","PlatformEventEmitter","event","callback","callbackIndex","_a","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombiner","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","contributions","contributionName","potentialOutput","outputIteration","contribution","mergeObjects","output","finalOutput","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","mergeObjectsInternal","startingPointObj","copyFromObj","NonValidatingDocumentCombiner","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","Mutex","AsyncMutex","MutexMap","mutexID","P","R","n","m","v","X","C","K","N","B","x","T","O","V","I","L","G","S","H","k","A","y","q","U","f","l","u","c","E","r","D","i","a","h","d","g","w","b","J","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","stringLength","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","getLocalizedIdFromBookNumber","bookNumber","localizationLanguage","getLocalizedString","id","Canon","bookName","parts","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","settingsDefs","removeJsonToTypeScriptTypesStuff","defs","def","projectSettingsDocumentSchema","settingsDocumentSchema","localizedStringsDefs","localizedStringsDocumentSchema","menuDocumentSchema"],"mappings":"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EA,MACA,MACA,MAEA,MAEA,MAEA,MAEA,MACA,MACA,MACA,MAEA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MAEA,MACA,MACA,KACF,EAAGC,EAAI,CACL,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,KACF,EAAGC,GAAI,CACL,UACA,SACA,YACA,UACA,cACA,SACA,SACA,OACA,WACA,WACA,UACA,UACA,eACA,eACA,OACA,WACA,kBACA,MACA,SACA,WACA,eACA,gBACA,SACA,WACA,eACA,UACA,kBACA,QACA,OACA,OACA,UACA,QACA,QACA,QACA,WACA,YACA,SACA,YACA,UACA,UACA,OACA,OACA,OACA,OACA,SACA,gBACA,gBACA,YACA,YACA,cACA,aACA,kBACA,kBACA,YACA,YACA,QACA,WACA,UACA,QACA,UACA,UACA,SACA,SACA,SACA,OACA,aACA,QACA,SACA,eACA,oBACA,0BACA,SACA,qBACA,sBACA,UACA,qBACA,cACA,cACA,cACA,cACA,mBACA,mBACA,qBACA,YACA,OACA,oBAGA,uBACA,uBACA,sBACA,yBACA,wBACA,qBACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,eACA,cACA,eACA,oBACA,qBACA,0BACA,0BACA,eACA,eACA,YACA,gBACA,cACA,eACA,iBACA,wBACA,mBACA,WACA,QACA,aACA,aACA,aACA,2BACA,4BACA,YACF,EAAGC,EAAIC,KACP,SAASC,EAAE,EAAG,EAAI,GAAI,CACpB,OAAO,IAAM,EAAI,EAAE,YAAa,GAAG,KAAKF,EAAIA,EAAE,CAAC,EAAI,CACrD,CACA,SAASG,EAAE,EAAG,CACZ,OAAOD,EAAE,CAAC,EAAI,CAChB,CACA,SAASE,GAAE,EAAG,CACZ,MAAM,EAAI,OAAO,GAAK,SAAWF,EAAE,CAAC,EAAI,EACxC,OAAO,GAAK,IAAM,GAAK,EACzB,CACA,SAASG,GAAE,EAAG,CACZ,OAAQ,OAAO,GAAK,SAAWH,EAAE,CAAC,EAAI,IA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AM,8BACR,CACF,CACF,CACF,EACA,qBAAsB,CACpB,YAAa,wCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6EACb,KAAM,qBACR,EACA,YAAa,CACX,YACE,iFACF,KAAM,qBACR,EACA,WAAY,CACV,KAAM,kCACR,CACF,EACA,SAAU,CAAC,QAAS,YAAY,CAClC,EACA,yBAA0B,CACxB,YAAa,0EACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,wBACR,CACF,EACA,qBAAsB,EACxB,EACA,eAAgB,CACd,YAAa,gDACb,MAAO,CACL,CACE,KAAM,2CACR,CACF,CACF,EACA,kCAAmC,CACjC,YAAa,yDACb,MAAO,CACL,CACE,KAAM,4BACR,EACA,CACE,KAAM,qCACR,CACF,CACF,EACA,mBAAoB,CAClB,YAAa,8DACb,MAAO,CACL,CACE,KAAM,qBACR,EACA,CACE,KAAM,yBACR,CACF,CACF,EACA,gBAAiB,CACf,YAAa,8CACb,KAAM,SACN,WAAY,CACV,oBAAqB,CACnB,YACE,2VACF,MAAO,CACL,CACE,KAAM,MACR,EACA,CACE,KAAM,QACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,QACR,CACF,CACF,CACF,EACA,oBAAqB,CACnB,YACE,6NACF,MAAO,CACL,CACE,KAAM,MACR,EACA,CACE,KAAM,QACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,QACR,CACF,CACF,CACF,CACF,CACF,EACA,qBAAsB,CACpB,YACE,sFACF,MAAO,CACL,CACE,KAAM,uBACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,uBACR,CACF,CACF,CACF,EACA,cAAe,CACb,YAAa,wCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,qEACb,KAAM,qBACR,EACA,YAAa,CACX,YAAa,yEACb,KAAM,qBACR,EACA,WAAY,CACV,KAAM,2BACR,CACF,EACA,SAAU,CAAC,QAAS,YAAY,CAClC,EACA,kBAAmB,CACjB,YAAa,0EACb,KAAM,SACN,kBAAmB,CACjB,sBAAuB,CACrB,KAAM,iBACR,CACF,EACA,qBAAsB,EACxB,EACA,QAAS,CACP,YAAa,gDACb,MAAO,CACL,CACE,KAAM,oCACR,CACF,CACF,EACA,2BAA4B,CAC1B,YAAa,yDACb,MAAO,CACL,CACE,KAAM,qBACR,EACA,CACE,KAAM,qCACR,CACF,CACF,EACA,YAAa,CACX,YAAa,sDACb,MAAO,CACL,CACE,KAAM,mBACR,EACA,CACE,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,uEACb,KAAM,qBACR,EACA,YAAa,CACX,YAAa,2EACb,KAAM,qBACR,CACF,EACA,SAAU,CAAC,OAAO,CACpB,CACF,CACF,EACA,yBAA0B,CACxB,YACE,2FACF,KAAM,6BACR,EACA,sBAAuB,CACrB,YACE,wFACF,KAAM,6BACR,EACA,oBAAqB,CACnB,YAAa,qEACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,mBACR,CACF,EACA,qBAAsB,EACxB,EACA,UAAW,CACT,YAAa,mDACb,MAAO,CACL,CACE,KAAM,kCACR,CACF,CACF,EACA,yBAA0B,CACxB,YAAa,uDACb,MAAO,CACL,CACE,KAAM,mBACR,EACA,CACE,KAAM,qCACR,CACF,CACF,EACA,4BAA6B,CAC3B,YACE,0NACF,IAAK,CACH,MAAO,CACL,CACE,KAAM,SACN,SAAU,CAAC,cAAc,CAC3B,EACA,CACE,KAAM,SACN,SAAU,CAAC,MAAM,CACnB,CACF,CACF,CACF,EACA,UAAW,CACT,YAAa,oDACb,KAAM,SACN,WAAY,CACV,QAAS,CACP,YAAa,sCACb,KAAM,KACR,EACA,YAAa,CACX,YACE,2HACF,KAAM,YACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,EACA,YAAa,CACX,YAAa,iFACb,KAAM,SACN,QAAS,mBACT,OAAQ,aACV,EACA,GAAI,CACF,YAAa,GACb,KAAM,SACN,QAAS,0BACT,OAAQ,IACV,CACF,EAUO,SAASC,EAAiCC,EAAW,CACrDA,GAIL,OAAO,OAAOA,CAAI,EAAE,QAASC,GAAa,CACxC,GAAKA,EAAI,KAIL,IAFA,WAAYA,GAAK,OAAOA,EAAI,OAE5BA,EAAI,OAAS,MAAO,CACtB,OAAOA,EAAI,KACX,MACF,CAEIA,EAAI,OAAS,UACfF,EAAiCE,EAAI,UAAU,EACjD,CACD,CACH,CAEAF,EAAiCD,CAAY,EAGtC,MAAMI,GAAgC,CAC3C,QAAS,+CACT,MAAO,gCACP,YACE,8FACF,MAAO,CACL,CACE,KAAM,8BACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,8BACR,CACF,CACF,EAEA,MAAOJ,CACT,EAEA,OAAO,OAAOI,EAA6B,EAGpC,MAAMC,GAAyB,CACpC,QAAS,+CACT,MAAO,wBACP,YACE,sFACF,MAAO,CACL,CACE,KAAM,uBACR,EACA,CACE,KAAM,QACN,MAAO,CACL,KAAM,uBACR,CACF,CACF,EAEA,MAAOL,CACT,EAEA,OAAO,OAAOK,EAAsB,ECjapC,MAAMC,GAAuB,CAC3B,gBAAiB,CACf,YACE,2IACF,KAAM,SACN,kBAAmB,CACjB,mBAAoB,CAClB,KAAM,8BACR,CACF,EACA,qBAAsB,EACxB,EACA,qBAAsB,CACpB,YAAa,kDACb,KAAM,QACR,EACA,gBAAiB,CACf,YACE,8IACF,KAAM,SACN,kBAAmB,CACjB,mBAAoB,CAClB,KAAM,wBACR,CACF,EACA,qBAAsB,EACxB,EACA,eAAgB,CACd,YAAa,0EACb,KAAM,SACN,WAAY,CACV,YAAa,CACX,YACE,sPACF,KAAM,qBACR,EACA,MAAO,CACL,YACE,4IACF,KAAM,QACR,CACF,CACF,EACA,YAAa,CACX,YAAa,iFACb,KAAM,SACN,QAAS,mBACT,OAAQ,aACV,CACF,EAEAL,EAAiCK,EAAoB,EAG9C,MAAMC,GAAiC,CAC5C,QAAS,+CACT,MAAO,qCACP,YACE,gGACF,KAAM,SACN,WAAY,CACV,SAAU,CACR,KAAM,yBACR,EACA,iBAAkB,CAChB,KAAM,SACN,qBAAsB,CACpB,KAAM,yBACR,CACF,CACF,EACA,MAAOD,EACT,EAEA,OAAO,OAAOC,EAA8B,ECyBrC,MAAMC,GAAqB,CAChC,MAAO,uBACP,KAAM,SACN,WAAY,CACV,SAAU,CACR,YAAa,qCACb,KAAM,yBACR,EACA,sBAAuB,CACrB,YAAa,8DACb,KAAM,yBACR,EACA,0BAA2B,CACzB,YAAa,kEACb,KAAM,0BACR,EACA,aAAc,CACZ,YAAa,mDACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,4BACR,CACF,EACA,qBAAsB,EACxB,CACF,EACA,SAAU,CAAC,WAAY,wBAAyB,4BAA6B,cAAc,EAC3F,qBAAsB,GACtB,MAAO,CACL,YAAa,CACX,YACE,2FACF,KAAM,SACN,QAAS,kBACX,EACA,eAAgB,CACd,YACE,oGACF,KAAM,SACN,QAAS,yBACX,EACA,mBAAoB,CAClB,YACE,uFACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,qCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6CACb,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YACE,6EACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,8EACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,QAAS,OAAO,EAC3B,qBAAsB,EACxB,CACF,EACA,WAAY,CACV,aAAc,CACZ,YACE,qFACF,KAAM,SACR,CACF,CACF,EACA,WAAY,CACV,YACE,uJACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,wCACb,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[8,9,10,14]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index d3a4e9f2ba..5c72e0441a 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -370,12 +370,13 @@ export declare const offsetVerse: (scrRef: ScriptureReference, offset: number) = * * Convert book number to a localized Id (a short description of the book). This should be used * whenever a book ID (short code) is shown to the user. It is primarily needed for people who do - * not read Roman script well /// and need to have books identified in a alternate script (e.g. + * not read Roman script well and need to have books identified in a alternate script (e.g. * Chinese or Russian) * * @param bookNumber - * @param localizationLanguage - * @param getLocalizedString + * @param localizationLanguage in BCP 47 format + * @param getLocalizedString function that provides the localized versions of the book ids and names + * asynchronously. * @returns */ export declare function getLocalizedIdFromBookNumber(bookNumber: number, localizationLanguage: string, getLocalizedString: (item: { @@ -1146,6 +1147,109 @@ export declare const menuDocumentSchema: { }; }; }; +/** Localized string value associated with this key */ +export type LocalizedStringValue = string; +/** The data an extension provides to inform Platform.Bible of the localized strings it provides. */ +export interface LocalizedStringDataContribution { + [k: string]: unknown; + metadata?: StringsMetadata; + localizedStrings?: { + [k: string]: LanguageStrings; + }; +} +/** + * Map whose keys are localized string keys and whose values provide additional non-locale-specific + * information about the localized string key + */ +export interface StringsMetadata { + [k: LocalizeKey]: StringMetadata; +} +/** Additional non-locale-specific information about a localized string key */ +export interface StringMetadata { + [k: string]: unknown; + /** + * Localized string key from which to get this value if one does not exist in the specified + * language. If a new key/value pair needs to be made to replace an existing one, this could help + * smooth over the transition if the meanings are close enough + */ + fallbackKey?: LocalizeKey; + /** + * Additional information provided by developers in English to help the translator to know how to + * translate this localized string accurately + */ + notes?: string; +} +/** + * Map whose keys are localized string keys and whose values provide information about how to + * localize strings for the localized string key + */ +export interface LanguageStrings { + [k: LocalizeKey]: LocalizedStringValue; +} +/** JSON schema object that aligns with the LocalizedStringDataContribution type */ +export declare const localizedStringsDocumentSchema: { + $schema: string; + title: string; + description: string; + type: string; + properties: { + metadata: { + $ref: string; + }; + localizedStrings: { + type: string; + additionalProperties: { + $ref: string; + }; + }; + }; + $defs: { + languageStrings: { + description: string; + type: string; + patternProperties: { + "^%[\\w\\-\\.]+%$": { + $ref: string; + }; + }; + additionalProperties: boolean; + }; + localizedStringValue: { + description: string; + type: string; + }; + stringsMetadata: { + description: string; + type: string; + patternProperties: { + "^%[\\w\\-\\.]+%$": { + $ref: string; + }; + }; + additionalProperties: boolean; + }; + stringMetadata: { + description: string; + type: string; + properties: { + fallbackKey: { + description: string; + $ref: string; + }; + notes: { + description: string; + type: string; + }; + }; + }; + localizeKey: { + description: string; + type: string; + pattern: string; + tsType: string; + }; + }; +}; /** The data an extension provides to inform Platform.Bible of the settings it provides */ export type SettingsContribution = SettingsGroup | SettingsGroup[]; /** A description of an extension's setting entry */ diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 930627a318..780e1288f0 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -1,8 +1,8 @@ -var ne = Object.defineProperty; -var oe = (t, e, r) => e in t ? ne(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; -var d = (t, e, r) => (oe(t, typeof e != "symbol" ? e + "" : e, r), r); -import { Mutex as ae } from "async-mutex"; -class pt { +var Ae = Object.defineProperty; +var Pe = (t, e, r) => e in t ? Ae(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; +var m = (t, e, r) => (Pe(t, typeof e != "symbol" ? e + "" : e, r), r); +import { Mutex as Te } from "async-mutex"; +class Ft { /** * Creates an instance of the class * @@ -12,10 +12,10 @@ class pt { * do not want a timeout at all. */ constructor(e, r = 1e4) { - d(this, "variableName"); - d(this, "promiseToValue"); - d(this, "resolver"); - d(this, "rejecter"); + m(this, "variableName"); + m(this, "promiseToValue"); + m(this, "resolver"); + m(this, "rejecter"); this.variableName = e, this.promiseToValue = new Promise((s, i) => { this.resolver = s, this.rejecter = i; }), r > 0 && setTimeout(() => { @@ -76,7 +76,7 @@ class pt { this.resolver = void 0, this.rejecter = void 0, Object.freeze(this); } } -class ue { +class Me { constructor() { /** * Subscribes a function to run when this event is emitted. @@ -86,21 +86,21 @@ class ue { * emitted * @alias event */ - d(this, "subscribe", this.event); + m(this, "subscribe", this.event); /** All callback functions that will run when this event is emitted. Lazy loaded */ - d(this, "subscriptions"); + m(this, "subscriptions"); /** Event for listeners to subscribe to. Lazy loaded */ - d(this, "lazyEvent"); + m(this, "lazyEvent"); /** Whether this emitter has been disposed */ - d(this, "isDisposed", !1); + m(this, "isDisposed", !1); /** Disposes of this event, preparing it to release from memory */ - d(this, "dispose", () => this.disposeFn()); + m(this, "dispose", () => this.disposeFn()); /** * Runs the subscriptions for the event * * @param event Event data to provide to subscribed callbacks */ - d(this, "emit", (e) => { + m(this, "emit", (e) => { this.emitFn(e); }); } @@ -145,7 +145,7 @@ class ue { return this.assertNotDisposed(), this.isDisposed = !0, this.subscriptions = void 0, this.lazyEvent = void 0, Promise.resolve(!0); } } -function dt() { +function Wt() { return "00-0-4-1-000".replace( /[^-]/g, (t) => ( @@ -155,36 +155,36 @@ function dt() { ) ); } -function le(t) { +function Be(t) { return typeof t == "string" || t instanceof String; } -function w(t) { +function B(t) { return JSON.parse(JSON.stringify(t)); } -function ht(t, e = 300) { - if (le(t)) +function Zt(t, e = 300) { + if (Be(t)) throw new Error("Tried to debounce a string! Could be XSS"); let r; return (...s) => { clearTimeout(r), r = setTimeout(() => t(...s), e); }; } -function mt(t, e, r) { +function Qt(t, e, r) { const s = /* @__PURE__ */ new Map(); return t.forEach((i) => { - const n = e(i), o = s.get(n), a = r ? r(i, n) : i; - o ? o.push(a) : s.set(n, [a]); + const o = e(i), n = s.get(o), a = r ? r(i, o) : i; + n ? n.push(a) : s.set(o, [a]); }), s; } -function ce(t) { +function De(t) { return typeof t == "object" && // We're potentially dealing with objects we didn't create, so they might contain `null` // eslint-disable-next-line no-null/no-null t !== null && "message" in t && // Type assert `error` to check it's `message`. // eslint-disable-next-line no-type-assertion/no-type-assertion typeof t.message == "string"; } -function fe(t) { - if (ce(t)) +function ke(t) { + if (De(t)) return t; try { return new Error(JSON.stringify(t)); @@ -192,24 +192,24 @@ function fe(t) { return new Error(String(t)); } } -function gt(t) { - return fe(t).message; +function Yt(t) { + return ke(t).message; } -function pe(t) { +function Ie(t) { return new Promise((e) => setTimeout(e, t)); } -function bt(t, e) { - const r = pe(e).then(() => { +function er(t, e) { + const r = Ie(e).then(() => { }); return Promise.any([r, t()]); } -function yt(t, e = "obj") { +function tr(t, e = "obj") { const r = /* @__PURE__ */ new Set(); Object.getOwnPropertyNames(t).forEach((i) => { try { typeof t[i] == "function" && r.add(i); - } catch (n) { - console.debug(`Skipping ${i} on ${e} due to error: ${n}`); + } catch (o) { + console.debug(`Skipping ${i} on ${e} due to error: ${o}`); } }); let s = Object.getPrototypeOf(t); @@ -217,20 +217,20 @@ function yt(t, e = "obj") { Object.getOwnPropertyNames(s).forEach((i) => { try { typeof t[i] == "function" && r.add(i); - } catch (n) { - console.debug(`Skipping ${i} on ${e}'s prototype due to error: ${n}`); + } catch (o) { + console.debug(`Skipping ${i} on ${e}'s prototype due to error: ${o}`); } }), s = Object.getPrototypeOf(s); return r; } -function vt(t, e = {}) { +function rr(t, e = {}) { return new Proxy(e, { get(r, s) { return s in r ? r[s] : async (...i) => (await t())[s](...i); } }); } -class de { +class Re { /** * Create a DocumentCombiner instance * @@ -238,15 +238,15 @@ class de { * @param options Options used by this object when combining documents */ constructor(e, r) { - d(this, "baseDocument"); - d(this, "contributions", /* @__PURE__ */ new Map()); - d(this, "latestOutput"); - d(this, "options"); - d(this, "onDidRebuildEmitter", new ue()); + m(this, "baseDocument"); + m(this, "contributions", /* @__PURE__ */ new Map()); + m(this, "latestOutput"); + m(this, "options"); + m(this, "onDidRebuildEmitter", new Me()); /** Event that emits to announce that the document has been rebuilt and the output has been updated */ // Need `onDidRebuildEmitter` to be instantiated before this line // eslint-disable-next-line @typescript-eslint/member-ordering - d(this, "onDidRebuild", this.onDidRebuildEmitter.subscribe); + m(this, "onDidRebuild", this.onDidRebuildEmitter.subscribe); this.baseDocument = e, this.options = r, this.updateBaseDocument(e); } /** @@ -256,7 +256,7 @@ class de { * @returns Recalculated output document given the new starting state and existing other documents */ updateBaseDocument(e) { - return this.validateBaseDocument(e), this.baseDocument = this.options.copyDocuments ? w(e) : e, this.baseDocument = this.transformBaseDocumentAfterValidation(this.baseDocument), this.rebuild(); + return this.validateBaseDocument(e), this.baseDocument = this.options.copyDocuments ? B(e) : e, this.baseDocument = this.transformBaseDocumentAfterValidation(this.baseDocument), this.rebuild(); } /** * Add or update one of the contribution documents for the composition process @@ -276,12 +276,12 @@ class de { addOrUpdateContribution(e, r) { this.validateContribution(e, r); const s = this.contributions.get(e); - let i = this.options.copyDocuments && r ? w(r) : r; + let i = this.options.copyDocuments && r ? B(r) : r; i = this.transformContributionAfterValidation(e, i), this.contributions.set(e, i); try { return this.rebuild(); - } catch (n) { - throw s ? this.contributions.set(e, s) : this.contributions.delete(e), new Error(`Error when setting the document named ${e}: ${n}`); + } catch (o) { + throw s ? this.contributions.set(e, s) : this.contributions.delete(e), new Error(`Error when setting the document named ${e}: ${o}`); } } /** @@ -328,12 +328,12 @@ class de { */ rebuild() { if (this.contributions.size === 0) { - let r = w(this.baseDocument); + let r = B(this.baseDocument); return r = this.transformFinalOutputBeforeValidation(r), this.validateOutput(r), this.latestOutput = r, this.onDidRebuildEmitter.emit(void 0), this.latestOutput; } let e = this.baseDocument; return this.contributions.forEach((r) => { - e = he( + e = xe( e, r, this.options.ignoreDuplicateProperties @@ -419,52 +419,52 @@ class de { return e; } } -function x(...t) { +function U(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || Array.isArray(r)) && (e = !1); }), e; } -function R(...t) { +function F(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || !Array.isArray(r)) && (e = !1); }), e; } -function he(t, e, r) { - const s = w(t); - return e ? H(s, w(e), r) : s; +function xe(t, e, r) { + const s = B(t); + return e ? ce(s, B(e), r) : s; } -function H(t, e, r) { +function ce(t, e, r) { if (!e) return t; - if (x(t, e)) { + if (U(t, e)) { const s = t, i = e; - Object.keys(i).forEach((n) => { - if (Object.hasOwn(s, n)) { - if (x(s[n], i[n])) - s[n] = H( + Object.keys(i).forEach((o) => { + if (Object.hasOwn(s, o)) { + if (U(s[o], i[o])) + s[o] = ce( // We know these are objects from the `if` check /* eslint-disable no-type-assertion/no-type-assertion */ - s[n], - i[n], + s[o], + i[o], r /* eslint-enable no-type-assertion/no-type-assertion */ ); - else if (R(s[n], i[n])) - s[n] = s[n].concat( - i[n] + else if (F(s[o], i[o])) + s[o] = s[o].concat( + i[o] ); else if (!r) - throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`); + throw new Error(`Cannot merge objects: key "${o}" already exists in the target object`); } else - s[n] = i[n]; + s[o] = i[o]; }); } else - R(t, e) && t.push(...e); + F(t, e) && t.push(...e); return t; } -class Nt extends de { +class sr extends Re { // Making the protected base constructor public // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor(e, r) { @@ -474,9 +474,9 @@ class Nt extends de { return this.latestOutput; } } -class $t { +class ir { constructor(e = "Anonymous") { - d(this, "unsubscribers", /* @__PURE__ */ new Set()); + m(this, "unsubscribers", /* @__PURE__ */ new Set()); this.name = e; } /** @@ -499,18 +499,925 @@ class $t { return this.unsubscribers.clear(), r.every((s, i) => (s || console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${i} failed!`), s)); } } -class me extends ae { +class qe extends Te { } -class wt { +class or { constructor() { - d(this, "mutexesByID", /* @__PURE__ */ new Map()); + m(this, "mutexesByID", /* @__PURE__ */ new Map()); } get(e) { let r = this.mutexesByID.get(e); - return r || (r = new me(), this.mutexesByID.set(e, r), r); + return r || (r = new qe(), this.mutexesByID.set(e, r), r); } } -const W = [ +var Ve = Object.defineProperty, ze = (t, e, r) => e in t ? Ve(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r, l = (t, e, r) => (ze(t, typeof e != "symbol" ? e + "" : e, r), r); +const S = [ + "GEN", + "EXO", + "LEV", + "NUM", + "DEU", + "JOS", + "JDG", + "RUT", + "1SA", + "2SA", + // 10 + "1KI", + "2KI", + "1CH", + "2CH", + "EZR", + "NEH", + "EST", + "JOB", + "PSA", + "PRO", + // 20 + "ECC", + "SNG", + "ISA", + "JER", + "LAM", + "EZK", + "DAN", + "HOS", + "JOL", + "AMO", + // 30 + "OBA", + "JON", + "MIC", + "NAM", + "HAB", + "ZEP", + "HAG", + "ZEC", + "MAL", + "MAT", + // 40 + "MRK", + "LUK", + "JHN", + "ACT", + "ROM", + "1CO", + "2CO", + "GAL", + "EPH", + "PHP", + // 50 + "COL", + "1TH", + "2TH", + "1TI", + "2TI", + "TIT", + "PHM", + "HEB", + "JAS", + "1PE", + // 60 + "2PE", + "1JN", + "2JN", + "3JN", + "JUD", + "REV", + "TOB", + "JDT", + "ESG", + "WIS", + // 70 + "SIR", + "BAR", + "LJE", + "S3Y", + "SUS", + "BEL", + "1MA", + "2MA", + "3MA", + "4MA", + // 80 + "1ES", + "2ES", + "MAN", + "PS2", + "ODA", + "PSS", + "JSA", + // actual variant text for JOS, now in LXA text + "JDB", + // actual variant text for JDG, now in LXA text + "TBS", + // actual variant text for TOB, now in LXA text + "SST", + // actual variant text for SUS, now in LXA text // 90 + "DNT", + // actual variant text for DAN, now in LXA text + "BLT", + // actual variant text for BEL, now in LXA text + "XXA", + "XXB", + "XXC", + "XXD", + "XXE", + "XXF", + "XXG", + "FRT", + // 100 + "BAK", + "OTH", + "3ES", + // Used previously but really should be 2ES + "EZA", + // Used to be called 4ES, but not actually in any known project + "5EZ", + // Used to be called 5ES, but not actually in any known project + "6EZ", + // Used to be called 6ES, but not actually in any known project + "INT", + "CNC", + "GLO", + "TDX", + // 110 + "NDX", + "DAG", + "PS3", + "2BA", + "LBA", + "JUB", + "ENO", + "1MQ", + "2MQ", + "3MQ", + // 120 + "REP", + "4BA", + "LAO" +], V = [ + "XXA", + "XXB", + "XXC", + "XXD", + "XXE", + "XXF", + "XXG", + "FRT", + "BAK", + "OTH", + "INT", + "CNC", + "GLO", + "TDX", + "NDX" +], fe = [ + "Genesis", + "Exodus", + "Leviticus", + "Numbers", + "Deuteronomy", + "Joshua", + "Judges", + "Ruth", + "1 Samuel", + "2 Samuel", + "1 Kings", + "2 Kings", + "1 Chronicles", + "2 Chronicles", + "Ezra", + "Nehemiah", + "Esther (Hebrew)", + "Job", + "Psalms", + "Proverbs", + "Ecclesiastes", + "Song of Songs", + "Isaiah", + "Jeremiah", + "Lamentations", + "Ezekiel", + "Daniel (Hebrew)", + "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", + "Tobit", + "Judith", + "Esther Greek", + "Wisdom of Solomon", + "Sirach (Ecclesiasticus)", + "Baruch", + "Letter of Jeremiah", + "Song of 3 Young Men", + "Susanna", + "Bel and the Dragon", + "1 Maccabees", + "2 Maccabees", + "3 Maccabees", + "4 Maccabees", + "1 Esdras (Greek)", + "2 Esdras (Latin)", + "Prayer of Manasseh", + "Psalm 151", + "Odes", + "Psalms of Solomon", + // WARNING, if you change the spelling of the *obsolete* tag be sure to update + // IsObsolete routine + "Joshua A. *obsolete*", + "Judges B. *obsolete*", + "Tobit S. *obsolete*", + "Susanna Th. *obsolete*", + "Daniel Th. *obsolete*", + "Bel Th. *obsolete*", + "Extra A", + "Extra B", + "Extra C", + "Extra D", + "Extra E", + "Extra F", + "Extra G", + "Front Matter", + "Back Matter", + "Other Matter", + "3 Ezra *obsolete*", + "Apocalypse of Ezra", + "5 Ezra (Latin Prologue)", + "6 Ezra (Latin Epilogue)", + "Introduction", + "Concordance ", + "Glossary ", + "Topical Index", + "Names Index", + "Daniel Greek", + "Psalms 152-155", + "2 Baruch (Apocalypse)", + "Letter of Baruch", + "Jubilees", + "Enoch", + "1 Meqabyan", + "2 Meqabyan", + "3 Meqabyan", + "Reproof (Proverbs 25-31)", + "4 Baruch (Rest of Baruch)", + "Laodiceans" +], W = We(); +function C(t, e = !0) { + return e && (t = t.toUpperCase()), t in W ? W[t] : 0; +} +function z(t) { + return C(t) > 0; +} +function Je(t) { + const e = typeof t == "string" ? C(t) : t; + return e >= 40 && e <= 66; +} +function Ge(t) { + return (typeof t == "string" ? C(t) : t) <= 39; +} +function he(t) { + return t <= 66; +} +function _e(t) { + const e = typeof t == "string" ? C(t) : t; + return me(e) && !he(e); +} +function* Xe() { + for (let t = 1; t <= S.length; t++) + yield t; +} +const Ke = 1, pe = S.length; +function He() { + return ["XXA", "XXB", "XXC", "XXD", "XXE", "XXF", "XXG"]; +} +function J(t, e = "***") { + const r = t - 1; + return r < 0 || r >= S.length ? e : S[r]; +} +function de(t) { + return t <= 0 || t > pe ? "******" : fe[t - 1]; +} +function Le(t) { + return de(C(t)); +} +function me(t) { + const e = typeof t == "number" ? J(t) : t; + return z(e) && !V.includes(e); +} +function Ue(t) { + const e = typeof t == "number" ? J(t) : t; + return z(e) && V.includes(e); +} +function Fe(t) { + return fe[t - 1].includes("*obsolete*"); +} +function We() { + const t = {}; + for (let e = 0; e < S.length; e++) + t[S[e]] = e + 1; + return t; +} +const E = { + allBookIds: S, + nonCanonicalIds: V, + bookIdToNumber: C, + isBookIdValid: z, + isBookNT: Je, + isBookOT: Ge, + isBookOTNT: he, + isBookDC: _e, + allBookNumbers: Xe, + firstBook: Ke, + lastBook: pe, + extraBooks: He, + bookNumberToId: J, + bookNumberToEnglishName: de, + bookIdToEnglishName: Le, + isCanonical: me, + isExtraMaterial: Ue, + isObsolete: Fe +}; +var w = /* @__PURE__ */ ((t) => (t[t.Unknown = 0] = "Unknown", t[t.Original = 1] = "Original", t[t.Septuagint = 2] = "Septuagint", t[t.Vulgate = 3] = "Vulgate", t[t.English = 4] = "English", t[t.RussianProtestant = 5] = "RussianProtestant", t[t.RussianOrthodox = 6] = "RussianOrthodox", t))(w || {}); +const N = class { + // private versInfo: Versification; + constructor(e) { + if (l(this, "name"), l(this, "fullPath"), l(this, "isPresent"), l(this, "hasVerseSegments"), l(this, "isCustomized"), l(this, "baseVersification"), l(this, "scriptureBooks"), l(this, "_type"), e != null) + typeof e == "string" ? this.name = e : this._type = e; + else + throw new Error("Argument null"); + } + get type() { + return this._type; + } + equals(e) { + return !e.type || !this.type ? !1 : e.type === this.type; + } +}; +l(N, "Original", new N(w.Original)), l(N, "Septuagint", new N(w.Septuagint)), l(N, "Vulgate", new N(w.Vulgate)), l(N, "English", new N(w.English)), l(N, "RussianProtestant", new N(w.RussianProtestant)), l(N, "RussianOrthodox", new N(w.RussianOrthodox)); +let j = N; +function Z(t, e) { + const r = e[0]; + for (let s = 1; s < e.length; s++) + t = t.split(e[s]).join(r); + return t.split(r); +} +var ge = /* @__PURE__ */ ((t) => (t[t.Valid = 0] = "Valid", t[t.UnknownVersification = 1] = "UnknownVersification", t[t.OutOfRange = 2] = "OutOfRange", t[t.VerseOutOfOrder = 3] = "VerseOutOfOrder", t[t.VerseRepeated = 4] = "VerseRepeated", t))(ge || {}); +const y = class f { + constructor(e, r, s, i) { + if (l(this, "firstChapter"), l(this, "lastChapter"), l(this, "lastVerse"), l(this, "hasSegmentsDefined"), l(this, "text"), l(this, "BBBCCCVVVS"), l(this, "longHashCode"), l(this, "versification"), l(this, "rtlMark", "‏"), l(this, "_bookNum", 0), l(this, "_chapterNum", 0), l(this, "_verseNum", 0), l(this, "_verse"), s == null && i == null) + if (e != null && typeof e == "string") { + const o = e, n = r != null && r instanceof j ? r : void 0; + this.setEmpty(n), this.parse(o); + } else if (e != null && typeof e == "number") { + const o = r != null && r instanceof j ? r : void 0; + this.setEmpty(o), this._verseNum = e % f.chapterDigitShifter, this._chapterNum = Math.floor( + e % f.bookDigitShifter / f.chapterDigitShifter + ), this._bookNum = Math.floor(e / f.bookDigitShifter); + } else if (r == null) + if (e != null && e instanceof f) { + const o = e; + this._bookNum = o.bookNum, this._chapterNum = o.chapterNum, this._verseNum = o.verseNum, this._verse = o.verse, this.versification = o.versification; + } else { + if (e == null) + return; + const o = e instanceof j ? e : f.defaultVersification; + this.setEmpty(o); + } + else + throw new Error("VerseRef constructor not supported."); + else if (e != null && r != null && s != null) + if (typeof e == "string" && typeof r == "string" && typeof s == "string") + this.setEmpty(i), this.updateInternal(e, r, s); + else if (typeof e == "number" && typeof r == "number" && typeof s == "number") + this._bookNum = e, this._chapterNum = r, this._verseNum = s, this.versification = i ?? f.defaultVersification; + else + throw new Error("VerseRef constructor not supported."); + else + throw new Error("VerseRef constructor not supported."); + } + /** + * @deprecated Will be removed in v2. Replace `VerseRef.parse('...')` with `new VerseRef('...')` + * or refactor to use `VerseRef.tryParse('...')` which has a different return type. + */ + static parse(e, r = f.defaultVersification) { + const s = new f(r); + return s.parse(e), s; + } + /** + * Determines if the verse string is in a valid format (does not consider versification). + */ + static isVerseParseable(e) { + return e.length > 0 && "0123456789".includes(e[0]) && !e.endsWith(this.verseRangeSeparator) && !e.endsWith(this.verseSequenceIndicator); + } + /** + * Tries to parse the specified string into a verse reference. + * @param str - The string to attempt to parse. + * @returns success: `true` if the specified string was successfully parsed, `false` otherwise. + * @returns verseRef: The result of the parse if successful, or empty VerseRef if it failed + */ + static tryParse(e) { + let r; + try { + return r = f.parse(e), { success: !0, verseRef: r }; + } catch (s) { + if (s instanceof T) + return r = new f(), { success: !1, verseRef: r }; + throw s; + } + } + /** + * Gets the reference as a comparable integer where the book, chapter, and verse each occupy 3 + * digits. + * @param bookNum - Book number (this is 1-based, not an index). + * @param chapterNum - Chapter number. + * @param verseNum - Verse number. + * @returns The reference as a comparable integer where the book, chapter, and verse each occupy 3 + * digits. + */ + static getBBBCCCVVV(e, r, s) { + return e % f.bcvMaxValue * f.bookDigitShifter + (r >= 0 ? r % f.bcvMaxValue * f.chapterDigitShifter : 0) + (s >= 0 ? s % f.bcvMaxValue : 0); + } + /** + * Parses a verse string and gets the leading numeric portion as a number. + * @param verseStr - verse string to parse + * @returns true if the entire string could be parsed as a single, simple verse number (1-999); + * false if the verse string represented a verse bridge, contained segment letters, or was invalid + */ + static tryGetVerseNum(e) { + let r; + if (!e) + return r = -1, { success: !0, vNum: r }; + r = 0; + let s; + for (let i = 0; i < e.length; i++) { + if (s = e[i], s < "0" || s > "9") + return i === 0 && (r = -1), { success: !1, vNum: r }; + if (r = r * 10 + +s - +"0", r > f.bcvMaxValue) + return r = -1, { success: !1, vNum: r }; + } + return { success: !0, vNum: r }; + } + /** + * Checks to see if a VerseRef hasn't been set - all values are the default. + */ + get isDefault() { + return this.bookNum === 0 && this.chapterNum === 0 && this.verseNum === 0 && this.versification == null; + } + /** + * Gets whether the verse contains multiple verses. + */ + get hasMultiple() { + return this._verse != null && (this._verse.includes(f.verseRangeSeparator) || this._verse.includes(f.verseSequenceIndicator)); + } + /** + * Gets or sets the book of the reference. Book is the 3-letter abbreviation in capital letters, + * e.g. `'MAT'`. + */ + get book() { + return E.bookNumberToId(this.bookNum, ""); + } + set book(e) { + this.bookNum = E.bookIdToNumber(e); + } + /** + * Gets or sets the chapter of the reference,. e.g. `'3'`. + */ + get chapter() { + return this.isDefault || this._chapterNum < 0 ? "" : this._chapterNum.toString(); + } + set chapter(e) { + const r = +e; + this._chapterNum = Number.isInteger(r) ? r : -1; + } + /** + * Gets or sets the verse of the reference, including range, segments, and sequences, e.g. `'4'`, + * or `'4b-5a, 7'`. + */ + get verse() { + return this._verse != null ? this._verse : this.isDefault || this._verseNum < 0 ? "" : this._verseNum.toString(); + } + set verse(e) { + const { success: r, vNum: s } = f.tryGetVerseNum(e); + this._verse = r ? void 0 : e.replace(this.rtlMark, ""), this._verseNum = s, !(this._verseNum >= 0) && ({ vNum: this._verseNum } = f.tryGetVerseNum(this._verse)); + } + /** + * Get or set Book based on book number, e.g. `42`. + */ + get bookNum() { + return this._bookNum; + } + set bookNum(e) { + if (e <= 0 || e > E.lastBook) + throw new T( + "BookNum must be greater than zero and less than or equal to last book" + ); + this._bookNum = e; + } + /** + * Gets or sets the chapter number, e.g. `3`. `-1` if not valid. + */ + get chapterNum() { + return this._chapterNum; + } + set chapterNum(e) { + this.chapterNum = e; + } + /** + * Gets or sets verse start number, e.g. `4`. `-1` if not valid. + */ + get verseNum() { + return this._verseNum; + } + set verseNum(e) { + this._verseNum = e; + } + /** + * String representing the versification (should ONLY be used for serialization/deserialization). + * + * @remarks This is for backwards compatibility when ScrVers was an enumeration. + */ + get versificationStr() { + var e; + return (e = this.versification) == null ? void 0 : e.name; + } + set versificationStr(e) { + this.versification = this.versification != null ? new j(e) : void 0; + } + /** + * Determines if the reference is valid. + */ + get valid() { + return this.validStatus === 0; + } + /** + * Get the valid status for this reference. + */ + get validStatus() { + return this.validateVerse(f.verseRangeSeparators, f.verseSequenceIndicators); + } + /** + * Gets the reference as a comparable integer where the book, + * chapter, and verse each occupy three digits and the verse is 0. + */ + get BBBCCC() { + return f.getBBBCCCVVV(this._bookNum, this._chapterNum, 0); + } + /** + * Gets the reference as a comparable integer where the book, + * chapter, and verse each occupy three digits. If verse is not null + * (i.e., this reference represents a complex reference with verse + * segments or bridge) this cannot be used for an exact comparison. + */ + get BBBCCCVVV() { + return f.getBBBCCCVVV(this._bookNum, this._chapterNum, this._verseNum); + } + /** + * Gets whether the verse is defined as an excluded verse in the versification. + * Does not handle verse ranges. + */ + // eslint-disable-next-line @typescript-eslint/class-literal-property-style + get isExcluded() { + return !1; + } + /** + * Parses the reference in the specified string. + * Optionally versification can follow reference as in GEN 3:11/4 + * Throw an exception if + * - invalid book name + * - chapter number is missing or not a number + * - verse number is missing or does not start with a number + * - versification is invalid + * @param verseStr - string to parse e.g. 'MAT 3:11' + */ + parse(e) { + if (e = e.replace(this.rtlMark, ""), e.includes("/")) { + const o = e.split("/"); + if (e = o[0], o.length > 1) + try { + const n = +o[1].trim(); + this.versification = new j(w[n]); + } catch { + throw new T("Invalid reference : " + e); + } + } + const r = e.trim().split(" "); + if (r.length !== 2) + throw new T("Invalid reference : " + e); + const s = r[1].split(":"), i = +s[0]; + if (s.length !== 2 || E.bookIdToNumber(r[0]) === 0 || !Number.isInteger(i) || i < 0 || !f.isVerseParseable(s[1])) + throw new T("Invalid reference : " + e); + this.updateInternal(r[0], s[0], s[1]); + } + /** + * Simplifies this verse ref so that it has no bridging of verses or + * verse segments like `'1a'`. + */ + simplify() { + this._verse = void 0; + } + /** + * Makes a clone of the reference. + * + * @returns The cloned VerseRef. + */ + clone() { + return new f(this); + } + toString() { + const e = this.book; + return e === "" ? "" : `${e} ${this.chapter}:${this.verse}`; + } + /** + * Compares this `VerseRef` with supplied one. + * @param verseRef - object to compare this one to. + * @returns `true` if this `VerseRef` is equal to the supplied on, `false` otherwise. + */ + equals(e) { + return e instanceof f ? e._bookNum === this._bookNum && e._chapterNum === this._chapterNum && e._verseNum === this._verseNum && e.verse === this.verse && e.versification != null && this.versification != null && e.versification.equals(this.versification) : !1; + } + /** + * Enumerate all individual verses contained in a VerseRef. + * Verse ranges are indicated by "-" and consecutive verses by ","s. + * Examples: + * GEN 1:2 returns GEN 1:2 + * GEN 1:1a-3b,5 returns GEN 1:1a, GEN 1:2, GEN 1:3b, GEN 1:5 + * GEN 1:2a-2c returns //! ?????? + * + * @param specifiedVersesOnly - if set to true return only verses that are + * explicitly specified only, not verses within a range. Defaults to `false`. + * @param verseRangeSeparators - Verse range separators. + * Defaults to `VerseRef.verseRangeSeparators`. + * @param verseSequenceSeparators - Verse sequence separators. + * Defaults to `VerseRef.verseSequenceIndicators`. + * @returns An array of all single verse references in this VerseRef. + */ + allVerses(e = !1, r = f.verseRangeSeparators, s = f.verseSequenceIndicators) { + if (this._verse == null || this.chapterNum <= 0) + return [this.clone()]; + const i = [], o = Z(this._verse, s); + for (const n of o.map((a) => Z(a, r))) { + const a = this.clone(); + a.verse = n[0]; + const h = a.verseNum; + if (i.push(a), n.length > 1) { + const p = this.clone(); + if (p.verse = n[1], !e) + for (let u = h + 1; u < p.verseNum; u++) { + const c = new f( + this._bookNum, + this._chapterNum, + u, + this.versification + ); + this.isExcluded || i.push(c); + } + i.push(p); + } + } + return i; + } + /** + * Validates a verse number using the supplied separators rather than the defaults. + */ + validateVerse(e, r) { + if (!this.verse) + return this.internalValid; + let s = 0; + for (const i of this.allVerses(!0, e, r)) { + const o = i.internalValid; + if (o !== 0) + return o; + const n = i.BBBCCCVVV; + if (s > n) + return 3; + if (s === n) + return 4; + s = n; + } + return 0; + } + /** + * Gets whether a single verse reference is valid. + */ + get internalValid() { + return this.versification == null ? 1 : this._bookNum <= 0 || this._bookNum > E.lastBook ? 2 : (E.isCanonical(this._bookNum), 0); + } + setEmpty(e = f.defaultVersification) { + this._bookNum = 0, this._chapterNum = -1, this._verse = void 0, this.versification = e; + } + updateInternal(e, r, s) { + this.bookNum = E.bookIdToNumber(e), this.chapter = r, this.verse = s; + } +}; +l(y, "defaultVersification", j.English), l(y, "verseRangeSeparator", "-"), l(y, "verseSequenceIndicator", ","), l(y, "verseRangeSeparators", [y.verseRangeSeparator]), l(y, "verseSequenceIndicators", [y.verseSequenceIndicator]), l(y, "chapterDigitShifter", 1e3), l(y, "bookDigitShifter", y.chapterDigitShifter * y.chapterDigitShifter), l(y, "bcvMaxValue", y.chapterDigitShifter - 1), /** +* The valid status of the VerseRef. +*/ +l(y, "ValidStatusType", ge); +class T extends Error { +} +var Q = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, O = {}, Ze = () => { + const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", i = "\\u1ab0-\\u1aff", o = "\\u1dc0-\\u1dff", n = e + r + s + i + o, a = "\\ufe0e\\ufe0f", h = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", p = `[${t}]`, u = `[${n}]`, c = "\\ud83c[\\udffb-\\udfff]", d = `(?:${u}|${c})`, v = `[^${t}]`, b = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", P = "[\\ud800-\\udbff][\\udc00-\\udfff]", x = "\\u200d", $e = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", Se = `[${h}]`, H = `${d}?`, L = `[${a}]?`, Oe = `(?:${x}(?:${[v, b, P].join("|")})${L + H})*`, je = L + H + Oe, Ce = `(?:${[`${v}${u}?`, u, b, P, p, Se].join("|")})`; + return new RegExp(`${$e}|${c}(?=${c})|${Ce + je}`, "g"); +}, Qe = Q && Q.__importDefault || function(t) { + return t && t.__esModule ? t : { default: t }; +}; +Object.defineProperty(O, "__esModule", { value: !0 }); +var I = Qe(Ze); +function q(t) { + if (typeof t != "string") + throw new Error("A string is expected as input"); + return t.match(I.default()) || []; +} +var Ye = O.toArray = q; +function G(t) { + if (typeof t != "string") + throw new Error("Input must be a string"); + var e = t.match(I.default()); + return e === null ? 0 : e.length; +} +var et = O.length = G; +function be(t, e, r) { + if (e === void 0 && (e = 0), typeof t != "string") + throw new Error("Input must be a string"); + (typeof e != "number" || e < 0) && (e = 0), typeof r == "number" && r < 0 && (r = 0); + var s = t.match(I.default()); + return s ? s.slice(e, r).join("") : ""; +} +var tt = O.substring = be; +function rt(t, e, r) { + if (e === void 0 && (e = 0), typeof t != "string") + throw new Error("Input must be a string"); + var s = G(t); + if (typeof e != "number" && (e = parseInt(e, 10)), e >= s) + return ""; + e < 0 && (e += s); + var i; + typeof r > "u" ? i = s : (typeof r != "number" && (r = parseInt(r, 10)), i = r >= 0 ? r + e : e); + var o = t.match(I.default()); + return o ? o.slice(e, i).join("") : ""; +} +var st = O.substr = rt; +function it(t, e, r, s) { + if (e === void 0 && (e = 16), r === void 0 && (r = "#"), s === void 0 && (s = "right"), typeof t != "string" || typeof e != "number") + throw new Error("Invalid arguments specified"); + if (["left", "right"].indexOf(s) === -1) + throw new Error("Pad position should be either left or right"); + typeof r != "string" && (r = String(r)); + var i = G(t); + if (i > e) + return be(t, 0, e); + if (i < e) { + var o = r.repeat(e - i); + return s === "left" ? o + t : t + o; + } + return t; +} +var ye = O.limit = it; +function ot(t, e, r) { + if (r === void 0 && (r = 0), typeof t != "string") + throw new Error("Input must be a string"); + if (t === "") + return e === "" ? 0 : -1; + r = Number(r), r = isNaN(r) ? 0 : r, e = String(e); + var s = q(t); + if (r >= s.length) + return e === "" ? s.length : -1; + if (e === "") + return r; + var i = q(e), o = !1, n; + for (n = r; n < s.length; n += 1) { + for (var a = 0; a < i.length && i[a] === s[n + a]; ) + a += 1; + if (a === i.length && i[a - 1] === s[n + a - 1]) { + o = !0; + break; + } + } + return o ? n : -1; +} +var nt = O.indexOf = ot; +function ar(t, e) { + if (!(e > g(t) || e < -g(t))) + return R(t, e, 1); +} +function ur(t, e) { + return e < 0 || e > g(t) - 1 ? "" : R(t, e, 1); +} +function lr(t, e) { + if (!(e < 0 || e > g(t) - 1)) + return R(t, e, 1).codePointAt(0); +} +function cr(t, e, r = g(t)) { + const s = ut(t, e); + return !(s === -1 || s + g(e) !== r); +} +function at(t, e, r = 0) { + const s = k(t, r); + return _(s, e) !== -1; +} +function _(t, e, r = 0) { + return nt(t, e, r); +} +function ut(t, e, r) { + let s = r === void 0 ? g(t) : r; + s < 0 ? s = 0 : s >= g(t) && (s = g(t) - 1); + for (let i = s; i >= 0; i--) + if (R(t, i, g(e)) === e) + return i; + return -1; +} +function g(t) { + return et(t); +} +function fr(t, e) { + const r = e.toUpperCase(); + return r === "NONE" ? t : t.normalize(r); +} +function hr(t, e, r = " ") { + return e <= g(t) ? t : ye(t, e, r, "right"); +} +function pr(t, e, r = " ") { + return e <= g(t) ? t : ye(t, e, r, "left"); +} +function Y(t, e) { + return e > t ? t : e < -t ? 0 : e < 0 ? e + t : e; +} +function dr(t, e, r) { + const s = g(t); + if (e > s || r && (e > r && !(e >= 0 && e < s && r < 0 && r > -s) || r < -s)) + return ""; + const i = Y(s, e), o = r ? Y(s, r) : void 0; + return k(t, i, o); +} +function ee(t, e, r) { + const s = []; + if (r !== void 0 && r <= 0) + return [t]; + if (e === "") + return ct(t).slice(0, r); + let i = e; + (typeof e == "string" || e instanceof RegExp && !at(e.flags, "g")) && (i = new RegExp(e, "g")); + const o = t.match(i); + let n = 0; + if (!o) + return [t]; + for (let a = 0; a < (r ? r - 1 : o.length); a++) { + const h = _(t, o[a], n), p = g(o[a]); + if (s.push(k(t, n, h)), n = h + p, r !== void 0 && s.length === r) + break; + } + return s.push(k(t, n)), s; +} +function lt(t, e, r = 0) { + return _(t, e, r) === r; +} +function R(t, e = 0, r = g(t) - e) { + return st(t, e, r); +} +function k(t, e, r = g(t)) { + return tt(t, e, r); +} +function ct(t) { + return Ye(t); +} +const ve = [ { shortName: "ERR", fullNames: ["ERROR"], chapters: -1 }, { shortName: "GEN", fullNames: ["Genesis"], chapters: 50 }, { shortName: "EXO", fullNames: ["Exodus"], chapters: 40 }, @@ -578,282 +1485,131 @@ const W = [ { shortName: "3JN", fullNames: ["3 John"], chapters: 1 }, { shortName: "JUD", fullNames: ["Jude"], chapters: 1 }, { shortName: "REV", fullNames: ["Revelation"], chapters: 22 } -], ge = 1, be = W.length - 1, ye = 1, ve = 1, Ne = (t) => { +], ft = 1, ht = ve.length - 1, pt = 1, dt = 1, mt = (t) => { var e; - return ((e = W[t]) == null ? void 0 : e.chapters) ?? -1; -}, Et = (t, e) => ({ - bookNum: Math.max(ge, Math.min(t.bookNum + e, be)), + return ((e = ve[t]) == null ? void 0 : e.chapters) ?? -1; +}, mr = (t, e) => ({ + bookNum: Math.max(ft, Math.min(t.bookNum + e, ht)), chapterNum: 1, verseNum: 1 -}), Ot = (t, e) => ({ +}), gr = (t, e) => ({ ...t, chapterNum: Math.min( - Math.max(ye, t.chapterNum + e), - Ne(t.bookNum) + Math.max(pt, t.chapterNum + e), + mt(t.bookNum) ), verseNum: 1 -}), jt = (t, e) => ({ +}), br = (t, e) => ({ ...t, - verseNum: Math.max(ve, t.verseNum + e) -}), St = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), Pt = (t) => async (...e) => { + verseNum: Math.max(dt, t.verseNum + e) +}); +async function yr(t, e, r) { + const s = E.bookNumberToId(t); + if (!lt(Intl.getCanonicalLocales(e)[0], "zh")) + return r({ + localizeKey: `LocalizedId.${s}`, + languagesToSearch: [e] + }); + const i = await r({ + localizeKey: `Book.${s}`, + languagesToSearch: [e] + }), o = ee(i, "-"); + return ee(o[0], "ÿ08")[0].trim(); +} +const vr = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), Nr = (t) => async (...e) => { const r = t.map(async (s) => s(...e)); return (await Promise.all(r)).every((s) => s); }; -var I = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, y = {}, $e = () => { - const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", i = "\\u1ab0-\\u1aff", n = "\\u1dc0-\\u1dff", o = e + r + s + i + n, a = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", p = `[${t}]`, u = `[${o}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, g = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", N = "[\\ud800-\\udbff][\\udc00-\\udfff]", P = "\\u200d", ee = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", te = `[${c}]`, D = `${f}?`, M = `[${a}]?`, re = `(?:${P}(?:${[g, m, N].join("|")})${M + D})*`, se = M + D + re, ie = `(?:${[`${g}${u}?`, u, m, N, p, te].join("|")})`; - return new RegExp(`${ee}|${l}(?=${l})|${ie + se}`, "g"); -}, we = I && I.__importDefault || function(t) { - return t && t.__esModule ? t : { default: t }; -}; -Object.defineProperty(y, "__esModule", { value: !0 }); -var j = we($e); -function A(t) { - if (typeof t != "string") - throw new Error("A string is expected as input"); - return t.match(j.default()) || []; +var gt = Object.getOwnPropertyNames, bt = Object.getOwnPropertySymbols, yt = Object.prototype.hasOwnProperty; +function te(t, e) { + return function(s, i, o) { + return t(s, i, o) && e(s, i, o); + }; } -var Ee = y.toArray = A; -function C(t) { - if (typeof t != "string") - throw new Error("Input must be a string"); - var e = t.match(j.default()); - return e === null ? 0 : e.length; +function D(t) { + return function(r, s, i) { + if (!r || !s || typeof r != "object" || typeof s != "object") + return t(r, s, i); + var o = i.cache, n = o.get(r), a = o.get(s); + if (n && a) + return n === s && a === r; + o.set(r, s), o.set(s, r); + var h = t(r, s, i); + return o.delete(r), o.delete(s), h; + }; } -var Oe = y.length = C; -function L(t, e, r) { - if (e === void 0 && (e = 0), typeof t != "string") - throw new Error("Input must be a string"); - (typeof e != "number" || e < 0) && (e = 0), typeof r == "number" && r < 0 && (r = 0); - var s = t.match(j.default()); - return s ? s.slice(e, r).join("") : ""; +function re(t) { + return gt(t).concat(bt(t)); } -var je = y.substring = L; -function Se(t, e, r) { - if (e === void 0 && (e = 0), typeof t != "string") - throw new Error("Input must be a string"); - var s = C(t); - if (typeof e != "number" && (e = parseInt(e, 10)), e >= s) - return ""; - e < 0 && (e += s); - var i; - typeof r > "u" ? i = s : (typeof r != "number" && (r = parseInt(r, 10)), i = r >= 0 ? r + e : e); - var n = t.match(j.default()); - return n ? n.slice(e, i).join("") : ""; +var Ne = Object.hasOwn || function(t, e) { + return yt.call(t, e); +}; +function A(t, e) { + return t || e ? t === e : t === e || t !== t && e !== e; } -var Pe = y.substr = Se; -function Ae(t, e, r, s) { - if (e === void 0 && (e = 16), r === void 0 && (r = "#"), s === void 0 && (s = "right"), typeof t != "string" || typeof e != "number") - throw new Error("Invalid arguments specified"); - if (["left", "right"].indexOf(s) === -1) - throw new Error("Pad position should be either left or right"); - typeof r != "string" && (r = String(r)); - var i = C(t); - if (i > e) - return L(t, 0, e); - if (i < e) { - var n = r.repeat(e - i); - return s === "left" ? n + t : t + n; - } - return t; +var Ee = "_owner", se = Object.getOwnPropertyDescriptor, ie = Object.keys; +function vt(t, e, r) { + var s = t.length; + if (e.length !== s) + return !1; + for (; s-- > 0; ) + if (!r.equals(t[s], e[s], s, s, t, e, r)) + return !1; + return !0; } -var Z = y.limit = Ae; -function Ce(t, e, r) { - if (r === void 0 && (r = 0), typeof t != "string") - throw new Error("Input must be a string"); - if (t === "") - return e === "" ? 0 : -1; - r = Number(r), r = isNaN(r) ? 0 : r, e = String(e); - var s = A(t); - if (r >= s.length) - return e === "" ? s.length : -1; - if (e === "") - return r; - var i = A(e), n = !1, o; - for (o = r; o < s.length; o += 1) { - for (var a = 0; a < i.length && i[a] === s[o + a]; ) - a += 1; - if (a === i.length && i[a - 1] === s[o + a - 1]) { - n = !0; - break; +function Nt(t, e) { + return A(t.getTime(), e.getTime()); +} +function oe(t, e, r) { + if (t.size !== e.size) + return !1; + for (var s = {}, i = t.entries(), o = 0, n, a; (n = i.next()) && !n.done; ) { + for (var h = e.entries(), p = !1, u = 0; (a = h.next()) && !a.done; ) { + var c = n.value, d = c[0], v = c[1], b = a.value, P = b[0], x = b[1]; + !p && !s[u] && (p = r.equals(d, P, o, u, t, e, r) && r.equals(v, x, d, P, t, e, r)) && (s[u] = !0), u++; } + if (!p) + return !1; + o++; } - return n ? o : -1; -} -var qe = y.indexOf = Ce; -function At(t, e) { - if (!(e > h(t) || e < -h(t))) - return S(t, e, 1); -} -function Ct(t, e) { - return e < 0 || e > h(t) - 1 ? "" : S(t, e, 1); + return !0; } -function qt(t, e) { - if (!(e < 0 || e > h(t) - 1)) - return S(t, e, 1).codePointAt(0); -} -function Tt(t, e, r = h(t)) { - const s = De(t, e); - return !(s === -1 || s + h(e) !== r); -} -function Te(t, e, r = 0) { - const s = O(t, r); - return q(s, e) !== -1; -} -function q(t, e, r = 0) { - return qe(t, e, r); -} -function De(t, e, r) { - let s = r === void 0 ? h(t) : r; - s < 0 ? s = 0 : s >= h(t) && (s = h(t) - 1); - for (let i = s; i >= 0; i--) - if (S(t, i, h(e)) === e) - return i; - return -1; -} -function h(t) { - return Oe(t); -} -function Dt(t, e) { - const r = e.toUpperCase(); - return r === "NONE" ? t : t.normalize(r); -} -function Mt(t, e, r = " ") { - return e <= h(t) ? t : Z(t, e, r, "right"); -} -function xt(t, e, r = " ") { - return e <= h(t) ? t : Z(t, e, r, "left"); -} -function B(t, e) { - return e > t ? t : e < -t ? 0 : e < 0 ? e + t : e; -} -function Rt(t, e, r) { - const s = h(t); - if (e > s || r && (e > r && !(e >= 0 && e < s && r < 0 && r > -s) || r < -s)) - return ""; - const i = B(s, e), n = r ? B(s, r) : void 0; - return O(t, i, n); -} -function It(t, e, r) { - const s = []; - if (r !== void 0 && r <= 0) - return [t]; - if (e === "") - return Me(t).slice(0, r); - let i = e; - (typeof e == "string" || e instanceof RegExp && !Te(e.flags, "g")) && (i = new RegExp(e, "g")); - const n = t.match(i); - let o = 0; - if (!n) - return [t]; - for (let a = 0; a < (r ? r - 1 : n.length); a++) { - const c = q(t, n[a], o), p = h(n[a]); - if (s.push(O(t, o, c)), o = c + p, r !== void 0 && s.length === r) - break; - } - return s.push(O(t, o)), s; -} -function Bt(t, e, r = 0) { - return q(t, e, r) === r; -} -function S(t, e = 0, r = h(t) - e) { - return Pe(t, e, r); -} -function O(t, e, r = h(t)) { - return je(t, e, r); -} -function Me(t) { - return Ee(t); -} -var xe = Object.getOwnPropertyNames, Re = Object.getOwnPropertySymbols, Ie = Object.prototype.hasOwnProperty; -function z(t, e) { - return function(s, i, n) { - return t(s, i, n) && e(s, i, n); - }; -} -function E(t) { - return function(r, s, i) { - if (!r || !s || typeof r != "object" || typeof s != "object") - return t(r, s, i); - var n = i.cache, o = n.get(r), a = n.get(s); - if (o && a) - return o === s && a === r; - n.set(r, s), n.set(s, r); - var c = t(r, s, i); - return n.delete(r), n.delete(s), c; - }; -} -function G(t) { - return xe(t).concat(Re(t)); -} -var X = Object.hasOwn || function(t, e) { - return Ie.call(t, e); -}; -function v(t, e) { - return t || e ? t === e : t === e || t !== t && e !== e; -} -var Q = "_owner", V = Object.getOwnPropertyDescriptor, J = Object.keys; -function Be(t, e, r) { - var s = t.length; - if (e.length !== s) - return !1; - for (; s-- > 0; ) - if (!r.equals(t[s], e[s], s, s, t, e, r)) - return !1; - return !0; -} -function ze(t, e) { - return v(t.getTime(), e.getTime()); -} -function _(t, e, r) { - if (t.size !== e.size) - return !1; - for (var s = {}, i = t.entries(), n = 0, o, a; (o = i.next()) && !o.done; ) { - for (var c = e.entries(), p = !1, u = 0; (a = c.next()) && !a.done; ) { - var l = o.value, f = l[0], g = l[1], m = a.value, N = m[0], P = m[1]; - !p && !s[u] && (p = r.equals(f, N, n, u, t, e, r) && r.equals(g, P, f, N, t, e, r)) && (s[u] = !0), u++; - } - if (!p) - return !1; - n++; - } - return !0; -} -function Ge(t, e, r) { - var s = J(t), i = s.length; - if (J(e).length !== i) +function Et(t, e, r) { + var s = ie(t), i = s.length; + if (ie(e).length !== i) return !1; - for (var n; i-- > 0; ) - if (n = s[i], n === Q && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !X(e, n) || !r.equals(t[n], e[n], n, n, t, e, r)) + for (var o; i-- > 0; ) + if (o = s[i], o === Ee && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !Ne(e, o) || !r.equals(t[o], e[o], o, o, t, e, r)) return !1; return !0; } -function $(t, e, r) { - var s = G(t), i = s.length; - if (G(e).length !== i) +function M(t, e, r) { + var s = re(t), i = s.length; + if (re(e).length !== i) return !1; - for (var n, o, a; i-- > 0; ) - if (n = s[i], n === Q && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !X(e, n) || !r.equals(t[n], e[n], n, n, t, e, r) || (o = V(t, n), a = V(e, n), (o || a) && (!o || !a || o.configurable !== a.configurable || o.enumerable !== a.enumerable || o.writable !== a.writable))) + for (var o, n, a; i-- > 0; ) + if (o = s[i], o === Ee && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !Ne(e, o) || !r.equals(t[o], e[o], o, o, t, e, r) || (n = se(t, o), a = se(e, o), (n || a) && (!n || !a || n.configurable !== a.configurable || n.enumerable !== a.enumerable || n.writable !== a.writable))) return !1; return !0; } -function Ve(t, e) { - return v(t.valueOf(), e.valueOf()); +function wt(t, e) { + return A(t.valueOf(), e.valueOf()); } -function Je(t, e) { +function $t(t, e) { return t.source === e.source && t.flags === e.flags; } -function K(t, e, r) { +function ne(t, e, r) { if (t.size !== e.size) return !1; - for (var s = {}, i = t.values(), n, o; (n = i.next()) && !n.done; ) { - for (var a = e.values(), c = !1, p = 0; (o = a.next()) && !o.done; ) - !c && !s[p] && (c = r.equals(n.value, o.value, n.value, o.value, t, e, r)) && (s[p] = !0), p++; - if (!c) + for (var s = {}, i = t.values(), o, n; (o = i.next()) && !o.done; ) { + for (var a = e.values(), h = !1, p = 0; (n = a.next()) && !n.done; ) + !h && !s[p] && (h = r.equals(o.value, n.value, o.value, n.value, t, e, r)) && (s[p] = !0), p++; + if (!h) return !1; } return !0; } -function _e(t, e) { +function St(t, e) { var r = t.length; if (e.length !== r) return !1; @@ -862,609 +1618,362 @@ function _e(t, e) { return !1; return !0; } -var Ke = "[object Arguments]", Ue = "[object Boolean]", Fe = "[object Date]", ke = "[object Map]", He = "[object Number]", We = "[object Object]", Le = "[object RegExp]", Ze = "[object Set]", Xe = "[object String]", Qe = Array.isArray, U = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, F = Object.assign, Ye = Object.prototype.toString.call.bind(Object.prototype.toString); -function et(t) { - var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, i = t.areObjectsEqual, n = t.arePrimitiveWrappersEqual, o = t.areRegExpsEqual, a = t.areSetsEqual, c = t.areTypedArraysEqual; - return function(u, l, f) { - if (u === l) +var Ot = "[object Arguments]", jt = "[object Boolean]", Ct = "[object Date]", At = "[object Map]", Pt = "[object Number]", Tt = "[object Object]", Mt = "[object RegExp]", Bt = "[object Set]", Dt = "[object String]", kt = Array.isArray, ae = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, ue = Object.assign, It = Object.prototype.toString.call.bind(Object.prototype.toString); +function Rt(t) { + var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, i = t.areObjectsEqual, o = t.arePrimitiveWrappersEqual, n = t.areRegExpsEqual, a = t.areSetsEqual, h = t.areTypedArraysEqual; + return function(u, c, d) { + if (u === c) return !0; - if (u == null || l == null || typeof u != "object" || typeof l != "object") - return u !== u && l !== l; - var g = u.constructor; - if (g !== l.constructor) + if (u == null || c == null || typeof u != "object" || typeof c != "object") + return u !== u && c !== c; + var v = u.constructor; + if (v !== c.constructor) return !1; - if (g === Object) - return i(u, l, f); - if (Qe(u)) - return e(u, l, f); - if (U != null && U(u)) - return c(u, l, f); - if (g === Date) - return r(u, l, f); - if (g === RegExp) - return o(u, l, f); - if (g === Map) - return s(u, l, f); - if (g === Set) - return a(u, l, f); - var m = Ye(u); - return m === Fe ? r(u, l, f) : m === Le ? o(u, l, f) : m === ke ? s(u, l, f) : m === Ze ? a(u, l, f) : m === We ? typeof u.then != "function" && typeof l.then != "function" && i(u, l, f) : m === Ke ? i(u, l, f) : m === Ue || m === He || m === Xe ? n(u, l, f) : !1; + if (v === Object) + return i(u, c, d); + if (kt(u)) + return e(u, c, d); + if (ae != null && ae(u)) + return h(u, c, d); + if (v === Date) + return r(u, c, d); + if (v === RegExp) + return n(u, c, d); + if (v === Map) + return s(u, c, d); + if (v === Set) + return a(u, c, d); + var b = It(u); + return b === Ct ? r(u, c, d) : b === Mt ? n(u, c, d) : b === At ? s(u, c, d) : b === Bt ? a(u, c, d) : b === Tt ? typeof u.then != "function" && typeof c.then != "function" && i(u, c, d) : b === Ot ? i(u, c, d) : b === jt || b === Pt || b === Dt ? o(u, c, d) : !1; }; } -function tt(t) { +function xt(t) { var e = t.circular, r = t.createCustomConfig, s = t.strict, i = { - areArraysEqual: s ? $ : Be, - areDatesEqual: ze, - areMapsEqual: s ? z(_, $) : _, - areObjectsEqual: s ? $ : Ge, - arePrimitiveWrappersEqual: Ve, - areRegExpsEqual: Je, - areSetsEqual: s ? z(K, $) : K, - areTypedArraysEqual: s ? $ : _e + areArraysEqual: s ? M : vt, + areDatesEqual: Nt, + areMapsEqual: s ? te(oe, M) : oe, + areObjectsEqual: s ? M : Et, + arePrimitiveWrappersEqual: wt, + areRegExpsEqual: $t, + areSetsEqual: s ? te(ne, M) : ne, + areTypedArraysEqual: s ? M : St }; - if (r && (i = F({}, i, r(i))), e) { - var n = E(i.areArraysEqual), o = E(i.areMapsEqual), a = E(i.areObjectsEqual), c = E(i.areSetsEqual); - i = F({}, i, { - areArraysEqual: n, - areMapsEqual: o, + if (r && (i = ue({}, i, r(i))), e) { + var o = D(i.areArraysEqual), n = D(i.areMapsEqual), a = D(i.areObjectsEqual), h = D(i.areSetsEqual); + i = ue({}, i, { + areArraysEqual: o, + areMapsEqual: n, areObjectsEqual: a, - areSetsEqual: c + areSetsEqual: h }); } return i; } -function rt(t) { - return function(e, r, s, i, n, o, a) { +function qt(t) { + return function(e, r, s, i, o, n, a) { return t(e, r, a); }; } -function st(t) { - var e = t.circular, r = t.comparator, s = t.createState, i = t.equals, n = t.strict; +function Vt(t) { + var e = t.circular, r = t.comparator, s = t.createState, i = t.equals, o = t.strict; if (s) - return function(c, p) { - var u = s(), l = u.cache, f = l === void 0 ? e ? /* @__PURE__ */ new WeakMap() : void 0 : l, g = u.meta; - return r(c, p, { - cache: f, + return function(h, p) { + var u = s(), c = u.cache, d = c === void 0 ? e ? /* @__PURE__ */ new WeakMap() : void 0 : c, v = u.meta; + return r(h, p, { + cache: d, equals: i, - meta: g, - strict: n + meta: v, + strict: o }); }; if (e) - return function(c, p) { - return r(c, p, { + return function(h, p) { + return r(h, p, { cache: /* @__PURE__ */ new WeakMap(), equals: i, meta: void 0, - strict: n + strict: o }); }; - var o = { + var n = { cache: void 0, equals: i, meta: void 0, - strict: n + strict: o }; - return function(c, p) { - return r(c, p, o); + return function(h, p) { + return r(h, p, n); }; } -var it = b(); -b({ strict: !0 }); -b({ circular: !0 }); -b({ +var zt = $(); +$({ strict: !0 }); +$({ circular: !0 }); +$({ circular: !0, strict: !0 }); -b({ +$({ createInternalComparator: function() { - return v; + return A; } }); -b({ +$({ strict: !0, createInternalComparator: function() { - return v; + return A; } }); -b({ +$({ circular: !0, createInternalComparator: function() { - return v; + return A; } }); -b({ +$({ circular: !0, createInternalComparator: function() { - return v; + return A; }, strict: !0 }); -function b(t) { +function $(t) { t === void 0 && (t = {}); - var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, i = t.createState, n = t.strict, o = n === void 0 ? !1 : n, a = tt(t), c = et(a), p = s ? s(c) : rt(c); - return st({ circular: r, comparator: c, createState: i, equals: p, strict: o }); + var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, i = t.createState, o = t.strict, n = o === void 0 ? !1 : o, a = xt(t), h = Rt(a), p = s ? s(h) : qt(h); + return Vt({ circular: r, comparator: h, createState: i, equals: p, strict: n }); } -function zt(t, e) { - return it(t, e); +function Er(t, e) { + return zt(t, e); } -function k(t, e, r) { - return JSON.stringify(t, (i, n) => { - let o = n; - return e && (o = e(i, o)), o === void 0 && (o = null), o; +function le(t, e, r) { + return JSON.stringify(t, (i, o) => { + let n = o; + return e && (n = e(i, n)), n === void 0 && (n = null), n; }, r); } -function nt(t, e) { +function Jt(t, e) { function r(i) { - return Object.keys(i).forEach((n) => { - i[n] === null ? i[n] = void 0 : typeof i[n] == "object" && (i[n] = r(i[n])); + return Object.keys(i).forEach((o) => { + i[o] === null ? i[o] = void 0 : typeof i[o] == "object" && (i[o] = r(i[o])); }), i; } const s = JSON.parse(t, e); if (s !== null) return typeof s == "object" ? r(s) : s; } -function Gt(t) { +function wr(t) { try { - const e = k(t); - return e === k(nt(e)); + const e = le(t); + return e === le(Jt(e)); } catch { return !1; } } -const Vt = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), ot = { - title: "Platform.Bible menus", - type: "object", - properties: { - mainMenu: { - description: "Top level menu for the application", - $ref: "#/$defs/multiColumnMenu" - }, - defaultWebViewTopMenu: { - description: "Default top menu for web views that don't specify their own", - $ref: "#/$defs/multiColumnMenu" - }, - defaultWebViewContextMenu: { - description: "Default context menu for web views that don't specify their own", - $ref: "#/$defs/singleColumnMenu" - }, - webViewMenus: { - description: "Menus that apply per web view in the application", - type: "object", - patternProperties: { - "^[\\w\\-]+\\.[\\w\\-]+$": { - $ref: "#/$defs/menusForOneWebView" - } +const $r = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), X = { + projectSettingsContribution: { + description: "The data an extension provides to inform Platform.Bible of the project settings it provides", + anyOf: [ + { + $ref: "#/$defs/projectSettingsGroup" }, - additionalProperties: !1 - } + { + type: "array", + items: { + $ref: "#/$defs/projectSettingsGroup" + } + } + ] }, - required: ["mainMenu", "defaultWebViewTopMenu", "defaultWebViewContextMenu", "webViewMenus"], - additionalProperties: !1, - $defs: { - localizeKey: { - description: "Identifier for a string that will be localized in a menu based on the user's UI language", - type: "string", - pattern: "^%[\\w\\-\\.]+%$" + projectSettingsGroup: { + description: "Group of related settings definitions", + type: "object", + properties: { + label: { + description: "localizeKey that displays in the project settings dialog as the group name", + $ref: "#/$defs/localizeKey" + }, + description: { + description: "localizeKey that displays in the project settings dialog to describe the group", + $ref: "#/$defs/localizeKey" + }, + properties: { + $ref: "#/$defs/projectSettingProperties" + } }, - referencedItem: { - description: "Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)", - type: "string", - pattern: "^[\\w\\-]+\\.[\\w\\-]+$" + required: ["label", "properties"] + }, + projectSettingProperties: { + description: "Object whose keys are setting IDs and whose values are settings objects", + type: "object", + patternProperties: { + "^[\\w\\-]+\\.[\\w\\-]+$": { + $ref: "#/$defs/projectSetting" + } }, - columnsWithHeaders: { - description: "Group of columns that can be combined with other columns to form a multi-column menu", - type: "object", - patternProperties: { - "^[\\w\\-]+\\.[\\w\\-]+$": { - description: "Single column with a header string", - type: "object", - properties: { - label: { - description: "Header text for this this column in the UI", - $ref: "#/$defs/localizeKey" - }, - localizeNotes: { - description: "Additional information provided by developers to help people who perform localization", + additionalProperties: !1 + }, + projectSetting: { + description: "A description of an extension's setting entry", + anyOf: [ + { + $ref: "#/$defs/extensionControlledProjectSetting" + } + ] + }, + extensionControlledProjectSetting: { + description: "Setting definition that is validated by the extension.", + allOf: [ + { + $ref: "#/$defs/projectSettingBase" + }, + { + $ref: "#/$defs/modifierExtensionControlled" + } + ] + }, + projectSettingBase: { + description: "Base information needed to describe a project setting entry", + allOf: [ + { + $ref: "#/$defs/settingBase" + }, + { + $ref: "#/$defs/modifierProject" + } + ] + }, + modifierProject: { + description: "Modifies setting type to be project setting", + type: "object", + properties: { + includeProjectTypes: { + description: "`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog", + anyOf: [ + { + type: "null" + }, + { + type: "string" + }, + { + type: "array", + items: { type: "string" - }, - order: { - description: "Relative order of this column compared to other columns (sorted ascending)", - type: "number" - }, - isExtensible: { - description: "Defines whether contributions are allowed to add menu groups to this column", - type: "boolean" } + } + ] + }, + excludeProjectTypes: { + description: "`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`", + anyOf: [ + { + type: "null" }, - required: ["label", "order"], - additionalProperties: !1 + { + type: "string" + }, + { + type: "array", + items: { + type: "string" + } + } + ] + } + } + }, + settingsContribution: { + description: "The data an extension provides to inform Platform.Bible of the settings it provides", + anyOf: [ + { + $ref: "#/$defs/settingsGroup" + }, + { + type: "array", + items: { + $ref: "#/$defs/settingsGroup" } + } + ] + }, + settingsGroup: { + description: "Group of related settings definitions", + type: "object", + properties: { + label: { + description: "localizeKey that displays in the settings dialog as the group name", + $ref: "#/$defs/localizeKey" + }, + description: { + description: "localizeKey that displays in the settings dialog to describe the group", + $ref: "#/$defs/localizeKey" }, properties: { - isExtensible: { - description: "Defines whether contributions are allowed to add columns to this multi-column menu", - type: "boolean" - } - } - }, - menuGroups: { - description: "Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.", - type: "object", - patternProperties: { - "^[\\w\\-]+\\.[\\w\\-]+$": { - description: "Single group that contains menu items", - type: "object", - oneOf: [ - { - properties: { - column: { - description: "Column where this group belongs, not required for single column menus", - $ref: "#/$defs/referencedItem" - }, - order: { - description: "Relative order of this group compared to other groups in the same column or submenu (sorted ascending)", - type: "number" - }, - isExtensible: { - description: "Defines whether contributions are allowed to add menu items to this menu group", - type: "boolean" - } - }, - required: ["order"], - additionalProperties: !1 - }, - { - properties: { - menuItem: { - description: "Menu item that anchors the submenu where this group belongs", - $ref: "#/$defs/referencedItem" - }, - order: { - description: "Relative order of this group compared to other groups in the same column or submenu (sorted ascending)", - type: "number" - }, - isExtensible: { - description: "Defines whether contributions are allowed to add menu items to this menu group", - type: "boolean" - } - }, - required: ["menuItem", "order"], - additionalProperties: !1 - } - ] - } - }, - additionalProperties: !1 - }, - menuItem: { - description: "Single item in a menu that can be clicked on to take an action or can be the parent of a submenu", - type: "object", - oneOf: [ - { - properties: { - id: { - description: "ID for this menu item that holds a submenu", - $ref: "#/$defs/referencedItem" - } - }, - required: ["id"] - }, - { - properties: { - command: { - description: "Name of the PAPI command to run when this menu item is selected.", - $ref: "#/$defs/referencedItem" - }, - iconPathBefore: { - description: "Path to the icon to display before the menu text", - type: "string" - }, - iconPathAfter: { - description: "Path to the icon to display after the menu text", - type: "string" - } - }, - required: ["command"] - } - ], - properties: { - label: { - description: "Key that represents the text of this menu item to display", - $ref: "#/$defs/localizeKey" - }, - tooltip: { - description: "Key that represents the text to display if a mouse pointer hovers over the menu item", - $ref: "#/$defs/localizeKey" - }, - searchTerms: { - description: "Key that represents additional words the platform should reference when users are searching for menu items", - $ref: "#/$defs/localizeKey" - }, - localizeNotes: { - description: "Additional information provided by developers to help people who perform localization", - type: "string" - }, - group: { - description: "Group to which this menu item belongs", - $ref: "#/$defs/referencedItem" - }, - order: { - description: "Relative order of this menu item compared to other menu items in the same group (sorted ascending)", - type: "number" - } - }, - required: ["label", "group", "order"], - unevaluatedProperties: !1 - }, - groupsAndItems: { - description: "Core schema for a column", - type: "object", - properties: { - groups: { - description: "Groups that belong in this menu", - $ref: "#/$defs/menuGroups" - }, - items: { - description: "List of menu items that belong in this menu", - type: "array", - items: { $ref: "#/$defs/menuItem" }, - uniqueItems: !0 - } - }, - required: ["groups", "items"] - }, - singleColumnMenu: { - description: "Menu that contains a column without a header", - type: "object", - allOf: [{ $ref: "#/$defs/groupsAndItems" }], - unevaluatedProperties: !1 - }, - multiColumnMenu: { - description: "Menu that can contain multiple columns with headers", - type: "object", - allOf: [ - { $ref: "#/$defs/groupsAndItems" }, - { - properties: { - columns: { - description: "Columns that belong in this menu", - $ref: "#/$defs/columnsWithHeaders" - } - }, - required: ["columns"] - } - ], - unevaluatedProperties: !1 - }, - menusForOneWebView: { - description: "Set of menus that are associated with a single tab", - type: "object", - properties: { - includeDefaults: { - description: "Indicates whether the platform default menus should be included for this webview", - type: "boolean" - }, - topMenu: { - description: "Menu that opens when you click on the top left corner of a tab", - $ref: "#/$defs/multiColumnMenu" - }, - contextMenu: { - description: "Menu that opens when you right click on the main body/area of a tab", - $ref: "#/$defs/singleColumnMenu" - } - }, - additionalProperties: !1 - } - } -}; -Object.freeze(ot); -const T = { - projectSettingsContribution: { - description: "The data an extension provides to inform Platform.Bible of the project settings it provides", - anyOf: [ - { - $ref: "#/$defs/projectSettingsGroup" - }, - { - type: "array", - items: { - $ref: "#/$defs/projectSettingsGroup" - } - } - ] - }, - projectSettingsGroup: { - description: "Group of related settings definitions", - type: "object", - properties: { - label: { - description: "localizeKey that displays in the project settings dialog as the group name", - $ref: "#/$defs/localizeKey" - }, - description: { - description: "localizeKey that displays in the project settings dialog to describe the group", - $ref: "#/$defs/localizeKey" - }, - properties: { - $ref: "#/$defs/projectSettingProperties" + $ref: "#/$defs/settingProperties" } }, required: ["label", "properties"] }, - projectSettingProperties: { + settingProperties: { description: "Object whose keys are setting IDs and whose values are settings objects", type: "object", patternProperties: { - "^[\\w\\-]+\\.[\\w\\-]+$": { - $ref: "#/$defs/projectSetting" + "^[\\w-]+\\.[\\w-]+$": { + $ref: "#/$defs/setting" } }, additionalProperties: !1 }, - projectSetting: { + setting: { description: "A description of an extension's setting entry", anyOf: [ { - $ref: "#/$defs/extensionControlledProjectSetting" + $ref: "#/$defs/extensionControlledSetting" } ] }, - extensionControlledProjectSetting: { + extensionControlledSetting: { description: "Setting definition that is validated by the extension.", allOf: [ { - $ref: "#/$defs/projectSettingBase" + $ref: "#/$defs/settingBase" }, { $ref: "#/$defs/modifierExtensionControlled" } ] }, - projectSettingBase: { - description: "Base information needed to describe a project setting entry", + settingBase: { + description: "Base information needed to describe a setting entry", allOf: [ { - $ref: "#/$defs/settingBase" + $ref: "#/$defs/stateBase" }, { - $ref: "#/$defs/modifierProject" + type: "object", + properties: { + label: { + description: "localizeKey that displays in the settings dialog as the setting name", + $ref: "#/$defs/localizeKey" + }, + description: { + description: "localizeKey that displays in the settings dialog to describe the setting", + $ref: "#/$defs/localizeKey" + } + }, + required: ["label"] } ] }, - modifierProject: { - description: "Modifies setting type to be project setting", - type: "object", - properties: { - includeProjectTypes: { - description: "`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog", - anyOf: [ - { - type: "null" - }, - { - type: "string" - }, - { - type: "array", - items: { - type: "string" - } - } - ] - }, - excludeProjectTypes: { - description: "`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`", - anyOf: [ - { - type: "null" - }, - { - type: "string" - }, - { - type: "array", - items: { - type: "string" - } - } - ] - } - } - }, - settingsContribution: { - description: "The data an extension provides to inform Platform.Bible of the settings it provides", - anyOf: [ - { - $ref: "#/$defs/settingsGroup" - }, - { - type: "array", - items: { - $ref: "#/$defs/settingsGroup" - } - } - ] - }, - settingsGroup: { - description: "Group of related settings definitions", - type: "object", - properties: { - label: { - description: "localizeKey that displays in the settings dialog as the group name", - $ref: "#/$defs/localizeKey" - }, - description: { - description: "localizeKey that displays in the settings dialog to describe the group", - $ref: "#/$defs/localizeKey" - }, - properties: { - $ref: "#/$defs/settingProperties" - } - }, - required: ["label", "properties"] - }, - settingProperties: { - description: "Object whose keys are setting IDs and whose values are settings objects", - type: "object", - patternProperties: { - "^[\\w-]+\\.[\\w-]+$": { - $ref: "#/$defs/setting" - } - }, - additionalProperties: !1 - }, - setting: { - description: "A description of an extension's setting entry", - anyOf: [ - { - $ref: "#/$defs/extensionControlledSetting" - } - ] - }, - extensionControlledSetting: { - description: "Setting definition that is validated by the extension.", - allOf: [ - { - $ref: "#/$defs/settingBase" - }, - { - $ref: "#/$defs/modifierExtensionControlled" - } - ] - }, - settingBase: { - description: "Base information needed to describe a setting entry", - allOf: [ - { - $ref: "#/$defs/stateBase" - }, - { - type: "object", - properties: { - label: { - description: "localizeKey that displays in the settings dialog as the setting name", - $ref: "#/$defs/localizeKey" - }, - description: { - description: "localizeKey that displays in the settings dialog to describe the setting", - $ref: "#/$defs/localizeKey" - } - }, - required: ["label"] - } - ] - }, - projectStateContribution: { - description: "The data an extension provides to inform Platform.Bible of the project state it provides", - $ref: "#/$defs/userStateProperties" - }, - userStateContribution: { - description: "The data an extension provides to inform Platform.Bible of the user state it provides", - $ref: "#/$defs/userStateProperties" - }, - userStateProperties: { - description: "Object whose keys are state IDs and whose values are state objects", + projectStateContribution: { + description: "The data an extension provides to inform Platform.Bible of the project state it provides", + $ref: "#/$defs/userStateProperties" + }, + userStateContribution: { + description: "The data an extension provides to inform Platform.Bible of the user state it provides", + $ref: "#/$defs/userStateProperties" + }, + userStateProperties: { + description: "Object whose keys are state IDs and whose values are state objects", type: "object", patternProperties: { "^[\\w\\-]+\\.[\\w\\-]+$": { @@ -1535,19 +2044,19 @@ const T = { tsType: "Id" } }; -function Y(t) { +function K(t) { t && Object.values(t).forEach((e) => { if (e.type) { if ("tsType" in e && delete e.tsType, e.type === "any") { delete e.type; return; } - e.type === "object" && Y(e.properties); + e.type === "object" && K(e.properties); } }); } -Y(T); -const at = { +K(X); +const Gt = { $schema: "https://json-schema.org/draft/2020-12/schema", title: "Project Settings Contribution", description: "The data an extension provides to inform Platform.Bible of the project settings it provides", @@ -1562,10 +2071,10 @@ const at = { } } ], - $defs: T + $defs: X }; -Object.freeze(at); -const ut = { +Object.freeze(Gt); +const _t = { $schema: "https://json-schema.org/draft/2020-12/schema", title: "Settings Contribution", description: "The data an extension provides to inform Platform.Bible of the settings it provides", @@ -1580,60 +2089,375 @@ const ut = { } } ], - $defs: T + $defs: X +}; +Object.freeze(_t); +const we = { + languageStrings: { + description: "Map whose keys are localized string keys and whose values provide information about how to localize strings for the localized string key", + type: "object", + patternProperties: { + "^%[\\w\\-\\.]+%$": { + $ref: "#/$defs/localizedStringValue" + } + }, + additionalProperties: !1 + }, + localizedStringValue: { + description: "Localized string value associated with this key", + type: "string" + }, + stringsMetadata: { + description: "Map whose keys are localized string keys and whose values provide additional non-locale-specific information about the localized string key", + type: "object", + patternProperties: { + "^%[\\w\\-\\.]+%$": { + $ref: "#/$defs/stringMetadata" + } + }, + additionalProperties: !1 + }, + stringMetadata: { + description: "Additional non-locale-specific information about a localized string key", + type: "object", + properties: { + fallbackKey: { + description: "Localized string key from which to get this value if one does not exist in the specified language. If a new key/value pair needs to be made to replace an existing one, this could help smooth over the transition if the meanings are close enough", + $ref: "#/$defs/localizeKey" + }, + notes: { + description: "Additional information provided by developers in English to help the translator to know how to translate this localized string accurately", + type: "string" + } + } + }, + localizeKey: { + description: "Identifier for a string that will be localized based on the user's UI language", + type: "string", + pattern: "^%[\\w\\-\\.]+%$", + tsType: "LocalizeKey" + } +}; +K(we); +const Xt = { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "Localized String Data Contribution", + description: "The data an extension provides to inform Platform.Bible of the localized strings it provides.", + type: "object", + properties: { + metadata: { + $ref: "#/$defs/stringsMetadata" + }, + localizedStrings: { + type: "object", + additionalProperties: { + $ref: "#/$defs/languageStrings" + } + } + }, + $defs: we +}; +Object.freeze(Xt); +const Kt = { + title: "Platform.Bible menus", + type: "object", + properties: { + mainMenu: { + description: "Top level menu for the application", + $ref: "#/$defs/multiColumnMenu" + }, + defaultWebViewTopMenu: { + description: "Default top menu for web views that don't specify their own", + $ref: "#/$defs/multiColumnMenu" + }, + defaultWebViewContextMenu: { + description: "Default context menu for web views that don't specify their own", + $ref: "#/$defs/singleColumnMenu" + }, + webViewMenus: { + description: "Menus that apply per web view in the application", + type: "object", + patternProperties: { + "^[\\w\\-]+\\.[\\w\\-]+$": { + $ref: "#/$defs/menusForOneWebView" + } + }, + additionalProperties: !1 + } + }, + required: ["mainMenu", "defaultWebViewTopMenu", "defaultWebViewContextMenu", "webViewMenus"], + additionalProperties: !1, + $defs: { + localizeKey: { + description: "Identifier for a string that will be localized in a menu based on the user's UI language", + type: "string", + pattern: "^%[\\w\\-\\.]+%$" + }, + referencedItem: { + description: "Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)", + type: "string", + pattern: "^[\\w\\-]+\\.[\\w\\-]+$" + }, + columnsWithHeaders: { + description: "Group of columns that can be combined with other columns to form a multi-column menu", + type: "object", + patternProperties: { + "^[\\w\\-]+\\.[\\w\\-]+$": { + description: "Single column with a header string", + type: "object", + properties: { + label: { + description: "Header text for this this column in the UI", + $ref: "#/$defs/localizeKey" + }, + localizeNotes: { + description: "Additional information provided by developers to help people who perform localization", + type: "string" + }, + order: { + description: "Relative order of this column compared to other columns (sorted ascending)", + type: "number" + }, + isExtensible: { + description: "Defines whether contributions are allowed to add menu groups to this column", + type: "boolean" + } + }, + required: ["label", "order"], + additionalProperties: !1 + } + }, + properties: { + isExtensible: { + description: "Defines whether contributions are allowed to add columns to this multi-column menu", + type: "boolean" + } + } + }, + menuGroups: { + description: "Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.", + type: "object", + patternProperties: { + "^[\\w\\-]+\\.[\\w\\-]+$": { + description: "Single group that contains menu items", + type: "object", + oneOf: [ + { + properties: { + column: { + description: "Column where this group belongs, not required for single column menus", + $ref: "#/$defs/referencedItem" + }, + order: { + description: "Relative order of this group compared to other groups in the same column or submenu (sorted ascending)", + type: "number" + }, + isExtensible: { + description: "Defines whether contributions are allowed to add menu items to this menu group", + type: "boolean" + } + }, + required: ["order"], + additionalProperties: !1 + }, + { + properties: { + menuItem: { + description: "Menu item that anchors the submenu where this group belongs", + $ref: "#/$defs/referencedItem" + }, + order: { + description: "Relative order of this group compared to other groups in the same column or submenu (sorted ascending)", + type: "number" + }, + isExtensible: { + description: "Defines whether contributions are allowed to add menu items to this menu group", + type: "boolean" + } + }, + required: ["menuItem", "order"], + additionalProperties: !1 + } + ] + } + }, + additionalProperties: !1 + }, + menuItem: { + description: "Single item in a menu that can be clicked on to take an action or can be the parent of a submenu", + type: "object", + oneOf: [ + { + properties: { + id: { + description: "ID for this menu item that holds a submenu", + $ref: "#/$defs/referencedItem" + } + }, + required: ["id"] + }, + { + properties: { + command: { + description: "Name of the PAPI command to run when this menu item is selected.", + $ref: "#/$defs/referencedItem" + }, + iconPathBefore: { + description: "Path to the icon to display before the menu text", + type: "string" + }, + iconPathAfter: { + description: "Path to the icon to display after the menu text", + type: "string" + } + }, + required: ["command"] + } + ], + properties: { + label: { + description: "Key that represents the text of this menu item to display", + $ref: "#/$defs/localizeKey" + }, + tooltip: { + description: "Key that represents the text to display if a mouse pointer hovers over the menu item", + $ref: "#/$defs/localizeKey" + }, + searchTerms: { + description: "Key that represents additional words the platform should reference when users are searching for menu items", + $ref: "#/$defs/localizeKey" + }, + localizeNotes: { + description: "Additional information provided by developers to help people who perform localization", + type: "string" + }, + group: { + description: "Group to which this menu item belongs", + $ref: "#/$defs/referencedItem" + }, + order: { + description: "Relative order of this menu item compared to other menu items in the same group (sorted ascending)", + type: "number" + } + }, + required: ["label", "group", "order"], + unevaluatedProperties: !1 + }, + groupsAndItems: { + description: "Core schema for a column", + type: "object", + properties: { + groups: { + description: "Groups that belong in this menu", + $ref: "#/$defs/menuGroups" + }, + items: { + description: "List of menu items that belong in this menu", + type: "array", + items: { $ref: "#/$defs/menuItem" }, + uniqueItems: !0 + } + }, + required: ["groups", "items"] + }, + singleColumnMenu: { + description: "Menu that contains a column without a header", + type: "object", + allOf: [{ $ref: "#/$defs/groupsAndItems" }], + unevaluatedProperties: !1 + }, + multiColumnMenu: { + description: "Menu that can contain multiple columns with headers", + type: "object", + allOf: [ + { $ref: "#/$defs/groupsAndItems" }, + { + properties: { + columns: { + description: "Columns that belong in this menu", + $ref: "#/$defs/columnsWithHeaders" + } + }, + required: ["columns"] + } + ], + unevaluatedProperties: !1 + }, + menusForOneWebView: { + description: "Set of menus that are associated with a single tab", + type: "object", + properties: { + includeDefaults: { + description: "Indicates whether the platform default menus should be included for this webview", + type: "boolean" + }, + topMenu: { + description: "Menu that opens when you click on the top left corner of a tab", + $ref: "#/$defs/multiColumnMenu" + }, + contextMenu: { + description: "Menu that opens when you right click on the main body/area of a tab", + $ref: "#/$defs/singleColumnMenu" + } + }, + additionalProperties: !1 + } + } }; -Object.freeze(ut); +Object.freeze(Kt); export { - pt as AsyncVariable, - de as DocumentCombiner, - ge as FIRST_SCR_BOOK_NUM, - ye as FIRST_SCR_CHAPTER_NUM, - ve as FIRST_SCR_VERSE_NUM, - be as LAST_SCR_BOOK_NUM, - me as Mutex, - wt as MutexMap, - Nt as NonValidatingDocumentCombiner, - ue as PlatformEventEmitter, - $t as UnsubscriberAsyncList, - Pt as aggregateUnsubscriberAsyncs, - St as aggregateUnsubscribers, - At as at, - Ct as charAt, - qt as codePointAt, - vt as createSyncProxyForAsyncObject, - ht as debounce, - w as deepClone, - zt as deepEqual, - nt as deserialize, - Tt as endsWith, - yt as getAllObjectFunctionNames, - Ne as getChaptersForBook, - gt as getErrorMessage, - mt as groupBy, - Vt as htmlEncode, - Te as includes, - q as indexOf, - Gt as isSerializable, - le as isString, - De as lastIndexOf, - ot as menuDocumentSchema, - dt as newGuid, - Dt as normalize, - Et as offsetBook, - Ot as offsetChapter, - jt as offsetVerse, - Mt as padEnd, - xt as padStart, - at as projectSettingsDocumentSchema, - k as serialize, - ut as settingsDocumentSchema, - Rt as slice, - It as split, - Bt as startsWith, - h as stringLength, - O as substring, - Me as toArray, - pe as wait, - bt as waitForDuration + Ft as AsyncVariable, + Re as DocumentCombiner, + ft as FIRST_SCR_BOOK_NUM, + pt as FIRST_SCR_CHAPTER_NUM, + dt as FIRST_SCR_VERSE_NUM, + ht as LAST_SCR_BOOK_NUM, + qe as Mutex, + or as MutexMap, + sr as NonValidatingDocumentCombiner, + Me as PlatformEventEmitter, + ir as UnsubscriberAsyncList, + Nr as aggregateUnsubscriberAsyncs, + vr as aggregateUnsubscribers, + ar as at, + ur as charAt, + lr as codePointAt, + rr as createSyncProxyForAsyncObject, + Zt as debounce, + B as deepClone, + Er as deepEqual, + Jt as deserialize, + cr as endsWith, + tr as getAllObjectFunctionNames, + mt as getChaptersForBook, + Yt as getErrorMessage, + yr as getLocalizedIdFromBookNumber, + Qt as groupBy, + $r as htmlEncode, + at as includes, + _ as indexOf, + wr as isSerializable, + Be as isString, + ut as lastIndexOf, + Xt as localizedStringsDocumentSchema, + Kt as menuDocumentSchema, + Wt as newGuid, + fr as normalize, + mr as offsetBook, + gr as offsetChapter, + br as offsetVerse, + hr as padEnd, + pr as padStart, + Gt as projectSettingsDocumentSchema, + le as serialize, + _t as settingsDocumentSchema, + dr as slice, + ee as split, + lt as startsWith, + g as stringLength, + k as substring, + ct as toArray, + Ie as wait, + er as waitForDuration }; //# sourceMappingURL=index.js.map diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index ee4ae79d75..62c4aa6c97 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/platform-event-emitter.model.ts","../src/util.ts","../src/document-combiner.ts","../src/non-validating-document-combiner.ts","../src/unsubscriber-async-list.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../../../node_modules/char-regex/index.js","../../../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts","../src/settings.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n\n/** Within type T, recursively change all properties to be optional */\nexport type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;\n\n/** Within type T, recursively change properties that were of type A to be of type B */\nexport type ReplaceType = T extends A\n ? B\n : T extends object\n ? { [K in keyof T]: ReplaceType }\n : T;\n","import PlatformEventEmitter from './platform-event-emitter.model';\nimport { deepClone } from './util';\n\ntype JsonObjectLike = { [key: string]: unknown };\ntype JsonArrayLike = unknown[];\n\nexport type JsonDocumentLike = JsonObjectLike | JsonArrayLike;\n\n/**\n * Options for DocumentCombiner objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (primarily in the form of JS objects\n * or arrays) together into a single output document.\n */\nexport default class DocumentCombiner {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n private readonly onDidRebuildEmitter = new PlatformEventEmitter();\n /** Event that emits to announce that the document has been rebuilt and the output has been updated */\n // Need `onDidRebuildEmitter` to be instantiated before this line\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly onDidRebuild = this.onDidRebuildEmitter.subscribe;\n\n /**\n * Create a DocumentCombiner instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateBaseDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n this.baseDocument = this.transformBaseDocumentAfterValidation(this.baseDocument);\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * Note: the order in which contribution documents are added can be considered to be indeterminate\n * as it is currently ordered by however `Map.forEach` provides the contributions. The order\n * matters when merging two arrays into one. Also, when `options.ignoreDuplicateProperties` is\n * `true`, the order also matters when adding the same property to an object that is already\n * provided previously. Please let us know if you have trouble because of indeterminate\n * contribution ordering.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n let documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n documentToSet = this.transformContributionAfterValidation(documentName, documentToSet);\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): JsonDocumentLike | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`${documentName} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete all present contribution documents for the composition process and return to the base\n * document\n *\n * @returns Recalculated output document consisting only of the base document\n */\n deleteAllContributions(): JsonDocumentLike | undefined {\n if (this.contributions.size <= 0) return this.latestOutput;\n\n // Save out all contributions\n const contributions = [...this.contributions.entries()];\n\n // Delete all contributions\n contributions.forEach(([contributionName]) => this.contributions.delete(contributionName));\n\n // Rebuild with no contributions\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting all contributions, put them back and rethrow\n contributions.forEach(([contributionName, document]) =>\n this.contributions.set(contributionName, document),\n );\n throw new Error(`Error when deleting all contributions: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutputBeforeValidation(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutputBeforeValidation(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n /**\n * Transform the starting document that is given to the combiner. This transformation occurs after\n * validating the base document and before combining any contributions.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the `baseDocument` passed in.\n *\n * @param baseDocument Initial input document. Already validated via `validateBaseDocument`\n * @returns Transformed base document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformBaseDocumentAfterValidation(baseDocument: JsonDocumentLike): JsonDocumentLike {\n return baseDocument;\n }\n\n /**\n * Transform the contributed document associated with `documentName`. This transformation occurs\n * after validating the contributed document and before combining with other documents.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the contributed `document` passed in.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine. Already validated via\n * `validateContribution`\n * @returns Transformed contributed document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformContributionAfterValidation(\n // @ts-expect-error this parameter is unused but may be used in child classes\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike {\n return document;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateBaseDocument(baseDocument: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateContribution(documentName: string, document: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateOutput(output: JsonDocumentLike): void {}\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation via `validateOutput`\n * before `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n // no-op intended to be overridden by child classes. Can't be static\n // eslint-disable-next-line class-methods-use-this\n protected transformFinalOutputBeforeValidation(finalOutput: JsonDocumentLike): JsonDocumentLike {\n return finalOutput;\n }\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Deep clone and recursively merge the properties of one object (copyFrom) into another\n * (startingPoint). Throws if copyFrom would overwrite values already existing in startingPoint.\n *\n * Does not modify the objects passed in.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n\n if (!copyFrom) return retVal;\n\n return mergeObjectsInternal(retVal, deepClone(copyFrom), ignoreDuplicateProperties);\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * WARNING: Modifies the argument objects in some way. Recommended to use `mergeObjects`\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjectsInternal(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n if (!copyFrom) return startingPoint;\n\n if (areNonArrayObjects(startingPoint, copyFrom)) {\n // Merge properties since they are both objects\n\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n const startingPointObj = startingPoint as JsonObjectLike;\n const copyFromObj = copyFrom as JsonObjectLike;\n /* eslint-enable no-type-assertion/no-type-assertion */\n Object.keys(copyFromObj).forEach((key: string | number) => {\n if (Object.hasOwn(startingPointObj, key)) {\n if (areNonArrayObjects(startingPointObj[key], copyFromObj[key])) {\n startingPointObj[key] = mergeObjectsInternal(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] as JsonObjectLike,\n copyFromObj[key] as JsonObjectLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPointObj[key], copyFromObj[key])) {\n // Concat the arrays since they are both arrays\n\n // We know these are arrays from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] = (startingPointObj[key] as JsonArrayLike).concat(\n copyFromObj[key] as JsonArrayLike,\n );\n /* eslint-enable no-type-assertion/no-type-assertion */\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n // Note that the first non-object non-array value that gets placed in a property stays.\n // New values do not override existing ones\n } else {\n startingPointObj[key] = copyFromObj[key];\n }\n });\n } else if (areArrayObjects(startingPoint, copyFrom)) {\n // Concat the arrays since they are both arrays\n\n // Push the contents of copyFrom into startingPoint since it is a const and was already deep cloned\n // We know these are objects from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n (startingPoint as JsonArrayLike).push(...(copyFrom as JsonArrayLike));\n /* eslint-enable no-type-assertion/no-type-assertion */\n }\n\n // Note that nothing happens if `startingPoint` is not an object or an array or if `startingPoint`\n // and `copyFrom` are not both object or both arrays. Should we throw? Should we push `copyFrom`'s\n // values into the array? Other? Maybe one day we can add some options to decide what to do in\n // this situation, but YAGNI for now\n\n return startingPoint;\n}\n\n// #endregion\n","import DocumentCombiner, { DocumentCombinerOptions, JsonDocumentLike } from './document-combiner';\n\nexport default class NonValidatingDocumentCombiner extends DocumentCombiner {\n // Making the protected base constructor public\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n super(baseDocument, options);\n }\n\n get output(): JsonDocumentLike | undefined {\n return this.latestOutput;\n }\n}\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * This function mirrors the `at` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Finds the Unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified offset,\n * undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > stringLength(string) || index < -stringLength(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `charAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a new string consisting of the single unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified offset, empty\n * string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > stringLength(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the character at the given\n * index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > stringLength(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * This function mirrors the `endsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether a string ends with the characters of this string.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be found. Default is\n * `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = stringLength(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * This function mirrors the `includes` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Performs a case-sensitive search to determine if searchString is found in string.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString. Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * This function mirrors the `indexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the index of the first occurrence of a given string.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Searches this string and returns the index of the last occurrence of the specified substring.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(string: string, searchString: string, position?: number): number {\n let validatedPosition = position === undefined ? stringLength(string) : position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= stringLength(string)) {\n validatedPosition = stringLength(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, stringLength(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * This function mirrors the `length` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes. Since `length` appears to be a\n * reserved keyword, the function was renamed to `stringLength`\n *\n * Returns the length of a string.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function stringLength(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * This function mirrors the `normalize` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * This function mirrors the `padEnd` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * This function mirrors the `padStart` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\n// This is a helper function that performs a correction on the slice index to make sure it\n// cannot go out of bounds\nfunction correctSliceIndex(length: number, index: number) {\n if (index > length) return length;\n if (index < -length) return 0;\n if (index < 0) return index + length;\n return index;\n}\n\n/**\n * This function mirrors the `slice` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const length: number = stringLength(string);\n if (\n indexStart > length ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(indexStart >= 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) ||\n indexEnd < -length))\n )\n return '';\n\n const newStart = correctSliceIndex(length, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * This function mirrors the `split` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits the\n * string at each occurrence of specified separator, but stops when limit entries have been placed\n * in the array.\n * @returns An array of strings, split at each point where separator occurs in the starting string.\n * Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = stringLength(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * This function mirrors the `startsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found (the index of\n * searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string, including when\n * searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * This function mirrors the `substr` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and length. This function is not exported because it is\n * considered deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String length minus start parameter`. Default is `String\n * length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(\n string: string,\n begin: number = 0,\n len: number = stringLength(string) - begin,\n): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * This function mirrors the `substring` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and end position.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = stringLength(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * This function mirrors the `toArray` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Converts a string to an array of string characters.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { ReplaceType } from './util';\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single context menu/submenu.\n * Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInSingleColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: OrderedExtensibleContainer | MenuGroupDetailsInSubMenu;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu within a\n * multi-column menu. Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInMultiColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: GroupsInSingleColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n /** Groups that belong in this menu */\n groups: GroupsInMultiColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus before they are localized */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n/**\n * Type that converts any menu type before it is localized to what it is after it is localized. This\n * can be applied to any menu type as needed.\n */\nexport type Localized = ReplaceType, ReferencedItem, string>;\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { LocalizeKey, ReferencedItem } from 'menus.model';\n\n/** The data an extension provides to inform Platform.Bible of the settings it provides */\nexport type SettingsContribution = SettingsGroup | SettingsGroup[];\n/** A description of an extension's setting entry */\nexport type Setting = ExtensionControlledSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledSetting = SettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a setting entry */\nexport type SettingBase = StateBase & {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the setting name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the setting */\n description?: LocalizeKey;\n};\n/** The data an extension provides to inform Platform.Bible of the project settings it provides */\nexport type ProjectSettingsContribution = ProjectSettingsGroup | ProjectSettingsGroup[];\n/** A description of an extension's setting entry */\nexport type ProjectSetting = ExtensionControlledProjectSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledProjectSetting = ProjectSettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a project setting entry */\nexport type ProjectSettingBase = SettingBase & ModifierProject;\n/** A description of an extension's user state entry */\nexport type UserState = ExtensionControlledState;\n/** State definition that is validated by the extension. */\nexport type ExtensionControlledState = StateBase & ModifierExtensionControlled;\n/** Group of related settings definitions */\nexport interface SettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the group */\n description?: LocalizeKey;\n properties: SettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface SettingProperties {\n [k: ReferencedItem]: Setting;\n}\n/** Base information needed to describe a state entry */\nexport interface StateBase {\n [k: string]: unknown;\n /** Default value for the state/setting */\n default: unknown;\n /**\n * A state/setting ID whose value to set to this state/setting's starting value the first time\n * this state/setting is loaded\n */\n derivesFrom?: ReferencedItem;\n}\n/**\n * Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the\n * extension provides the component and the validator for the state/setting, so the state/setting is\n * controlled by the extension.\n */\nexport interface ModifierExtensionControlled {\n [k: string]: unknown;\n platformType?: undefined;\n type?: undefined;\n}\n/** Group of related settings definitions */\nexport interface ProjectSettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the project settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the project settings dialog to describe the group */\n description?: LocalizeKey;\n properties: ProjectSettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface ProjectSettingProperties {\n [k: ReferencedItem]: ProjectSetting;\n}\n/** Modifies setting type to be project setting */\nexport interface ModifierProject {\n [k: string]: unknown;\n /**\n * `RegExp` pattern(s) to match against `projectType` (using the\n * [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)\n * function) to determine whether this project setting should be displayed in the Project Settings\n * Dialog of that `projectType`. null means do not show on any Project Settings dialog\n */\n includeProjectTypes?: undefined | string | string[];\n /**\n * `RegExp` pattern to match against `projectType` to determine if this project setting should\n * absolutely not be displayed in the Project Settings dialog of that `projectType` even if it\n * matches with `includeProjectTypes`\n */\n excludeProjectTypes?: undefined | string | string[];\n}\n/** The data an extension provides to inform Platform.Bible of the user state it provides */\nexport interface UserStateContribution {\n [k: ReferencedItem]: UserState;\n}\n/** The data an extension provides to inform Platform.Bible of the project state it provides */\nexport interface ProjectStateContribution {\n [k: ReferencedItem]: UserState;\n}\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\nconst settingsDefs = {\n projectSettingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n },\n projectSettingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the project settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description:\n 'localizeKey that displays in the project settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/projectSettingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n projectSettingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/projectSetting',\n },\n },\n additionalProperties: false,\n },\n projectSetting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledProjectSetting',\n },\n ],\n },\n extensionControlledProjectSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/projectSettingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n projectSettingBase: {\n description: 'Base information needed to describe a project setting entry',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierProject',\n },\n ],\n },\n modifierProject: {\n description: 'Modifies setting type to be project setting',\n type: 'object',\n properties: {\n includeProjectTypes: {\n description:\n '`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n excludeProjectTypes: {\n description:\n '`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n },\n },\n settingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n },\n settingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/settingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n settingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w-]+\\\\.[\\\\w-]+$': {\n $ref: '#/$defs/setting',\n },\n },\n additionalProperties: false,\n },\n setting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledSetting',\n },\n ],\n },\n extensionControlledSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n settingBase: {\n description: 'Base information needed to describe a setting entry',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the setting name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the setting',\n $ref: '#/$defs/localizeKey',\n },\n },\n required: ['label'],\n },\n ],\n },\n projectStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the user state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateProperties: {\n description: 'Object whose keys are state IDs and whose values are state objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/userState',\n },\n },\n additionalProperties: false,\n },\n userState: {\n description: \"A description of an extension's user state entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledState',\n },\n ],\n },\n extensionControlledState: {\n description: 'State definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n modifierExtensionControlled: {\n description:\n 'Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the extension provides the component and the validator for the state/setting, so the state/setting is controlled by the extension.',\n not: {\n anyOf: [\n {\n type: 'object',\n required: ['platformType'],\n },\n {\n type: 'object',\n required: ['type'],\n },\n ],\n },\n },\n stateBase: {\n description: 'Base information needed to describe a state entry',\n type: 'object',\n properties: {\n default: {\n description: 'default value for the state/setting',\n type: 'any',\n },\n derivesFrom: {\n description:\n \"a state/setting ID whose value to set to this state/setting's starting value the first time this state/setting is loaded\",\n $ref: '#/$defs/id',\n },\n },\n required: ['default'],\n },\n localizeKey: {\n description: \"Identifier for a string that will be localized based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n tsType: 'LocalizeKey',\n },\n id: {\n description: '',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n tsType: 'Id',\n },\n};\n\n/**\n * Json-schema-to-typescript has some added stuff that isn't actually compatible with JSON schema,\n * so we remove them here\n *\n * @param defs The `$defs` property of a JSON schema (will be modified in place)\n */\n// JSON schema types are weird, so we'll just be careful\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction removeJsonToTypeScriptTypesStuff(defs: any) {\n if (!defs) return;\n\n // JSON schema types are weird, so we'll just be careful\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.values(defs).forEach((def: any) => {\n if (!def.type) return;\n\n if ('tsType' in def) delete def.tsType;\n\n if (def.type === 'any') {\n delete def.type;\n return;\n }\n\n if (def.type === 'object') {\n removeJsonToTypeScriptTypesStuff(def.properties);\n }\n });\n}\n\nremoveJsonToTypeScriptTypesStuff(settingsDefs);\n\n/** JSON schema object that aligns with the ProjectSettingsContribution type */\nexport const projectSettingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Project Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(projectSettingsDocumentSchema);\n\n/** JSON schema object that aligns with the {@link SettingsContribution} type */\nexport const settingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(settingsDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","PlatformEventEmitter","event","callback","callbackIndex","_a","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombiner","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","contributions","contributionName","potentialOutput","outputIteration","contribution","mergeObjects","output","finalOutput","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","mergeObjectsInternal","startingPointObj","copyFromObj","NonValidatingDocumentCombiner","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","stringLength","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema","settingsDefs","removeJsonToTypeScriptTypesStuff","defs","def","projectSettingsDocumentSchema","settingsDocumentSchema"],"mappings":"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","x_google_ignoreList":[10,11,13]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/platform-event-emitter.model.ts","../src/util.ts","../src/document-combiner.ts","../src/non-validating-document-combiner.ts","../src/unsubscriber-async-list.ts","../src/mutex.ts","../src/mutex-map.ts","../../../node_modules/@sillsdev/scripture/dist/index.es.js","../../../node_modules/char-regex/index.js","../../../node_modules/stringz/dist/index.js","../src/string-util.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/settings.model.ts","../src/localized-strings.model.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n\n/** Within type T, recursively change all properties to be optional */\nexport type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;\n\n/** Within type T, recursively change properties that were of type A to be of type B */\nexport type ReplaceType = T extends A\n ? B\n : T extends object\n ? { [K in keyof T]: ReplaceType }\n : T;\n","import PlatformEventEmitter from './platform-event-emitter.model';\nimport { deepClone } from './util';\n\ntype JsonObjectLike = { [key: string]: unknown };\ntype JsonArrayLike = unknown[];\n\nexport type JsonDocumentLike = JsonObjectLike | JsonArrayLike;\n\n/**\n * Options for DocumentCombiner objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (primarily in the form of JS objects\n * or arrays) together into a single output document.\n */\nexport default class DocumentCombiner {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n private readonly onDidRebuildEmitter = new PlatformEventEmitter();\n /** Event that emits to announce that the document has been rebuilt and the output has been updated */\n // Need `onDidRebuildEmitter` to be instantiated before this line\n // eslint-disable-next-line @typescript-eslint/member-ordering\n readonly onDidRebuild = this.onDidRebuildEmitter.subscribe;\n\n /**\n * Create a DocumentCombiner instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateBaseDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n this.baseDocument = this.transformBaseDocumentAfterValidation(this.baseDocument);\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * Note: the order in which contribution documents are added can be considered to be indeterminate\n * as it is currently ordered by however `Map.forEach` provides the contributions. The order\n * matters when merging two arrays into one. Also, when `options.ignoreDuplicateProperties` is\n * `true`, the order also matters when adding the same property to an object that is already\n * provided previously. Please let us know if you have trouble because of indeterminate\n * contribution ordering.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n let documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n documentToSet = this.transformContributionAfterValidation(documentName, documentToSet);\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): JsonDocumentLike | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`${documentName} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete all present contribution documents for the composition process and return to the base\n * document\n *\n * @returns Recalculated output document consisting only of the base document\n */\n deleteAllContributions(): JsonDocumentLike | undefined {\n if (this.contributions.size <= 0) return this.latestOutput;\n\n // Save out all contributions\n const contributions = [...this.contributions.entries()];\n\n // Delete all contributions\n contributions.forEach(([contributionName]) => this.contributions.delete(contributionName));\n\n // Rebuild with no contributions\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting all contributions, put them back and rethrow\n contributions.forEach(([contributionName, document]) =>\n this.contributions.set(contributionName, document),\n );\n throw new Error(`Error when deleting all contributions: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutputBeforeValidation(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutputBeforeValidation(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n this.onDidRebuildEmitter.emit(undefined);\n return this.latestOutput;\n }\n\n /**\n * Transform the starting document that is given to the combiner. This transformation occurs after\n * validating the base document and before combining any contributions.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the `baseDocument` passed in.\n *\n * @param baseDocument Initial input document. Already validated via `validateBaseDocument`\n * @returns Transformed base document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformBaseDocumentAfterValidation(baseDocument: JsonDocumentLike): JsonDocumentLike {\n return baseDocument;\n }\n\n /**\n * Transform the contributed document associated with `documentName`. This transformation occurs\n * after validating the contributed document and before combining with other documents.\n *\n * WARNING: If you do not create the combiner with option `copyDocuments: true` or clone inside\n * this method, this method will directly modify the contributed `document` passed in.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine. Already validated via\n * `validateContribution`\n * @returns Transformed contributed document\n */\n // We just don't need `this` here. This is basically a no-op function that is available to child\n // classes to override\n // eslint-disable-next-line class-methods-use-this\n protected transformContributionAfterValidation(\n // @ts-expect-error this parameter is unused but may be used in child classes\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike {\n return document;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateBaseDocument(baseDocument: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateContribution(documentName: string, document: JsonDocumentLike): void {}\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n // no-op intended to be overridden by child classes. Can't be static\n // @ts-expect-error ts(6133) parameter doesn't need to be used but still needs the right name\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n protected validateOutput(output: JsonDocumentLike): void {}\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation via `validateOutput`\n * before `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n // no-op intended to be overridden by child classes. Can't be static\n // eslint-disable-next-line class-methods-use-this\n protected transformFinalOutputBeforeValidation(finalOutput: JsonDocumentLike): JsonDocumentLike {\n return finalOutput;\n }\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Deep clone and recursively merge the properties of one object (copyFrom) into another\n * (startingPoint). Throws if copyFrom would overwrite values already existing in startingPoint.\n *\n * Does not modify the objects passed in.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n\n if (!copyFrom) return retVal;\n\n return mergeObjectsInternal(retVal, deepClone(copyFrom), ignoreDuplicateProperties);\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * WARNING: Modifies the argument objects in some way. Recommended to use `mergeObjects`\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @param ignoreDuplicateProperties Whether to ignore object properties that are present in\n * `copyFrom` that are already present in `startingPoint`. If `false`, throws when an object\n * property in `copyFrom` is already present in `startingPoint`\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjectsInternal(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n if (!copyFrom) return startingPoint;\n\n if (areNonArrayObjects(startingPoint, copyFrom)) {\n // Merge properties since they are both objects\n\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n const startingPointObj = startingPoint as JsonObjectLike;\n const copyFromObj = copyFrom as JsonObjectLike;\n /* eslint-enable no-type-assertion/no-type-assertion */\n Object.keys(copyFromObj).forEach((key: string | number) => {\n if (Object.hasOwn(startingPointObj, key)) {\n if (areNonArrayObjects(startingPointObj[key], copyFromObj[key])) {\n startingPointObj[key] = mergeObjectsInternal(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] as JsonObjectLike,\n copyFromObj[key] as JsonObjectLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPointObj[key], copyFromObj[key])) {\n // Concat the arrays since they are both arrays\n\n // We know these are arrays from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPointObj[key] = (startingPointObj[key] as JsonArrayLike).concat(\n copyFromObj[key] as JsonArrayLike,\n );\n /* eslint-enable no-type-assertion/no-type-assertion */\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n // Note that the first non-object non-array value that gets placed in a property stays.\n // New values do not override existing ones\n } else {\n startingPointObj[key] = copyFromObj[key];\n }\n });\n } else if (areArrayObjects(startingPoint, copyFrom)) {\n // Concat the arrays since they are both arrays\n\n // Push the contents of copyFrom into startingPoint since it is a const and was already deep cloned\n // We know these are objects from the `else if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n (startingPoint as JsonArrayLike).push(...(copyFrom as JsonArrayLike));\n /* eslint-enable no-type-assertion/no-type-assertion */\n }\n\n // Note that nothing happens if `startingPoint` is not an object or an array or if `startingPoint`\n // and `copyFrom` are not both object or both arrays. Should we throw? Should we push `copyFrom`'s\n // values into the array? Other? Maybe one day we can add some options to decide what to do in\n // this situation, but YAGNI for now\n\n return startingPoint;\n}\n\n// #endregion\n","import DocumentCombiner, { DocumentCombinerOptions, JsonDocumentLike } from './document-combiner';\n\nexport default class NonValidatingDocumentCombiner extends DocumentCombiner {\n // Making the protected base constructor public\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n super(baseDocument, options);\n }\n\n get output(): JsonDocumentLike | undefined {\n return this.latestOutput;\n }\n}\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","var P = Object.defineProperty;\nvar R = (t, e, s) => e in t ? P(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;\nvar n = (t, e, s) => (R(t, typeof e != \"symbol\" ? e + \"\" : e, s), s);\nclass z {\n constructor() {\n n(this, \"books\");\n n(this, \"firstSelectedBookNum\");\n n(this, \"lastSelectedBookNum\");\n n(this, \"count\");\n n(this, \"selectedBookNumbers\");\n n(this, \"selectedBookIds\");\n }\n}\nconst m = [\n \"GEN\",\n \"EXO\",\n \"LEV\",\n \"NUM\",\n \"DEU\",\n \"JOS\",\n \"JDG\",\n \"RUT\",\n \"1SA\",\n \"2SA\",\n // 10\n \"1KI\",\n \"2KI\",\n \"1CH\",\n \"2CH\",\n \"EZR\",\n \"NEH\",\n \"EST\",\n \"JOB\",\n \"PSA\",\n \"PRO\",\n // 20\n \"ECC\",\n \"SNG\",\n \"ISA\",\n \"JER\",\n \"LAM\",\n \"EZK\",\n \"DAN\",\n \"HOS\",\n \"JOL\",\n \"AMO\",\n // 30\n \"OBA\",\n \"JON\",\n \"MIC\",\n \"NAM\",\n \"HAB\",\n \"ZEP\",\n \"HAG\",\n \"ZEC\",\n \"MAL\",\n \"MAT\",\n // 40\n \"MRK\",\n \"LUK\",\n \"JHN\",\n \"ACT\",\n \"ROM\",\n \"1CO\",\n \"2CO\",\n \"GAL\",\n \"EPH\",\n \"PHP\",\n // 50\n \"COL\",\n \"1TH\",\n \"2TH\",\n \"1TI\",\n \"2TI\",\n \"TIT\",\n \"PHM\",\n \"HEB\",\n \"JAS\",\n \"1PE\",\n // 60\n \"2PE\",\n \"1JN\",\n \"2JN\",\n \"3JN\",\n \"JUD\",\n \"REV\",\n \"TOB\",\n \"JDT\",\n \"ESG\",\n \"WIS\",\n // 70\n \"SIR\",\n \"BAR\",\n \"LJE\",\n \"S3Y\",\n \"SUS\",\n \"BEL\",\n \"1MA\",\n \"2MA\",\n \"3MA\",\n \"4MA\",\n // 80\n \"1ES\",\n \"2ES\",\n \"MAN\",\n \"PS2\",\n \"ODA\",\n \"PSS\",\n \"JSA\",\n // actual variant text for JOS, now in LXA text\n \"JDB\",\n // actual variant text for JDG, now in LXA text\n \"TBS\",\n // actual variant text for TOB, now in LXA text\n \"SST\",\n // actual variant text for SUS, now in LXA text // 90\n \"DNT\",\n // actual variant text for DAN, now in LXA text\n \"BLT\",\n // actual variant text for BEL, now in LXA text\n \"XXA\",\n \"XXB\",\n \"XXC\",\n \"XXD\",\n \"XXE\",\n \"XXF\",\n \"XXG\",\n \"FRT\",\n // 100\n \"BAK\",\n \"OTH\",\n \"3ES\",\n // Used previously but really should be 2ES\n \"EZA\",\n // Used to be called 4ES, but not actually in any known project\n \"5EZ\",\n // Used to be called 5ES, but not actually in any known project\n \"6EZ\",\n // Used to be called 6ES, but not actually in any known project\n \"INT\",\n \"CNC\",\n \"GLO\",\n \"TDX\",\n // 110\n \"NDX\",\n \"DAG\",\n \"PS3\",\n \"2BA\",\n \"LBA\",\n \"JUB\",\n \"ENO\",\n \"1MQ\",\n \"2MQ\",\n \"3MQ\",\n // 120\n \"REP\",\n \"4BA\",\n \"LAO\"\n], v = [\n \"XXA\",\n \"XXB\",\n \"XXC\",\n \"XXD\",\n \"XXE\",\n \"XXF\",\n \"XXG\",\n \"FRT\",\n \"BAK\",\n \"OTH\",\n \"INT\",\n \"CNC\",\n \"GLO\",\n \"TDX\",\n \"NDX\"\n], X = [\n \"Genesis\",\n \"Exodus\",\n \"Leviticus\",\n \"Numbers\",\n \"Deuteronomy\",\n \"Joshua\",\n \"Judges\",\n \"Ruth\",\n \"1 Samuel\",\n \"2 Samuel\",\n \"1 Kings\",\n \"2 Kings\",\n \"1 Chronicles\",\n \"2 Chronicles\",\n \"Ezra\",\n \"Nehemiah\",\n \"Esther (Hebrew)\",\n \"Job\",\n \"Psalms\",\n \"Proverbs\",\n \"Ecclesiastes\",\n \"Song of Songs\",\n \"Isaiah\",\n \"Jeremiah\",\n \"Lamentations\",\n \"Ezekiel\",\n \"Daniel (Hebrew)\",\n \"Hosea\",\n \"Joel\",\n \"Amos\",\n \"Obadiah\",\n \"Jonah\",\n \"Micah\",\n \"Nahum\",\n \"Habakkuk\",\n \"Zephaniah\",\n \"Haggai\",\n \"Zechariah\",\n \"Malachi\",\n \"Matthew\",\n \"Mark\",\n \"Luke\",\n \"John\",\n \"Acts\",\n \"Romans\",\n \"1 Corinthians\",\n \"2 Corinthians\",\n \"Galatians\",\n \"Ephesians\",\n \"Philippians\",\n \"Colossians\",\n \"1 Thessalonians\",\n \"2 Thessalonians\",\n \"1 Timothy\",\n \"2 Timothy\",\n \"Titus\",\n \"Philemon\",\n \"Hebrews\",\n \"James\",\n \"1 Peter\",\n \"2 Peter\",\n \"1 John\",\n \"2 John\",\n \"3 John\",\n \"Jude\",\n \"Revelation\",\n \"Tobit\",\n \"Judith\",\n \"Esther Greek\",\n \"Wisdom of Solomon\",\n \"Sirach (Ecclesiasticus)\",\n \"Baruch\",\n \"Letter of Jeremiah\",\n \"Song of 3 Young Men\",\n \"Susanna\",\n \"Bel and the Dragon\",\n \"1 Maccabees\",\n \"2 Maccabees\",\n \"3 Maccabees\",\n \"4 Maccabees\",\n \"1 Esdras (Greek)\",\n \"2 Esdras (Latin)\",\n \"Prayer of Manasseh\",\n \"Psalm 151\",\n \"Odes\",\n \"Psalms of Solomon\",\n // WARNING, if you change the spelling of the *obsolete* tag be sure to update\n // IsObsolete routine\n \"Joshua A. *obsolete*\",\n \"Judges B. *obsolete*\",\n \"Tobit S. *obsolete*\",\n \"Susanna Th. *obsolete*\",\n \"Daniel Th. *obsolete*\",\n \"Bel Th. *obsolete*\",\n \"Extra A\",\n \"Extra B\",\n \"Extra C\",\n \"Extra D\",\n \"Extra E\",\n \"Extra F\",\n \"Extra G\",\n \"Front Matter\",\n \"Back Matter\",\n \"Other Matter\",\n \"3 Ezra *obsolete*\",\n \"Apocalypse of Ezra\",\n \"5 Ezra (Latin Prologue)\",\n \"6 Ezra (Latin Epilogue)\",\n \"Introduction\",\n \"Concordance \",\n \"Glossary \",\n \"Topical Index\",\n \"Names Index\",\n \"Daniel Greek\",\n \"Psalms 152-155\",\n \"2 Baruch (Apocalypse)\",\n \"Letter of Baruch\",\n \"Jubilees\",\n \"Enoch\",\n \"1 Meqabyan\",\n \"2 Meqabyan\",\n \"3 Meqabyan\",\n \"Reproof (Proverbs 25-31)\",\n \"4 Baruch (Rest of Baruch)\",\n \"Laodiceans\"\n], C = K();\nfunction N(t, e = !0) {\n return e && (t = t.toUpperCase()), t in C ? C[t] : 0;\n}\nfunction B(t) {\n return N(t) > 0;\n}\nfunction x(t) {\n const e = typeof t == \"string\" ? N(t) : t;\n return e >= 40 && e <= 66;\n}\nfunction T(t) {\n return (typeof t == \"string\" ? N(t) : t) <= 39;\n}\nfunction O(t) {\n return t <= 66;\n}\nfunction V(t) {\n const e = typeof t == \"string\" ? N(t) : t;\n return I(e) && !O(e);\n}\nfunction* L() {\n for (let t = 1; t <= m.length; t++)\n yield t;\n}\nconst G = 1, S = m.length;\nfunction H() {\n return [\"XXA\", \"XXB\", \"XXC\", \"XXD\", \"XXE\", \"XXF\", \"XXG\"];\n}\nfunction k(t, e = \"***\") {\n const s = t - 1;\n return s < 0 || s >= m.length ? e : m[s];\n}\nfunction A(t) {\n return t <= 0 || t > S ? \"******\" : X[t - 1];\n}\nfunction y(t) {\n return A(N(t));\n}\nfunction I(t) {\n const e = typeof t == \"number\" ? k(t) : t;\n return B(e) && !v.includes(e);\n}\nfunction q(t) {\n const e = typeof t == \"number\" ? k(t) : t;\n return B(e) && v.includes(e);\n}\nfunction U(t) {\n return X[t - 1].includes(\"*obsolete*\");\n}\nfunction K() {\n const t = {};\n for (let e = 0; e < m.length; e++)\n t[m[e]] = e + 1;\n return t;\n}\nconst f = {\n allBookIds: m,\n nonCanonicalIds: v,\n bookIdToNumber: N,\n isBookIdValid: B,\n isBookNT: x,\n isBookOT: T,\n isBookOTNT: O,\n isBookDC: V,\n allBookNumbers: L,\n firstBook: G,\n lastBook: S,\n extraBooks: H,\n bookNumberToId: k,\n bookNumberToEnglishName: A,\n bookIdToEnglishName: y,\n isCanonical: I,\n isExtraMaterial: q,\n isObsolete: U\n};\nvar l = /* @__PURE__ */ ((t) => (t[t.Unknown = 0] = \"Unknown\", t[t.Original = 1] = \"Original\", t[t.Septuagint = 2] = \"Septuagint\", t[t.Vulgate = 3] = \"Vulgate\", t[t.English = 4] = \"English\", t[t.RussianProtestant = 5] = \"RussianProtestant\", t[t.RussianOrthodox = 6] = \"RussianOrthodox\", t))(l || {});\nconst u = class u {\n // private versInfo: Versification;\n constructor(e) {\n n(this, \"name\");\n n(this, \"fullPath\");\n n(this, \"isPresent\");\n n(this, \"hasVerseSegments\");\n n(this, \"isCustomized\");\n n(this, \"baseVersification\");\n n(this, \"scriptureBooks\");\n n(this, \"_type\");\n if (e != null)\n typeof e == \"string\" ? this.name = e : this._type = e;\n else\n throw new Error(\"Argument null\");\n }\n get type() {\n return this._type;\n }\n equals(e) {\n return !e.type || !this.type ? !1 : e.type === this.type;\n }\n};\nn(u, \"Original\", new u(l.Original)), n(u, \"Septuagint\", new u(l.Septuagint)), n(u, \"Vulgate\", new u(l.Vulgate)), n(u, \"English\", new u(l.English)), n(u, \"RussianProtestant\", new u(l.RussianProtestant)), n(u, \"RussianOrthodox\", new u(l.RussianOrthodox));\nlet c = u;\nfunction E(t, e) {\n const s = e[0];\n for (let r = 1; r < e.length; r++)\n t = t.split(e[r]).join(s);\n return t.split(s);\n}\nvar D = /* @__PURE__ */ ((t) => (t[t.Valid = 0] = \"Valid\", t[t.UnknownVersification = 1] = \"UnknownVersification\", t[t.OutOfRange = 2] = \"OutOfRange\", t[t.VerseOutOfOrder = 3] = \"VerseOutOfOrder\", t[t.VerseRepeated = 4] = \"VerseRepeated\", t))(D || {});\nconst i = class i {\n constructor(e, s, r, o) {\n /** Not yet implemented. */\n n(this, \"firstChapter\");\n /** Not yet implemented. */\n n(this, \"lastChapter\");\n /** Not yet implemented. */\n n(this, \"lastVerse\");\n /** Not yet implemented. */\n n(this, \"hasSegmentsDefined\");\n /** Not yet implemented. */\n n(this, \"text\");\n /** Not yet implemented. */\n n(this, \"BBBCCCVVVS\");\n /** Not yet implemented. */\n n(this, \"longHashCode\");\n /** The versification of the reference. */\n n(this, \"versification\");\n n(this, \"rtlMark\", \"‏\");\n n(this, \"_bookNum\", 0);\n n(this, \"_chapterNum\", 0);\n n(this, \"_verseNum\", 0);\n n(this, \"_verse\");\n if (r == null && o == null)\n if (e != null && typeof e == \"string\") {\n const a = e, h = s != null && s instanceof c ? s : void 0;\n this.setEmpty(h), this.parse(a);\n } else if (e != null && typeof e == \"number\") {\n const a = s != null && s instanceof c ? s : void 0;\n this.setEmpty(a), this._verseNum = e % i.chapterDigitShifter, this._chapterNum = Math.floor(\n e % i.bookDigitShifter / i.chapterDigitShifter\n ), this._bookNum = Math.floor(e / i.bookDigitShifter);\n } else if (s == null)\n if (e != null && e instanceof i) {\n const a = e;\n this._bookNum = a.bookNum, this._chapterNum = a.chapterNum, this._verseNum = a.verseNum, this._verse = a.verse, this.versification = a.versification;\n } else {\n if (e == null)\n return;\n const a = e instanceof c ? e : i.defaultVersification;\n this.setEmpty(a);\n }\n else\n throw new Error(\"VerseRef constructor not supported.\");\n else if (e != null && s != null && r != null)\n if (typeof e == \"string\" && typeof s == \"string\" && typeof r == \"string\")\n this.setEmpty(o), this.updateInternal(e, s, r);\n else if (typeof e == \"number\" && typeof s == \"number\" && typeof r == \"number\")\n this._bookNum = e, this._chapterNum = s, this._verseNum = r, this.versification = o ?? i.defaultVersification;\n else\n throw new Error(\"VerseRef constructor not supported.\");\n else\n throw new Error(\"VerseRef constructor not supported.\");\n }\n /**\n * @deprecated Will be removed in v2. Replace `VerseRef.parse('...')` with `new VerseRef('...')`\n * or refactor to use `VerseRef.tryParse('...')` which has a different return type.\n */\n static parse(e, s = i.defaultVersification) {\n const r = new i(s);\n return r.parse(e), r;\n }\n /**\n * Determines if the verse string is in a valid format (does not consider versification).\n */\n static isVerseParseable(e) {\n return e.length > 0 && \"0123456789\".includes(e[0]) && !e.endsWith(this.verseRangeSeparator) && !e.endsWith(this.verseSequenceIndicator);\n }\n /**\n * Tries to parse the specified string into a verse reference.\n * @param str - The string to attempt to parse.\n * @returns success: `true` if the specified string was successfully parsed, `false` otherwise.\n * @returns verseRef: The result of the parse if successful, or empty VerseRef if it failed\n */\n static tryParse(e) {\n let s;\n try {\n return s = i.parse(e), { success: !0, verseRef: s };\n } catch (r) {\n if (r instanceof d)\n return s = new i(), { success: !1, verseRef: s };\n throw r;\n }\n }\n /**\n * Gets the reference as a comparable integer where the book, chapter, and verse each occupy 3\n * digits.\n * @param bookNum - Book number (this is 1-based, not an index).\n * @param chapterNum - Chapter number.\n * @param verseNum - Verse number.\n * @returns The reference as a comparable integer where the book, chapter, and verse each occupy 3\n * digits.\n */\n static getBBBCCCVVV(e, s, r) {\n return e % i.bcvMaxValue * i.bookDigitShifter + (s >= 0 ? s % i.bcvMaxValue * i.chapterDigitShifter : 0) + (r >= 0 ? r % i.bcvMaxValue : 0);\n }\n /**\n * Parses a verse string and gets the leading numeric portion as a number.\n * @param verseStr - verse string to parse\n * @returns true if the entire string could be parsed as a single, simple verse number (1-999);\n * false if the verse string represented a verse bridge, contained segment letters, or was invalid\n */\n static tryGetVerseNum(e) {\n let s;\n if (!e)\n return s = -1, { success: !0, vNum: s };\n s = 0;\n let r;\n for (let o = 0; o < e.length; o++) {\n if (r = e[o], r < \"0\" || r > \"9\")\n return o === 0 && (s = -1), { success: !1, vNum: s };\n if (s = s * 10 + +r - +\"0\", s > i.bcvMaxValue)\n return s = -1, { success: !1, vNum: s };\n }\n return { success: !0, vNum: s };\n }\n /**\n * Checks to see if a VerseRef hasn't been set - all values are the default.\n */\n get isDefault() {\n return this.bookNum === 0 && this.chapterNum === 0 && this.verseNum === 0 && this.versification == null;\n }\n /**\n * Gets whether the verse contains multiple verses.\n */\n get hasMultiple() {\n return this._verse != null && (this._verse.includes(i.verseRangeSeparator) || this._verse.includes(i.verseSequenceIndicator));\n }\n /**\n * Gets or sets the book of the reference. Book is the 3-letter abbreviation in capital letters,\n * e.g. `'MAT'`.\n */\n get book() {\n return f.bookNumberToId(this.bookNum, \"\");\n }\n set book(e) {\n this.bookNum = f.bookIdToNumber(e);\n }\n /**\n * Gets or sets the chapter of the reference,. e.g. `'3'`.\n */\n get chapter() {\n return this.isDefault || this._chapterNum < 0 ? \"\" : this._chapterNum.toString();\n }\n set chapter(e) {\n const s = +e;\n this._chapterNum = Number.isInteger(s) ? s : -1;\n }\n /**\n * Gets or sets the verse of the reference, including range, segments, and sequences, e.g. `'4'`,\n * or `'4b-5a, 7'`.\n */\n get verse() {\n return this._verse != null ? this._verse : this.isDefault || this._verseNum < 0 ? \"\" : this._verseNum.toString();\n }\n set verse(e) {\n const { success: s, vNum: r } = i.tryGetVerseNum(e);\n this._verse = s ? void 0 : e.replace(this.rtlMark, \"\"), this._verseNum = r, !(this._verseNum >= 0) && ({ vNum: this._verseNum } = i.tryGetVerseNum(this._verse));\n }\n /**\n * Get or set Book based on book number, e.g. `42`.\n */\n get bookNum() {\n return this._bookNum;\n }\n set bookNum(e) {\n if (e <= 0 || e > f.lastBook)\n throw new d(\n \"BookNum must be greater than zero and less than or equal to last book\"\n );\n this._bookNum = e;\n }\n /**\n * Gets or sets the chapter number, e.g. `3`. `-1` if not valid.\n */\n get chapterNum() {\n return this._chapterNum;\n }\n set chapterNum(e) {\n this.chapterNum = e;\n }\n /**\n * Gets or sets verse start number, e.g. `4`. `-1` if not valid.\n */\n get verseNum() {\n return this._verseNum;\n }\n set verseNum(e) {\n this._verseNum = e;\n }\n /**\n * String representing the versification (should ONLY be used for serialization/deserialization).\n *\n * @remarks This is for backwards compatibility when ScrVers was an enumeration.\n */\n get versificationStr() {\n var e;\n return (e = this.versification) == null ? void 0 : e.name;\n }\n set versificationStr(e) {\n this.versification = this.versification != null ? new c(e) : void 0;\n }\n /**\n * Determines if the reference is valid.\n */\n get valid() {\n return this.validStatus === 0;\n }\n /**\n * Get the valid status for this reference.\n */\n get validStatus() {\n return this.validateVerse(i.verseRangeSeparators, i.verseSequenceIndicators);\n }\n /**\n * Gets the reference as a comparable integer where the book,\n * chapter, and verse each occupy three digits and the verse is 0.\n */\n get BBBCCC() {\n return i.getBBBCCCVVV(this._bookNum, this._chapterNum, 0);\n }\n /**\n * Gets the reference as a comparable integer where the book,\n * chapter, and verse each occupy three digits. If verse is not null\n * (i.e., this reference represents a complex reference with verse\n * segments or bridge) this cannot be used for an exact comparison.\n */\n get BBBCCCVVV() {\n return i.getBBBCCCVVV(this._bookNum, this._chapterNum, this._verseNum);\n }\n /**\n * Gets whether the verse is defined as an excluded verse in the versification.\n * Does not handle verse ranges.\n */\n // eslint-disable-next-line @typescript-eslint/class-literal-property-style\n get isExcluded() {\n return !1;\n }\n /**\n * Parses the reference in the specified string.\n * Optionally versification can follow reference as in GEN 3:11/4\n * Throw an exception if\n * - invalid book name\n * - chapter number is missing or not a number\n * - verse number is missing or does not start with a number\n * - versification is invalid\n * @param verseStr - string to parse e.g. 'MAT 3:11'\n */\n parse(e) {\n if (e = e.replace(this.rtlMark, \"\"), e.includes(\"/\")) {\n const a = e.split(\"/\");\n if (e = a[0], a.length > 1)\n try {\n const h = +a[1].trim();\n this.versification = new c(l[h]);\n } catch {\n throw new d(\"Invalid reference : \" + e);\n }\n }\n const s = e.trim().split(\" \");\n if (s.length !== 2)\n throw new d(\"Invalid reference : \" + e);\n const r = s[1].split(\":\"), o = +r[0];\n if (r.length !== 2 || f.bookIdToNumber(s[0]) === 0 || !Number.isInteger(o) || o < 0 || !i.isVerseParseable(r[1]))\n throw new d(\"Invalid reference : \" + e);\n this.updateInternal(s[0], r[0], r[1]);\n }\n /**\n * Simplifies this verse ref so that it has no bridging of verses or\n * verse segments like `'1a'`.\n */\n simplify() {\n this._verse = void 0;\n }\n /**\n * Makes a clone of the reference.\n *\n * @returns The cloned VerseRef.\n */\n clone() {\n return new i(this);\n }\n toString() {\n const e = this.book;\n return e === \"\" ? \"\" : `${e} ${this.chapter}:${this.verse}`;\n }\n /**\n * Compares this `VerseRef` with supplied one.\n * @param verseRef - object to compare this one to.\n * @returns `true` if this `VerseRef` is equal to the supplied on, `false` otherwise.\n */\n equals(e) {\n return e instanceof i ? e._bookNum === this._bookNum && e._chapterNum === this._chapterNum && e._verseNum === this._verseNum && e.verse === this.verse && e.versification != null && this.versification != null && e.versification.equals(this.versification) : !1;\n }\n /**\n * Enumerate all individual verses contained in a VerseRef.\n * Verse ranges are indicated by \"-\" and consecutive verses by \",\"s.\n * Examples:\n * GEN 1:2 returns GEN 1:2\n * GEN 1:1a-3b,5 returns GEN 1:1a, GEN 1:2, GEN 1:3b, GEN 1:5\n * GEN 1:2a-2c returns //! ??????\n *\n * @param specifiedVersesOnly - if set to true return only verses that are\n * explicitly specified only, not verses within a range. Defaults to `false`.\n * @param verseRangeSeparators - Verse range separators.\n * Defaults to `VerseRef.verseRangeSeparators`.\n * @param verseSequenceSeparators - Verse sequence separators.\n * Defaults to `VerseRef.verseSequenceIndicators`.\n * @returns An array of all single verse references in this VerseRef.\n */\n allVerses(e = !1, s = i.verseRangeSeparators, r = i.verseSequenceIndicators) {\n if (this._verse == null || this.chapterNum <= 0)\n return [this.clone()];\n const o = [], a = E(this._verse, r);\n for (const h of a.map((g) => E(g, s))) {\n const g = this.clone();\n g.verse = h[0];\n const w = g.verseNum;\n if (o.push(g), h.length > 1) {\n const p = this.clone();\n if (p.verse = h[1], !e)\n for (let b = w + 1; b < p.verseNum; b++) {\n const J = new i(\n this._bookNum,\n this._chapterNum,\n b,\n this.versification\n );\n this.isExcluded || o.push(J);\n }\n o.push(p);\n }\n }\n return o;\n }\n /**\n * Validates a verse number using the supplied separators rather than the defaults.\n */\n validateVerse(e, s) {\n if (!this.verse)\n return this.internalValid;\n let r = 0;\n for (const o of this.allVerses(!0, e, s)) {\n const a = o.internalValid;\n if (a !== 0)\n return a;\n const h = o.BBBCCCVVV;\n if (r > h)\n return 3;\n if (r === h)\n return 4;\n r = h;\n }\n return 0;\n }\n /**\n * Gets whether a single verse reference is valid.\n */\n get internalValid() {\n return this.versification == null ? 1 : this._bookNum <= 0 || this._bookNum > f.lastBook ? 2 : (f.isCanonical(this._bookNum), 0);\n }\n setEmpty(e = i.defaultVersification) {\n this._bookNum = 0, this._chapterNum = -1, this._verse = void 0, this.versification = e;\n }\n updateInternal(e, s, r) {\n this.bookNum = f.bookIdToNumber(e), this.chapter = s, this.verse = r;\n }\n};\nn(i, \"defaultVersification\", c.English), n(i, \"verseRangeSeparator\", \"-\"), n(i, \"verseSequenceIndicator\", \",\"), n(i, \"verseRangeSeparators\", [i.verseRangeSeparator]), n(i, \"verseSequenceIndicators\", [i.verseSequenceIndicator]), n(i, \"chapterDigitShifter\", 1e3), n(i, \"bookDigitShifter\", i.chapterDigitShifter * i.chapterDigitShifter), n(i, \"bcvMaxValue\", i.chapterDigitShifter - 1), /**\n * The valid status of the VerseRef.\n */\nn(i, \"ValidStatusType\", D);\nlet M = i;\nclass d extends Error {\n}\nexport {\n z as BookSet,\n f as Canon,\n c as ScrVers,\n l as ScrVersType,\n M as VerseRef,\n d as VerseRefException\n};\n//# sourceMappingURL=index.es.js.map\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * This function mirrors the `at` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Finds the Unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified offset,\n * undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > stringLength(string) || index < -stringLength(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `charAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a new string consisting of the single unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified offset, empty\n * string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > stringLength(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the character at the given\n * index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > stringLength(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * This function mirrors the `endsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether a string ends with the characters of this string.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be found. Default is\n * `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = stringLength(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * This function mirrors the `includes` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Performs a case-sensitive search to determine if searchString is found in string.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString. Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * This function mirrors the `indexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the index of the first occurrence of a given string.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Searches this string and returns the index of the last occurrence of the specified substring.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(string: string, searchString: string, position?: number): number {\n let validatedPosition = position === undefined ? stringLength(string) : position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= stringLength(string)) {\n validatedPosition = stringLength(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, stringLength(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * This function mirrors the `length` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes. Since `length` appears to be a\n * reserved keyword, the function was renamed to `stringLength`\n *\n * Returns the length of a string.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function stringLength(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * This function mirrors the `normalize` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * This function mirrors the `padEnd` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * This function mirrors the `padStart` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\n// This is a helper function that performs a correction on the slice index to make sure it\n// cannot go out of bounds\nfunction correctSliceIndex(length: number, index: number) {\n if (index > length) return length;\n if (index < -length) return 0;\n if (index < 0) return index + length;\n return index;\n}\n\n/**\n * This function mirrors the `slice` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const length: number = stringLength(string);\n if (\n indexStart > length ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(indexStart >= 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) ||\n indexEnd < -length))\n )\n return '';\n\n const newStart = correctSliceIndex(length, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * This function mirrors the `split` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits the\n * string at each occurrence of specified separator, but stops when limit entries have been placed\n * in the array.\n * @returns An array of strings, split at each point where separator occurs in the starting string.\n * Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = stringLength(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * This function mirrors the `startsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found (the index of\n * searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string, including when\n * searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * This function mirrors the `substr` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and length. This function is not exported because it is\n * considered deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String length minus start parameter`. Default is `String\n * length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(\n string: string,\n begin: number = 0,\n len: number = stringLength(string) - begin,\n): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * This function mirrors the `substring` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and end position.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = stringLength(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * This function mirrors the `toArray` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Converts a string to an array of string characters.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","import { Canon } from '@sillsdev/scripture';\nimport { BookInfo, ScriptureReference } from './scripture.model';\nimport { split, startsWith } from './string-util';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n\n/**\n * https://github.com/ubsicap/Paratext/blob/master/ParatextData/SILScriptureExtensions.cs#L72\n *\n * Convert book number to a localized Id (a short description of the book). This should be used\n * whenever a book ID (short code) is shown to the user. It is primarily needed for people who do\n * not read Roman script well and need to have books identified in a alternate script (e.g.\n * Chinese or Russian)\n *\n * @param bookNumber\n * @param localizationLanguage in BCP 47 format\n * @param getLocalizedString function that provides the localized versions of the book ids and names\n * asynchronously.\n * @returns\n */\nexport async function getLocalizedIdFromBookNumber(\n bookNumber: number,\n localizationLanguage: string,\n getLocalizedString: (item: {\n localizeKey: string;\n languagesToSearch?: string[];\n }) => Promise,\n) {\n const id = Canon.bookNumberToId(bookNumber);\n\n if (!startsWith(Intl.getCanonicalLocales(localizationLanguage)[0], 'zh'))\n return getLocalizedString({\n localizeKey: `LocalizedId.${id}`,\n languagesToSearch: [localizationLanguage],\n });\n\n // For Chinese the normal book name is already fairly short.\n const bookName = await getLocalizedString({\n localizeKey: `Book.${id}`,\n languagesToSearch: [localizationLanguage],\n });\n const parts = split(bookName, '-');\n // some entries had a second name inside ideographic parenthesis\n const parts2 = split(parts[0], '\\xff08')\n const retVal = parts2[0].trim();\n return retVal;\n}\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { LocalizeKey, ReferencedItem } from 'menus.model';\n\n/** The data an extension provides to inform Platform.Bible of the settings it provides */\nexport type SettingsContribution = SettingsGroup | SettingsGroup[];\n/** A description of an extension's setting entry */\nexport type Setting = ExtensionControlledSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledSetting = SettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a setting entry */\nexport type SettingBase = StateBase & {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the setting name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the setting */\n description?: LocalizeKey;\n};\n/** The data an extension provides to inform Platform.Bible of the project settings it provides */\nexport type ProjectSettingsContribution = ProjectSettingsGroup | ProjectSettingsGroup[];\n/** A description of an extension's setting entry */\nexport type ProjectSetting = ExtensionControlledProjectSetting;\n/** Setting definition that is validated by the extension. */\nexport type ExtensionControlledProjectSetting = ProjectSettingBase & ModifierExtensionControlled;\n/** Base information needed to describe a project setting entry */\nexport type ProjectSettingBase = SettingBase & ModifierProject;\n/** A description of an extension's user state entry */\nexport type UserState = ExtensionControlledState;\n/** State definition that is validated by the extension. */\nexport type ExtensionControlledState = StateBase & ModifierExtensionControlled;\n/** Group of related settings definitions */\nexport interface SettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the settings dialog to describe the group */\n description?: LocalizeKey;\n properties: SettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface SettingProperties {\n [k: ReferencedItem]: Setting;\n}\n/** Base information needed to describe a state entry */\nexport interface StateBase {\n [k: string]: unknown;\n /** Default value for the state/setting */\n default: unknown;\n /**\n * A state/setting ID whose value to set to this state/setting's starting value the first time\n * this state/setting is loaded\n */\n derivesFrom?: ReferencedItem;\n}\n/**\n * Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the\n * extension provides the component and the validator for the state/setting, so the state/setting is\n * controlled by the extension.\n */\nexport interface ModifierExtensionControlled {\n [k: string]: unknown;\n platformType?: undefined;\n type?: undefined;\n}\n/** Group of related settings definitions */\nexport interface ProjectSettingsGroup {\n [k: string]: unknown;\n /** LocalizeKey that displays in the project settings dialog as the group name */\n label: LocalizeKey;\n /** LocalizeKey that displays in the project settings dialog to describe the group */\n description?: LocalizeKey;\n properties: ProjectSettingProperties;\n}\n/** Object whose keys are setting IDs and whose values are settings objects */\nexport interface ProjectSettingProperties {\n [k: ReferencedItem]: ProjectSetting;\n}\n/** Modifies setting type to be project setting */\nexport interface ModifierProject {\n [k: string]: unknown;\n /**\n * `RegExp` pattern(s) to match against `projectType` (using the\n * [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)\n * function) to determine whether this project setting should be displayed in the Project Settings\n * Dialog of that `projectType`. null means do not show on any Project Settings dialog\n */\n includeProjectTypes?: undefined | string | string[];\n /**\n * `RegExp` pattern to match against `projectType` to determine if this project setting should\n * absolutely not be displayed in the Project Settings dialog of that `projectType` even if it\n * matches with `includeProjectTypes`\n */\n excludeProjectTypes?: undefined | string | string[];\n}\n/** The data an extension provides to inform Platform.Bible of the user state it provides */\nexport interface UserStateContribution {\n [k: ReferencedItem]: UserState;\n}\n/** The data an extension provides to inform Platform.Bible of the project state it provides */\nexport interface ProjectStateContribution {\n [k: ReferencedItem]: UserState;\n}\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\nconst settingsDefs = {\n projectSettingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n },\n projectSettingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the project settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description:\n 'localizeKey that displays in the project settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/projectSettingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n projectSettingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/projectSetting',\n },\n },\n additionalProperties: false,\n },\n projectSetting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledProjectSetting',\n },\n ],\n },\n extensionControlledProjectSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/projectSettingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n projectSettingBase: {\n description: 'Base information needed to describe a project setting entry',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierProject',\n },\n ],\n },\n modifierProject: {\n description: 'Modifies setting type to be project setting',\n type: 'object',\n properties: {\n includeProjectTypes: {\n description:\n '`RegExp` pattern(s) to match against `projectType` (using the [`test`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) function) to determine whether this project setting should be displayed in the Project Settings Dialog of that `projectType`. null means do not show on any Project Settings dialog',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n excludeProjectTypes: {\n description:\n '`RegExp` pattern to match against `projectType` to determine if this project setting should absolutely not be displayed in the Project Settings dialog of that `projectType` even if it matches with `includeProjectTypes`',\n anyOf: [\n {\n type: 'null',\n },\n {\n type: 'string',\n },\n {\n type: 'array',\n items: {\n type: 'string',\n },\n },\n ],\n },\n },\n },\n settingsContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n },\n settingsGroup: {\n description: 'Group of related settings definitions',\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the group name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the group',\n $ref: '#/$defs/localizeKey',\n },\n properties: {\n $ref: '#/$defs/settingProperties',\n },\n },\n required: ['label', 'properties'],\n },\n settingProperties: {\n description: 'Object whose keys are setting IDs and whose values are settings objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w-]+\\\\.[\\\\w-]+$': {\n $ref: '#/$defs/setting',\n },\n },\n additionalProperties: false,\n },\n setting: {\n description: \"A description of an extension's setting entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledSetting',\n },\n ],\n },\n extensionControlledSetting: {\n description: 'Setting definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/settingBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n settingBase: {\n description: 'Base information needed to describe a setting entry',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n type: 'object',\n properties: {\n label: {\n description: 'localizeKey that displays in the settings dialog as the setting name',\n $ref: '#/$defs/localizeKey',\n },\n description: {\n description: 'localizeKey that displays in the settings dialog to describe the setting',\n $ref: '#/$defs/localizeKey',\n },\n },\n required: ['label'],\n },\n ],\n },\n projectStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the project state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateContribution: {\n description:\n 'The data an extension provides to inform Platform.Bible of the user state it provides',\n $ref: '#/$defs/userStateProperties',\n },\n userStateProperties: {\n description: 'Object whose keys are state IDs and whose values are state objects',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/userState',\n },\n },\n additionalProperties: false,\n },\n userState: {\n description: \"A description of an extension's user state entry\",\n anyOf: [\n {\n $ref: '#/$defs/extensionControlledState',\n },\n ],\n },\n extensionControlledState: {\n description: 'State definition that is validated by the extension.',\n allOf: [\n {\n $ref: '#/$defs/stateBase',\n },\n {\n $ref: '#/$defs/modifierExtensionControlled',\n },\n ],\n },\n modifierExtensionControlled: {\n description:\n 'Modifies state/setting type to be extension-controlled. \"Extension-controlled\" means the extension provides the component and the validator for the state/setting, so the state/setting is controlled by the extension.',\n not: {\n anyOf: [\n {\n type: 'object',\n required: ['platformType'],\n },\n {\n type: 'object',\n required: ['type'],\n },\n ],\n },\n },\n stateBase: {\n description: 'Base information needed to describe a state entry',\n type: 'object',\n properties: {\n default: {\n description: 'default value for the state/setting',\n type: 'any',\n },\n derivesFrom: {\n description:\n \"a state/setting ID whose value to set to this state/setting's starting value the first time this state/setting is loaded\",\n $ref: '#/$defs/id',\n },\n },\n required: ['default'],\n },\n localizeKey: {\n description: \"Identifier for a string that will be localized based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n tsType: 'LocalizeKey',\n },\n id: {\n description: '',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n tsType: 'Id',\n },\n};\n\n/**\n * Json-schema-to-typescript has some added stuff that isn't actually compatible with JSON schema,\n * so we remove them here\n *\n * @param defs The `$defs` property of a JSON schema (will be modified in place)\n */\n// JSON schema types are weird, so we'll just be careful\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function removeJsonToTypeScriptTypesStuff(defs: any) {\n if (!defs) return;\n\n // JSON schema types are weird, so we'll just be careful\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.values(defs).forEach((def: any) => {\n if (!def.type) return;\n\n if ('tsType' in def) delete def.tsType;\n\n if (def.type === 'any') {\n delete def.type;\n return;\n }\n\n if (def.type === 'object') {\n removeJsonToTypeScriptTypesStuff(def.properties);\n }\n });\n}\n\nremoveJsonToTypeScriptTypesStuff(settingsDefs);\n\n/** JSON schema object that aligns with the ProjectSettingsContribution type */\nexport const projectSettingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Project Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the project settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/projectSettingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/projectSettingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(projectSettingsDocumentSchema);\n\n/** JSON schema object that aligns with the {@link SettingsContribution} type */\nexport const settingsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Settings Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the settings it provides',\n anyOf: [\n {\n $ref: '#/$defs/settingsGroup',\n },\n {\n type: 'array',\n items: {\n $ref: '#/$defs/settingsGroup',\n },\n },\n ],\n\n $defs: settingsDefs,\n};\n\nObject.freeze(settingsDocumentSchema);\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { LocalizeKey } from 'menus.model';\nimport { removeJsonToTypeScriptTypesStuff } from './settings.model';\n\n/** Localized string value associated with this key */\nexport type LocalizedStringValue = string;\n\n/** The data an extension provides to inform Platform.Bible of the localized strings it provides. */\nexport interface LocalizedStringDataContribution {\n [k: string]: unknown;\n metadata?: StringsMetadata;\n localizedStrings?: {\n [k: string]: LanguageStrings;\n };\n}\n/**\n * Map whose keys are localized string keys and whose values provide additional non-locale-specific\n * information about the localized string key\n */\nexport interface StringsMetadata {\n [k: LocalizeKey]: StringMetadata;\n}\n/** Additional non-locale-specific information about a localized string key */\nexport interface StringMetadata {\n [k: string]: unknown;\n /**\n * Localized string key from which to get this value if one does not exist in the specified\n * language. If a new key/value pair needs to be made to replace an existing one, this could help\n * smooth over the transition if the meanings are close enough\n */\n fallbackKey?: LocalizeKey;\n /**\n * Additional information provided by developers in English to help the translator to know how to\n * translate this localized string accurately\n */\n notes?: string;\n}\n/**\n * Map whose keys are localized string keys and whose values provide information about how to\n * localize strings for the localized string key\n */\nexport interface LanguageStrings {\n [k: LocalizeKey]: LocalizedStringValue;\n}\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n\nconst localizedStringsDefs = {\n languageStrings: {\n description:\n 'Map whose keys are localized string keys and whose values provide information about how to localize strings for the localized string key',\n type: 'object',\n patternProperties: {\n '^%[\\\\w\\\\-\\\\.]+%$': {\n $ref: '#/$defs/localizedStringValue',\n },\n },\n additionalProperties: false,\n },\n localizedStringValue: {\n description: 'Localized string value associated with this key',\n type: 'string',\n },\n stringsMetadata: {\n description:\n 'Map whose keys are localized string keys and whose values provide additional non-locale-specific information about the localized string key',\n type: 'object',\n patternProperties: {\n '^%[\\\\w\\\\-\\\\.]+%$': {\n $ref: '#/$defs/stringMetadata',\n },\n },\n additionalProperties: false,\n },\n stringMetadata: {\n description: 'Additional non-locale-specific information about a localized string key',\n type: 'object',\n properties: {\n fallbackKey: {\n description:\n 'Localized string key from which to get this value if one does not exist in the specified language. If a new key/value pair needs to be made to replace an existing one, this could help smooth over the transition if the meanings are close enough',\n $ref: '#/$defs/localizeKey',\n },\n notes: {\n description:\n 'Additional information provided by developers in English to help the translator to know how to translate this localized string accurately',\n type: 'string',\n },\n },\n },\n localizeKey: {\n description: \"Identifier for a string that will be localized based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n tsType: 'LocalizeKey',\n },\n};\n\nremoveJsonToTypeScriptTypesStuff(localizedStringsDefs);\n\n/** JSON schema object that aligns with the LocalizedStringDataContribution type */\nexport const localizedStringsDocumentSchema = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: 'Localized String Data Contribution',\n description:\n 'The data an extension provides to inform Platform.Bible of the localized strings it provides.',\n type: 'object',\n properties: {\n metadata: {\n $ref: '#/$defs/stringsMetadata',\n },\n localizedStrings: {\n type: 'object',\n additionalProperties: {\n $ref: '#/$defs/languageStrings',\n },\n },\n },\n $defs: localizedStringsDefs,\n};\n\nObject.freeze(localizedStringsDocumentSchema);\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\nimport { ReplaceType } from './util';\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single context menu/submenu.\n * Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInSingleColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: OrderedExtensibleContainer | MenuGroupDetailsInSubMenu;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu within a\n * multi-column menu. Groups are separated using a line within the menu/submenu.\n */\nexport type GroupsInMultiColumnMenu = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: GroupsInSingleColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n /** Groups that belong in this menu */\n groups: GroupsInMultiColumnMenu;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus before they are localized */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n/**\n * Type that converts any menu type before it is localized to what it is after it is localized. This\n * can be applied to any menu type as needed.\n */\nexport type Localized = ReplaceType, ReferencedItem, string>;\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","PlatformEventEmitter","event","callback","callbackIndex","_a","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombiner","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","contributions","contributionName","potentialOutput","outputIteration","contribution","mergeObjects","output","finalOutput","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","mergeObjectsInternal","startingPointObj","copyFromObj","NonValidatingDocumentCombiner","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","Mutex","AsyncMutex","MutexMap","mutexID","P","R","n","m","v","X","C","K","N","B","x","T","O","V","I","L","G","S","H","k","A","y","q","U","f","l","u","c","E","r","D","i","a","h","d","g","w","b","J","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","stringLength","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","getLocalizedIdFromBookNumber","bookNumber","localizationLanguage","getLocalizedString","id","Canon","bookName","parts","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","settingsDefs","removeJsonToTypeScriptTypesStuff","defs","def","projectSettingsDocumentSchema","settingsDocumentSchema","localizedStringsDefs","localizedStringsDocumentSchema","menuDocumentSchema"],"mappings":"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AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AACF,GAAGC,IAAI;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAGC,KAAI;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAA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","x_google_ignoreList":[8,9,10,14]} \ No newline at end of file diff --git a/lib/platform-bible-utils/package.json b/lib/platform-bible-utils/package.json index f4087df617..b666127b12 100644 --- a/lib/platform-bible-utils/package.json +++ b/lib/platform-bible-utils/package.json @@ -40,6 +40,7 @@ "lint-fix:scripts": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs}\" && npm run lint:scripts", "test": "jest --silent" }, + "peerDependencies": {}, "dependencies": { "async-mutex": "^0.4.1" }, diff --git a/lib/platform-bible-utils/src/index.ts b/lib/platform-bible-utils/src/index.ts index ccc3ddfe05..ff612b4948 100644 --- a/lib/platform-bible-utils/src/index.ts +++ b/lib/platform-bible-utils/src/index.ts @@ -67,6 +67,14 @@ export type { PlatformEventHandler, PlatformEvent, PlatformEventAsync } from './ export type { ScriptureReference, BookInfo } from './scripture.model'; export type { Unsubscriber, UnsubscriberAsync } from './unsubscriber'; export type { DocumentCombinerOptions, JsonDocumentLike } from './document-combiner'; +export type { + LanguageStrings, + LocalizedStringDataContribution, + LocalizedStringValue, + StringMetadata, + StringsMetadata, +} from './localized-strings.model'; +export { localizedStringsDocumentSchema } from './localized-strings.model'; export type { LocalizeKey, ReferencedItem, diff --git a/lib/platform-bible-utils/src/localized-strings.model.ts b/lib/platform-bible-utils/src/localized-strings.model.ts new file mode 100644 index 0000000000..f1a7cefc22 --- /dev/null +++ b/lib/platform-bible-utils/src/localized-strings.model.ts @@ -0,0 +1,128 @@ +//---------------------------------------------------------------------------------------------- +// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets +// changed so they align. +//---------------------------------------------------------------------------------------------- + +import { LocalizeKey } from 'menus.model'; +import { removeJsonToTypeScriptTypesStuff } from './settings.model'; + +/** Localized string value associated with this key */ +export type LocalizedStringValue = string; + +/** The data an extension provides to inform Platform.Bible of the localized strings it provides. */ +export interface LocalizedStringDataContribution { + [k: string]: unknown; + metadata?: StringsMetadata; + localizedStrings?: { + [k: string]: LanguageStrings; + }; +} +/** + * Map whose keys are localized string keys and whose values provide additional non-locale-specific + * information about the localized string key + */ +export interface StringsMetadata { + [k: LocalizeKey]: StringMetadata; +} +/** Additional non-locale-specific information about a localized string key */ +export interface StringMetadata { + [k: string]: unknown; + /** + * Localized string key from which to get this value if one does not exist in the specified + * language. If a new key/value pair needs to be made to replace an existing one, this could help + * smooth over the transition if the meanings are close enough + */ + fallbackKey?: LocalizeKey; + /** + * Additional information provided by developers in English to help the translator to know how to + * translate this localized string accurately + */ + notes?: string; +} +/** + * Map whose keys are localized string keys and whose values provide information about how to + * localize strings for the localized string key + */ +export interface LanguageStrings { + [k: LocalizeKey]: LocalizedStringValue; +} + +//---------------------------------------------------------------------------------------------- +// NOTE: If you change the schema below, make sure the TS types above get changed so they align. +//---------------------------------------------------------------------------------------------- + +const localizedStringsDefs = { + languageStrings: { + description: + 'Map whose keys are localized string keys and whose values provide information about how to localize strings for the localized string key', + type: 'object', + patternProperties: { + '^%[\\w\\-\\.]+%$': { + $ref: '#/$defs/localizedStringValue', + }, + }, + additionalProperties: false, + }, + localizedStringValue: { + description: 'Localized string value associated with this key', + type: 'string', + }, + stringsMetadata: { + description: + 'Map whose keys are localized string keys and whose values provide additional non-locale-specific information about the localized string key', + type: 'object', + patternProperties: { + '^%[\\w\\-\\.]+%$': { + $ref: '#/$defs/stringMetadata', + }, + }, + additionalProperties: false, + }, + stringMetadata: { + description: 'Additional non-locale-specific information about a localized string key', + type: 'object', + properties: { + fallbackKey: { + description: + 'Localized string key from which to get this value if one does not exist in the specified language. If a new key/value pair needs to be made to replace an existing one, this could help smooth over the transition if the meanings are close enough', + $ref: '#/$defs/localizeKey', + }, + notes: { + description: + 'Additional information provided by developers in English to help the translator to know how to translate this localized string accurately', + type: 'string', + }, + }, + }, + localizeKey: { + description: "Identifier for a string that will be localized based on the user's UI language", + type: 'string', + pattern: '^%[\\w\\-\\.]+%$', + tsType: 'LocalizeKey', + }, +}; + +removeJsonToTypeScriptTypesStuff(localizedStringsDefs); + +/** JSON schema object that aligns with the LocalizedStringDataContribution type */ +export const localizedStringsDocumentSchema = { + $schema: 'https://json-schema.org/draft/2020-12/schema', + title: 'Localized String Data Contribution', + description: + 'The data an extension provides to inform Platform.Bible of the localized strings it provides.', + type: 'object', + properties: { + metadata: { + $ref: '#/$defs/stringsMetadata', + }, + localizedStrings: { + type: 'object', + additionalProperties: { + $ref: '#/$defs/languageStrings', + }, + }, + }, + $defs: localizedStringsDefs, +}; + +Object.freeze(localizedStringsDocumentSchema); diff --git a/lib/platform-bible-utils/src/scripture-util.ts b/lib/platform-bible-utils/src/scripture-util.ts index 06f9957888..f4487d40ca 100644 --- a/lib/platform-bible-utils/src/scripture-util.ts +++ b/lib/platform-bible-utils/src/scripture-util.ts @@ -106,13 +106,13 @@ export const offsetVerse = (scrRef: ScriptureReference, offset: number): Scriptu * * Convert book number to a localized Id (a short description of the book). This should be used * whenever a book ID (short code) is shown to the user. It is primarily needed for people who do - * not read Roman script well and need to have books identified in a alternate script (e.g. - * Chinese or Russian) + * not read Roman script well and need to have books identified in a alternate script (e.g. Chinese + * or Russian) * * @param bookNumber - * @param localizationLanguage in BCP 47 format - * @param getLocalizedString function that provides the localized versions of the book ids and names - * asynchronously. + * @param localizationLanguage In BCP 47 format + * @param getLocalizedString Function that provides the localized versions of the book ids and names + * asynchronously. * @returns */ export async function getLocalizedIdFromBookNumber( @@ -138,7 +138,7 @@ export async function getLocalizedIdFromBookNumber( }); const parts = split(bookName, '-'); // some entries had a second name inside ideographic parenthesis - const parts2 = split(parts[0], '\xff08') + const parts2 = split(parts[0], '\xff08'); const retVal = parts2[0].trim(); return retVal; } diff --git a/lib/platform-bible-utils/src/settings.model.ts b/lib/platform-bible-utils/src/settings.model.ts index 5fe1fcfe2b..15ec7fd543 100644 --- a/lib/platform-bible-utils/src/settings.model.ts +++ b/lib/platform-bible-utils/src/settings.model.ts @@ -401,7 +401,7 @@ const settingsDefs = { */ // JSON schema types are weird, so we'll just be careful // eslint-disable-next-line @typescript-eslint/no-explicit-any -function removeJsonToTypeScriptTypesStuff(defs: any) { +export function removeJsonToTypeScriptTypesStuff(defs: any) { if (!defs) return; // JSON schema types are weird, so we'll just be careful diff --git a/src/extension-host/extension-host.ts b/src/extension-host/extension-host.ts index fddbe0b831..4f90688ed8 100644 --- a/src/extension-host/extension-host.ts +++ b/src/extension-host/extension-host.ts @@ -14,6 +14,7 @@ import { registerCommand } from '@shared/services/command.service'; import { initialize as initializeMenuData } from '@extension-host/services/menu-data.service-host'; import { initialize as initializeSettingsService } from '@extension-host/services/settings.service-host'; import { startProjectSettingsService } from '@extension-host/services/project-settings.service-host'; +import { initialize as initializeLocalizationService } from '@extension-host/services/localization.service-host'; // #region Test logs @@ -64,6 +65,7 @@ networkService await startProjectLookupService(); // Prepare for contributions to be contributed from extensions before the extensions come online + await initializeLocalizationService(); await initializeMenuData(); await initializeSettingsService(); await startProjectSettingsService(); diff --git a/src/extension-host/extension-types/extension-manifest.model.ts b/src/extension-host/extension-types/extension-manifest.model.ts index 3f0b4624d2..c09eaf8444 100644 --- a/src/extension-host/extension-types/extension-manifest.model.ts +++ b/src/extension-host/extension-types/extension-manifest.model.ts @@ -36,6 +36,8 @@ export type ExtensionManifest = { settings?: string; /** Path to the JSON file that defines the project settings this extension is adding. */ projectSettings?: string; + /** Path to the JSON file that defines the localized strings this extension is adding. */ + localizedStrings?: string; /** * List of events that occur that should cause this extension to be activated. Not yet * implemented. diff --git a/src/extension-host/services/extension.service.ts b/src/extension-host/services/extension.service.ts index c02adb6c3f..835affa4f3 100644 --- a/src/extension-host/services/extension.service.ts +++ b/src/extension-host/services/extension.service.ts @@ -32,6 +32,7 @@ import LogError from '@shared/log-error.model'; import { ExtensionManifest } from '@extension-host/extension-types/extension-manifest.model'; import { menuDocumentCombiner } from '@extension-host/services/menu-data.service-host'; import menuDataService from '@shared/services/menu-data.service'; +import { localizedStringsDocumentCombiner } from '@extension-host/services/localization.service-host'; import { settingsDocumentCombiner } from '@extension-host/services/settings.service-host'; import { PLATFORM_NAMESPACE } from '@shared/data/platform.data'; import { projectSettingsDocumentCombiner } from './project-settings.service-host'; @@ -762,9 +763,27 @@ async function resyncContributions( menuDocumentCombiner.deleteAllContributions(); settingsDocumentCombiner.deleteAllContributions(); projectSettingsDocumentCombiner.deleteAllContributions(); + localizedStringsDocumentCombiner.deleteAllContributions(); await Promise.all( extensionsToAdd.map(async (extension) => { + if (extension.localizedStrings) { + try { + // TODO: Provide a way to make sure extensions don't tell us to read files outside their dir + const localizedStringsJson = await nodeFS.readFileText( + joinUriPaths(extension.dirUri, extension.localizedStrings), + ); + const localizedStringsDocument = JSON.parse(localizedStringsJson); + localizedStringsDocumentCombiner.addOrUpdateContribution( + extension.name, + localizedStringsDocument, + ); + } catch (error) { + logger.warn( + `Could not add localized strings contribution for ${extension.name}: ${error}`, + ); + } + } if (extension.menus) { try { // TODO: Provide a way to make sure extensions don't tell us to read files outside their dir diff --git a/src/main/services/localization.service-host.test.ts b/src/extension-host/services/localization.service-host.test.ts similarity index 53% rename from src/main/services/localization.service-host.test.ts rename to src/extension-host/services/localization.service-host.test.ts index 41afadab04..7f1686d504 100644 --- a/src/main/services/localization.service-host.test.ts +++ b/src/extension-host/services/localization.service-host.test.ts @@ -1,14 +1,16 @@ -import { testingLocalizationService } from '@main/services/localization.service-host'; +import { testingLocalizationService } from '@extension-host/services/localization.service-host'; +import logger from '@shared/services/logger.service'; import { SettingNames } from 'papi-shared-types'; +import { LocalizeKey } from 'platform-bible-utils'; const MOCK_FILES: { [uri: string]: string } = { 'resources://assets/localization/en.json': `{ - "some_localization_key": "This is the English text for %some_localization_key%.", - "submitButton": "Submit" + "%some_localization_key%": "This is the English text for %some_localization_key%.", + "%submitButton%": "Submit" }`, 'resources://assets/localization/fr.json': `{ - "some_localization_key": "Ceci est le texte en français pour %some_localization_key%.", - "submitButton": "Soumettre" + "%some_localization_key%": "Ceci est le texte en français pour %some_localization_key%.", + "%submitButton%": "Soumettre" }`, 'resources://assets/localization/metadata.json': `{ "%yes%": { @@ -50,6 +52,13 @@ jest.mock('@node/services/node-file-system.service', () => ({ }, })); +jest.mock('@shared/services/logger.service', () => ({ + __esModule: true, + default: { + warn: jest.fn(() => {}), + }, +})); + let localizationDataProviderEngine: Awaited< ReturnType >; @@ -57,9 +66,12 @@ beforeAll(async () => { localizationDataProviderEngine = await testingLocalizationService.implementLocalizationDataProviderEngine(); }); +afterEach(() => { + jest.restoreAllMocks(); +}); test('Correct localized value returned to match single localizeKey', async () => { - const LOCALIZE_KEY: string = 'submitButton'; + const LOCALIZE_KEY = '%submitButton%'; const response = await localizationDataProviderEngine.getLocalizedString({ localizeKey: LOCALIZE_KEY, locales: ['fr'], @@ -68,79 +80,93 @@ test('Correct localized value returned to match single localizeKey', async () => }); test('Correct localized values returned to match array of localizeKeys', async () => { - const LOCALIZE_KEYS: string[] = ['submitButton', 'some_localization_key']; + const LOCALIZE_KEYS: LocalizeKey[] = ['%submitButton%', '%some_localization_key%']; const response = await localizationDataProviderEngine.getLocalizedStrings({ localizeKeys: LOCALIZE_KEYS, locales: ['fr'], }); expect(response).toEqual({ - submitButton: 'Soumettre', - some_localization_key: 'Ceci est le texte en français pour %some_localization_key%.', + '%submitButton%': 'Soumettre', + '%some_localization_key%': 'Ceci est le texte en français pour %some_localization_key%.', }); }); -test('Error returned with localizeKey that does not exist', async () => { - const LOCALIZE_KEY = 'the_wrong_key'; - await expect( - localizationDataProviderEngine.getLocalizedString({ +test('Key returned with localizeKey that does not exist', async () => { + const LOCALIZE_KEY = '%the_wrong_key%'; + expect( + await localizationDataProviderEngine.getLocalizedString({ localizeKey: LOCALIZE_KEY, locales: ['fr'], }), - ).rejects.toThrow( - 'No localizations found for key or fallback key in any of the given languages for localize key: the_wrong_key', + ).toEqual('%the_wrong_key%'); + expect(logger.warn).toHaveBeenCalledWith( + 'No localizations found for key or fallback key in any of the given languages for localize key: %the_wrong_key%', ); }); -test('Error returned with localizeKeys that do not exist', async () => { - const LOCALIZE_KEYS = ['the_wrong_key', 'the_other_wrong_key']; - await expect( - localizationDataProviderEngine.getLocalizedStrings({ +test('Keys returned with localizeKeys that do not exist', async () => { + const LOCALIZE_KEYS: LocalizeKey[] = ['%the_wrong_key%', '%the_other_wrong_key%']; + expect( + await localizationDataProviderEngine.getLocalizedStrings({ localizeKeys: LOCALIZE_KEYS, locales: ['fr'], }), - ).rejects.toThrow( - 'No localizations found for key or fallback key in any of the given languages for localize key: the_wrong_key', + ).toEqual({ + '%the_wrong_key%': '%the_wrong_key%', + '%the_other_wrong_key%': '%the_other_wrong_key%', + }); + expect(logger.warn).toHaveBeenCalledWith( + 'No localizations found for key or fallback key in any of the given languages for localize key: %the_wrong_key%', + ); + expect(logger.warn).toHaveBeenCalledWith( + 'No localizations found for key or fallback key in any of the given languages for localize key: %the_other_wrong_key%', ); }); -test('Error returned with localizeKeys where one exists but the other does not', async () => { - const LOCALIZE_KEYS = ['submitButton', 'the_wrong_key']; - await expect( - localizationDataProviderEngine.getLocalizedStrings({ +test('Strings and keys returned with localizeKeys where one exists but the other does not', async () => { + const LOCALIZE_KEYS: LocalizeKey[] = ['%submitButton%', '%the_wrong_key%']; + expect( + await localizationDataProviderEngine.getLocalizedStrings({ localizeKeys: LOCALIZE_KEYS, locales: ['fr'], }), - ).rejects.toThrow( - 'No localizations found for key or fallback key in any of the given languages for localize key: the_wrong_key', + ).toEqual({ + '%submitButton%': 'Soumettre', + '%the_wrong_key%': '%the_wrong_key%', + }); + expect(logger.warn).toHaveBeenCalledWith( + 'No localizations found for key or fallback key in any of the given languages for localize key: %the_wrong_key%', ); }); test('Error returned with localizeKey and incorrectly formatted language code', async () => { - const LOCALIZE_KEY = 'submitButton'; // irrelevant because it will throw for language code before it accesses key/value pairs + const LOCALIZE_KEY = '%submitButton%'; // irrelevant because it will throw for language code before it accesses key/value pairs await expect( localizationDataProviderEngine.getLocalizedString({ localizeKey: LOCALIZE_KEY, locales: ['IncorrectlyFormattedLang001'], }), - ).rejects.toThrow( - 'Localization service - No match for language code IncorrectlyFormattedLang001', + ).rejects.toThrow('Incorrect locale information provided'); + expect(logger.warn).toHaveBeenCalledWith( + 'getCanonicalLocales failed for IncorrectlyFormattedLang001 with error RangeError: Incorrect locale information provided', ); }); test('Error returned with localizeKeys and incorrect language code', async () => { - const LOCALIZE_KEYS = ['submitButton', 'some_localization_key']; // irrelevant because it will throw for language code before it accesses key/value pairs + const LOCALIZE_KEYS: LocalizeKey[] = ['%submitButton%', '%some_localization_key%']; // irrelevant because it will throw for language code before it accesses key/value pairs await expect( localizationDataProviderEngine.getLocalizedStrings({ localizeKeys: LOCALIZE_KEYS, locales: ['Incorrect locale information provided001'], }), - ).rejects.toThrow( - 'Localization service - No match for language code Incorrect locale information provided001', + ).rejects.toThrow('Incorrect locale information provided'); + expect(logger.warn).toHaveBeenCalledWith( + 'getCanonicalLocales failed for Incorrect locale information provided001 with error RangeError: Incorrect locale information provided', ); }); test('Default language is english when no language provided with localizeKey', async () => { - const LOCALIZE_KEY = 'submitButton'; + const LOCALIZE_KEY = '%submitButton%'; const response = await localizationDataProviderEngine.getLocalizedString({ localizeKey: LOCALIZE_KEY, }); @@ -148,18 +174,18 @@ test('Default language is english when no language provided with localizeKey', a }); test('Default language is english when no language provided with localizeKeys', async () => { - const LOCALIZE_KEYS = ['submitButton', 'some_localization_key']; + const LOCALIZE_KEYS: LocalizeKey[] = ['%submitButton%', '%some_localization_key%']; const response = await localizationDataProviderEngine.getLocalizedStrings({ localizeKeys: LOCALIZE_KEYS, }); expect(response).toEqual({ - some_localization_key: 'This is the English text for %some_localization_key%.', - submitButton: 'Submit', + '%some_localization_key%': 'This is the English text for %some_localization_key%.', + '%submitButton%': 'Submit', }); }); test('Good key and missing but valid language code return default English', async () => { - const LOCALIZE_KEY = 'submitButton'; + const LOCALIZE_KEY = '%submitButton%'; globalThis.isPackaged = true; const response = await localizationDataProviderEngine.getLocalizedString({ localizeKey: LOCALIZE_KEY, @@ -169,13 +195,13 @@ test('Good key and missing but valid language code return default English', asyn }); test('Good keys and missing but valid language code return default English', async () => { - const LOCALIZE_KEYS = ['submitButton', 'some_localization_key']; + const LOCALIZE_KEYS: LocalizeKey[] = ['%submitButton%', '%some_localization_key%']; const response = await localizationDataProviderEngine.getLocalizedStrings({ localizeKeys: LOCALIZE_KEYS, locales: ['qya-Latn'], }); expect(response).toEqual({ - some_localization_key: 'This is the English text for %some_localization_key%.', - submitButton: 'Submit', + '%some_localization_key%': 'This is the English text for %some_localization_key%.', + '%submitButton%': 'Submit', }); }); diff --git a/src/main/services/localization.service-host.ts b/src/extension-host/services/localization.service-host.ts similarity index 80% rename from src/main/services/localization.service-host.ts rename to src/extension-host/services/localization.service-host.ts index 129c4724bf..24aae10138 100644 --- a/src/main/services/localization.service-host.ts +++ b/src/extension-host/services/localization.service-host.ts @@ -5,33 +5,46 @@ LocalizationDataDataTypes, LocalizationSelector, LocalizationSelectors, - LocalizedStringMetadata, localizationServiceObjectToProxy, } from '@shared/services/localization.service-model'; import dataProviderService from '@shared/services/data-provider.service'; import IDataProviderEngine, { DataProviderEngine } from '@shared/models/data-provider-engine.model'; import { DataProviderUpdateInstructions } from '@shared/models/data-provider.model'; import * as nodeFS from '@node/services/node-file-system.service'; -import { deserialize, createSyncProxyForAsyncObject } from 'platform-bible-utils'; +import { + deserialize, + createSyncProxyForAsyncObject, + LocalizedStringDataContribution, + StringsMetadata, + LocalizeKey, +} from 'platform-bible-utils'; import logger from '@shared/services/logger.service'; import { joinUriPaths } from '@node/utils/util'; import path from 'path'; import settingsService from '@shared/services/settings.service'; +import LocalizedStringsDocumentCombiner from '@shared/utils/localized-strings-document-combiner'; const LOCALIZATION_ROOT_URI = joinUriPaths('resources://', 'assets', 'localization'); // BCP 47 validation regex from https://stackoverflow.com/questions/7035825/regular-expression-for-a-language-tag-as-defined-by-bcp47 const LANGUAGE_CODE_REGEX = /^(?(?:en-GB-oed|i-(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|t(?:a[oy]|su))|sgn-(?:BE-(?:FR|NL)|CH-DE))|(?:art-lojban|cel-gaulish|no-(?:bok|nyn)|zh-(?:guoyu|hakka|min(?:-nan)?|xiang)))|(?:(?(?:[A-Za-z]{2,3}(?:-(?[A-Za-z]{3}(?:-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(?:-(?