# حُمرَة. جُزْس ديب ديف: كيف تعمل وكيف تمددها؟

<!--category-- Mermaid, JavaScript, SVG, Diagrams -->
<datetime class="hidden">2025-11-09T16:00</datetime>

# أولاً

> ملاحظة: هذا جزء من تجاربي مع AI/ طريقة لإنفاق 1000 دولار كرمز ائتمانات الويب. لقد أطعمت هذه مجموعة من الأوراق، فهمي، أسئلة كان علي توليد هذه المقالة. إنها ممتعة وتملأ فجوة لم أرها ملأها في أي مكان آخر.

> **ويستند هذا المقال إلى مواد سابقة:** إذا لم تكن قد فعلت بالفعل، تحقق من [إضافة حوريّة. js مع](/blog/mermaidandhtmx), [مُدِّر المواضيع للمُحْرَمَة](/blog/switchingthemesformermaid)، و ، ، ، ، ، ، ، ، ، ، ، [تعزيز حورية الحورية مع البان/الزوم والتصدير](/blog/enhancingmermaiddiagramswithpanzoomandexport)هذا الغوص العميق يفسّر الداخليات وراء تلك التنفيذات.

حورية البحر. js رائعة حقاً. اكتب نصاً بسيطاً ، احصل على رسوم بيانية جميلة. لا مزيد من التعثر مع Visio أو رسم.io ، فقدان ملفات المصدر ، أو الحفاظ على ملفات صور منفصلة. كل شيء يعيش في علامة ، تحكم النسخة جنباً إلى جنب مع رمزك.

ولكن أردت أن أعرف *كيف* في الواقع يعمل تحت الغطاء. كيف يفعل هذا:

```mermaid
graph LR
    A[Text] --> B[Magic?]
    B --> C[Beautiful Diagram]
```

و الأهم من ذلك، كيف يمكنك ربطه به لإضافة سمات مثل بان/زوم، التبديل المواضيعي، و خاصية التصدير التي بنيتها لهذا الموقع (متاحة الآن كما يلي: [@medorlymedlyluccid/memed-enhancements](https://www.npmjs.com/package/@mostlylucid/mermaid-enhancements))?

بعد الكثير من البحث من خلال شفرة مصدر حورية البحر وبناء الامتدادات الحقيقية، هنا كل شيء تعلمته عن كيفية عمل حورية البحر داخليا وكيفية توسيعه بشكل صحيح.

[TOC]

# ما هو (ميرميدج) ؟

تقوم حورية البحر بتحويل تعاريف النص إلى رسوم بيانية. فكر في "ماركداون للرسميات."

**الطريقة القديمة:**

1. 
2. 
3. كصادرات
4. مُخْطَطَة في الطُّقق
5. ابحث المصدر ملفّ حرّر إعادة تصدير استبدل صورة...

**طريقة الحورية:**

1. 
2. م أنجز

تحديث الإيطالية فقط حرّر نص النسخة تحكم هو فقط نص يعمل بوصة هدف? نعم!

## 

تدعم الحوريات عدداً سخيفاً من أنواع الرسوم البيانية:

```mermaid
graph LR
    A[Flowcharts] --> B[Sequence Diagrams]
    B --> C[Class Diagrams]
    C --> D[State Diagrams]
    D --> E[ER Diagrams]
    E --> F[Gantt Charts]
    F --> G[Pie Charts]
    G --> H[Git Graphs]
    H --> I[User Journeys]
    I --> J[And many more...]
```

انظر S انظر [« فآ » م](https://mermaid.js.org/intro/) للقائمة الكاملة.

# كيف تعمل الحَمَمَة : الخط

هذا ما يحدث عندما تقوم حورية البحر بتقديم رسم بياني:

```mermaid
graph TD
    A[Text Definition] --> B[Lexer/Tokenizer]
    B --> C[Parser]
    C --> D[AST Built]
    D --> E[Diagram Type Detected]
    E --> F[Type-Specific Renderer]
    F --> G[SVG Generated]
    G --> H[Inserted into DOM]
    H --> I[Your Enhancements Run]

    style A stroke:#059669,stroke-width:3px,color:#10b981
    style D stroke:#2563eb,stroke-width:3px,color:#3b82f6
    style G stroke:#7c3aed,stroke-width:3px,color:#8b5cf6
    style I stroke:#d97706,stroke-width:3px,color:#f59e0b
```

دعونا نكسر كل خطوة.

## الخطوة 1: النص التعريف

يبدأ كل شيء بالنص. تكتب الرسوم البيانية في DSL (اللغة الخاصة بالمجال):

```javascript
// Flowchart
const diagram = `
graph TD
    A[Start] --> B{Is it working?}
    B -->|Yes| C[Great!]
    B -->|No| D[Debug time]
`;
```

## الخطوة 2: التحليل البرمجي

الـ elder يكسر نص بوصة رمزيّات. على سبيل المثال، هذا سطر:

```
A[Start] --> B{Decision}
```

مثل:

```javascript
[
    { type: 'NODE_ID', value: 'A' },
    { type: 'NODE_TEXT', value: 'Start' },
    { type: 'ARROW', value: '-->' },
    { type: 'NODE_ID', value: 'B' },
    { type: 'NODE_TEXT', value: 'Decision' },
    { type: 'NODE_SHAPE', value: 'diamond' }  // from { }
]
```

## الخطوة 3: التنازل والجيل

يستهلك المحلل الرسومات ويبني شجرة لصياغة الملخصات (AST):

```javascript
// Simplified AST structure
{
    type: 'flowchart',
    direction: 'TD',
    nodes: [
        { id: 'A', text: 'Start', shape: 'rect' },
        { id: 'B', text: 'Decision', shape: 'diamond' }
    ],
    edges: [
        { from: 'A', to: 'B', type: 'arrow' }
    ]
}
```

تستخدم حورية الحورية حوريات مختلفة لـ كل نوع تخطيطي. هذه غالباً ما يتم توليدها من الملفات التي تستخدم [J](https://github.com/zaach/jison) (مثل Yacc/Bison for JavaScript).

## الخطوة 4: المخطط

تقوم الحورية بكشف نوع الرسم البياني من السطر الأول:

```javascript
// Simplified detection logic
if (text.match(/^\s*graph/)) return 'flowchart';
if (text.match(/^\s*sequenceDiagram/)) return 'sequence';
if (text.match(/^\s*classDiagram/)) return 'class';
// ... etc
```

## خطوة 5: خطوة خطوة 5: منح

ولكل نوع من أنواع الرسوم البيانية مُصَنِّع خاص به. يأخذ المُعَدِّل AST ويولِّد عناصر SVG.

فيما يتعلق بتدفقات الصور التجارية، تستخدم حَرِمَة الحَرْمَمَة [](https://github.com/dagrejs/dagre) لمكتبة تخطيط الرسوم البيانية. بالنسبة للآخرين، تستخدم خوارزميات مخصصة أو مكتبات مثل Cytoscape.

```javascript
// Simplified flowchart renderer
export const draw = function (text, id, version, diagObj) {
    const graph = diagObj.db;  // The AST
    const svg = d3.select(`#${id}`);

    // Render nodes
    graph.getVertices().forEach(vertex => {
        drawNode(svg, vertex);
    });

    // Render edges
    graph.getEdges().forEach(edge => {
        drawEdge(svg, edge);
    });

    // Apply layout algorithm
    dagre.layout(graph);
};
```

## الخطوة 6: توليد SVG

المُجَرِّر يُنتِج رَمْز SVG:

```xml
<svg xmlns="http://www.w3.org/2000/svg">
    <g class="node">
        <rect x="0" y="0" width="100" height="50"/>
        <text x="50" y="25">Start</text>
    </g>
    <g class="edge">
        <path d="M 100 25 L 200 25" stroke="#333"/>
    </g>
</svg>
```

## الخطوة 7: إدراج

المُحْوَلَة تُفِد كُل `.mermaid` ويستبدلها بـ SVG translated SVG:

```javascript
// From mermaid.ts
export const init = async function (config, nodes) {
    const nodesToProcess = nodes || document.querySelectorAll('.mermaid');

    for (const node of nodesToProcess) {
        const id = `mermaid-${Date.now()}-${Math.random()}`;
        const txt = node.textContent;

        const { svg } = await render(id, txt);
        node.innerHTML = svg;
    }
};
```

## الخطوة 8: مرحلة ما بعد المعالجة (حيث تدخل)

بعد إدخال الحوريّة SVG، يمكنك تعزيزها. هنا حيث كلّ مؤازراتي في:

- دالة البان/المازوم
- 
- القدرات التصديرية
- نقل السممة

المزيد حول هذا أدناه.

# مُمَدْدِد الحَحْمَة: نقاط التمدّد

الآن بما أننا نعرف كيف تعمل حورية البحر، دعونا نستكشف كيف نوسعها.

## الدالة

وأهم عملية تمديد أساسية هي التشكيلة التالية:

```javascript
import mermaid from 'mermaid';

mermaid.initialize({
    startOnLoad: true,
    theme: 'dark',
    securityLevel: 'loose',
    flowchart: {
        curve: 'basis',
        padding: 15
    }
});
```

## 2 - تكييف الموضوع

لقد غطيت هذا بشكل مكثف في [مُدِّر المواضيع للمُحْرَمَة](/blog/switchingthemesformermaid)لكن هذا هو التنفيذ الرئيسي:

### المشكلة مع مُحوِّل الموضوع

و لا يمكنك تغييره بعد ذلك. ولكن إذا أردت إعادة إدخال الرسوم التخطيطية مع سمة جديدة، تحتاج إلى مصدر الرسم الأصلي - أي حورية *لا يخزن في DOM*.

### الإحلال

يخزن المحتوى الأصلي قبل التصريف، ثم يسترجع ويعاد الاسترجاع عند التبديل

```javascript
// From my theme-switcher implementation
const originalData = new Map();

// Save original content before first render
const saveOriginalData = async () => {
    const elements = document.querySelectorAll('.mermaid');
    elements.forEach(element => {
        const id = element.id || `mermaid-${Date.now()}`;
        element.id = id;

        // Store the original diagram source
        if (!originalData.has(id)) {
            originalData.set(id, element.textContent?.trim());
        }
    });
};

// When theme changes, restore and re-render
const loadMermaid = async (theme) => {
    mermaid.initialize({
        startOnLoad: false,
        theme: theme
    });

    const elements = document.querySelectorAll('.mermaid');
    for (const element of elements) {
        const source = originalData.get(element.id);
        if (source) {
            element.innerHTML = '';  // Clear
            element.removeAttribute('data-processed');

            const { svg } = await mermaid.render(
                `mermaid-svg-${element.id}`,
                source
            );
            element.innerHTML = svg;
        }
    }
};
```

**طرق الكشف عن مواضيع متعددة** (المواقع التي تعالج فيها المواضيع بشكل مختلف):

```javascript
function detectTheme() {
    // Check various sources
    if (typeof window.__themeState !== 'undefined') {
        return window.__themeState;
    }
    if (localStorage.theme) {
        return localStorage.theme;
    }
    if (document.documentElement.classList.contains('dark')) {
        return 'dark';
    }
    if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        return 'dark';
    }
    return 'light';
}
```

انظر S انظر [كود مُزِّر الموضوع الكامل](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/src/js/memmaid_theme_switch.js) للتفاصيل.

## 3- تعزيزات ما بعد المناقصة

هنا حيث يحدث السحر الحقيقي. بعد أن تقوم حورية البحر بترجمة، يمكنك إضافة خصائص تفاعلية.

لقد غطيت هذا بشكل مكثف في [تعزيز حورية الحورية مع البان/الزوم والتصدير](/blog/enhancingmermaiddiagramswithpanzoomandexport)لذا سأسلط الضوء على التقنيات الرئيسية هنا

### 

أنشئ حاوية غلاف للضوابط:

```javascript
function wrapDiagram(element) {
    if (element.closest('.mermaid-wrapper')) {
        return element.closest('.mermaid-wrapper');
    }

    const wrapper = document.createElement('div');
    wrapper.className = 'mermaid-wrapper';
    wrapper.id = `wrapper-${element.id}`;

    element.parentNode.insertBefore(wrapper, element);
    wrapper.appendChild(element);

    return wrapper;
}
```

### مضافاً بان/ زوم

& بوصة [Svg-pan- zoom](https://github.com/bumbu/svg-pan-zoom):

```javascript
import svgPanZoom from 'svg-pan-zoom';

const panZoomInstances = new Map();

function initPanZoom(svgElement, diagramId) {
    // Clean up existing instance
    if (panZoomInstances.has(diagramId)) {
        panZoomInstances.get(diagramId).destroy();
        panZoomInstances.delete(diagramId);
    }

    const instance = svgPanZoom(svgElement, {
        zoomEnabled: true,
        controlIconsEnabled: false,
        fit: true,
        center: true,
        minZoom: 0.1,
        maxZoom: 10
    });

    panZoomInstances.set(diagramId, instance);
    return instance;
}
```

### % مُنتفر المُنتفر

لا يمكن إنشاء هذا النظام:

```javascript
function createControlButtons(container, diagramId) {
    const controlsDiv = document.createElement('div');
    controlsDiv.className = 'mermaid-controls';

    const buttons = [
        { icon: 'bx-fullscreen', title: 'Fullscreen', action: 'fullscreen' },
        { icon: 'bx-zoom-in', title: 'Zoom In', action: 'zoomIn' },
        { icon: 'bx-zoom-out', title: 'Zoom Out', action: 'zoomOut' },
        { icon: 'bx-reset', title: 'Reset', action: 'reset' },
        { icon: 'bx-move', title: 'Pan', action: 'pan' },
        { icon: 'bx-image', title: 'Export PNG', action: 'exportPng' },
        { icon: 'bx-code-alt', title: 'Export SVG', action: 'exportSvg' }
    ];

    buttons.forEach(btn => {
        const button = document.createElement('button');
        button.className = `mermaid-control-btn bx ${btn.icon}`;
        button.setAttribute('data-action', btn.action);
        button.setAttribute('data-diagram-id', diagramId);
        controlsDiv.appendChild(button);
    });

    container.appendChild(controlsDiv);
}
```

### أي شيء حدث (الصفعة!)

لا ترفق المستمعين على كل زر. استخدم مصدر الحدث:

```javascript
document.addEventListener('click', (e) => {
    const target = e.target;
    if (!target.classList.contains('mermaid-control-btn')) return;

    const action = target.getAttribute('data-action');
    const diagramId = target.getAttribute('data-diagram-id');
    const panZoom = panZoomInstances.get(diagramId);

    switch (action) {
        case 'zoomIn': panZoom?.zoomIn(); break;
        case 'zoomOut': panZoom?.zoomOut(); break;
        case 'reset': panZoom?.reset(); break;
        // ... etc
    }
});
```

### 

**التحدي:** عناصر SVG لها خصائص ديناميكية، تحويلات شاملة/زومية، وأساليب موروثة. لكي يتم التصدير بشكل صحيح، تحتاج إلى:

1. مُنْقل الـSVG
2. _اخل
3. 
4. حوّل إلى PNG أو SVG

& بوصة [html إلى صورة](https://github.com/bubkoo/html-to-image):

```javascript
import { toPng, toSvg } from 'html-to-image';

async function exportDiagram(container, format, diagramId) {
    const svgElement = container.querySelector('svg');
    if (!svgElement) return;

    // Clone to avoid modifying original
    const clonedSvg = svgElement.cloneNode(true);

    // Get or calculate viewBox
    let viewBox = clonedSvg.getAttribute('viewBox');
    if (!viewBox) {
        const bbox = svgElement.getBBox();
        viewBox = `${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`;
        clonedSvg.setAttribute('viewBox', viewBox);
    }

    // Set explicit dimensions
    const [, , width, height] = viewBox.split(' ').map(Number);
    clonedSvg.setAttribute('width', width);
    clonedSvg.setAttribute('height', height);

    // Remove pan-zoom transforms
    clonedSvg.removeAttribute('style');

    // Create off-screen container
    const temp = document.createElement('div');
    temp.style.position = 'absolute';
    temp.style.left = '-9999px';
    temp.appendChild(clonedSvg);
    document.body.appendChild(temp);

    // Export
    const dataUrl = format === 'png'
        ? await toPng(clonedSvg, { pixelRatio: 2 })
        : await toSvg(clonedSvg);

    downloadFile(dataUrl, `diagram-${Date.now()}.${format}`);

    // Cleanup
    document.body.removeChild(temp);
}
```

**التفاصيل الجوهرية:**

- **دعم العرض** - تلتقط الرسم البياني الكامل، ليس فقط الجزء الظاهري
- **التــي عــد الت عــد الت عــل الت عــل الت** - تجنب التأثير على الرسم البياني المعروض
- **بكيكل الراتيثيو: 2** - كبار كبار كبار المسؤولين من أجل صادرات بابوا غينيا الجديدة

انظر S انظر [(رمز التصدير الكامل)](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/src/js/mermaid_enhancements.js#L148) لمزيد من التفاصيل.

# المجموعة الكاملة من عناصر التعزيز

لقد حزمت كل هذه التعزيزات [@medorlymedlyluccid/memed-enhancements](https://www.npmjs.com/package/@mostlylucid/mermaid-enhancements)انظر: [إدخالات مُحسنات مُنْشِشِشِر كحزمة Nnpm](/blog/publishingmermaidenhancementsnpm) لتفاصيل كاملة.

هذه هي الطريقة التي تنسجم بها مع بعضها البعض:

```mermaid
graph TB
    A[User Initializes] --> B[init Function]
    B --> C[initMermaid]
    B --> D[enhanceMermaidDiagrams]

    C --> E[Theme Detection]
    C --> F[Event Listeners]
    C --> G[Mermaid Rendering]

    E --> E1[Global State]
    E --> E2[LocalStorage]
    E --> E3[DOM Class]
    E --> E4[OS Preference]

    F --> F1[Custom Events]
    F --> F2[Media Query]

    G --> H[Apply Enhancements]
    D --> H

    H --> I[Wrap Diagrams]
    H --> J[Init Pan/Zoom]
    H --> K[Add Controls]

    I --> L[Interactive Diagram]
    J --> L
    K --> L

    L --> M[User Interactions]
    M --> M1[Zoom In/Out]
    M --> M2[Pan]
    M --> M3[Fullscreen]
    M --> M4[Export PNG/SVG]

    style A stroke:#059669,stroke-width:3px,color:#10b981
    style L stroke:#2563eb,stroke-width:3px,color:#3b82f6
    style M stroke:#7c3aed,stroke-width:3px,color:#8b5cf6
```

## 

```bash
npm install @mostlylucid/mermaid-enhancements
```

```typescript
import { init } from '@mostlylucid/mermaid-enhancements';
import '@mostlylucid/mermaid-enhancements/styles.css';

await init();
```

هذه هي! رسومات حورية البحر الخاصة بك الآن:

- الأمم المتحدة
- ● صندوق ضوئي كامل الفرز
- □ بابوا غينيا الجديدة/تصدير SVG
- □ تحوّل محور تلقائي
- التصميم الرجعي

# التكامل مع HTMX

كما أنا مغطى في [إضافة حوريّة. js مع](/blog/mermaidandhtmx)عليك إعادة تأريخ الحوريّة بعد مبادلة المحتوى HTMX:

```javascript
// On page load
document.addEventListener('DOMContentLoaded', function () {
    mermaid.initialize({ startOnLoad: true });
});

// After HTMX swaps content
document.body.addEventListener('htmx:afterSwap', function(evt) {
    mermaid.run();
});
```

مع حزمة التعزيزات:

```javascript
import { init, enhanceMermaidDiagrams } from '@mostlylucid/mermaid-enhancements';

// Initial load
await init();

// After HTMX swap
document.body.addEventListener('htmx:afterSwap', async function() {
    await init();  // Re-init Mermaid with current theme
    enhanceMermaidDiagrams();  // Re-apply enhancements
});
```

# أفضل الممارسات

بعد بناء هذه الأشياء وتصحيح حالات الحافة الغريبة، وهنا ما يعمل:

## 1 - يجب أن يكون المخزن الأصلي

الحوريّة لا تحافظ على مصدر الرسم التخطيطيّ الأصليّ بعد التخلّص منه، يجب أن تخزنه بنفسك:

```javascript
const originalData = new Map();

// Before first render
element.setAttribute('data-original-code', element.textContent);
originalData.set(element.id, element.textContent);

// When re-rendering
element.innerHTML = originalData.get(element.id);
```

## 2- حالات النظافة

تسربات الذاكرة حقيقية. تدمير الحالات قبل إنشاء حالات جديدة:

```javascript
if (panZoomInstances.has(id)) {
    try {
        panZoomInstances.get(id).destroy();
    } catch (e) {
        console.warn('Failed to destroy:', e);
    }
    panZoomInstances.delete(id);
}
```

## لا شيء

لا ترفق مستمعات إلى فرادى الأزرار:

```javascript
// ❌ Don't do this
buttons.forEach(btn => {
    btn.addEventListener('click', handler);
});

// ✅ Do this
document.addEventListener('click', (e) => {
    if (e.target.matches('.mermaid-control-btn')) {
        handleClick(e.target);
    }
});
```

## قاذفة قاذفة قاذفة قاذفة سحابة سحابة سحابة

المُحمّل الصاروخي يُؤخّر جافاScript تنفيذ. انتظر للمُتَوَقّعات:

```javascript
function waitForDependencies(maxAttempts = 50) {
    return new Promise((resolve) => {
        let attempts = 0;

        const check = () => {
            if (window.mermaid && window.htmx && window.Alpine) {
                resolve();
            } else if (attempts >= maxAttempts) {
                resolve();  // Give up
            } else {
                attempts++;
                setTimeout(check, Math.min(50 * Math.pow(1.2, attempts), 500));
            }
        };

        check();
    });
}
```

واستبعد نصك الرئيسي من تحميل Rocket:

```html
<script src="main.js" data-cfasync="false"></script>
```

## 5- التوقيت هو كل شيء

 `requestAnimationFrame` أفضل توقيتاً من التعسف `setTimeout`:

```javascript
// After Mermaid renders
await mermaid.run();

// Wait for paint before enhancing
await new Promise(resolve => {
    requestAnimationFrame(() => {
        requestAnimationFrame(() => {
            enhanceMermaidDiagrams();
            resolve();
        });
    });
});
```

## 6 - المناولة الدفاعية SVG

الـ SVGs يمكن أن تكون غريبة.

```javascript
const svgElement = container.querySelector('svg');
if (!svgElement) {
    console.warn('No SVG found');
    return;
}

// Clone before modifying
const cloned = svgElement.cloneNode(true);

// Ensure viewBox exists
let viewBox = cloned.getAttribute('viewBox');
if (!viewBox) {
    const bbox = svgElement.getBBox();
    viewBox = `${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`;
}
```

# م_ م_ م_ م_ م_ م_ م_ م_ م_ م_ م_ م_ م

## المُسند المُنتج المُنتج

مع التمهيد المناسب، يجب أن ترى:

```
Saving original data
Loading mermaid with theme: dark
Mermaid initialized
Enhanced 3 diagrams
```

## أولاً - المؤهلات

بعد التنفيذ:

- [ [المخططات التي يجري تقديمها في تحميل الصفحة
- [ العمل المتعلق بضوابط السيطرة على البان/الزوم
- [ (X، انقر خارج، ESC)
- [ رسوم بيانية كاملة
- [ [محافظات تصدير SVG
- [ [تعمل بعد مقايضة المحتوى HTMX
- [ / theme تحويل إعادة استخدامات بشكل صحيح / them en en them re- rethers بشكل صحيح
- [ *
- [ / / / / / / /  نمط نمط نمط نمط
- [ واو - إمكانية الاطلاع على المفتاح

## 

**الـمُشَكِّل:**

- 
- مُحمِل`window.mermaid`)
- 

**لا يعمل بان/زوم لا يعمل:**

- تحقق من Svg- an- zoom مسقط
- افحص لـ متضارب CSSS`pointer-events: none`)
- 

**المصدرات فقط زاوية:**

- حفظ
- نقل
- 1 م ع (ر م)

**السمة ليس التبديل:**

- لم يتم حفظ
- `data-processed` 
- المستمعون لأحداث غير مسجلون

# لجنة البلدان

## & التمهيد

لا تُحمِل التعزيزات قبل الحاجة:

```javascript
let enhancementsLoaded = false;

async function loadEnhancements() {
    if (enhancementsLoaded) return;

    const { enhanceMermaidDiagrams } = await import('./enhancements.js');
    enhanceMermaidDiagrams();
    enhancementsLoaded = true;
}

// Load on first interaction
document.addEventListener('click', (e) => {
    if (e.target.closest('.mermaid')) {
        loadEnhancements();
    }
}, { once: true });
```

## مراقب المراقبة

مُسندة مُسندة إلى مُنتَزَع:

```javascript
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            renderDiagram(entry.target);
            observer.unobserve(entry.target);
        }
    });
}, { rootMargin: '100px' });

document.querySelectorAll('.mermaid').forEach(el => {
    observer.observe(el);
});
```

## ثانياً - النفـفـس

عند إعادة تحجيم أو تغيير الموضوع:

```javascript
let timeout;
window.addEventListener('resize', () => {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
        panZoomInstances.forEach(instance => {
            instance.resize();
            instance.fit();
        });
    }, 250);
});
```

# في الإستنتاج

لكن فهم كيفية عملها داخلياً يسمح لك ببناء بعض التعزيزات الرائعة حقاً. الرؤى الرئيسية:

1. **جاري البحث**: النص / اليكسر / Parser / AST / Render / SVG
2. **نقاط الاتصال**الموضوع، المواضيع، تعزيزات ما بعد التقديم
3. **مجلد**الحوريّة لا تفعل ذلك من أجلك
4. ****:: أن تكون التسريبات في الذاكرة حقيقية
5. **لا شيء**:: تحسين الأداء
6. **مراس**: تُعالج المواقع مواضيع مختلفة عن بعضها البعض:
7. **المسائل**الاستخدام: الاستخدام: `requestAnimationFrame`

كل التقنيات التي غطيتها هنا تستخدم في الإنتاج في هذا الموقع [@medorlymedlyluccid/memed-enhancements](https://www.npmjs.com/package/@mostlylucid/mermaid-enhancements)المصدر الكامل متاح في [الناويـب اللـكـس غالبيـاً منهـا/معظمهـا من العارضات](https://github.com/scottgal/mostlylucidweb/tree/main/mostlylucid-mermaid).

## الوظائف المتصلة بها

- [إضافة حوريّة. js مع](/blog/mermaidandhtmx)
- [مُدِّر المواضيع للمُحْرَمَة](/blog/switchingthemesformermaid)
- [تعزيز حورية الحورية مع البان/الزوم والتصدير](/blog/enhancingmermaiddiagramswithpanzoomandexport)
- [إدخالات مُحسنات مُنْشِشِشِر كحزمة Nnpm](/blog/publishingmermaidenhancementsnpm)

## الموارد الخارجة عن

- [الوثائق](https://mermaid.js.org/)
- [حَجْب الحِين](https://github.com/mermaid-js/mermaid)
- [Svg-pan- zoom](https://github.com/bumbu/svg-pan-zoom)
- [html إلى صورة](https://github.com/bubkoo/html-to-image)
- [مجموعة تعزيزات مُعِرِم](https://www.npmjs.com/package/@mostlylucid/mermaid-enhancements)

جرب الضوابط على الرسوم البيانية في الأعلى!