Hifz app content provenance — acquired 2026-10-16 QURAN TEXT First-party source: Tanzil Project, Uthmani text version 1.1. Download page: https://tanzil.net/download/ Exact download URL and selected options are in quran-integrity.json. The original UTF-8 download is sources/quran-uthmani-tanzil-v1.1.txt. The original full copyright/terms notice is reproduced in LICENSE-Tanzil.txt and in quran.json metadata.copyrightNotice. Keep those notices with this data. Display clear attribution to Tanzil Project and a link to https://tanzil.net. No Unicode normalization, text trimming, spelling correction, paraphrasing, transliteration or generated Quran text was applied. All 6236 app verse strings were compared to the original source individually. Hash manifests detect local changes; they are not independent scholarly review. METADATA First-party source: https://tanzil.net/res/text/metadata/quran-data.xml 114 chapters; per-verse juz and Medina Mushaf page indices are derived from the source's partition start positions. Chapter names/counts are source data. BASMALA / NUMBERING Reference: https://tanzil.net/docs/a_note_on_bismillah In chapter 1, basmala is numbered verse 1. Do not display it a second time. In chapters 2–114 except 9, the source includes an unnumbered basmala at the beginning of verse 1. quran.json preserves that whole verse string verbatim. For visual separation only, use chapter.basmala and basmalaPrefixLength. The basmalas of chapters 95 and 97 preserve the source's special shadda. Chapter 9 has no introductory basmala. Never insert one into that chapter. AUDIO AND TIMINGS First-party catalog: https://www.mp3quran.net/api/v3/ayat_timing/reads API documentation: https://www.mp3quran.net/eng/timing-api Endpoint: https://www.mp3quran.net/api/v3/ayat_timing?surah=1&read=123 Row schema: {ayah: number, start_time: number, end_time: number, ...} Times are milliseconds. An ayah 0 row is an introductory/un-numbered segment, not an additional numbered Quran verse. Some reads omit the introductory row. Use the exact read's folder_url + three-digit chapter number + .mp3 for audio. Do not pair timing data with another server/recording of the same reciter. Original full API responses (including page polygon fields) are retained under sources/timings/{readId}/{surah}.json. Compact unchanged time fields are under timings/{readId}/{surah}.json. Each file has a source/content hash record. Audio is streamed from the first-party source; no audio files are redistributed. Selected Hafs read IDs: 123 — Mishary Rashid Alafasy: 114 structurally complete chapter timelines. 118 — Mahmoud Khalil Al-Husary: 113 complete; chapter 1 is missing ayah 7. 112 — Muhammad Siddiq Al-Minshawi: 113 complete; chapter 9 is missing ayah 129. 53 — Abdul Basit Abdus Samad: 114 structurally complete chapter timelines. 54 — Abdul Rahman Al-Sudais: 114 structurally complete chapter timelines. 30 — Saad Al-Ghamdi: 114 structurally complete chapter timelines. Total: 684 captured chapter timelines, 682 pass full numbered-verse coverage, positive-duration, ordered-time and inter-verse-nonoverlap checks. The two incomplete upstream timelines must not enable synchronized highlighting. Use reciter.timingSurahs as the allowlist; invalidTimingSurahs records reasons. During uncovered intros/interludes no verse should be highlighted. No timings were invented, stretched, shifted, filled in, or borrowed from another reader. Structural coverage checks do not establish word-level timing accuracy. These are ayah-level boundaries supplied by the provider, not word-level boundaries. Sample audio HEAD checks for all six chapter-1 resources returned audio/mpeg, Access-Control-Allow-Origin: *, and Accept-Ranges: bytes on acquisition date. Extended-catalog Kurdish reads (extra-reciters.json), acquired 2026-10-24 with acquire-quran-timings.py --extra 221,268,38. The live catalog folder_url equals each record's server and audioTemplate folder, so timings belong to the exact played files. Same structural checks as above, plus: the largest end_time must be <= the headless-Chrome metadata duration of that exact file + 2 s (scripts/measure-timing-audio.mjs; evidence in sources/timing-audio-durations). 221 — Raad Mohammad Al-Kurdi: 111 enabled; 23 and 55 end ~46-50 s after the served audio; 24 ends 627 s after the browser duration (the file's iTunSMPB tag declares 1486 s and Chrome stops playback there). 268 — Peshawa Qadr Al-Kurdi: 113 enabled; 24 ends 197 s after the browser duration (same iTunSMPB truncation, playback stops at 1365.9 s). 38 — Shirzad Abdulrahman Taher: 114 enabled. Total with the six above: 1026 snapshots, 1020 enabled, 6 disabled. FONTS Unmodified Amiri Quran Regular and Noto Sans Arabic Variable from the official google/fonts repository. Font URLs/checksums and full SIL OFL licenses are in ../fonts. Amiri Quran covers all non-ASCII codepoints in the acquired text. Noto Sans Arabic covers the Kurdish characters کڕڵۆێەگپچژڤ. REPRODUCE / VERIFY python scripts/acquire-quran-assets.py python scripts/acquire-quran-timings.py node scripts/measure-timing-audio.mjs 221 268 38 (needs PLAYWRIGHT_MODULE, CHROME_PATH) python scripts/acquire-quran-timings.py --extra 221,268,38 node scripts/verify-quran-assets.mjs Acquisition makes live first-party network requests; verification is offline.