{"id":41859698,"url":"https://github.com/adelpro/quran-search-engine","last_synced_at":"2026-01-25T11:13:41.933Z","repository":{"id":332940310,"uuid":"1135541349","full_name":"adelpro/quran-search-engine","owner":"adelpro","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-16T20:21:07.000Z","size":1796,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-17T01:13:11.727Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adelpro.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-16T08:42:44.000Z","updated_at":"2026-01-16T19:43:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adelpro/quran-search-engine","commit_stats":null,"previous_names":["adelpro/quran-search-engine"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/adelpro/quran-search-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adelpro%2Fquran-search-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adelpro%2Fquran-search-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adelpro%2Fquran-search-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adelpro%2Fquran-search-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adelpro","download_url":"https://codeload.github.com/adelpro/quran-search-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adelpro%2Fquran-search-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28752666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T10:25:12.305Z","status":"ssl_error","status_checked_at":"2026-01-25T10:25:11.933Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-25T11:13:41.779Z","updated_at":"2026-01-25T11:13:41.905Z","avatar_url":"https://github.com/adelpro.png","language":"TypeScript","funding_links":[],"categories":["Quranic Text and Reading (170 projects)"],"sub_categories":["Python"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/800x450.png\" width=\"850\" height=\"400\" alt=\"quran-search-engine logo\" /\u003e\n\u003c/p\u003e\n\n# quran-search-engine\n\n[![npm](https://img.shields.io/npm/v/quran-search-engine)](https://www.npmjs.com/package/quran-search-engine)\n[![downloads](https://img.shields.io/npm/dm/quran-search-engine)](https://www.npmjs.com/package/quran-search-engine)\n![TypeScript](https://img.shields.io/badge/ts-yes-blue)\n[![Changelog](https://img.shields.io/badge/changelog-view-brightgreen)](https://github.com/adelpro/quran-search-engine/releases)\n![license](https://img.shields.io/npm/l/quran-search-engine)\n\nStateless, UI-agnostic Quran (Qur'an) search engine for Arabic text in pure TypeScript:\n\n- Arabic normalization\n- Exact text search\n- Lemma + root matching (via morphology + word map)\n- Highlight ranges (UI-agnostic)\n\n## Table of contents\n\n- [Why this library](#why-this-library)\n- [Installation](#installation)\n- [Development Setup](#development-setup)\n- [Quickstart](#quickstart)\n- [Public API](#public-api)\n- [How scoring works](#how-scoring-works)\n- [Multi-word search](#multi-word-search)\n- [Core types](#core-types)\n- [Non-goals](#non-goals)\n- [Example apps](#example-apps)\n- [Testing](#testing)\n- [Development](#development)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Why this library\n\nMost Quran search solutions are:\n\n- tightly coupled to a UI\n- server-bound or stateful\n- hard to customize or extend\n- weakly typed\n\n**quran-search-engine** is designed to be:\n\n- UI-agnostic (React, Vue, React Native, Node)\n- fully client-side or server-side\n- stateless and deterministic\n- TypeScript-first and strongly typed\n\nYou control the data, rendering, and persistence.\n\n## Installation\n\nThis project uses **pnpm** as the default package manager for optimal performance, caching, and workspace management. pnpm provides:\n\n- **Faster installs** through global content-addressable storage\n- **Efficient disk usage** by hard-linking packages from a global store\n- **Better workspace support** for monorepo management\n- **Strict dependency resolution** preventing phantom dependencies\n\n```bash\npnpm install quran-search-engine\n```\n\n\u003cdetails\u003e \u003csummary\u003eOther package managers\u003c/summary\u003e\n\u003cbr\u003e\nnpm install quran-search-engine \u003cbr\u003e\nyarn add quran-search-engine \u003cbr\u003e\n\n\u003c/details\u003e\n\n## Development Setup\n\nThis is a **pnpm workspace** monorepo containing the main library and example applications. The workspace is configured in `pnpm-workspace.yaml` to include:\n\n- The main library (root package)\n- All examples in the `examples/` directory\n\n### Prerequisites\n\nInstall pnpm if you haven't already:\n\n```bash\nnpm install -g pnpm\n# or\ncorepack enable pnpm\n```\n\n### Setup Commands\n\n```bash\n# Install all dependencies for the workspace and examples\npnpm install\n\n# Build the main library\npnpm build\n\n# Run tests across the workspace\npnpm test\n```\n\n## Quickstart\n\n\u003e Note: examples assume an async context (Node 18+, ESM, or browser).\n\n```ts\nimport {\n  search,\n  loadMorphology,\n  loadQuranData,\n  loadWordMap,\n  type SearchResponse,\n} from 'quran-search-engine';\n\nconst [quranData, morphologyMap, wordMap] = await Promise.all([\n  loadQuranData(),\n  loadMorphology(),\n  loadWordMap(),\n]);\n// Example output:\n// quranData.length =\u003e 6236\n// morphologyMap.size =\u003e 6236\n// Object.keys(wordMap).length =\u003e (depends on dataset)\n\nconst response: SearchResponse = search('الله الرحمن', quranData, morphologyMap, wordMap, {\n  lemma: true,\n  root: true,\n});\n\nresponse.results.forEach((v) =\u003e {\n  console.log(v.sura_id, v.aya_id, v.matchType, v.matchScore);\n});\n// Example output:\n// 1 1 exact 6\n// 1 3 lemma 4\n```\n\nJavaScript (Node / ESM):\n\n```js\nimport { search, loadMorphology, loadQuranData, loadWordMap } from 'quran-search-engine';\n\nconst [quranData, morphologyMap, wordMap] = await Promise.all([\n  loadQuranData(),\n  loadMorphology(),\n  loadWordMap(),\n]);\n\nconst response = search('الله الرحمن', quranData, morphologyMap, wordMap, {\n  lemma: true,\n  root: true,\n});\n\nconsole.log(response.results[0]);\n// Example output (shape):\n// { gid: 1, matchType: 'exact', matchScore: 6, matchedTokens: ['...'], ... }\n```\n\n## Public API\n\nEverything documented below is exported from `quran-search-engine` (aligned with `src/index.ts`).\n\n### Data loading\n\n\u003e Note: The bundled lemma (morphology) data and word map were downloaded from Quranic Arabic Corpus v4.0: \u003chttps://corpus.quran.com\u003e\n\n#### `loadQuranData()`\n\nUse case: load the Quran dataset once at app startup (browser or Node), then reuse in searches.\n\n```ts\nimport { loadQuranData, type QuranText } from 'quran-search-engine';\n\nconst quranData: QuranText[] = await loadQuranData();\n// Example output:\n// quranData[0] =\u003e { gid: 1, uthmani: '...', standard: '...', sura_id: 1, aya_id: 1, ... }\n```\n\n#### `loadMorphology()`\n\nUse case: enable lemma/root search and scoring.\n\n```ts\nimport { loadMorphology, type MorphologyAya } from 'quran-search-engine';\n\nconst morphologyMap: Map\u003cnumber, MorphologyAya\u003e = await loadMorphology();\n// Example output:\n// morphologyMap.get(1) =\u003e { gid: 1, lemmas: ['...'], roots: ['...'] }\n```\n\n#### `loadWordMap()`\n\nUse case: map normalized query tokens to their canonical lemma/root.\n\n```ts\nimport { loadWordMap, type WordMap } from 'quran-search-engine';\n\nconst wordMap: WordMap = await loadWordMap();\n// Example output:\n// wordMap['الله'] =\u003e { lemma: 'الله', root: 'ا ل ه' }\n```\n\n### Normalization\n\n#### `removeTashkeel(text)`\n\nUse case: stripping diacritics (tashkeel) for display or simple comparisons.\n\n```ts\nimport { removeTashkeel } from 'quran-search-engine';\n\nconst out = removeTashkeel('بِسْمِ ٱللَّهِ');\n// out =\u003e 'بسم الله'\n```\n\n#### `normalizeArabic(text)`\n\nUse case: preparing user input for searching (unifies alef variants, removes tashkeel, etc).\n\n```ts\nimport { normalizeArabic } from 'quran-search-engine';\n\nconst out = normalizeArabic('بِسْمِ ٱللَّهِ');\n// out =\u003e 'بسم الله'\n```\n\n### Search\n\n#### `search(query, quranData, morphologyMap, wordMap, options?, pagination?)`\n\nMain entry point. Combines:\n\n- Exact text matching\n- Lemma/root matching (when enabled and available)\n- Fuzzy fallback (Fuse) per token\n\nUse case: your primary API for Quran search results + scoring + pagination.\n\nSet `options.fuzzy = false` to disable fuzzy fallback.\n\n```ts\nimport { search } from 'quran-search-engine';\n\nconst response = search(\n  'الله الرحمن',\n  quranData,\n  morphologyMap,\n  wordMap,\n  { lemma: true, root: true },\n  { page: 1, limit: 10 },\n);\n// Example output:\n// response.pagination =\u003e { totalResults: 42, totalPages: 5, currentPage: 1, limit: 10 }\n// response.counts =\u003e { simple: 10, lemma: 18, root: 9, fuzzy: 5, total: 42 }\n// response.results[0] =\u003e { gid: 123, matchType: 'exact', matchScore: 9, matchedTokens: ['...'], ... }\n```\n\n| Match type | Score per hit        |\n| ---------- | -------------------- |\n| Exact      | +3                   |\n| Lemma      | +2                   |\n| Root       | +1                   |\n| Fuzzy      | +0.5 (fallback only) |\n\nIf you need a simple “contains all tokens in a field” filter for your own data, you can do:\n\n```ts\nimport { normalizeArabic } from 'quran-search-engine';\n\nexport function containsAllTokens(value: string, query: string): boolean {\n  const normalizedQuery = normalizeArabic(query);\n  if (!normalizedQuery) return false;\n\n  const tokens = normalizedQuery.split(/\\s+/);\n  const normalizedValue = normalizeArabic(value);\n  return tokens.every((token) =\u003e normalizedValue.includes(token));\n}\n```\n\n#### Custom datasets\n\n`search` accepts any dataset shape as long as each record satisfies `VerseInput`:\n\n```ts\nexport type VerseInput = {\n  gid: number;\n  uthmani: string;\n  standard: string;\n};\n```\n\nMinimum requirements:\n\n- `gid`: unique verse id (used to join with `morphologyMap`)\n- `standard`: used for exact text matching\n- `uthmani`: used for fuzzy fallback and commonly used for highlighting in UI (if you don’t have it, set it to `standard`)\n\nCustom dataset example:\n\n```ts\nimport { search, type VerseInput, type WordMap, type MorphologyAya } from 'quran-search-engine';\n\ntype MyVerse = VerseInput \u0026 {\n  sura: number;\n  aya: number;\n  translation_en?: string;\n};\n\nconst myQuranData: MyVerse[] = [\n  {\n    gid: 1,\n    standard: 'بسم الله الرحمن الرحيم',\n    uthmani: 'بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ',\n    sura: 1,\n    aya: 1,\n    translation_en: 'In the name of Allah, the Entirely Merciful, the Especially Merciful.',\n  },\n];\n\nconst morphologyMap = new Map\u003cnumber, MorphologyAya\u003e();\nconst wordMap: WordMap = {};\n\nconst response = search('الله الرحمن', myQuranData, morphologyMap, wordMap, {\n  lemma: false,\n  root: false,\n});\n// Example output:\n// response.results[0] =\u003e { gid: 1, sura: 1, aya: 1, matchType: 'exact', matchScore: 6, ... }\n```\n\nFor lemma/root matching, provide both:\n\n- `morphologyMap: Map\u003cnumber, MorphologyAya\u003e` where `MorphologyAya` is `{ gid, lemmas: string[], roots: string[] }`\n- `wordMap: WordMap` where each normalized token maps to `{ lemma?: string; root?: string }`\n\n### Highlighting (UI-agnostic)\n\n#### `getHighlightRanges(text, matchedTokens, tokenTypes?)`\n\nComputes non-overlapping highlight ranges. This is pure (no HTML output), so the consumer controls rendering.\n\nUse case: highlight matches in UI without `dangerouslySetInnerHTML`.\n\n```ts\nimport { getHighlightRanges } from 'quran-search-engine';\n\nconst ranges = getHighlightRanges(verse.uthmani, verse.matchedTokens, verse.tokenTypes);\n// Example output (shape):\n// [\n//   { start: 12, end: 23, token: 'الله', matchType: 'exact' },\n//   { start: 30, end: 45, token: 'الرحمن', matchType: 'lemma' },\n// ]\n```\n\nReact rendering example:\n\n```tsx\nimport { getHighlightRanges, type ScoredQuranText } from 'quran-search-engine';\nimport type { ReactNode } from 'react';\n\nexport function Verse({ verse }: { verse: ScoredQuranText }) {\n  const ranges = getHighlightRanges(verse.uthmani, verse.matchedTokens, verse.tokenTypes);\n  if (ranges.length === 0) return \u003cspan\u003e{verse.uthmani}\u003c/span\u003e;\n\n  const parts: ReactNode[] = [];\n  let cursor = 0;\n\n  ranges.forEach((r, i) =\u003e {\n    if (cursor \u003c r.start) parts.push(verse.uthmani.slice(cursor, r.start));\n    parts.push(\n      \u003cspan key={`${r.start}-${r.end}-${i}`} className={`highlight highlight-${r.matchType}`}\u003e\n        {verse.uthmani.slice(r.start, r.end)}\n      \u003c/span\u003e,\n    );\n    cursor = r.end;\n  });\n\n  if (cursor \u003c verse.uthmani.length) parts.push(verse.uthmani.slice(cursor));\n\n  return \u003cspan\u003e{parts}\u003c/span\u003e;\n}\n```\n\n## How scoring works\n\n`search` returns `ScoredQuranText` results with `matchScore`, `matchType`, `matchedTokens`, and `tokenTypes`.\n\n- The query is cleaned to Arabic letters/spaces, then normalized, then split by whitespace into tokens.\n- For each query token, scoring accumulates across match layers:\n  - Exact word matches in the verse: `+3` per matched word\n  - Lemma matches (when enabled): `+2` per matched word\n  - Root matches (when enabled): `+1` per matched word\n  - Fuzzy matches: only used as a fallback when the verse has no exact/lemma/root matches; `+0.5` per fuzzy segment extracted from Fuse indices\n- `matchedTokens` is deduplicated (used for highlighting).\n- `matchType` is the best “overall” type seen on that verse (`exact` \u003e `lemma` \u003e `root` \u003e `fuzzy`/`none`).\n\n## Multi-word search\n\n`search` supports multi-word queries.\n\n- Query tokenization: the normalized query is split by whitespace.\n- AND logic:\n  - `search` intersects matches per token, so results must match every token (via exact, lemma/root, or fuzzy fallback for that token).\n\nExample:\n\n```ts\nconst response = search('الله الرحمن', quranData, morphologyMap, wordMap, {\n  lemma: true,\n  root: true,\n});\n// Example output:\n// response.results =\u003e all returned verses match BOTH tokens (AND logic)\n```\n\n## Core types\n\nThese are the main types you’ll interact with when calling `search(...)` and rendering results.\n\n```ts\nimport type {\n  HighlightRange,\n  MatchType,\n  MorphologyAya,\n  PaginationOptions,\n  QuranText,\n  ScoredQuranText,\n  SearchOptions,\n  SearchCounts,\n  SearchResponse,\n  WordMap,\n} from 'quran-search-engine';\n```\n\n### `QuranText`\n\nOne verse record in the dataset (input to `search`).\n\n```ts\nexport type QuranText = {\n  gid: number;\n  uthmani: string;\n  standard: string;\n  sura_id: number;\n  aya_id: number;\n  aya_id_display: string;\n  page_id: number;\n  juz_id: number;\n  sura_name: string;\n  sura_name_en: string;\n  sura_name_romanization: string;\n  standard_full: string;\n};\n```\n\n### `MorphologyAya`\n\nMorphology info for one verse (looked up by `gid` via a `Map\u003cnumber, MorphologyAya\u003e`).\n\n```ts\nexport type MorphologyAya = {\n  gid: number;\n  lemmas: string[];\n  roots: string[];\n};\n```\n\n### `WordMap`\n\nDictionary mapping a normalized token to lemma/root. Used to resolve query tokens into canonical forms for lemma/root matching.\n\n```ts\nexport type WordMap = {\n  [normalizedToken: string]: {\n    lemma?: string;\n    root?: string;\n  };\n};\n```\n\n### `SearchOptions`\n\nToggles for linguistic matching:\n\n```ts\nexport type SearchOptions = {\n  lemma: boolean;\n  root: boolean;\n  fuzzy?: boolean;\n};\n```\n\n### `PaginationOptions`\n\nControls paging (defaults are applied if omitted):\n\n```ts\nexport type PaginationOptions = {\n  page?: number;\n  limit?: number;\n};\n```\n\n### `MatchType`\n\nOverall “best” match class for a verse:\n\n```ts\nexport type MatchType = 'exact' | 'lemma' | 'root' | 'fuzzy' | 'none';\n```\n\n### `ScoredQuranText`\n\nThe verse returned by `search`, including scoring and highlighting metadata:\n\n```ts\nexport type ScoredQuranText = QuranText \u0026 {\n  matchScore: number;\n  matchType: MatchType;\n  matchedTokens: string[];\n  tokenTypes?: Record\u003cstring, MatchType\u003e;\n};\n```\n\n### `SearchResponse`\n\nFull response from `search`:\n\n```ts\nexport type SearchResponse = {\n  results: ScoredQuranText[];\n  counts: SearchCounts;\n  pagination: {\n    totalResults: number;\n    totalPages: number;\n    currentPage: number;\n    limit: number;\n  };\n};\n```\n\n### `HighlightRange`\n\nRange output from `getHighlightRanges(...)`:\n\n```ts\nexport type HighlightRange = {\n  start: number;\n  end: number;\n  token: string;\n  matchType: MatchType;\n};\n```\n\n## Non-goals\n\nThis library does not aim to provide:\n\n- AI or semantic interpretation\n- Tafsir or meaning inference\n- Opinionated UI rendering\n- Server-side indexing infrastructure\n\nIt focuses strictly on deterministic Quran text search.\n\n## Example apps\n\n\u003e [!IMPORTANT]\n\u003e **Note for Developers**: This project uses a pnpm workspace with `workspace:*` links. If you make changes to the library's source code in `src/`, you **must build the library** using `pnpm build` (or run it in watch mode with `pnpm build --watch`) for those changes to be reflected in the example applications.\n\nSeveral example applications are available in the `examples/` directory:\n\n- **React + Vite**: Full-featured web app with search UI (`examples/vite-react`)\n- **Vanilla TypeScript**: Simple browser-based search without frameworks (`examples/vanilla-ts`)\n- **Angular**: Standalone Angular app with highlighted results (`examples/angular`)\n- **Node.js**: Server-side search with command-line interface (`examples/nodejs`)\n\nTo run an example:\n\n```bash\npnpm install\npnpm -C examples/\u003cexample-name\u003e dev\n```\n\nScripts by example:\n\n- `examples/vite-react`: `pnpm -C examples/vite-react dev`\n- `examples/vanilla-ts`: `pnpm -C examples/vanilla-ts dev`\n- `examples/angular`: `pnpm -C examples/angular start`\n- `examples/nodejs`: `pnpm -C examples/nodejs start`\n\n## Testing\n\nThis project includes comprehensive test coverage and verification tools.\n\n### Running Tests\n\n```bash\n# Run all tests\npnpm test\n\n# Run tests in watch mode\npnpm test --watch\n\n# Run tests with coverage\npnpm test --coverage\n```\n\n### Test Coverage\n\nThe test suite covers:\n\n- **Core Search Logic**: `search()` and `simpleSearch()` functions\n- **Tokenization**: Exact, lemma, and root matching algorithms\n- **Arabic Normalization**: Text processing utilities (`removeTashkeel`, `normalizeArabic`)\n- **Data Loading**: Quran data, morphology, and word map loading utilities\n- **Highlighting**: UI-agnostic highlight range generation\n\n**Note**: These are **unit tests** that test individual functions in isolation. For integration testing, see the Verification Script below.\n\n### Verification Script\n\nFor comprehensive end-to-end verification, run the included verification script:\n\n```bash\n# Build the library first\npnpm build\n\n# Then run verification (requires tsx or similar TypeScript runner)\npnpm tsx scripts/verify-loader.ts\n```\n\nThis script performs **integration testing** that validates the complete search pipeline:\n\n- **Data Loading**: Tests Quran data, morphology, and word map loading with performance timing\n- **Simple Search**: Validates basic text search functionality\n- **Advanced Search**: Tests morphological matching (lemma/root), scoring, and pagination\n- **Pagination**: Verifies page navigation and result differentiation across pages\n- **Highlighting**: Tests token extraction for UI highlighting features\n\n**Key Differences from Unit Tests:**\n\n- **Scope**: Integration test vs. isolated unit tests\n- **Dependencies**: Tests real data loading and full function pipelines\n- **Performance**: Measures actual loading times and search performance\n- **End-to-End**: Validates the complete user workflow from data to results\n- **Purpose**: Catches integration issues that unit tests might miss\n\n### Test Structure\n\n```bash\nsrc/\n├── core/\n│   ├── search.test.ts       # Search algorithm tests\n│   └── tokenization.test.ts # Token matching tests\n└── utils/\n    ├── loader.test.ts       # Data loading tests\n    ├── normalization.test.ts # Text processing tests\n    └── highlight.ts         # Highlighting utilities\n```\n\n## Development\n\n```bash\npnpm run lint\npnpm run test\npnpm run build\n```\n\n## Contributing\n\n- Open an issue to discuss larger changes before starting implementation.\n- Keep changes focused and include tests when applicable.\n- Ensure checks pass locally: `pnpm run lint \u0026\u0026 pnpm run test \u0026\u0026 pnpm run build`.\n\n## Contact\n\n- Adel Benyahia — \u003ccontact@adelpro.us.kg\u003e\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadelpro%2Fquran-search-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadelpro%2Fquran-search-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadelpro%2Fquran-search-engine/lists"}