From 2329d3161669098e8646f084c052cf17c19fdb92 Mon Sep 17 00:00:00 2001 From: yemen Date: Tue, 21 Jul 2026 19:03:58 +0300 Subject: [PATCH 1/4] fix(rewayatfans): improve novel listing and chapter extraction - Fetch novels from listing page with pagination support - Add cover images via _embed parameter - Fix chapter number extraction from title instead of slug - Add normalized title matching for better search - Support Arabic novel pages with HTML chapter extraction - Version bump to 4.0.0 --- plugins/arabic/rewayatfans.ts | 191 +++++++++++++++++++++++----------- 1 file changed, 128 insertions(+), 63 deletions(-) diff --git a/plugins/arabic/rewayatfans.ts b/plugins/arabic/rewayatfans.ts index a5ee909d9..d9ed578a7 100644 --- a/plugins/arabic/rewayatfans.ts +++ b/plugins/arabic/rewayatfans.ts @@ -3,18 +3,19 @@ import { fetchApi } from '@libs/fetch'; import { Plugin } from '@/types/plugin'; type WPPage = { - id: number; title: { rendered: string }; slug: string; - link: string; - content: { rendered: string }; date: string; + featured_media: number; + _embedded?: { + 'wp:featuredmedia'?: Array<{ source_url: string }>; + }; }; class RewayatFans implements Plugin.PluginBase { id = 'rewayatfans'; name = 'روايات فانز'; - version = '3.0.0'; + version = '4.0.0'; icon = 'src/ar/rewayatfans/icon.png'; site = 'https://rewayatfans.com/'; @@ -30,60 +31,66 @@ class RewayatFans implements Plugin.PluginBase { return res.text(); } + private getCover(page: WPPage): string { + return page._embedded?.['wp:featuredmedia']?.[0]?.source_url || ''; + } + async popularNovels( page: number, { showLatestNovels }: Plugin.PopularNovelsOptions, ): Promise { if (showLatestNovels) { const pages = await this.fetchJson( - `${this.site}wp-json/wp/v2/pages?per_page=20&page=${page}&orderby=date&order=desc&_fields=slug,title`, + `${this.site}wp-json/wp/v2/pages?per_page=20&page=${page}&orderby=date&order=desc&_embed`, ); - return pages.map(p => ({ - name: this.extractNovelName(p.title.rendered), - path: p.slug, - cover: '', - })); - } - const allNovels = await this.getAllNovels(); - const pageSize = 20; - const start = (page - 1) * pageSize; - return allNovels.slice(start, start + pageSize); - } - - private async getAllNovels(): Promise { - const seen = new Set(); - const novels: Plugin.NovelItem[] = []; + const seen = new Set(); + const novels: Plugin.NovelItem[] = []; - let pg = 1; - let hasMore = true; - - while (hasMore) { - const pages = await this.fetchJson( - `${this.site}wp-json/wp/v2/pages?per_page=100&page=${pg}&_fields=slug,title`, - ); - - if (pages.length === 0) { - hasMore = false; - break; - } - - for (const page of pages) { - const novelName = this.extractNovelName(page.title.rendered); + for (const p of pages) { + const novelName = this.extractNovelName(p.title.rendered); if (novelName && !seen.has(novelName)) { seen.add(novelName); novels.push({ name: novelName, - path: page.slug, - cover: '', + path: p.slug, + cover: this.getCover(p), }); } } - if (pages.length < 100) hasMore = false; - pg++; + return novels; } + const listingPath = + page === 1 + ? `${this.site}%D9%82%D8%A7%D8%A6%D9%85%D8%A9-%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D9%8A%D8%A7%D8%AA/` + : `${this.site}%D9%82%D8%A7%D8%A6%D9%85%D8%A9-%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D9%8A%D8%A7%D8%AT/page/${page}/`; + + const html = await this.fetchHtml(listingPath); + const $ = parseHTML(html); + const novels: Plugin.NovelItem[] = []; + const seen = new Set(); + + $('div.entry-content a').each((_, el) => { + const href = $(el).attr('href') || ''; + const name = $(el).text().trim(); + + if ( + name.length > 3 && + href.includes('rewayatfans.com/') && + !name.includes('الرئيسية') && + !name.includes('روايات فانز') && + !name.includes('قائمة الروايات') && + !name.includes('قائمة المكتملة') && + !seen.has(name) + ) { + seen.add(name); + const slug = href.replace(/\/$/, '').split('/').pop() || ''; + novels.push({ name, path: slug, cover: '' }); + } + }); + return novels; } @@ -95,16 +102,70 @@ class RewayatFans implements Plugin.PluginBase { }; const slugBase = novelPath.replace(/\/$/, '').split('/').pop() || novelPath; - const searchTerm = slugBase - .replace(/-\d+$/, '') - .replace(/-/g, ' '); + const isArabic = !/[a-zA-Z]/.test(slugBase); + + if (isArabic) { + const html = await this.fetchHtml(`${this.site}${novelPath}/`); + const $ = parseHTML(html); + novel.name = $('title').text().replace(/\s*[–|].*$/, '').trim(); + + const allSlugs = new Set(); + $('a[href]').each((_, el) => { + const href = $(el).attr('href') || ''; + const match = href.match( + /rewayatfans\.com\/([a-z][a-z0-9-]+-\d+)\/?$/, + ); + if (match) { + allSlugs.add(match[1]); + } + }); + + const prefixCounts = new Map(); + for (const slug of allSlugs) { + const prefix = slug.replace(/-\d+$/, ''); + prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1); + } + + let bestPrefix = ''; + let bestCount = 0; + for (const [prefix, count] of prefixCounts) { + if (count > bestCount) { + bestPrefix = prefix; + bestCount = count; + } + } + + for (const slug of allSlugs) { + if (slug.startsWith(bestPrefix)) { + const numMatch = slug.match(/(\d+)$/); + const chapterNum = numMatch ? parseInt(numMatch[1], 10) : 0; + novel.chapters!.push({ + name: `${novel.name} ${chapterNum}`, + path: slug, + chapterNumber: chapterNum, + }); + } + } + + novel.chapters!.sort( + (a, b) => (a.chapterNumber || 0) - (b.chapterNumber || 0), + ); + return novel; + } + + const novelPrefix = slugBase.replace(/-\d+$/, ''); + const searchName = novelPrefix.replace(/-/g, ' '); + + const normalize = (s: string) => + s.toLowerCase().replace(/[^a-z0-9\s]/g, '').replace(/\s+/g, ' ').trim(); + const normalizedSearch = normalize(searchName); let pg = 1; let hasMore = true; while (hasMore) { const pages = await this.fetchJson( - `${this.site}wp-json/wp/v2/pages?search=${encodeURIComponent(searchTerm)}&per_page=100&page=${pg}&_fields=slug,title,date`, + `${this.site}wp-json/wp/v2/pages?search=${encodeURIComponent(searchName)}&per_page=100&page=${pg}&_fields=slug,title,date`, ); if (pages.length === 0) { @@ -112,20 +173,23 @@ class RewayatFans implements Plugin.PluginBase { break; } - for (const page of pages) { - const postSlug = page.slug; - if (postSlug.startsWith(slugBase.replace(/-\d+$/, ''))) { + for (const p of pages) { + const normalizedTitle = normalize(p.title.rendered); + if ( + p.slug.startsWith(novelPrefix) || + normalizedTitle.startsWith(normalizedSearch) + ) { if (!novel.name) { - novel.name = this.extractNovelName(page.title.rendered); + novel.name = this.extractNovelName(p.title.rendered); } - const numMatch = postSlug.match(/(\d+)$/); + const numMatch = p.title.rendered.match(/(\d+)\s*$/); const chapterNum = numMatch ? parseInt(numMatch[1], 10) : 0; novel.chapters!.push({ - name: page.title.rendered, - path: postSlug, + name: p.title.rendered, + path: p.slug, chapterNumber: chapterNum, - releaseTime: page.date, + releaseTime: p.date, }); } } @@ -134,11 +198,12 @@ class RewayatFans implements Plugin.PluginBase { pg++; } - if (novel.chapters!.length > 0) { - novel.chapters!.sort((a, b) => (a.chapterNumber || 0) - (b.chapterNumber || 0)); - if (!novel.name && novel.chapters!.length > 0) { - novel.name = this.extractNovelName(novel.chapters![0].name); - } + novel.chapters!.sort( + (a, b) => (a.chapterNumber || 0) - (b.chapterNumber || 0), + ); + + if (!novel.name && novel.chapters!.length > 0) { + novel.name = this.extractNovelName(novel.chapters![0].name); } return novel; @@ -150,8 +215,8 @@ class RewayatFans implements Plugin.PluginBase { ); const arr = Array.isArray(pages) ? pages : [pages]; - if (arr.length > 0 && arr[0].content?.rendered) { - const $ = parseHTML(arr[0].content.rendered); + if (arr.length > 0 && (arr[0] as any).content?.rendered) { + const $ = parseHTML((arr[0] as any).content.rendered); $('script, style, .sharedaddy, .jp-relatedposts, .wp-block-spacer').remove(); return $.html(); } @@ -168,20 +233,20 @@ class RewayatFans implements Plugin.PluginBase { page: number, ): Promise { const pages = await this.fetchJson( - `${this.site}wp-json/wp/v2/pages?search=${encodeURIComponent(searchTerm)}&per_page=20&page=${page}&_fields=slug,title`, + `${this.site}wp-json/wp/v2/pages?search=${encodeURIComponent(searchTerm)}&per_page=20&page=${page}&_embed`, ); const seen = new Set(); const novels: Plugin.NovelItem[] = []; - for (const page of pages) { - const novelName = this.extractNovelName(page.title.rendered); + for (const p of pages) { + const novelName = this.extractNovelName(p.title.rendered); if (novelName && !seen.has(novelName)) { seen.add(novelName); novels.push({ name: novelName, - path: page.slug, - cover: '', + path: p.slug, + cover: this.getCover(p), }); } } From 2f44a8fc7fa33519f3588b8d39b8d9a8aa27866d Mon Sep 17 00:00:00 2001 From: yemen Date: Tue, 21 Jul 2026 19:34:02 +0300 Subject: [PATCH 2/4] fix(rewayatfans): make listing page the default main page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Always fetch from listing page (قائمة-الروايات) regardless of showLatestNovels flag - Version bump to 4.1.0 --- plugins/arabic/rewayatfans.ts | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/plugins/arabic/rewayatfans.ts b/plugins/arabic/rewayatfans.ts index d9ed578a7..97600526b 100644 --- a/plugins/arabic/rewayatfans.ts +++ b/plugins/arabic/rewayatfans.ts @@ -15,7 +15,7 @@ type WPPage = { class RewayatFans implements Plugin.PluginBase { id = 'rewayatfans'; name = 'روايات فانز'; - version = '4.0.0'; + version = '4.1.0'; icon = 'src/ar/rewayatfans/icon.png'; site = 'https://rewayatfans.com/'; @@ -39,29 +39,6 @@ class RewayatFans implements Plugin.PluginBase { page: number, { showLatestNovels }: Plugin.PopularNovelsOptions, ): Promise { - if (showLatestNovels) { - const pages = await this.fetchJson( - `${this.site}wp-json/wp/v2/pages?per_page=20&page=${page}&orderby=date&order=desc&_embed`, - ); - - const seen = new Set(); - const novels: Plugin.NovelItem[] = []; - - for (const p of pages) { - const novelName = this.extractNovelName(p.title.rendered); - if (novelName && !seen.has(novelName)) { - seen.add(novelName); - novels.push({ - name: novelName, - path: p.slug, - cover: this.getCover(p), - }); - } - } - - return novels; - } - const listingPath = page === 1 ? `${this.site}%D9%82%D8%A7%D8%A6%D9%85%D8%A9-%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D9%8A%D8%A7%D8%AA/` From ce5d1954775058a96782bac372ddd2494a4b8043 Mon Sep 17 00:00:00 2001 From: yemen Date: Tue, 21 Jul 2026 19:58:55 +0300 Subject: [PATCH 3/4] fix(rewayatfans): revert to API-based approach for reliability - Use WordPress API for popularNovels with _embed for cover images - Use API-based chapter search with title number extraction - Remove problematic listing page HTML parsing - Cover images and chapter lists now work correctly - Version bump to 4.2.0 --- plugins/arabic/rewayatfans.ts | 91 ++++++----------------------------- 1 file changed, 15 insertions(+), 76 deletions(-) diff --git a/plugins/arabic/rewayatfans.ts b/plugins/arabic/rewayatfans.ts index 97600526b..ea3b72db7 100644 --- a/plugins/arabic/rewayatfans.ts +++ b/plugins/arabic/rewayatfans.ts @@ -15,7 +15,7 @@ type WPPage = { class RewayatFans implements Plugin.PluginBase { id = 'rewayatfans'; name = 'روايات فانز'; - version = '4.1.0'; + version = '4.2.0'; icon = 'src/ar/rewayatfans/icon.png'; site = 'https://rewayatfans.com/'; @@ -39,34 +39,24 @@ class RewayatFans implements Plugin.PluginBase { page: number, { showLatestNovels }: Plugin.PopularNovelsOptions, ): Promise { - const listingPath = - page === 1 - ? `${this.site}%D9%82%D8%A7%D8%A6%D9%85%D8%A9-%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D9%8A%D8%A7%D8%AA/` - : `${this.site}%D9%82%D8%A7%D8%A6%D9%85%D8%A9-%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D9%8A%D8%A7%D8%AT/page/${page}/`; + const pages = await this.fetchJson( + `${this.site}wp-json/wp/v2/pages?per_page=20&page=${page}&orderby=date&order=desc&_embed`, + ); - const html = await this.fetchHtml(listingPath); - const $ = parseHTML(html); - const novels: Plugin.NovelItem[] = []; const seen = new Set(); + const novels: Plugin.NovelItem[] = []; - $('div.entry-content a').each((_, el) => { - const href = $(el).attr('href') || ''; - const name = $(el).text().trim(); - - if ( - name.length > 3 && - href.includes('rewayatfans.com/') && - !name.includes('الرئيسية') && - !name.includes('روايات فانز') && - !name.includes('قائمة الروايات') && - !name.includes('قائمة المكتملة') && - !seen.has(name) - ) { - seen.add(name); - const slug = href.replace(/\/$/, '').split('/').pop() || ''; - novels.push({ name, path: slug, cover: '' }); + for (const p of pages) { + const novelName = this.extractNovelName(p.title.rendered); + if (novelName && !seen.has(novelName)) { + seen.add(novelName); + novels.push({ + name: novelName, + path: p.slug, + cover: this.getCover(p), + }); } - }); + } return novels; } @@ -79,57 +69,6 @@ class RewayatFans implements Plugin.PluginBase { }; const slugBase = novelPath.replace(/\/$/, '').split('/').pop() || novelPath; - const isArabic = !/[a-zA-Z]/.test(slugBase); - - if (isArabic) { - const html = await this.fetchHtml(`${this.site}${novelPath}/`); - const $ = parseHTML(html); - novel.name = $('title').text().replace(/\s*[–|].*$/, '').trim(); - - const allSlugs = new Set(); - $('a[href]').each((_, el) => { - const href = $(el).attr('href') || ''; - const match = href.match( - /rewayatfans\.com\/([a-z][a-z0-9-]+-\d+)\/?$/, - ); - if (match) { - allSlugs.add(match[1]); - } - }); - - const prefixCounts = new Map(); - for (const slug of allSlugs) { - const prefix = slug.replace(/-\d+$/, ''); - prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1); - } - - let bestPrefix = ''; - let bestCount = 0; - for (const [prefix, count] of prefixCounts) { - if (count > bestCount) { - bestPrefix = prefix; - bestCount = count; - } - } - - for (const slug of allSlugs) { - if (slug.startsWith(bestPrefix)) { - const numMatch = slug.match(/(\d+)$/); - const chapterNum = numMatch ? parseInt(numMatch[1], 10) : 0; - novel.chapters!.push({ - name: `${novel.name} ${chapterNum}`, - path: slug, - chapterNumber: chapterNum, - }); - } - } - - novel.chapters!.sort( - (a, b) => (a.chapterNumber || 0) - (b.chapterNumber || 0), - ); - return novel; - } - const novelPrefix = slugBase.replace(/-\d+$/, ''); const searchName = novelPrefix.replace(/-/g, ' '); From cf26ea7c2546a9bac337961290e603f754d33196 Mon Sep 17 00:00:00 2001 From: yemen Date: Wed, 22 Jul 2026 08:57:18 +0300 Subject: [PATCH 4/4] fix(markazriwayat): version 1.0.0 and clean hidden HTML - Set version to 1.0.0 as requested by maintainer - Add removal of hidden HTML elements in parseChapter - Clean display:none, hidden, and .hidden elements --- plugins/arabic/Markazriwayat.ts | 230 ++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 plugins/arabic/Markazriwayat.ts diff --git a/plugins/arabic/Markazriwayat.ts b/plugins/arabic/Markazriwayat.ts new file mode 100644 index 000000000..3e1dbfa88 --- /dev/null +++ b/plugins/arabic/Markazriwayat.ts @@ -0,0 +1,230 @@ +import { load as parseHTML } from 'cheerio'; +import { fetchApi } from '@libs/fetch'; +import { Plugin } from '@libs/types'; +import { defaultCover } from '@libs/defaultCover'; +import { NovelStatus } from '@libs/novelStatus'; +import { FilterTypes, Filters } from '@libs/filterInputs'; + +class Markazriwayat implements Plugin.PluginBase { + id = 'markazriwayat'; + name = 'ظ…ط±ظƒط² ط§ظ„ط±ظˆط§ظٹط§طھ'; + version = '1.0.0'; + icon = 'src/ar/markazriwayat/icon.png'; + site = 'https://markazriwayat.com/'; + + private UA = + 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36'; + + filters: Filters = { + order: { + type: FilterTypes.Picker, + label: 'ط§ظ„طھط±طھظٹط¨', + value: '', + options: [ + { label: 'ط§ظ„ط£ظƒط«ط± ط´ط¹ط¨ظٹط©', value: 'popular' }, + { label: 'ط§ظ„ط£ط­ط¯ط«', value: 'new' }, + { label: 'ط§ظ„ط£ط¹ظ„ظ‰ طھظ‚ظٹظٹظ…ط§ظ‹', value: 'rating' }, + ], + }, + }; + + private async fetchHtml(url: string): Promise { + const res = await fetchApi(url, { + headers: { 'User-Agent': this.UA }, + }); + if (!res.ok) throw new Error(`Request failed: ${res.status}`); + return res.text(); + } + + private parseNovelCards(html: string): Plugin.NovelItem[] { + const $ = parseHTML(html); + const novels: Plugin.NovelItem[] = []; + const seen = new Set(); + + $('a.lib-card').each((_, el) => { + const $el = $(el); + const href = $el.attr('href') || ''; + const path = href.replace(this.site, '').replace(/\/$/, ''); + const name = $el.find('.lib-card__title').text().trim(); + const cover = + $el.find('img').attr('data-src') || + $el.find('img').attr('data-defer-src') || + defaultCover; + + if (name && path && !seen.has(path)) { + seen.add(path); + novels.push({ name, path, cover }); + } + }); + + return novels; + } + + async popularNovels( + page: number, + { filters, showLatestNovels }: Plugin.PopularNovelsOptions, + ): Promise { + let url = `${this.site}`; + if (showLatestNovels) { + url += 'new/'; + } else { + const order = filters?.order?.value || 'popular'; + if (order === 'new') url += 'new/'; + else if (order === 'rating') url += 'ranking/'; + else url += 'popular/'; + } + if (page > 1) url += `page/${page}/`; + + const html = await this.fetchHtml(url); + return this.parseNovelCards(html); + } + + async searchNovels( + searchTerm: string, + page: number, + ): Promise { + try { + const apiUrl = `${this.site}wp-json/theam/v1/novel-search?term=${encodeURIComponent(searchTerm)}&per_page=20`; + const res = await fetchApi(apiUrl, { + headers: { 'User-Agent': this.UA }, + }); + if (!res.ok) return []; + const data = await res.json(); + return (data.items || []).map((item: any) => ({ + name: item.title, + path: item.link.replace(this.site, ''), + cover: item.cover || defaultCover, + })); + } catch { + // Fallback: use library search HTML + try { + const url = `${this.site}library/?search=${encodeURIComponent(searchTerm)}`; + const html = await this.fetchHtml(url); + return this.parseNovelCards(html); + } catch { + return []; + } + } + } + + async parseNovel(novelPath: string): Promise { + const html = await this.fetchHtml(`${this.site}${novelPath}`); + const $ = parseHTML(html); + + const novel: Plugin.SourceNovel = { + path: novelPath, + name: $('h1').first().text().trim() || 'Untitled', + cover: defaultCover, + summary: '', + author: '', + status: NovelStatus.Unknown, + genres: '', + chapters: [], + }; + + // Cover + const coverImg = $('img').filter(function () { + const src = $(this).attr('data-src') || $(this).attr('src') || ''; + return src.includes('wp-content/uploads') && !src.includes('cropped-'); + }).first(); + novel.cover = + coverImg.attr('data-src') || + coverImg.attr('data-defer-src') || + defaultCover; + + // Status + const statusEl = $('.status-pill').first(); + const statusClass = statusEl.attr('class') || ''; + if (statusClass.includes('is-ongoing')) novel.status = NovelStatus.Ongoing; + else if (statusClass.includes('is-complete')) + novel.status = NovelStatus.Completed; + else if (statusClass.includes('is-stopped')) + novel.status = NovelStatus.OnHiatus; + + // Author + const authorLink = $('a[href*="/author/"]').first(); + if (authorLink.length) novel.author = authorLink.text().trim(); + + // Summary + novel.summary = $('#manga-summary').text().trim(); + + // Genres + const genreParts: string[] = []; + $('a.pill, a[href*="/genre/"], a[href*="/tasnif/"]').each((_, el) => { + const t = $(el).text().trim(); + if (t) genreParts.push(t); + }); + novel.genres = genreParts.join(', '); + + // Chapters: read total from HTML, generate paths directly (fast, no API) + const chapters: Plugin.ChapterItem[] = []; + + const totalText = $('.manga-stat__value').last().text().trim(); + const totalMatch = totalText.match(/(\d+)/); + const totalChapters = totalMatch ? parseInt(totalMatch[1], 10) : 0; + + const firstRow = $('div.ch-row').first(); + const firstLink = firstRow.find('a').first().attr('href') || ''; + const firstNum = firstRow.attr('data-ch-num') || ''; + + if (totalChapters > 0 && firstLink && firstNum) { + const escapedNum = firstNum.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const basePath = firstLink.replace(new RegExp(`${escapedNum}/?$`), ''); + const basePathRelative = basePath.replace(this.site, ''); + + for (let i = 1; i <= totalChapters; i++) { + chapters.push({ + name: `ط§ظ„ظپطµظ„ ${i}`, + path: basePathRelative + i + '/', + chapterNumber: i, + }); + } + } else { + $('div.ch-row').each((_, el) => { + const a = $(el).find('a').first(); + const name = + $(el).find('.ch-title').text().trim() || + a.attr('aria-label') || + ''; + const href = a.attr('href') || ''; + const date = $(el).find('.ch-date').text().trim(); + const chNum = $(el).attr('data-ch-num') || ''; + if (name && href) { + chapters.push({ + name, + path: href.replace(this.site, ''), + releaseTime: date || null, + chapterNumber: chNum ? parseInt(chNum, 10) : chapters.length + 1, + }); + } + }); + } + + novel.chapters = chapters; + + return novel; + } + + async parseChapter(chapterPath: string): Promise { + const html = await this.fetchHtml(`${this.site}${chapterPath}`); + const $ = parseHTML(html); + + $( + 'script, style, .sharedaddy, .jp-relatedposts, .wp-block-spacer, .reading-nav, .ads, .advertisement, .nav-links, .comments-area', + ).remove(); + + $('[style*="display:none"], [style*="display: none"], [hidden], .hidden').remove(); + + const content = + $( + '.reading-content, .entry-content, .chapter-content, .text-left', + ) + .first() + .html() || ''; + + return content || '

المحتوى غير متاح.

'; + } +} + +export default new Markazriwayat(); +