# 🦷 React Advanced Odontogram

[![Download](https://img.shields.io/badge/Download-React--Odontogram--Modul-blue?style=for-the-badge&logo=github)](https://github.com/ZoliQua/React-Odontogram-Modul/releases)
[![Version](https://img.shields.io/badge/version-2.2.1-green?style=for-the-badge)](https://github.com/ZoliQua/React-Odontogram-Modul)
[![npm](https://img.shields.io/npm/v/react-advanced-odontogram?style=for-the-badge&logo=npm&color=CB3837)](https://www.npmjs.com/package/react-advanced-odontogram)
[![License](https://img.shields.io/badge/license-MIT-orange?style=for-the-badge)](https://github.com/ZoliQua/React-Odontogram-Modul/blob/main/LICENSE)
[![DOI](../src/assets/zenodo.21156787.svg)](https://doi.org/10.5281/zenodo.21156787)

[![React](https://img.shields.io/badge/React-18-61DAFB?style=for-the-badge&logo=react)](https://reactjs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5-3178C6?style=for-the-badge&logo=typescript)](https://www.typescriptlang.org/)

---

> 🌐 **Languages:**  🇬🇧 [English](README-en.md) | 🇪🇸 [Español](README-es.md) | 🇩🇪 [Deutsch](README-de.md) | 🇭🇺 [Magyar](README-hu.md) | 🇮🇹 [Italiano](README-it.md) | 🇸🇰 [Slovenčina](README-sk.md) | 🇵🇱 [Polski](README-pl.md) | 🇷🇺 [Русский](README-ru.md) | 🇧🇷 [Português (BR)](README-pt-br.md) | 🇸🇦 [العربية](README-ar.md) | 🇨🇳 [简体中文](README-zh.md) | 🇫🇷 [Français](README-fr.md)

---

## 🇸🇦 العربية

*(النسخة العربية من هذا الملف التعريفي (README) — مترجمة عن النسخة الإنجليزية الأصلية، بحسب الإصدار v1.49.0)*

### 📋 نظرة عامة
هذا المشروع محرر تخطيط أسنان (أودونتوغرام) تفاعلي يعمل داخل المتصفح، ويدعم تسجيل حالة الأسنان بسرعة من خلال واجهة مستخدم نظيفة وواضحة. يعرض المشروع قوالب أسنان بصيغة SVG متعددة الطبقات لتمثيل الترميمات، والنخر (التسوس)، وحالة العلاج اللبي (علاج قناة الجذر)، ودرجة حركة السن، وتفاصيل سريرية أخرى، مع توفير إمكانية التحديد المتعدد، ومرشحات التحديد، وأنماط حالة جاهزة مسبقًا.

---
![مخطط الأسنان – معاينة (العربية)](screenshot_ar_odontogram.png)

🔗 **رابط الاختبار:** https://react-odontogram-modul.vercel.app/

---

### 📦 الاستخدام كحزمة npm

يُشحَن الأودونتوغرام كمكتبة مكوّنات React مستقلة بذاتها على npm:
[`react-advanced-odontogram`](https://www.npmjs.com/package/react-advanced-odontogram).

#### المتطلبات
- **React 18 أو 19** (مُعلَنة كاعتمادية نظير (peer dependency) — يوفّرها تطبيقك).
- **حزمة تجميع (bundler)** تفهم حقل `exports` وصيغة ESM: Vite، webpack 5، Next.js، Rollup، esbuild، Parcel. الحزمة **ESM فقط**.
- Node **الإصدار 18 فأعلى** للأدوات.

#### التثبيت

```bash
npm install react-advanced-odontogram react react-dom
```

#### الاستخدام الأساسي

اعرض `OdontogramShell` واستورد ملف التنسيق **مرة واحدة فقط** في أي مكان من تطبيقك:

```tsx
import { OdontogramShell } from "react-advanced-odontogram";
import "react-advanced-odontogram/style.css";

export function Chart() {
  return (
    <OdontogramShell
      language="ar"          // hu | en | de | es | it | sk | pl | ru | pt-br | ar | zh | fr
      numberingSystem="FDI"  // FDI | Universal | Palmer
      darkMode={false}
    />
  );
}
```

#### خصائص المكوّن (props)

`OdontogramShell` مكوّن مُتحكَّم به (controlled component). أكثر الخصائص شيوعًا:

| الخاصية | النوع | الافتراضي | الوصف |
|------|------|---------|-------------|
| `language` | `Language` | `"hu"` | لغة الواجهة (`hu`/`en`/`de`/`es`/`it`/`sk`/`pl`/`ru`/`pt-br`/`ar`/`zh`). |
| `numberingSystem` | `"FDI" \| "Universal" \| "Palmer"` | `"FDI"` | نظام ترقيم الأسنان. |
| `darkMode` | `boolean` | `false` | مفتاح تبديل السمة الداكنة. |
| `readOnly` | `boolean` | `false` | تعطيل كل إمكانيات التحرير (عرض فقط). |
| `themeConfig` | `OdontogramThemeConfig` | — | تجاوز متغيرات CSS الخاصة بالسمة (`--odon-*`). |
| `plugins` | `OdontogramPlugin[]` | — | تسجيل إضافات حالة مخصّصة / طبقات إضافية. |
| `enableNotes` | `boolean` | `false` | تفعيل الملاحظات لكل سن. |
| `enableIcdas` | `boolean` | `false` | تفعيل تقييم النخر وفق ICDAS II. |
| `onLanguageChange` / `onNumberingChange` / `onDarkModeChange` | `(value) => void` | — | تُستدعى عندما يغيّر المستخدم الإعداد من الواجهة. |

تُقبَل أيضًا خصائص أدقّ لمستوى التفصيل (`pulpDetailLevel`، `secondaryCariesMode`، `rootCariesMode`، `radiographicDepthMode`، `wearDetailLevel`، `discolorationDetailLevel`، `surfaceNotation`، `showStatusCard`، `showOrthoCard`) — راجع أنواع `.d.ts` المرفقة للاطلاع على القائمة الكاملة المُنمَّطة.

#### واجهة برمجية عامة (تصديرات مسمّاة)

`OdontogramShell` هو التصدير الافتراضي وتصدير مسمّى في آن واحد. واجهة الحالة الآمرة (imperative)، ومكوّن `PerioChart` المستقل، والجولة التعريفية الموجَّهة، وجميع الأنواع العامة هي تصديرات مسمّاة من نقطة الدخول ذاتها:

```ts
import {
  OdontogramShell,           // also the default export
  PerioChart,                // standalone periodontal chart component
  // read state
  getOdontogramSummary,
  getToothStateSummary,
  onStateChange,             // subscribe to state changes
  // export / import
  exportFhir,                // HL7 FHIR R4 bundle
  exportSvg, exportImage,    // vector / raster chart export
  setImportFormat,
  // control
  setReadOnly, getReadOnly,
  clearSelection,
  registerPlugins, setPluginState, getPluginState,
  startIntroTour,            // launch the onboarding tour
  // …and many more setX/getX settings functions
} from "react-advanced-odontogram";
```

كامل الواجهة (نحو 44 دالة + أنواع مثل `OdontogramSummary`، `OdontogramThemeConfig`، `OdontogramPlugin`، `FhirExportOptions`، `PerioViewMode`، …) مُنمَّطة بالكامل ضمن التصريحات المرفقة.

#### الاستخدام مع Next.js (موجِّه التطبيق App Router)

المكوّن يعمل من جهة العميل فقط، لذا اعرضه من مكوّن عميل (Client Component):

```tsx
"use client";
import { OdontogramShell } from "react-advanced-odontogram";
import "react-advanced-odontogram/style.css";

export default function OdontogramClient() {
  return <OdontogramShell language="ar" numberingSystem="FDI" />;
}
```

أو حمّله عبر استيراد ديناميكي مخصَّص لجهة العميل فقط: `dynamic(() => import("./OdontogramClient"), { ssr: false })`.

#### ملاحظات مهمة وقيود حالية
- **ESM فقط** — تنشر الحزمة وحدة ES واحدة (`dist/odontogram.js`) بالإضافة إلى مدخل تصريحات الأنواع (`dist/index.d.ts`). وهي موجَّهة لاستبانة وحدات حزم التجميع (bundler)؛ لا يوجد بناء CommonJS.
- **ملف التنسيق منفصل** — **يجب** عليك استيراد `react-advanced-odontogram/style.css` مرة واحدة؛ فهو لا يُحقَن تلقائيًا. التنسيق عبارة عن CSS عام محصور ضمن `.odontogram-root` ومُتحكَّم به عبر متغيرات CSS من نوع `--odon-*`.
- **العرض من جهة الخادم / جهة العميل فقط** — يقرأ المكوّن DOM عند التركيب (`document`)، لذا يجب أن يعمل داخل المتصفح. في أطر عمل SSR، اعرضه ضمن مكوّن عميل (`"use client"`) أو عبر استيراد ديناميكي مخصَّص لجهة العميل فقط.
- **الأصول مكتفية ذاتيًا** — تُدرَج رسومات الأسنان والأيقونات بصيغة SVG ضمن حزمة JavaScript وقت البناء؛ **لا يوجد** أي طلب أصول وقت التشغيل يلزم إعداده، ولا شيء إضافي يلزم نسخه إلى مجلدك العام.
- **نسخة واحدة لكل صفحة** — حالة المحرك حاليًا هي كائن وحيد (singleton) على مستوى الوحدة (module)، لذا فإن عرض نسختين من `<OdontogramShell>` في الصفحة نفسها سيجعلهما تتشاركان حالة مخطط واحد. دعم النسخ المتعددة مخطَّط له في إصدار مستقبلي.

---

### ✨ الميزات الرئيسية
- 🖱️ تحديد سريع وتحديد متعدد (CMD/CTRL + نقر)
- 🦷 أنواع الأسنان: دائم، لبني (مؤقت)، زرعة، تحت اللثة، مفقود
- 🦷 نسيج السن الأساسي (مستقل عن أي ترميم): طبيعي، جذر متبقٍّ (radix)، مكسور، مُجهَّز لتركيب تاج
- 👑 الترميمات حسب النوع × المادة: تاج / حشوة داخلية (إنلاي) / حشوة فوقية (أونلاي) / قشرة (فينير) / جسر من الإيماكس، الذهب، الغراديا، الزركونيا، المعدن، المعدن الخزفي، التيليسكوب أو مؤقت (الأونلاي بمنظر إطباقي فقط) — تُختار من قائمة منسدلة مُجمَّعة واحدة "Fix: Crown – …" بأقل عدد من النقرات؛ تاجات `metal` القديمة تُرحَّل تلقائيًا إلى `metal-ceramic` (معدن خزفي)؛ الزرعات تستخدم نفس نموذج النوع × المادة، مع طبقة موصل زرعة إضافية. القائمة المنسدلة مقيّدة بحسب نوع السن: الزرعة تعرض فقط تاج/جسر (بالإضافة إلى خيارات التثبيت الخمسة أدناه)؛ السن المفقود/الفراغ يعرض فقط جسرًا وسيطًا (بالإضافة إلى طقم جزئي/كامل متحرك)؛ نسيج `radix` يخفي عنصر التحكم بالترميم تمامًا (لا يمكن تسجيل أي ترميم على جذر متبقٍّ)
- 🦿 تركيبات متحركة/بمرابط على محور `prosthesis` المخصص (مدخلات "Kivehető:" في القائمة المنسدلة المجمّعة): دعامة التئام الزرعة، لوكاتور، لوكاتور مع طقم علوي، بار، بار مع طقم علوي؛ طقم جزئي أو كامل متحرك مدعوم بالأسنان
- 🌉 أسنان الجسر تعرض غطاء التاج وموصل السرج معًا؛ تراكب امتداد جسر متعدد الأسنان يرسم موصلًا واحدًا متصلًا ومتوافقًا مع شكل القوس عبر أسنان الجسر المتتالية (الوسائط + الدعامات) والفراغات بينها (يستخدم القوسان العلوي والسفلي هندسة سرج متطابقة انعكاسيًا، بحيث يبقى الموصل متماشيًا في كلا القوسين)، وهو مُضمَّن في تصدير PNG/JPG/SVG؛ تطبيق جسر عبر نمط حالة جاهز يعيد حساب التراكب فورًا
- 🔍 تسجيل النخر على 6 أسطح: قريب من الوسط، بعيد عن الوسط، دهليزي، لساني، إطباقي، تحت التاج
- 🪥 مواد الحشو لكل سطح: أملغم، حشوة تجميلية (كومبوزيت)، أيونومر زجاجي، مؤقتة
- 🏥 مُحدِّد واحد مدمج لـ"حالة اللب/العلاج اللبي" (مُجمَّع: لب حيوي مقابل معالَج/لبّي): الحالات اللبّية (حشوة دوائية، حشوة قناة جذر، حشوة قناة جذر غير مكتملة، وتد ألياف زجاجية، وتد معدني) وتشخيص اللب وفق AAE (`pulpDx`: طبيعي / التهاب لب قابل للعكس / غير قابل للعكس / نخر اللب) متنافيان — فالسن المعالَج بقناة الجذر (`endo` مضبوط) لا يمكن أن يحمل في الوقت نفسه تشخيص لب حيوي؛ وعند المعالجة يُعاد ضبط `pulpDx` إلى `normal` ويُخفى رمز اللب المريض. التهاب اللب القابل للعكس يُعرض برمز لب مصغَّر. إعداد اختياري لثلاثة مستويات من تفاصيل اللب (`pulpDetailLevel`: بسيط / AAE / لاتيني عملي) يُظهر عبر `pulpLatin` تسعة أنماط لبّية فرعية باللاتينية العملية (pulpa sana … gangraena pulpae)؛ ويبقى الاستئصال والوتد المجاوز للُّب مؤشرين خاصين منفصلين
- 🦴 التشخيص القمي (`apicalDx`: التهاب دواعم السن القمي العرَضي/اللاعرَضي، خراج قمي حاد/مزمن، التهاب العظم المتكاثف) يتحكم مباشرة برمز الآفة حول الذروة؛ ويظهر محدِّد فرعي للنوع (ورم حبيبي/كيس) فقط تحت التهاب دواعم السن القمي العرَضي/اللاعرَضي (وقد أُلغي نوع "الخراج" الفرعي الزائد عن الحاجة — لأنه مشمول أصلًا ضمن التشخيص القمي)
- 🩹 بطاقة مدمجة لـ"الجذر ودواعم السن" (قسم قابل للطي واحد لنتائج الجذر/حول الذروة ونتائج دواعم السن)
- ⚕️ التعديلات: التهاب حول الذروة (يظهر فقط في الأسنان المفقودة/سنخ الخلع؛ ويُخفى في الأسنان الموجودة حيث يتحكم `apicalDx` وحده برمز الآفة، وفي الزرعات حيث يغطيها `periImplant`)، مرض دواعم السن، درجات حركة السن (M1/M2/M3، مخفية في الزرعات)
- 🦷🔩 حالة ما حول الزرعة (`periImplant`: none / mucositis / peri-implantitis-mild / -moderate / -severe) — وفق تصنيف الورشة العالمية 2018، تُعرض كمحدِّد مخصص في الزرعات؛ التهاب المخاطية حول الزرعة يعيد استخدام رمز اللثة الدواعمي، بينما التهاب ما حول الزرعة يضيف طبقة `peri-implant-bone-loss` متدرجة (عتامة 0.4/0.7/1.0). لم تعد الزرعات تعرض رمز آفة حول الذروة — إذ يُعبَّر عن التهابها عبر هذا المحور بدلًا من ذلك — وتُخفى خانات تعديل دواعم السن في الزرعات (وأُلغيت إعادة تسمية خانة "التهاب ما حول الزرعة" المؤقتة)
- 🏷️ مؤشرات خاصة: الحاجة إلى تاج، الحاجة إلى استبدال تاج، فراغ مغلق بعد الفقد، خطة خلع، إغلاق الشقوق، فقدان نقطة التماس
- 👁️ مفاتيح تبديل للمنظر الإطباقي، وأسنان العقل، وإظهار العظم واللب
- 🔢 12 مرشح تحديد (الكل، الموجود، الدائم، اللبني، الزرعات، المفقود، العلوي/السفلي، الأمامي/الأضراس)
- 📊 أنماط حالة جاهزة مسبقًا (إعادة الضبط، التسنين اللبني، التسنين المختلط، انعدام الأسنان)
- 📦 34 قالب ترميم جاهزًا مسبقًا (جسور، أطقم متحركة، أطقم بار مع زرعات)
- 💾 تصدير/استيراد الحالة بصيغة JSON (الإصدار 2.20؛ لا تزال الاستيرادات تقبل الإصدارات القديمة 1.4 ومن 2.0 حتى 2.19 وتُرحَّل تلقائيًا، مع حالات مخصصة للإضافات وملاحظات لكل سن)
- 🔗 تصدير HL7 FHIR R4 (حزمة تجميعية (Bundle) من ملاحظات (Observations) لكل سن، مع ترميز أسنان وفق ISO 3950 للتسنين الدائم، ونظام ترميز محلي — مع التخطيط لدعم ترميز SNOMED CT مستقبلًا)
- ✚ واجهة تحديد أسطح على شكل صليب/علامة زائد (B/M/O/D/L) للنخر والحشوات
- 🧱 مواد ترميم لكل سطح على حدة (حشوات مختلطة، مثل أملغم دهليزي + كومبوزيت بعيد عن الوسط)
- 🖼️ تصدير صورة PNG/JPG/SVG للمخطط (قابل للتنزيل؛ يُنشأ PNG/JPG بالتحويل النقطي من SVG متجهي)
- 🦷 النخر/النخر الثانوي آلة حالة لكل سطح: السطح المصاب بالنخر بلا حشوة يُعرض كنخر أولي (بعتامة متدرجة حسب مقياس ICDAS)؛ وبمجرد وجود حشوة على ذلك السطح يُعرض بدلًا من ذلك كنخر متكرر (طبقة `subcaries-{surface}`، بتقييم CARS) — ولا تكون الحالتان نشطتين معًا على السطح نفسه أبدًا
- 🎯 شدة موحّدة لكل سطح (`cariesSeverity`، من 0 إلى 6، تحل محل حقلي عمق ICDAS ودرجة CARS المنفصلين سابقًا): تُقرأ كعمق ICDAS على سطح أولي، وكدرجة CARS مُسمّاة (سليم … تجويف واسع) على سطح متكرر، عبر نافذة منبثقة سياقية تعرض فقط المقياس المناسب لحالة السطح الراهنة
- 🌱 نخر الجذر (`rootCaries`: none / active / arrested / active-cavitated)، يفعّل طبقة الرسم المخصصة لنخر الجذر بعتامة تعتمد على الشدة (نشِط 0.5 / متوقف 0.7 / نشِط وتجويفي بعتامة كاملة)
- 📡 عمق النخر الشعاعي (`radiographicDepth`: none / E1 / E2 / D1 / D2 / D3 لكل سطح)، مستقل عن مقياس الشدة البصري ICDAS/CARS، يظهر كشارة ويُصدَّر عبر ملاحظة FHIR خاصة به
- 🎚️ ثلاثة إعدادات لدرجة تفصيل النخر (`secondaryCariesMode`, `rootCariesMode`, `radiographicDepthMode`) بالإضافة إلى مفتاح `cariesDepthEnabled`، تختصر كل مقياس إلى واجهة اختيار أبسط دون فقدان القيمة المخزّنة
- 🩹 سطر ملخص للنخر الثانوي في لوحة الحشوات: يسرد أي سن محدد فيه نخر متكرر وأسطحه أسفل عناصر تحكم الحشو (مثل: "36 (O) has subcaries set on its filling.")
- 🪛 عيوب حشو لكل سطح (`fillingDefect`: none / marginal / fracture / wear) في الترميمات المباشرة، بمعزل عن النخر المتكرر — تُسجَّل عبر مؤشر لكل سطح في بطاقة الحشوات (يعكس مؤشر عمق النخر، مع قائمة خياراته مكدسة عموديًا)، وتُعرض على المخطط، وتظهر في التلميح وفي ملخص حشوات الفم الكامل بتسمية صريحة (مثل: "36 (O) – Filling defect: O: marginal")، بنفس الطريقة التي يُسمّى بها النخر المتكرر في سطر النخر؛ كما تعرض بطاقة الحشوات ملاحظة تنبيهية لأي سن محدد لديه عيب حشو مسجَّل (مثل: "36 has a filling defect recorded.")، بالتوازي مع ملاحظة النخر الثانوي القائمة
- 🦷💥 بري (تآكل) السن مصنّف حسب السبب السريري والموضع (`wearEdge`: none / attrition / erosion، قاطعي/إطباقي؛ `wearCervical`: none / abrasion / abfraction / erosion، عنقي) — يحل محل علمي التحكم السابقين (تشغيل/إيقاف) لبري الصرير؛ يُسجَّل عبر قائمتين منسدلتين في سطر البري، ويعيد استخدام رسوم البري الحالية، ويظهر في التلميح وفي قسم ملخص جديد للفم الكامل بعنوان "Wear"
- 🎨 تصبّغ السن حسب السبب (`discoloration`: none / tetracycline / fluorosis / nonvital / extrinsic / other) في الأسنان الدائمة واللبنية — يلوّن تاج السن الطبيعي المعروض بلون تمثيلي عندما لا يحمل السن ترميمًا وله نسيج طبيعي؛ يظهر في التلميح وفي قسم ملخص جديد للفم الكامل بعنوان "Discoloration"؛ ويكمل مجموعة الحالات السطحية والبنيوية إلى جانب عيوب الحشو والبري
- ✏️ الأسنان الأمامية (القواطع والأنياب) تُسمّي سطحها الإطباقي "قاطعي" (incisal) في كل أنحاء الواجهة (القائمة، النافذة المنبثقة، الملخصات)؛ ويبقى مفتاح السطح المخزَّن `occlusal`
- 🔤 ترميز أسطح مراعٍ للموضع (الإعدادات ← تفاصيل السن ← "ترميز السطح"، بسيط/كامل، الافتراضي كامل): في الوضع الكامل يتبع حرف/تسمية سطح النخر والحشو تشريح السن — الإطباقي ← I/قاطعي في الأسنان الأمامية، الدهليزي ← L/شفوي في الأسنان الأمامية، اللساني ← P/حنكي في الأسنان العلوية و L/لساني في الأسنان السفلية (لا يتأثر القريب من الوسط/البعيد عن الوسط/تحت التاج)؛ الوضع البسيط يستخدم دائمًا المجموعة العامة B/M/O/D/L/SC بصرف النظر عن موضع السن. ينطبق على ملخص الفم الكامل وعلى محددَي أسطح كل من النخر وعيب الحشو (الحرف + التسمية)؛ ولا يتأثر مفتاح السطح المخزَّن
- 🦷↕️ تسجيل تقويم الأسنان لكل سن (`orthoAppliance`: none / bracket / band؛ `orthoDrift`: none / mesial / distal؛ `orthoVertical`: none / extrusion / intrusion؛ `orthoRotation`: قيمة منطقية) على سن طبيعي موجود (دائم أو لبني) — يعيد استخدام رسوم التقويم الخاملة منذ الإصدار v2.5.0 (دون إضافة SVG جديد)؛ يظهر على المخطط، وفي التلميح، وفي قسم ملخص جديد للفم الكامل بعنوان "Orthodontics"
- 🪨 الجير، وامتصاص الجذر المصنَّف كداخلي أو عنقي خارجي (`resorptionType`)
- 📏 عمق النخر لكل سطح (سطحي / عاجي / عميق)، أو تقييم اختياري وفق ICDAS II (من 0 إلى 6) عبر `enableIcdas`
- 🩹 مفتاح تبديل لتسرب حافة التاج، يظهر فقط عند وجود ترميم تاج أو جسر
- 🧰 شريط أيقونات علوي موحَّد مع نافذة إعدادات بعلامات تبويب (عام / اللوحات / تفاصيل السن / النخر / اللب / الملاحظات / دواعم السن — الترقيم، الملاحظات، إظهار اللوحات، ICDAS، مفتاح عمق النخر، درجة تفصيل نخر الجذر/النخر الشعاعي، مستوى تفصيل اللب، مستوى تفصيل بري/تصبّغ السن، معلومات السن)
- 🗂️ الإعدادات ← علامة التبويب "اللوحات": إظهار/إخفاء مستقل للوحتَي ملخص الحالات وتقويم الأسنان لكامل الفم
- 🦷🩺 الإعدادات ← علامة التبويب "دواعم السن": 16 مفتاح إظهار/إخفاء لكل مؤشر من صفوف مخطط دواعم السن (مجمّعة: الجيب/النظافة/المخاطية اللثوية/الدعم/ما حول الزرعة — PD/GM/CAL/BOP، البلاك، PI، GI، إظهار CEJ، تقعر الجذر، KG، GT، تفرع الجذور، الحركة، تصنيف ميلر، mPI، mBI)، لكل منها وصف، بالإضافة إلى خيار عرض أسماء المؤشرات مترجمة مقابل قياسية (القياسي = اسم علمي إنجليزي/لاتيني ثابت في كل لغات الواجهة؛ وتبقى التلميحات مترجمة دائمًا بصرف النظر عن هذا الإعداد). كلاهما إعدادان على مستوى التطبيق (مثل `perioViewMode`) — وليسا أبدًا جزءًا من حمولة التصدير
- 🩹 دُمِجت إعدادات النخر الثانوي (CARS) في علامة تبويب إعدادات النخر، وتموضعت أعلى العمق الشعاعي (أُلغيت علامة التبويب المنفصلة "النخر الثانوي")
- 🎚️ مستوى تفصيل تفاصيل السن (الإعدادات ← تفاصيل السن): إعداد بسيط/معقّد لبري السن وللتصبغ. الوضع البسيط يعرض مفتاح نعم/لا لكل نتيجة (تفعيل البري ← attrition/abrasion، تفعيل التصبغ ← other)؛ الوضع المعقد (الافتراضي) يبقي القوائم المنسدلة للنوع/السبب، وتُحفظ القيمة المخزَّنة عند التبديل بين المستويين
- 📋 لوحة معلومات السن: ملخص نصي حي لكامل المخطط (عدد الأسنان، قوائم الموجود/المفقود، النخر بما فيه الثانوي، الحشوات، علاجات قناة الجذر، التركيبات، الزرعات، حالة دواعم السن) — تظهر افتراضيًا، وقابلة للتبديل من الإعدادات
- 🗂️ قائمة تصدير موحّدة منسدلة (JSON للحالة / FHIR / PNG / JPG)
- 📥 قائمة استيراد منسدلة مع استيراد FHIR (تُعيد قراءة الحزم المُصدَّرة سابقًا)
- ⏳ طبقة تغطية للتقدم أثناء تصدير الصورة
- 🎓 جولة تعريفية تفاعلية من 12 خطوة
- 🔢 ثلاثة أنظمة ترقيم (FDI، العالمي، بالمر)
- 🌐 دعم متعدد اللغات (HU/EN/DE/ES/IT/SK/PL/RU/PT-BR) مع مبدّل لغة (أكثر من 190 مفتاح ترجمة لكل لغة)
- 🌗 دعم الوضع الداكن بزر تبديل (مستقل أو متحكَّم به من التطبيق الأصل)
- 🎨 إعدادات سمة مخصصة (خاصية `themeConfig`) عبر خصائص CSS المخصصة (`--odon-*`)
- 📱 تجربة لمس محسّنة للجوال: نافذة تكبير عند اللمس، قائمة سياق بالضغط المطوّل، تكبير بالقرص (Pinch-to-zoom)، أهداف لمس بحجم WCAG 44px، تنقل بتبديل القوس
- 🔌 نظام إضافات SVG مخصص: حقن تراكبات بصرية، حالة مخصصة لكل سن، دعم تصدير/استيراد JSON
- ⚠️ تحذيرات تحقق من الحالة لتركيبات حالة الأسنان غير المتوافقة
- 🏷️ تلميح تلقائي لحالة السن على بلاطات الأسنان (يعرض كل الحالات النشطة)
- 🩺 تلميح حديث لكل سن ولوحة ملخص لكامل الفم: يعرض كلاهما المجموعة الكاملة من النتائج السريرية (تشخيص اللب/القمة + النوع الفرعي للآفة، امتصاص الجذر، حالة ما حول الزرعة، نخر الجذر المتدرج، الجير، تسرب حافة التاج، الكسر، فقدان التماس، البري المصنَّف حسب الحافة/العنق)، مع قسم مخصص بعنوان "Diagnoses" في اللوحة، وقسم مخصص بعنوان "Wear"، ومؤشر خشِن لشدة النخر (سطحي/متوسط/عميق)
- ♿ إمكانية الوصول عبر لوحة المفاتيح (WCAG): أدوار ARIA لصندوق القوائم/الخيارات، تحديد بـEnter/مسافة، تنقل بأسهم لوحة المفاتيح، إطارات تركيز مرئية (focus-visible)
- 🔒 وضع للقراءة فقط: تعطيل جميع التفاعلات لحالات الاستخدام مثل الطباعة/التقرير/العرض
- ✨ رسوم متحركة للتحديد: إطار متقطع نابض وظل توهج على الأسنان المحددة (مع دعم `prefers-reduced-motion`)
- 📝 ملاحظات لكل سن: نقر مزدوج لإضافة/تعديل الملاحظات، أيقونة ملاحظة بجانب رقم السن، تلميح عند المرور بالمؤشر يعرض نص الملاحظة، سطر "ملاحظات فردية" في لوحة ملخص كامل الفم، وتضمينها في تقرير PDF، تصدير/استيراد JSON
- 🔀 فصل مخطط الحالة ↔ الخطة: مفتاح تبديل `Status | Plan` في رأس المخطط يبدّل بين مخطط **الحالة** الراهنة ومخطط **الخطة** (المعالجة المقصودة بعد العلاج)، ولكل منهما حالات أسنانه الخاصة؛ يبدأ مخطط الخطة كنسخة من الحالة عند أول تبديل إليه، ولا تؤثر التعديلات في أحد المخططين على الآخر أبدًا. يستهدف التصدير/الاستيراد (`exportStatus`/`exportFhir`/استيراد الملف) دائمًا مخطط الحالة؛ ويُقرأ/يُكتب مخطط الخطة بشكل منفصل عبر واجهته البرمجية الخاصة (انظر واجهة برمجة التطبيقات العامة أدناه) — وعند اختلافه عن الحالة، يُدرج كقسم إضافي `plan` في تصدير JSON
- 📝 مربع "ما الذي تغيّر": كلما اختلفت الخطة عن الحالة الراهنة، يسرد مربع أسفل لوحة معلومات السن كل فرق لكل سن ولكل محور معالجة (الوجود، النسيج الأساسي، الترميم، التركيبة، التاج المخطط له، التقويم، اللب/العلاج اللبي، القمة) كسطر بصيغة `tooth: axis  from → to`؛ ومتاح أيضًا برمجيًا عبر `getPlanChanges()`

![مخطط اللثة للفم الكامل (العربية)](screenshot_ar_perio.png)

- 🩺 تسجيل دواعم السن: **عمق الجيب**، و**الحافة اللثوية**، و**النزف عند السبر** (+ التقيّح) لكل موضع، في المواضع الستة القياسية لكل سن، مع **مستوى الالتصاق السريري المشتق (CAL = عمق الجيب + الحافة اللثوية)**، والانحسار، ونسبة **%BOP** لكامل الفم. **مخطط دواعم سن رسومي لكامل الفم** — يُرسم كل قوس كـ**رسمي SVG منفصلين، دهليزي وحنكي/لساني** (بإعادة استخدام رسوم الأسنان بتوجيه موحّد من التاج نحو الشريط في كلا الجانبين؛ مع **رسم زرعة** خاص لأسنان الزرعات) مع **خط CEJ** أحمر، و**شبكة توجيه مرقّمة بالمليمتر**، و**منحنى للحافة اللثوية/عمق الجيب** فوق الأسنان، مقسَّمة بواسطة **شريط مركزي لمؤشرات دواعم السن** (بعنوان `▲ Buccal … Lingual/Palatal ▼`) يحمل المؤشرات المشتركة لكل سن — **تصنيف ميلر** في الأعلى تمامًا، و**البلاك/PI/GI/mPI/mBI** تُعرض كـ**بلاطة معينية تشريحية** لكل سن (الرأس الدهليزي للأعلى، الرأس اللساني للأسفل، مع تبديل القريب من الوسط/البعيد عنه في الصف الأوسط حسب الجانب بحيث يشير القريب من الوسط دائمًا نحو منتصف القوس)؛ وصفوف الأرقام (بأسماء المؤشرات الكاملة — PD/GM/CAL/BOP + الحركة + تفرع الجذور — في خلايا أكبر وأكثر ملاءمة للمس) مصفوفة في أعمدة، مع ملخص (متوسط PD/CAL، %BOP، %PI)، وإدخال بـ**تقدم تلقائي عبر لوحة المفاتيح**؛ ويتمدد المخطط **ديناميكيًا ليملأ العرض المتاح**، ويستجيب لأي حجم نافذة. يُعرض كمفتاح تبديل عرض `Odontogram | Periodontal Status`، حيث تُعاد صياغة اللوحة اليمنى إلى **شريط جانبي سياقي لدواعم السن** (بيانات المريض، وتصنيف 2017، وملخص كامل الفم) طوال نشاط ذلك العرض (مع خيار في الإعدادات لإعادة كل العرض إلى **نافذة منبثقة**)، ويبقى أيضًا **مكونًا قابلًا للاستدعاء بشكل منفصل** (تصدير `PerioChart`) بحيث يمكن للتطبيق المضيف استدعاء مخطط دواعم السن بمعزل عن الأودونتوغرام الأساسي. تصدير **FHIR** لكل موضع عبر لوحة دواعم السن في LOINC (`74029-0`؛ PD `32910-2`، الانحسار `32911-0`، CAL `32912-8`)
- 🅿️ تنسيق مقترَح: في وضع الخطة، تُعرض النتائج التي **تضيفها** الخطة مقارنة بالحالة الراهنة (تاج مخطط له، خلع، حركة تقويمية، تركيبة، ...) بحدود خارجية متقطعة وملوَّنة مميزة تدل على أنها "مقترحة"، بحيث تُقرأ الخطة كنيّة لا كواقع — مع مفتاح توضيحي "متقطع = مقترَح" في بطاقة المخطط. يبقى العرض في وضع الحالة مطابقًا تمامًا بايتًا بايت؛ والمعالجة موجودة فقط في الخطة وتُعاد ضبطها بالكامل عند العودة إلى الحالة
- 🚦 تقييد وضع الخطة: يعرض مخطط الخطة فقط ما يمكن لطبيب الأسنان أن *يفعله* — يعرض المحدِّد الأساسي فقط مفقود / دائم / زرعة، وتُخفى النتائج الخاصة بالحالة فقط (النخر، بري السن، التصبّغ، وكامل قسم دواعم السن — الحركة، شبكة السبر بالمواضع الستة، تعديلات الالتهاب/دواعم السن، الجير، حالة ما حول الزرعة)؛ بينما يحتفظ عنصر التحكم باللب/العلاج اللبي بـ**معالجة** العلاج اللبي (قناة الجذر / الوتد / استئصال الذروة / الوتد المجاوز للُّب) مع إخفاء **تشخيص** اللب/القمة وامتصاص الجذر. يبقى كل من الترميم، والتركيبة، والتقويم، والحاجة إلى تاج/استبداله، وخطة الخلع قابلاً للتخطيط
- 🧪 نجاح 1746 اختبارًا آليًا (مع تخطي اختبار إضافي واحد) (Vitest) عبر 164 ملف اختبار (165 إجمالاً) تغطي الترقيم، والترجمات، والأنماط الجاهزة، والدعم متعدد اللغات، ومكوّن App، والسمة، واللمس، والإضافات، وإمكانية الوصول، وتكافؤ محاور التشخيص/المحاور السريرية
- 📖 توثيق واجهة برمجة تطبيقات بواسطة TypeDoc مع تعليقات JSDoc على جميع الصادرات العامة (`npm run docs`)

### 📦 الوحدات
- 🦷 شبكة الأودونتوغرام وواجهة بلاطات الأسنان
- 🎛️ عناصر التحكم ولوحة الحالة
- 🎨 محرك طبقات SVG والقوالب
- 🔢 ترقيم الأسنان وربط التسميات (FDI/العالمي/بالمر)
- 🌐 الترجمة والتوطين (HU/EN/DE/ES/IT/SK/PL/RU/PT-BR)
- 💾 تصدير/استيراد الحالة
- 📋 إضافات الحالة: قوالب ترميم جاهزة مسبقًا
- 🎨 إعدادات السمة: لوحة ألوان قابلة للتخصيص عبر خصائص CSS من نوع `--odon-*`
- 📱 تفاعلات لمس للجوال (تكبير باللمس، الضغط المطوّل، التكبير بالقرص، تبديل القوس)
- 🔌 نظام إضافات SVG مخصص
- ⚠️ نظام تحقق من الحالة والتلميحات
- ♿ إمكانية الوصول عبر لوحة المفاتيح ودعم ARIA
- 🔒 وضع القراءة فقط
- ✨ رسوم متحركة للتحديد
- 📝 نظام ملاحظات لكل سن
- 🧪 مجموعة اختبارات آلية (Vitest + Testing Library)

### 🛠️ عناصر التحكم في الواجهة

**🔝 الشريط العلوي:**
- مبدّل اللغة (قائمة منسدلة HU/EN/DE/ES/IT/SK/PL/RU/PT-BR)
- زر تبديل الوضع الداكن (أيقونة شمس/قمر، يبدّل بين السمة الفاتحة والداكنة)
- مبدّل نظام الترقيم (قائمة منسدلة FDI/العالمي/بالمر)
- زرا تصدير الحالة / استيراد الحالة

**📊 رأس المخطط:**
- مفتاح تبديل المنظر الإطباقي
- مفتاح تبديل إظهار أسنان العقل
- مفتاح تبديل إظهار العظم
- مفتاح تبديل إظهار اللب
- زر مسح التحديد

**🔍 مرشحات التحديد:**
- تحديد الكل / كل الموجود / الدائم / اللبني / الزرعات / كل المفقود
- تحديد العلوي / الأمامي العلوي 6 / أضراس علوية
- تحديد السفلي / الأمامي السفلي 6 / أضراس سفلية

**📋 أنماط الحالة الجاهزة:**
- إعادة ضبط الكل (إعادة ضبط الفم)
- تسنين لبني
- تسنين مختلط
- مفتاح تبديل انعدام الأسنان

**📦 قائمة إضافات الحالة المنسدلة:**
- جسور زركونيا علوية/سفلية (12-22، 13-23، 16-26، قوس كامل)
- جسور معدنية علوية/سفلية (12-22، 13-23، 16-26، قوس كامل)
- أطقم جزئية متحركة علوية/سفلية
- أطقم كاملة متحركة علوية/سفلية
- أطقم بار مع زرعات علوية/سفلية

**🦷 لوحة محرر السن** (للسن/الأسنان المحددة، مجمّعة في بطاقات قابلة للطي):
- **سطر أساسي:** تحديد السن (النوع الأساسي بما في ذلك أنماط التاج المكسور) ونسيج السن (طبيعي/جذر متبقٍّ/مكسور/مُجهَّز لتاج)
- **سطر الترميم:** القائمة المنسدلة المدمجة "Fix: …" / "Kivehető: …" للترميم (خيارات ثابتة لـ`restorationType`×`restorationMaterial` بالإضافة إلى خيارات تثبيت/تحريك `prosthesis`، مقيّدة حسب نوع السن)؛ خانة تسرب حافة التاج (تاج/جسر فقط)؛ خانات موقع التاج المكسور؛ مفاتيح الحاجة إلى تاج / الحاجة إلى استبدال تاج
- **سطر البري والتصبّغ:** قائمة منسدلة لنوع بري القاطع/الإطباقي، قائمة منسدلة لنوع البري العنقي، قائمة منسدلة لسبب التصبّغ (يتحول كل منها إلى مفتاح بسيط نعم/لا ضمن الإعدادات ← تفاصيل السن ← الوضع البسيط)
- **بطاقة التقويم:** الجهاز، الانزياح القريب من الوسط/البعيد عنه، الحركة العمودية (بروز/انغراس)، مفتاح الدوران — تظهر على سن طبيعي موجود
- **بطاقة النخر:** قائمة منسدلة لوضع عمق النخر، خانة نخر تحت التاج، قائمة منسدلة لشدة نخر الجذر، ومحدِّد أسطح النخر B/M/O/D/L مع نافذة منبثقة سياقية لعمق ICDAS/CARS وشارة للعمق الشعاعي
- **بطاقة الحشوات:** قائمة منسدلة لمادة الحشو، محدِّد حشو لكل سطح (مع مادة لكل سطح)، مؤشر عيب حشو لكل سطح (هامشي/كسر/بري)، ملاحظات تنبيهية للنخر الثانوي وعيب الحشو
- **بطاقة الجذر ودواعم السن:** المحدِّد المدمج لحالة اللب/العلاج اللبي، محدِّد التشخيص القمي، محدِّد النوع الفرعي للآفة حول الذروة (التهاب دواعم السن القمي العرَضي/اللاعرَضي فقط)، محدِّد نوع امتصاص الجذر، محدِّد درجة الحركة، محدِّد حالة ما حول الزرعة (للزرعات فقط)
- **مؤشرات خاصة:** خطة/جرح الخلع، فراغ مغلق بعد الفقد، إغلاق الشقوق، فقدان نقطة التماس، الجير، الوتد المجاوز للُّب، استئصال الذروة، دعامة الجسر

### 🦷 أنواع الأسنان والحالات

**تحديد السن (النوع الأساسي):**
| القيمة | الوصف |
|---|---|
| `none` | سن مفقود |
| `tooth-base` | سن دائم |
| `milktooth` | سن لبني (مؤقت) |
| `implant` | زرعة سنية |
| `tooth-under-gum` | سن تحت اللثة (لم يبزغ) |

**أنماط السن المكسور:**
`tooth-broken-inicisal`, `tooth-broken-distal-inicisal`, `tooth-broken-distal`, `tooth-broken-mesial-distal-inicisal`, `tooth-broken-mesial-distal`, `tooth-broken-mesial-inicisal`, `tooth-broken-mesial`, `no-tooth-after-extraction`

**نسيج السن الأساسي (الأسنان الدائمة):**
`natural` (الافتراضي)، `radix` (جذر متبقٍّ)، `broken` (مكسور)، `crownprep` (مُجهَّز لتاج)

**نوع الترميم (الأسنان الدائمة):**
`none`, `crown`, `inlay`, `onlay` (بمنظر إطباقي فقط), `veneer`, `bridge`

**مادة الترميم (الأسنان الدائمة):**
`none`, `emax`, `gold`, `gradia`, `zircon`, `metal`, `metal-ceramic` (تُرحَّل إليها تاجات `metal` القديمة), `telescope`, `temporary`

**خيارات الترميم مقيّدة حسب نوع السن** (الدالة `restorationOptions()` في `src/registry/restorations.ts`): تعرض الزرعة فقط أنواع ترميم `crown`/`bridge` (مركبة مع طبقة موصل زرعة) بالإضافة إلى مدخلات `prosthesis` الخمسة أدناه؛ ويعرض السن المفقود/الفراغ فقط وسيط جسر `bridge` بالإضافة إلى مدخلي `prosthesis` للأطقم المتحركة؛ ويُخفي نسيج `radix` عنصر التحكم بالترميم تمامًا. الحقلان المسطّحان القديمان `crownMaterial`/`bridgeUnit` (قيم تثبيت الزرعة/الجسر من قبل الإصدار v1.14) أُلغيا من النموذج الحيّ — ولا يُقبلان إلا كمسار ترحيل للقراءة فقط للحمولات القديمة.

**التركيبة** (`prosthesis`؛ محور تحريك/تثبيت متعامد، يظهر كمدخلات "Kivehető:" في القائمة المنسدلة المدمجة للترميم):
`none`, `healing-abutment`, `locator`, `locator-denture`, `bar`, `bar-denture` (تثبيتات على الزرعة، مع أو بدون طقم علوي)، `removable-partial`, `removable-full` (أطقم مدعومة بالأسنان على سن مفقود/فراغ). يحمل السن إما ترميمًا ثابتًا أو تركيبة، لا كليهما أبدًا — فضبط أحدهما يمسح الآخر.

**تسرب حافة التاج** (`crownLeakage`؛ منطقية): تظهر فقط عندما يكون `restorationType` مساويًا لـ`crown` أو `bridge`؛ وتُفعِّل طبقة الرسم `crown-leakage`.

**خيارات العلاج اللبي (الأسنان الدائمة):**
`none`, `endo-medical-filling`, `endo-filling`, `endo-filling-incomplete`, `endo-glass-pin`, `endo-metal-pin`

**خيارات العلاج اللبي (الأسنان اللبنية):**
`none`, `endo-medical-filling`

يظهر `endo` و`pulpDx` عبر عنصر `<select>` واحد مدمج بعنوان "حالة اللب/العلاج اللبي" (مُجمَّع: لب حيوي مقابل معالَج/لبّي) وهما متنافيان — فاختيار خيار معالَج (`endo != none`) يعيد ضبط `pulpDx` إلى `normal`، واختيار تشخيص لب يعيد ضبط `endo` إلى `none`.

**مواد الحشو (الأسنان الدائمة):**
`amalgam`, `composite`, `gic`, `temporary`

**مواد الحشو (الأسنان اللبنية):**
`composite`, `gic`, `temporary`

**أسطح الحشو/النخر:**
`mesial`, `distal`, `buccal`, `lingual`, `occlusal`, `subcrown` (للنخر فقط)

**التعديلات:**
`inflammation` (حول الذروة)، `parodontal` (دواعم السن)، `mobility` (M1/M2/M3)

**نوع الآفة حول الذروة** (`periapicalType`؛ يحدد نوع رمز الآفة حول الذروة الفرعي، ويظهر فقط تحت التهاب دواعم السن القمي العرَضي/اللاعرَضي):
`none`, `granuloma`, `cyst` — خيارات للتسجيل؛ لا تزال القيمة القديمة `abscess` مقبولة/مخزَّنة لكنها لم تعد معروضة في المحدِّد، لأنها تكرر التشخيص القمي. عند الاستيراد تُحذف: تُدمج ضمن `apicalDx` إذا كان السن يحمل مُعدِّل الالتهاب، وإلا تُصفَّر إلى `none`

**تشخيص اللب** (وفق مصطلحات AAE؛ `pulpDx`):
`normal`, `reversible-pulpitis` (يعرض رمز لب مصغَّر), `irreversible-pulpitis`, `necrosis` — متنافٍ مع `endo`؛ يُطبَّع إلى `normal` عند معالجة السن بقناة الجذر

**تشخيص اللب باللاتينية العملية** (`pulpLatin`؛ يظهر في محدِّد اللب فقط عندما يكون `pulpDetailLevel` مساويًا لـ`latin`):
`none`, `pulpa-sana`, `hyperaemia-pulpae`, `pulpitis-acuta-serosa`, `pulpitis-acuta-purulenta`, `pulpitis-chronica-clausa`, `pulpitis-chronica-ulcerosa`, `pulpitis-chronica-hyperplastica`, `necrosis-pulpae`, `gangraena-pulpae`

**مستوى تفصيل اللب** (`pulpDetailLevel`، إعداد عام): `simple`, `aae` (الافتراضي), `latin` — يتحكم في مفردات اللب التي يعرضها المحدِّد

**التشخيص القمي** (`apicalDx`؛ يتحكم برمز الآفة حول الذروة):
`normal`, `symptomatic-apical-periodontitis`, `asymptomatic-apical-periodontitis`, `acute-apical-abscess`, `chronic-apical-abscess`, `condensing-osteitis`

**نوع امتصاص الجذر** (`resorptionType`):
`none`, `internal`, `external-cervical`

**حالة ما حول الزرعة** (`periImplant`؛ للزرعات فقط، وفق تصنيف الورشة العالمية 2018): يعيد `mucositis` استخدام رمز اللثة الدواعمي؛ ويضيف `peri-implantitis-*` طبقة `peri-implant-bone-loss` بعتامة متدرجة حسب الشدة (خفيف 0.4 / متوسط 0.7 / شديد 1.0). لم تعد الزرعات تعرض رمز الآفة حول الذروة (يُعبَّر عن التهابها عبر هذا المحور بدلًا من ذلك)، وتُخفى في الزرعات خانتا التعديل `mods` للالتهاب/دواعم السن:
`none`, `mucositis`, `peri-implantitis-mild`, `peri-implantitis-moderate`, `peri-implantitis-severe`

**شدة النخر** (`cariesSeverity`؛ حقل موحّد لكل سطح، من `0` إلى `6`): على سطح بلا حشو، تُقرأ كمقياس عمق النخر ICDAS (`superficial` / `dentin` / `deep`، أو رموز ICDAS II الخام من `0` إلى `6` عند ضبط `enableIcdas`) وتُفعِّل الطبقة الأولية `caries-{surface}`؛ وعلى سطح فيه حشو، تُقرأ كدرجة CARS مُسمّاة (`0` سليم … `6` تجويف واسع) وتُفعِّل بدلًا من ذلك طبقة `subcaries-{surface}` (النخر المتكرر) — ولا يكون السطح أوليًا ومتكررًا في آن واحد أبدًا

**نخر الجذر** (`rootCaries`؛ يفعِّل طبقة الرسم `caries-root` على سن موجود، بعتامة تعتمد على الشدة — `active` بعتامة 0.5 / `arrested` بعتامة 0.7 / `active-cavitated` بعتامة كاملة):
`none`, `active`, `arrested`, `active-cavitated`

**عمق النخر الشعاعي** (`radiographicDepth`؛ لكل سطح، مستقل عن مقياس الشدة البصري ICDAS/CARS المسمى `cariesSeverity`):
`none`, `E1`, `E2`, `D1`, `D2`, `D3`

**إعدادات درجة تفصيل النخر** (عامة): `secondaryCariesMode` (`simple`/`standard`/`full`، الافتراضي `standard`)، `rootCariesMode` (`simple`/`severity`، الافتراضي `simple`)، `radiographicDepthMode` (`off`/`threeLevel`/`detailed`، الافتراضي `off`)، `cariesDepthEnabled` (منطقية، الافتراضي `true`) — يختصر كل منها مقياسه إلى واجهة اختيار أبسط دون تغيير القيمة المخزَّنة

**مؤشرات خاصة:**
`crownNeeded`, `crownReplace`, `missingClosed`, `extractionPlan`, `extractionWound`, `bridgePillar`, `fissureSealing`, `contactMesial`, `contactDistal`, `endoResection`, `calculus`, `parapulpalPin`

**بري السن** (`wearEdge`, `wearCervical`؛ نوع سريري لكل موضع، مقيّد بسن أساسي + بلا ترميم + نسيج طبيعي؛ يُفعِّل الطبقتين الحاليتين `tooth-bruxism-wear`/`tooth-bruxism-neck-wear`):
`wearEdge`: `none`, `attrition`, `erosion` — `wearCervical`: `none`, `abrasion`, `abfraction`, `erosion`

**التصبّغ** (`discoloration`؛ سبب لكل سن، مقيّد بسن أساسي طبيعي أو لبني + بلا ترميم + نسيج طبيعي؛ يلوّن تعبئة تاج السن الطبيعي المعروض — دون إضافة SVG جديد):
`none`, `tetracycline`, `fluorosis`, `nonvital`, `extrinsic`, `other`

**عيب الحشو** (`fillingDefect`؛ لكل سطح، نتيجة على ترميم مباشر بمعزل عن النخر المتكرر — مقيّد بالأسطح الموجودة في `fillingSurfaceMaterials`؛ يُفعِّل طبقة الرسم `defect-{surface}`):
`none`, `marginal`, `fracture`, `wear`

**التقويم** (`orthoAppliance`, `orthoDrift`, `orthoVertical`, `orthoRotation`؛ لكل سن، مقيّد بسن طبيعي موجود — دائم أو لبني):
`orthoAppliance`: `none`, `bracket`, `band` — `orthoDrift`: `none`, `mesial`, `distal` — `orthoVertical`: `none`, `extrusion` (رمز سهم لأعلى), `intrusion` (رمز سهم لأسفل) — `orthoRotation`: منطقية

**إعدادات تفاصيل/ترميز السن** (إعدادات جلسة عامة، الإعدادات ← تفاصيل السن): `wearDetailLevel` و`discolorationDetailLevel` (`ToothDetailLevel`: `simple`/`complex`، الافتراضي `complex` — يعرض الوضع البسيط مفتاح نعم/لا بدل القائمة المنسدلة الكاملة للنوع/السبب، دون تعديل القيمة المخزَّنة) و`surfaceNotation` (`simple`/`full`، الافتراضي `full` — يتحكم فيما إذا كانت حروف/تسميات أسطح النخر/الحشو مراعية للموضع؛ انظر "ترميز أسطح مراعٍ للموضع" أعلاه)

### ⚙️ الإعدادات
تُفتح من أيقونة الترس في الشريط العلوي؛ وهي نافذة حوار ARIA من نوع `dialog` بتخطيط تبويبي محاصر للتركيز (Esc أو النقر خارج الخلفية للإغلاق، وأسهم لوحة المفاتيح للتنقل بين علامات التبويب). جميع الإعدادات هي حالة واجهة مستخدم على مستوى الجلسة فقط، ما لم يُذكر خلاف ذلك — ولا يعدّل أيٌّ منها بيانات كل سن أو حمولة التصدير.

- **عام:** نظام الترقيم (FDI/العالمي/بالمر)، اللغة، السمة الداكنة/الفاتحة، إظهار لوحة معلومات السن
- **اللوحات:** إظهار/إخفاء مستقل لبطاقة الحالات لكامل الفم وبطاقة التقويم (كلاهما مرئي افتراضيًا)
- **تفاصيل السن:** مستوى تفصيل البري ومستوى تفصيل التصبّغ (بسيط/معقد، كل منهما افتراضيًا معقد)، ترميز السطح (بسيط/كامل، الافتراضي كامل)
- **النخر:** مفتاح تقييم ICDAS II (`enableIcdas`)، مفتاح عمق النخر (`cariesDepthEnabled`)، درجة تفصيل نخر الجذر (`rootCariesMode`: بسيط/شدة)، درجة تفصيل النخر الثانوي/CARS (`secondaryCariesMode`: بسيط/قياسي/كامل)، درجة تفصيل العمق الشعاعي (`radiographicDepthMode`: إيقاف/ثلاث درجات/مفصّل) — دُمجت علامة التبويب المنفصلة سابقًا "النخر الثانوي" في هذه العلامة، مع تموضع عنصر تحكم CARS مباشرة أعلى العمق الشعاعي
- **اللب:** مستوى تفصيل اللب (`pulpDetailLevel`: بسيط/AAE/لاتيني عملي، الافتراضي AAE) — يتحكم في المفردات التي يعرضها محدِّد "حالة اللب/العلاج اللبي"؛ ويؤدي تغييره إلى تحديث ملخص كامل الفم وكل تلميح مفتوح مباشرة
- **الملاحظات:** تفعيل/تعطيل الملاحظات لكل سن (`enableNotes`)
- **دواعم السن:** مفاتيح إظهار/إخفاء لكل مؤشر من صفوف مخطط دواعم السن الستة عشر (`perioRowVisibility`، الافتراضي إظهار الكل)، مجمّعة إلى الجيب (PD/GM/CAL/BOP) / النظافة (البلاك/PI/GI) / المخاطية اللثوية (إظهار CEJ/تقعر الجذر/KG/GT) / الدعم (تفرع الجذور/الحركة/تصنيف ميلر) / ما حول الزرعة (mPI/mBI)، ولكل صف وصفه الخاص؛ بالإضافة إلى وضع أسماء مؤشرات مترجمة مقابل قياسية (`perioIndexNameMode`: `translated` افتراضيًا / `canonical` — اسم علمي إنجليزي/لاتيني ثابت يُعرض في كل لغات الواجهة). إعدادات على مستوى التطبيق فقط (تعكس `perioViewMode`) — لا تُسلسَل أبدًا، وتبقى التلميحات مترجمة في كلا الوضعين

### 🖼️ نظام قوالب SVG

**قوالب الأسنان** (في `src/assets/teeth-svgs/`):
| القالب | الأسنان التي تستخدمه |
|---|---|
| `11.svg` | 11, 12, 21, 22, 31, 32, 41, 42 (القواطع) |
| `13.svg` | 13, 23, 33, 43 (الأنياب) |
| `14.svg` / `14_occl.svg` | 14, 15, 24, 25, 34, 35, 44, 45 (الضواحك) |
| `16.svg` / `16_occl.svg` | 16, 17, 18, 26, 27, 28, 36, 37, 38, 46, 47, 48 (الأضراس) |

تُدار القوالب بزاوية 180 درجة للفك السفلي وتُعكس أفقيًا للجانب الأيسر.

**أيقونات SVG** (في `src/assets/icon-svgs/`):
`icon_8.svg` (أسنان العقل), `icon_gum.svg` (العظم), `icon_no_selection.svg` (مسح التحديد), `icon_occl.svg` (المنظر الإطباقي), `icon_pulp.svg` (اللب)

### 🔢 أنظمة الترقيم

**FDI (وفق ISO 3950):** الأسنان الدائمة 11-18، 21-28، 31-38، 41-48. الأسنان اللبنية 51-55، 61-65، 71-75، 81-85.

**العالمي (الولايات المتحدة):** الأسنان الدائمة مرقّمة من 1 إلى 32. الأسنان اللبنية بحروف من A إلى T.

**بالمر (زيجموندي-بالمر):** صيغة الربع + الموضع (مثل UR-1، LL-5). تستخدم الأسنان اللبنية حروفًا من A إلى E لكل ربع.

### 🚀 الاستخدام
التطوير:
```bash
npm install
npm run dev
```
البناء:
```bash
npm run build
```
المعاينة:
```bash
npm run preview
```

### 🔗 التكامل
يمكن تضمين هذا المكوّن في أي تطبيق React.
مثال:
```tsx
import App from "./App";

export default function Host(){
  return (
    <App
      language="en"
      onLanguageChange={(lang) => console.log(lang)}
      numberingSystem="FDI"
      onNumberingChange={(system) => console.log(system)}
      darkMode={false}
      onDarkModeChange={(dark) => console.log(dark)}
    />
  );
}
```

**تكامل الوضع الداكن:**
- **الوضع المستقل:** احذف خاصية `darkMode` — يدير المكوّن حالة السمة الخاصة به عبر زر التبديل في الشريط العلوي ويضيف/يزيل الفئة `.dark` على `<html>`.
- **الوضع المتحكَّم به:** مرّر `darkMode` و`onDarkModeChange` — يتحكم التطبيق الأصل بالسمة. يظل زر التبديل ظاهرًا لكنه يستدعي `onDarkModeChange` بدلًا من إدارة حالة داخلية. يكون التطبيق الأصل مسؤولًا عن إضافة/إزالة الفئة `.dark` على `<html>`.

**سمة مخصصة:**
```tsx
<App
  themeConfig={{
    colors: {
      accent: '#e74c3c',
      background: '#fafafa',
      text: '#222222',
    },
  }}
/>
```

**تكامل الإضافات:**
```tsx
import App, { type OdontogramPlugin, setPluginState } from "./App";

const myPlugin: OdontogramPlugin = {
  id: "implant-brand",
  label: { en: "Implant Brand", hu: "Implantátum márka" },
  layer: "overlay",
  renderSvg: (toothNo, _quadrant, state) => {
    if (!state) return null;
    return `<text x="16" y="60" font-size="6" fill="#3b7bff">${state}</text>`;
  },
};

<App plugins={[myPlugin]} />

// تعيين حالة الإضافة لسن معين:
setPluginState(11, "implant-brand", "Straumann");
```

### 🧪 الاختبار
```bash
npm run test           # تشغيل كل الاختبارات الـ1704 (مع تخطي اختبار إضافي واحد)
npm run test:watch     # وضع المراقبة
npm run test:coverage  # تقرير التغطية
```

### 📖 توثيق واجهة برمجة التطبيقات
```bash
npm run docs           # توليد توثيق TypeDoc داخل docs/
```

### 📡 واجهة برمجة التطبيقات العامة

**خصائص المكوّن:**

| الخاصية | النوع | الافتراضي | الوصف |
|---|---|---|---|
| `language` | `string` | `'hu'` | لغة الواجهة (hu/en/de/es/it/sk/pl/ru/pt-br) |
| `onLanguageChange` | `(lang) => void` | — | استدعاء عند تغيير اللغة |
| `numberingSystem` | `string` | `'FDI'` | نظام الترقيم (FDI/Universal/Palmer) |
| `onNumberingChange` | `(system) => void` | — | استدعاء عند تغيير نظام الترقيم |
| `darkMode` | `boolean` | `undefined` | حالة الوضع الداكن. احذفها للوضع المستقل. |
| `onDarkModeChange` | `(dark) => void` | — | استدعاء عند تبديل الوضع الداكن. مطلوب للوضع المتحكَّم به. |
| `themeConfig` | `OdontogramThemeConfig` | `undefined` | تجاوزات ألوان مخصصة عبر خصائص CSS المخصصة (`--odon-*`). |
| `plugins` | `OdontogramPlugin[]` | `undefined` | إضافات SVG مخصصة للتراكبات البصرية وحالة كل سن. |
| `readOnly` | `boolean` | `undefined` | تعطيل كل التفاعلات (نقر، لمس، لوحة مفاتيح). مفيد لعروض الطباعة/التقارير. |
| `enableNotes` | `boolean` | `undefined` | تفعيل الملاحظات لكل سن. نقر مزدوج على سن لإضافة/تعديل الملاحظات. |

**الدوال المُصدَّرة للتحكم الخارجي:**

| الدالة | الوصف |
|---|---|
| `initOdontogram()` | تهيئة المحرك ورسم كل الأسنان |
| `destroyOdontogram()` | تنظيف المحرك وإزالة مستمعي الأحداث |
| `setNumberingSystem(system)` | التبديل بين FDI والعالمي وبالمر |
| `clearSelection()` | إلغاء تحديد كل الأسنان |
| `setOcclusalVisible(on)` | تبديل إظهار المنظر الإطباقي |
| `setWisdomVisible(on)` | إظهار/إخفاء أسنان العقل |
| `setShowBase(on)` | إظهار/إخفاء طبقة العظم |
| `setHealthyPulpVisible(on)` | إظهار/إخفاء اللب السليم |
| `registerPlugins(plugins)` | تسجيل إضافات SVG مخصصة |
| `setPluginState(toothNo, pluginId, value)` | ضبط حالة إضافة مخصصة لسن معين |
| `getPluginState(toothNo, pluginId)` | قراءة حالة إضافة مخصصة لسن معين |
| `getToothStateSummary(toothNo)` | الحصول على ملخص مترجم لكل الحالات النشطة لسن معين |
| `getOdontogramSummary()` | الحصول على ملخص نصي منظَّم ومترجم لكامل المخطط (أعداد، أقسام) |
| `onStateChange(callback)` | الاشتراك في تغييرات الحالة؛ تُعيد دالة لإلغاء الاشتراك |
| `setReadOnly(value)` | تفعيل/تعطيل وضع القراءة فقط |
| `getReadOnly()` | قراءة حالة القراءة فقط الراهنة |
| `setNotesEnabled(value)` | تفعيل/تعطيل الملاحظات لكل سن |
| `getNotesEnabled()` | قراءة حالة تفعيل الملاحظات الراهنة |
| `setPulpDetailLevel(level)` | ضبط مفردات محدِّد اللب — `"simple"` أو `"aae"` أو `"latin"` |
| `getPulpDetailLevel()` | قراءة مستوى تفصيل اللب الراهن |
| `getChartMode()` | قراءة المخطط النشط حاليًا — `"status"` أو `"plan"` |
| `setChartMode(mode)` | تبديل المخطط النشط إلى `"status"` أو `"plan"`؛ يُنسخ مخطط الخطة نسخًا عميقًا من الحالة عند دخوله لأول مرة |
| `getStatusChart()` | الحصول على حمولة مخطط الحالة (`{version, globals, teeth}`)، بصرف النظر عن المخطط النشط حاليًا |
| `getPlanChart()` | الحصول على حمولة مخطط الخطة (`{version, globals, teeth}`)، بصرف النظر عن المخطط النشط حاليًا |
| `setPlanChart(payload)` | استبدال أسنان مخطط الخطة من حمولة معينة (تبقى الحالة دون مساس)؛ يُعلِّم مخطط الخطة كمُهيَّأ |
| `getPlanChanges()` | الحصول على فرق الحالة→الخطة المُنظَّم (`{ toothNo, axis, from, to }[]`) — إدخال واحد لكل سن ولكل محور معالجة يختلف بين مخططَي الحالة والخطة؛ فارغ عند عدم وجود خطة. يظهر أيضًا ضمن `getOdontogramSummary()` باسم `plannedChanges` |
| `setPerioSite(toothNo, site, patch)` | ضبط بيانات دواعم السن لأحد المواضع الستة (`patch` = `{ pd?, gm?, bop?, sup? }`)؛ القيمة `pd` بـ null أو أقل من 1 تلغي تسجيل الموضع. يتحقق من الصحة ويحدّ القيم (PD من 1 إلى 15، GM من −10 إلى +20) |
| `getToothPerio(toothNo)` | الحصول على سجل دواعم السن لكل موضع لسن معين (المواضع المسجَّلة فقط) |
| `getToothCal(toothNo)` | الحصول على مستوى الالتصاق السريري المشتق لكل موضع (`pd + الحافة اللثوية`) لسن معين |
| `getPerioSummary()` | مجاميع دواعم السن لكامل الفم: عدد المواضع المسجَّلة، عدد مواضع النزف، %BOP، أسوأ CAL، أقصى PD |
| `getPerioChart()` | الحصول على سجلات دواعم السن لكل سن في المخطط النشط |
| `PerioChart` | مكوّن React (صادر مسمّى) — تراكب مخطط دواعم السن لكامل الفم (`{ open, onClose }`)، قابل للتركيب بمعزل عن `OdontogramShell` لتكامل التطبيق المضيف |
| `openPerioOverlay()` / `closePerioOverlay()` / `isPerioOverlayOpen()` | فتح/إغلاق/استعلام برمجي عن تراكب مخطط دواعم السن — يتيح للتطبيق المضيف استدعاء مخطط دواعم السن بمعزل عن الأودونتوغرام الأساسي (بمشاركة حالة الحالة نفسها) |
| `getPerioViewMode()` / `setPerioViewMode(mode)` | قراءة/ضبط طريقة عرض مخطط دواعم السن — `"toggle"` (مفتاح تبديل عرض `Odontogram | Dental Chart`، الافتراضي) أو `"popup"` (التراكب) |
| `getPerioOverlayLayer()` / `setPerioOverlayLayer(layer)` | قراءة/ضبط تراكب تمييز مخطط الأسنان — `"none"` (الافتراضي) / `"pd"` / `"cal"` / `"gr"` / `"plaque"` / `"bop"` / `"pd5"` / `"pd6"` / `"cairo"`؛ يعيد تلوين الأسنان وفق ذلك المقياس (عرض فقط فوق البيانات الموجودة) |
| `getToothRecessionType(toothNo)` | الحصول على **نوع انحسار القاهرة (Cairo)** المشتق — `"none"` / `"rt1"` / `"rt2"` / `"rt3"` (يُحسب من مستوى الالتصاق السريري بين الحيّز الداخلي والدهليزي للسن) |
| `setCejVisibility(toothNo, v)` / `getCejVisibility(toothNo)` | إظهار CEJ لكل سن — `"none"` / `"detectable"` / `"not-detectable"` |
| `setRootConcavity(toothNo, v)` / `getRootConcavity(toothNo)` | تقعر سطح الجذر لكل سن — `"none"` / `"mild"` / `"deep"` |
| `setPlaqueIndex(toothNo, surface, grade)` / `getPlaqueIndex(toothNo, surface)` | درجة مؤشر البلاك سيلنس-لوي لكل سطح — من `0` إلى `3` |
| `setGingivalIndex(toothNo, surface, grade)` / `getGingivalIndex(toothNo, surface)` | درجة مؤشر اللثة لوي-سيلنس لكل سطح — من `0` إلى `3` |
| `setKeratinizedWidth(toothNo, mm)` / `getKeratinizedWidth(toothNo)` | عرض اللثة المتقرنة الدهليزية لكل سن بالمليمتر — من `0` إلى `15`، أو `null` إذا لم تُسجَّل |
| `setGingivalThickness(toothNo, v)` / `getGingivalThickness(toothNo)` | نمط سماكة اللثة لكل سن — `"unknown"` / `"thin"` / `"medium"` / `"thick"` |
| `setMillerClass(toothNo, v)` / `getMillerClass(toothNo)` | درجة انحسار ميلر لكل سن — `"none"` / `"i"` / `"ii"` / `"iii"` / `"iv"` |
| `setPeriImplantPlaque(toothNo, surface, grade)` / `getPeriImplantPlaque(toothNo, surface)` | للزرعات فقط — درجة مؤشر البلاك المعدَّل لمومبيلي (mPI) لكل سطح — من `0` إلى `3`؛ لا تأثير له على سن غير زرعة |
| `setPeriImplantBleeding(toothNo, surface, grade)` / `getPeriImplantBleeding(toothNo, surface)` | للزرعات فقط — درجة مؤشر نزف الأخدود المعدَّل لمومبيلي (mBI) لكل سطح — من `0` إلى `3`؛ لا تأثير له على سن غير زرعة |
| `furcationEntrances(toothNo)` | مداخل تفرع الجذور لسن معين — `["mesial","distal","buccal"]` (الأضراس العلوية)، `["buccal","lingual"]` (الأضراس السفلية)، `["mesial","distal"]` (الضواحك الأولى العلوية)، وإلا `[]` |
| `setFurcation(toothNo, entrance, grade)` / `getToothFurcation(toothNo)` | ضبط/قراءة إصابة تفرع الجذور لكل مدخل (درجة غليكمان من `1` إلى `4`؛ `null` تمسح القيمة) |
| `setPlaque(toothNo, surface, present)` / `getToothPlaque(toothNo)` | ضبط/قراءة وجود بلاك أوليري لكل سطح (قريب من الوسط/بعيد عنه/دهليزي/لساني)؛ يغذّي نسبة PI% لكامل الفم في `getPerioSummary()` |
| `getCaseMeta()` | الحصول على كائن البيانات الوصفية على مستوى الحالة (`{age, smokingStatus, cigarettesPerDay, diabetesStatus, hba1c, toothLossPerio, maxRblPercent, patientName, patientDob, examDate}`) — كتلة واحدة مشتركة، وليست لكل سن أو بحسب حالة مزدوجة (تعكس مفتاح الحمولة العلوي `globals`)؛ تغذّي تصنيف مراحل/درجات دواعم السن ورأس تقرير PDF |
| `setPatientName(v)` | ضبط اسم مريض الحالة (بعد إزالة المسافات؛ سلسلة فارغة أو `null` تمسحه) — بيانات هوية فقط، ولا تدخل أبدًا في اشتقاق دواعم السن |
| `setPatientDob(v)` | ضبط تاريخ ميلاد مريض الحالة (`YYYY-MM-DD`؛ القيمة غير الصالحة/الفارغة تمسحه) — بيانات هوية لتقرير PDF فقط |
| `setExamDate(v)` | ضبط تاريخ الفحص للحالة (`YYYY-MM-DD`؛ القيمة غير الصالحة/الفارغة تمسحه) |
| `setCaseAge(v)` | ضبط عمر مريض الحالة بالسنوات — من `0` إلى `120`، أو `null` للمسح |
| `setSmokingStatus(v)` | ضبط حالة التدخين للحالة — `"unknown"` / `"never"` / `"former"` / `"current"` |
| `setCigarettesPerDay(v)` | ضبط عدد السجائر يوميًا (ذو معنى فقط عندما تكون حالة التدخين `"current"`) — من `0` إلى `99`، أو `null` للمسح |
| `setDiabetesStatus(v)` | ضبط حالة السكري للحالة — `"unknown"` / `"none"` / `"present"` |
| `setHba1c(v)` | ضبط نسبة HbA1c% (ذو معنى فقط عندما تكون حالة السكري `"present"`) — من `3.0` إلى `20.0` (بمنزلة عشرية واحدة)، أو `null` للمسح |
| `setToothLossPerio(v)` | ضبط عدد الأسنان المفقودة بسبب التهاب دواعم السن — من `0` إلى `32`، أو `null` للمسح |
| `setMaxRblPercent(v)` | ضبط أقصى نسبة فقدان عظمي شعاعي% — من `0` إلى `100`، أو `null` للمسح |
| `resetCaseMeta()` | إعادة ضبط كائن البيانات الوصفية للحالة إلى قيمه الافتراضية الفارغة |
| `getPerioClassification()` | الحصول على تصنيف دواعم السن وفق الورشة العالمية 2017 (`{diagnosis, stage, grade, extent, derived, overridden}`) — يُشتق التشخيص/المرحلة/الدرجة/المدى من بيانات دواعم السن المسجَّلة والبيانات الوصفية للحالة، مع استبدال كل محور بتجاوز السريري عند ضبطه (تعرض `derived` دائمًا القيم المحسوبة غير المعدَّلة، وتحدد `overridden` المحاور التي جرى تجاوزها) |
| `setDiagnosisOverride(v)` | تجاوز تشخيص دواعم السن المشتق — `"health"` / `"gingivitis"` / `"periodontitis"`، أو `null` للمسح (العودة إلى القيمة المشتقة) |
| `setStageOverride(v)` | تجاوز مرحلة دواعم السن المشتقة — `"I"` / `"II"` / `"III"` / `"IV"`، أو `null` للمسح (العودة إلى القيمة المشتقة) |
| `setGradeOverride(v)` | تجاوز درجة دواعم السن المشتقة — `"A"` / `"B"` / `"C"`، أو `null` للمسح (العودة إلى القيمة المشتقة) |
| `setExtentOverride(v)` | تجاوز مدى دواعم السن المشتق — `"localized"` / `"generalized"` / `"molar-incisor"`، أو `null` للمسح (العودة إلى القيمة المشتقة) |
| `exportFhir(options?)` | تصدير المخطط كحزمة تجميعية HL7 FHIR R4 (تنزيل JSON). مرجع اختياري `{ subject }`؛ وإلا يُضمَّن مريض بديل مؤقت |
| `exportImage(format)` | تنزيل المخطط كصورة — `"png"` أو `"jpg"` |
| `exportSvg()` | تنزيل المخطط كملف SVG متجهي قابل للتحجيم |
| `hasAnyPerioData()` | `true` إذا كان أي محور من محاور دواعم السن مسجَّلًا في أي مكان في الفم — يتحكم في التخطي التلقائي لتصدير دواعم السن ويعطّل عناصر قائمة تصدير دواعم السن في مخطط فارغ |
| `exportPerioSvg()` | تنزيل مخطط دواعم السن الكامل (رسوم الأسنان + الصفوف الرقمية + تصنيف 2017) كملف SVG متجهي مستقل، يُبنى بلا واجهة مباشرة من الحالة عبر `buildPerioSvg()` |
| `exportPerioImage(format)` | تنزيل مخطط دواعم السن كصورة نقطية — `"png"` أو `"jpg"` |
| `exportPdf(opts)` | تنزيل تقرير PDF أصلي عبر jsPDF (`{patientData, odontogramChart, odontogramDescription, individualNotes, perioStatus, perioDescription}`، كل قسم اختياري) — نص متجهي بالإضافة إلى صور نقطية للأسنان/مخطط دواعم السن؛ يُتخطى قسم الملاحظات الفردية تلقائيًا عندما لا يحمل أي سن ملاحظة، ويُتخطى قسما دواعم السن تلقائيًا كلما كانت `hasAnyPerioData()` تساوي `false`، بصرف النظر عن `opts` |
| `importFhirBundle(input)` | استيراد حزمة FHIR R4 (كائن أو نص JSON) صادرة عن هذه الوحدة |
| `setImportFormat(format)` | ضبط المحلِّل المستخدَم للاستيراد التالي للملف — `"status"` أو `"fhir"` |
| `startIntroTour()` | إطلاق الجولة التعريفية التفاعلية من 12 خطوة |

### 💾 صيغة تصدير/استيراد الحالة
ينشئ التصدير ملف JSON (الإصدار `2.20`؛ لا تزال الاستيرادات تقبل الإصدارات القديمة `1.4` ومن `2.0` حتى `2.19` وتُرحَّل تلقائيًا) يحتوي على:

**الحقول العامة:**
- `wisdomVisible` - إظهار أسنان العقل
- `showBase` - إظهار طبقة العظم
- `occlusalVisible` - تفعيل المنظر الإطباقي
- `showHealthyPulp` - إظهار اللب السليم
- `edentulous` - تفعيل وضع انعدام الأسنان

**حقول لكل سن (32 سنًّا):**
- `toothSelection` - نوع السن الأساسي
- `toothSubstrate` - نسيج السن الأساسي (طبيعي/جذر متبقٍّ/مكسور/مُجهَّز لتاج)، مستقل عن أي ترميم
- `restorationType` - نوع الترميم (none/crown/inlay/onlay/veneer/bridge)
- `restorationMaterial` - مادة الترميم (emax/gold/gradia/zircon/metal/metal-ceramic/telescope/temporary)، مرتبطة بـ`restorationType`
- `prosthesis` - محور التحريك/التثبيت (none/healing-abutment/locator/locator-denture/bar/bar-denture/removable-partial/removable-full)، يتنافى مع `restorationType` الثابت من نوع تاج/جسر
- `crownLeakage` - علامة تسرب حافة التاج، ذات معنى فقط عندما يكون `restorationType` تاجًا أو جسرًا
- `endo` - الحالة اللبّية؛ تتنافى مع `pulpDx` (تُعرضان معًا عبر محدِّد واحد مدمج لحالة اللب/العلاج اللبي — معالجة السن تطبّع `pulpDx` إلى `normal`)
- `mods` - مصفوفة التعديلات (الالتهاب، دواعم السن)؛ أُلغي `inflammation` من الواجهة في الأسنان الموجودة (حيث يتحكم `apicalDx` بالرمز هناك) لكنه لا يزال ساريًا على الأسنان المفقودة/سنخ الخلع
- `caries` - أسطح النخر النشطة
- `cariesActiveDepth` - قيمة عمق ICDAS التي يحتفظ بها محدِّد عمق النخر عند تطبيق سطح جديد (ليست قيمة مخزَّنة لكل سطح؛ انظر `cariesSeverity` للحقل المخزَّن لكل سطح)
- `rootCaries` - شدة نخر الجذر (none/active/arrested/active-cavitated)
- `cariesSeverity` - شدة موحّدة لكل سطح (0-6): عمق ICDAS على سطح أولي (غير مملوء)، درجة CARS على سطح متكرر (مملوء)
- `radiographicDepth` - عمق النخر الشعاعي لكل سطح (none/E1/E2/D1/D2/D3)، مستقل عن المقياس البصري ICDAS/CARS
- `fillingMaterial` - مادة الحشو
- `fillingSurfaces` - الأسطح المحشوة
- `fillingSurfaceMaterials` - مادة الحشو لكل سطح (حشوات مختلطة، مثل أملغم دهليزي + كومبوزيت بعيد عن الوسط)
- `fillingDefect` - عيب الحشو لكل سطح (none/marginal/fracture/wear)، مقيّد بالسطح المحشو، مستقل عن النخر المتكرر
- `pulpDx` - تشخيص اللب وفق AAE (normal/reversible-pulpitis/irreversible-pulpitis/necrosis)؛ يعرض reversible-pulpitis رمزًا مصغَّرًا
- `pulpLatin` - النوع الفرعي للُّب باللاتينية العملية (يظهر في محدِّد اللب فقط عندما يكون `pulpDetailLevel` مساويًا لـ`latin`)
- `apicalDx` - التشخيص القمي الذي يتحكم برمز الآفة حول الذروة
- `periapicalType` - النوع الفرعي للآفة حول الذروة (none/granuloma/cyst)، يظهر فقط تحت التهاب دواعم السن القمي العرَضي/اللاعرَضي؛ لا تزال القيمة القديمة `abscess` مقبولة عند الاستيراد
- `resorptionType` - نوع امتصاص الجذر (none/internal/external-cervical)
- `periImplant` - حالة ما حول الزرعة للزرعات فقط (none/mucositis/peri-implantitis-mild/-moderate/-severe)، وفق تصنيف الورشة العالمية 2018
- `endoResection` - علامة استئصال الذروة
- `fissureSealing` - علامة إغلاق الشقوق
- `calculus` - علامة الجير
- `contactMesial` - فقدان نقطة التماس القريبة من الوسط
- `contactDistal` - فقدان نقطة التماس البعيدة عن الوسط
- `wearEdge` - نوع البري القاطعي/الإطباقي (none/attrition/erosion)
- `wearCervical` - نوع البري العنقي (none/abrasion/abfraction/erosion)
- `discoloration` - سبب التصبّغ لكل سن (none/tetracycline/fluorosis/nonvital/extrinsic/other)، يلوّن تعبئة تاج السن الطبيعي على سن أساسي/لبني طبيعي بلا ترميم
- `orthoAppliance` - جهاز التقويم (none/bracket/band)
- `orthoDrift` - انزياح التقويم (none/mesial/distal)
- `orthoVertical` - الحركة العمودية للتقويم (none/extrusion/intrusion)
- `orthoRotation` - علامة دوران التقويم
- `brokenMesial`, `brokenIncisal`, `brokenDistal` - مواقع الكسر
- `extractionWound` - جرح ما بعد الخلع
- `extractionPlan` - خلع مخطط له
- `parapulpalPin` - علامة الوتد المجاوز للُّب
- `bridgePillar` - سن دعامة الجسر
- `mobility` - درجة الحركة (none/m1/m2/m3)
- `crownNeeded` - مؤشر الحاجة إلى تاج
- `crownReplace` - مؤشر الحاجة إلى استبدال تاج
- `missingClosed` - فراغ مغلق بعد الخلع
- `customStates` - حالات مخصصة للإضافات (كائن، مفتاحه معرّف الإضافة)
- `note` - ملاحظة نصية لكل سن (نص، اختياري — يظهر فقط عند عدم كونه فارغًا)

**الحقل العلوي `plan` (من الإصدار 2.11 فصاعدًا):**
- `plan` - كائن اختياري، بنفس بنية `teeth` (الحقول لكل سن أعلاه)، يحمل مخطط **الخطة** (المعالجة المقصودة بعد العلاج). يظهر فقط عندما جرى تهيئة مخطط الخطة (تم التبديل عبر مفتاح `Status | Plan` إلى الخطة مرة واحدة على الأقل) وكان محتواه مختلفًا عن مخطط الحالة — أما التصدير المقتصر على الحالة فيحذفه كليًا ويبقى مطابقًا بايتًا بايت لتصدير سابق للإصدار 2.11 باستثناء رقم الإصدار. عند الاستيراد، يؤدي غياب `plan` إلى مسح/إلغاء تهيئة مخطط الخطة (ولا يُحيي أبدًا خطة قديمة من قبل الاستيراد)؛ ووجوده يستعيد مخطط الخطة إلى جانب الحالة. يمكن أيضًا قراءة/كتابة مخطط الخطة بمعزل عن التصدير/الاستيراد عبر `getPlanChart()`/`setPlanChart()` (انظر واجهة برمجة التطبيقات العامة أعلاه)، وتُعيد `getStatusChart()` دائمًا حمولة الحالة الأساسية بصرف النظر عن وضع المخطط النشط.

**الحقل العلوي `case` (من الإصدار 2.17 فصاعدًا، وموسَّع في 2.18 و2.19 و2.20):**
- `case` - كائن اختياري يحمل بيانات وصفية على مستوى الحالة (وليست لكل سن)، مشتركة بين مخططَي الحالة والخطة (يعكس مفتاح الحمولة العلوي `globals`). يُحذف عند الفراغ: يغيب كليًا عندما يكون كل حقل في قيمته الافتراضية، بحيث يبقى تصدير بلا بيانات حالة مطابقًا بايتًا بايت باستثناء رقم الإصدار. الحقول (يُحذف كل منها عند قيمته الافتراضية): `age`؛ `smokingStatus` (+ `cigarettesPerDay`)؛ `diabetesStatus` (+ `hba1c`)؛ `toothLossPerio`؛ `maxRblPercent`؛ تجاوزات السريري الأربعة لكل محور من تصنيف 2017 وهي `diagnosisOverride` / `stageOverride` / `gradeOverride` / `extentOverride`؛ و(من الإصدار 2.19) `patientName` / `examDate`؛ و(من الإصدار 2.20) `patientDob`. تغذّي هذه البيانات تصنيف مراحل/درجات دواعم السن ورأس تقرير PDF؛ وتُقرأ/تُكتب عبر `getCaseMeta()` ودوال `setCase*` (انظر واجهة برمجة التطبيقات العامة أعلاه). اسم المريض وتاريخ الميلاد وتاريخ الفحص بيانات هوية للمخطط فقط — وهي **ليست** جزءًا من تصدير FHIR.

### 🖨️ التصدير
إلى جانب تصدير الأودونتوغرام الخاص به بصيغة JSON للحالة / FHIR / PNG / JPG / SVG، يملك **مخطط دواعم السن** مسار تصدير خاصًا به:
- **SVG/PNG/JPG لدواعم السن:** ترسم `exportPerioSvg()` / `exportPerioImage("png"|"jpg")` مخطط دواعم السن الكامل (رسوم الأسنان + الصفوف الرقمية + تصنيف 2017) كملف SVG متجهي مستقل واحد (`buildPerioSvg()`)، بمعزل عن عنصر DOM الخاص بمكوّن `PerioChart` المُركَّب. تُعطَّل عناصر قائمة التصدير الثلاثة كلما كانت `hasAnyPerioData()` تساوي `false` (لا يوجد شيء متعلق بدواعم السن ليُصدَّر من مخطط فارغ).
- **تقرير PDF:** يفتح عنصر "PDF report…" في قائمة التصدير نافذة `ExportOptionsModal` — وهي حوار إعدادات (حقول اسم المريض وتاريخ الميلاد وتاريخ الفحص، مرتبطة مباشرة بالبيانات الوصفية للحالة، مع تاريخ فحص افتراضي هو اليوم الحالي؛ وخانات اختيار للأقسام: بيانات المريض، مخطط الأسنان، وصف مخطط الأسنان، الملاحظات الفردية — مُعطَّلة عندما لا يحمل أي سن ملاحظة — حالة دواعم السن، وصف دواعم السن) قبل استدعاء `exportPdf(opts)`. عند ترك حقول الهوية فارغة تُستخدم قيم بديلة ("John Doe" / "1980-01-01") بحيث ينجح التصدير دائمًا. يُجمَّع ملف PDF بشكل أصلي عبر jsPDF — نص متجهي بواسطة `.text()`، وصور نقطية للأسنان/مخطط دواعم السن بواسطة `.addImage()` — **دون الاعتماد على مكتبة svg2pdf.js**. يُتخطى قسم الملاحظات الفردية تلقائيًا عندما لا يحمل أي سن ملاحظة، ويُتخطى قسما دواعم السن تلقائيًا كلما كانت `hasAnyPerioData()` تساوي `false`، بصرف النظر عن خانات الحوار.
- **تقييد mPI/mBI حسب وجود زرعة:** لا تُعرض مؤشرات مومبيلي حول الزرعة (mPI/mBI) كصفوف إلا في قوس يحتوي على سن زرعة واحد على الأقل — سواء في مخطط دواعم السن الحي أو في تصديري SVG/PDF.
- اسم المريض وتاريخ الميلاد وتاريخ الفحص بيانات هوية للمخطط فقط (الحمولة `2.20`، إضافية) — وهي **ليست** جزءًا من تصدير FHIR.

### 📁 هيكل المجلدات
- `src/App.tsx` - غلاف الواجهة، عناصر تحكم الشريط العلوي، مبدّل اللغة/الترقيم/الوضع الداكن/السمة/الإضافات
- `src/odontogram.ts` - محرك طبقات SVG، إدارة حالة الأسنان، تفاعلات اللمس، تراكبات الإضافات، ربط الواجهة
- `src/plugin.ts` - نوع `OdontogramPlugin`، `PluginLayer`، الدالة `getQuadrant()`، أولويات z-index في `LAYER_Z`
- `src/theme.ts` - نوع `OdontogramThemeConfig` والأداة المساعدة `applyThemeConfig()`
- `src/status_extras.ts` - 34 قالب ترميم جاهزًا مسبقًا (جسور، أطقم، تراكيب بار)
- `src/i18n/` - الترجمات (HU/EN/DE/ES/IT/SK/PL/RU/PT-BR) وخطاف الترجمة
- `src/utils/numbering.ts` - تحويل الترقيم بين FDI والعالمي وبالمر
- `src/registry/` - سجل تصريحي لمحاور الحالة السريرية: ربط حقول FHIR، تفعيل مجموعة SVG الواضحة/العلامات المنطقية، مصفوفة نوع×مادة الترميم، قوائم خيارات الواجهة (مصدر وحيد للحقيقة يولّد التصدير/الاستيراد وFHIR وواجهة المحدِّدات)
- `src/fhir/` - تصدير/استيراد HL7 FHIR R4: `toFhir.ts`/`fromFhir.ts`، أنظمة الترميز، ربط الحقول، الأنواع الأولية
- `src/bridgeOverlay.ts` - تراكب موصل امتداد الجسر متعدد الأسنان (هندسة سرج مراعية لشكل القوس)
- `src/SettingsModal.tsx` - نافذة إعدادات بعلامات تبويب (عام/اللوحات/تفاصيل السن/النخر/اللب/الملاحظات/دواعم السن)
- `src/perioExport.ts` - `buildPerioSvg()`: مخطط دواعم السن الكامل كملف SVG متجهي مستقل واحد
- `src/perioPdf.ts` - مُجمِّع تقرير jsPDF النقي الخاص بـ`exportPdf()` (الدالة `assemblePdf`)
- `src/ExportOptionsModal.tsx` - حوار إعدادات التصدير الخاص بعنصر "PDF report…"
- `src/__tests__/` + `src/registry/__tests__/` - مجموعة اختبارات Vitest (1704 اختبارًا ناجحًا، مع تخطي اختبار واحد، عبر 163 ملفًا)
- `src/assets/teeth-svgs/` - قوالب أسنان SVG (6 ملفات: القواطع، الأنياب، الضواحك، الأضراس + مناظر إطباقية)
- `src/assets/icon-svgs/` - أيقونات SVG لشريط الأدوات (5 ملفات)

### ⚙️ حزمة التقنيات
- React 18 + Vite + TypeScript
- Tailwind CSS لتنسيق الواجهة
- طبقات SVG عبر معالجة DOM (حالة غير مرتبطة بـReact لأجل الأداء)
- نظام ترجمة داخلي خفيف الوزن
- Vitest + Testing Library للاختبارات الآلية
- TypeDoc لتوثيق واجهة برمجة التطبيقات
- اسم مستعار لمسار Vite: `@` يشير إلى `./src`

### 📝 ملاحظات
- تُحمَّل قوالب SVG من `src/assets/teeth-svgs` و`src/assets/icon-svgs`، لذا يجب أن يخدم الاستضافة الثابتة المجلد العام.
- يستخدم محرك الأودونتوغرام حالته الداخلية الخاصة (وليست حالة React) لأجل الأداء والبساطة.
- تملك الأسنان اللبنية مجموعة مواد متاحة مخفَّضة (لا حشوات أملغم، ولا علاج لبّي بوتد).
- تملك أسنان الزرعات مجموعة خيارات تاج/دعامة مختلفة عن الأسنان الطبيعية.

### 📖 كيفية الاستشهاد

إذا استخدمت هذه الوحدة في عملك، يُرجى الاستشهاد بها.

**هذا الإصدار (v1.49.0):**
> Dul, Z. (2026). *React Advanced Odontogram* (v1.49.0). Zenodo. https://doi.org/10.5281/zenodo.21156787

**كل الإصدارات (معرّف DOI المفاهيمي):** https://doi.org/10.5281/zenodo.21156787

> يشير معرّف DOI المفاهيمي أعلاه، الشامل لكل الإصدارات، دائمًا إلى أحدث
> إصدار مؤرشف؛ ويُصدَر معرّف DOI خاص بكل إصدار عند أرشفته على Zenodo.
> وإلى حين أرشفة الإصدار v1.49.0، يُرجى الاستشهاد به عبر معرّف DOI المفاهيمي.

البيانات الوصفية للاستشهاد القابلة للقراءة الآلية موجودة في [`CITATION.cff`](../CITATION.cff).
