The same cell, two engines
Every row below is a real Excel number format taken from our KSA test fixture. The value is 14131000 for the currency rows and Excel serial 45662, which is 5 January 2025, for the date rows. The middle column was produced by running ssf@0.11.2 locally: that is the standalone publication of the format engine SheetJS ships, and it sits underneath a large share of the spreadsheet viewers on the web.
| Criterion | What the format asks for | ssf 0.11.2 | Sifrsys |
|---|---|---|---|
| [$-2060401]#,##0.00Locale directive, no currency glyph | Arabic-Indic digits, no symbol | $14,131,000.00 | ١٤٬١٣١٬٠٠٠٫٠٠ |
| [$-060401]dd/mm/yyyyHijri calendar id inside the locale token | The Hijri date | 05/01/2025 | 05/07/1446 |
| B2dd/mm/yyyyExplicit Hijri calendar prefix | The Hijri date | 05/01/1444 | 05/07/1446 |
| [$SAR-401]\ #,##0.00ISO code carried in the token | SAR before the number | SAR 14,131,000.00 | SAR 14,131,000.00 |
| [$ر.س-401]#,##0.00Riyal symbol carried in the token | The riyal symbol | ر.س14,131,000.00 | ر.س14,131,000.00 |
The last two rows matter as much as the first three. Those formats already rendered correctly, so we leave them exactly alone. The one thing worse than an unhandled format is a regressed one.
The dollar sign that was never in the file
Look at row one again. A cell formatted [$-2060401]#,##0.00 carries no currency glyph at all: there is nothing between the $ and the -. The token is a locale directive that packs three instructions, Arabic language, Umm al-Qura calendar, and a top nibble asking for the locale's own digits. The engine read the marker character as a symbol and printed an American dollar sign onto a Saudi balance sheet. In a diligence data room that is not a cosmetic defect. It is a fourteen million riyal line item wearing the wrong currency.
We drop empty-symbol locale tokens before formatting, and apply Arabic-Indic digits to the finished string so digits and separators convert together: ١٤٬١٣١٬٠٠٠٫٠٠ and not ١٤,١٣١,٠٠٠.٠٠. Half a conversion looks broken in a way that is worse than none.
Right to left is structural, not styling
A model built in Arabic Excel writes rightToLeft onto the sheet view. Column A belongs on the right edge. When a viewer ignores that flag, the label column lands on the far side of the screen from the numbers it labels, and the frozen header pane pins to the wrong edge, so the labels scroll away and leave a wall of unattributed figures.
- Read the flagsheetView rightToLeft on the sheet, readingOrder on the cell
- Mirror the gridColumn A at the right edge, dir on the table rather than the scroller
- Move the originSticky columns pin right, so left becomes right
- Normalise the scrollOffset runs negative from the right edge; every measurement is absolute
Cell-level reading order is resolved separately from sheet direction, so an English assumptions block inside an Arabic model keeps its own direction on the same sheet, which is what a bilingual model actually looks like.
What was measured
- KSA number formats100%
- Display strings100%
- Merged cells100%
- Alignment100%
- Font styles100%
- Fills99.7%
Bilingual diligence, one thread
A Riyadh process rarely runs in one language. The advisor's memo is in English, the commercial registration and the board minutes are in Arabic, and counsel asks in whichever language the document was in. Q&A threads are free text, so a question asked in Arabic can be answered in English inside one thread, under the same permission boundaries that govern documents.
When a participant asks the AI, the answer cites the exact page in the PDF or the exact cell range in the workbook, rendered as Q3_Model.xlsx · Revenue!B14:F34with absolute 1-based sheet rows. Tapping the citation opens the workbook at that sheet and washes those cells. That matters more here than elsewhere: a partner who does not read Arabic needs to see the cell, not take the model's word for it.
The retrieval filter runs inside the SQL query, on tenant id and the per-participant document access function, rather than after retrieval or as an instruction in the prompt. On a sell side with three competing bidders in one room, that boundary is the product.
Where the data sits
There is no in-Kingdom hosting region. The primary database, object storage and application hosting run in the United States, and document processing is transient in Germany. Every subprocessor and its country is published on the Trust Center. What is true today: buckets are private and never publicly readable, permissions resolve on the server, AI retrieval is fenced inside the SQL query, and every document view is written to a hash-chained audit log. The full residency and compliance position is here.
Cost
Flat published plans: a free tier, Teams at $399 a month, Pro at $999 a month, custom Enterprise. AI is included in every paid tier rather than sold as an add-on, and there are no per-page fees, which is the pricing model that makes a document-heavy Saudi diligence unpredictable elsewhere. The 14-day trial needs no credit card, and the price-lock commitment means no surprise mid-contract increase, with 90 days notice for any change. Detail on pricing, including the Founding 10 terms: the first ten paying companies keep their signup price for the life of the subscription, and we move documents, folder structure and permission setup out of the current data room ourselves at no charge.
Related: Data rooms across the GCC · هذه الصفحة بالعربية · Cross-border MENA deals