@seliseblocks/mailcraft 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/DOCS.md +240 -12
  2. package/README.md +11 -3
  3. package/README.md.txt +134 -0
  4. package/dist/mailcraft-editor.bundle.js +51 -39
  5. package/dist/mailcraft-editor.bundle.js.map +3 -3
  6. package/examples/templates/order-confirmed.html +80 -80
  7. package/examples/vanilla.html +242 -23
  8. package/package.json +7 -2
  9. package/src/core/assets.js +10 -15
  10. package/src/core/binder.js +120 -118
  11. package/src/core/blocks.js +14 -1
  12. package/src/core/css-cascade.js +117 -117
  13. package/src/core/editor-core.js +1530 -1492
  14. package/src/core/export.js +142 -55
  15. package/src/core/i18n/ar.js +219 -177
  16. package/src/core/i18n/bg.js +196 -152
  17. package/src/core/i18n/bn.js +218 -176
  18. package/src/core/i18n/ca.js +196 -152
  19. package/src/core/i18n/cs.js +196 -152
  20. package/src/core/i18n/da.js +196 -152
  21. package/src/core/i18n/de-CH.js +196 -152
  22. package/src/core/i18n/de.js +196 -152
  23. package/src/core/i18n/dz.js +221 -179
  24. package/src/core/i18n/el.js +196 -152
  25. package/src/core/i18n/en.js +3 -10
  26. package/src/core/i18n/es.js +196 -152
  27. package/src/core/i18n/et.js +196 -152
  28. package/src/core/i18n/fi.js +196 -152
  29. package/src/core/i18n/fr.js +196 -152
  30. package/src/core/i18n/hr.js +196 -152
  31. package/src/core/i18n/hu.js +196 -152
  32. package/src/core/i18n/index.js +83 -83
  33. package/src/core/i18n/it.js +196 -152
  34. package/src/core/i18n/lt.js +196 -152
  35. package/src/core/i18n/lv.js +196 -152
  36. package/src/core/i18n/nb.js +196 -152
  37. package/src/core/i18n/nl.js +196 -152
  38. package/src/core/i18n/pl.js +196 -152
  39. package/src/core/i18n/pt.js +196 -152
  40. package/src/core/i18n/ro.js +196 -152
  41. package/src/core/i18n/ru.js +196 -152
  42. package/src/core/i18n/sk.js +196 -152
  43. package/src/core/i18n/sl.js +196 -152
  44. package/src/core/i18n/sv.js +196 -152
  45. package/src/core/i18n/tables.js +50 -50
  46. package/src/core/i18n/tr.js +196 -152
  47. package/src/core/i18n/uk.js +196 -152
  48. package/src/core/icons.js +237 -235
  49. package/src/core/ids.js +1 -1
  50. package/src/core/import-html.js +1025 -959
  51. package/src/core/layout-style.js +100 -100
  52. package/src/core/parse.js +10 -10
  53. package/src/core/placeholder.js +15 -15
  54. package/src/core/sanitize.js +141 -141
  55. package/src/core/storage-limits.js +184 -184
  56. package/src/core/storage.js +85 -85
  57. package/src/core/theme.js +1 -1
  58. package/src/core/variables.js +11 -11
  59. package/src/index.js +9 -9
  60. package/src/mailcraft-editor.js +26 -14
  61. package/src/render/block-body.js +49 -6
  62. package/src/render/canvas.js +31 -2
  63. package/src/render/fields.js +602 -588
  64. package/src/render/focus-preserve.js +158 -158
  65. package/src/render/rte.js +241 -212
  66. package/src/render/screenshot.js +132 -132
  67. package/src/render/story.js +415 -415
  68. package/src/render/style.js +8 -0
  69. package/types/index.d.ts +419 -0
@@ -1,177 +1,219 @@
1
- /**
2
- * Arabic (العربية) — `ar`. Right-to-left -- pair with `dir="rtl"` (the
3
- * editor defaults `dir` from `isRtl(locale)` automatically unless the host
4
- * sets `dir` explicitly).
5
- *
6
- * AI-drafted, not reviewed by a native speaker. Correctable one key at a
7
- * time via `.messages` overrides.
8
- */
9
- export const AR = {
10
- 'action.undoHint': 'تراجع — ⌘Z',
11
- 'action.redoHint': 'إعادة — ⌘⇧Z',
12
- 'action.chromeToDark': 'داكن',
13
- 'action.chromeToLight': 'فاتح',
14
- 'action.chromeHint': 'وضع المحرر فاتح / داكن',
15
- 'action.aiCopy': 'نص',
16
- 'action.aiCopyHint': 'صياغة نص بالذكاء الاصطناعي',
17
- 'action.code': 'الكود',
18
- 'action.codeHint': 'تحرير HTML الخام مع معاينة مباشرة',
19
- 'action.preview': 'معاينة',
20
- 'action.export': 'تصدير',
21
-
22
- 'device.desktop': 'سطح المكتب',
23
- 'device.desktopHint': 'عرض سطح المكتب',
24
- 'device.mobile': 'الجوال',
25
- 'device.mobileHint': 'عرض الجوال',
26
- 'device.dark': 'داكن',
27
- 'device.darkHint': 'وضع الوارد الداكن',
28
-
29
- 'status.autosaveOn': 'الحفظ التلقائي مفعّل',
30
- 'status.saved': 'تم الحفظ {time}',
31
- 'status.saveFailed': 'لم يتم الحفظ التخزين ممتلئ',
32
-
33
- 'canvas.meta': '{rows} صفوف · {blocks} كتل · {width}px',
34
-
35
- 'tab.design': 'النمط',
36
- 'tab.designHint': 'تنسيق العنصر المحدد',
37
- 'tab.blocks': 'الكتل',
38
- 'tab.blocksHint': 'كتل المحتوى والمتغيرات',
39
- 'tab.rows': 'الأقسام',
40
- 'tab.rowsHint': 'تخطيطات الأقسام ونموذج اللوحة',
41
- 'tab.files': 'الملفات',
42
- 'tab.filesHint': 'مكتبة الأصول',
43
- 'tab.layers': 'البنية',
44
- 'tab.layersHint': 'بنية المستند',
45
- 'tab.theme': 'السمة',
46
- 'tab.themeHint': 'الأنماط العامة',
47
- 'tab.data': 'المتغيرات',
48
- 'tab.dataHint': 'المتغيرات المقدَّمة من برنامجك',
49
-
50
- 'inspector.blockProperties': 'خصائص الكتلة',
51
- 'inspector.sectionProperties': 'خصائص القسم',
52
- 'inspector.title': 'المفتش',
53
- 'inspector.sectionLabel': 'قسم',
54
- 'inspector.nothingSelected': 'لا يوجد تحديد',
55
- 'action.duplicateHint': 'مضاعفة — ⌘D',
56
- 'action.deleteHint': 'حذف ',
57
- 'inspector.emptyBody':
58
- 'اختر صفًا أو كتلة على اللوحة لتنسيقه هنا. اسحب الكتل من تبويب <strong style="color: var(--ed-text); font-weight: 600;">الكتل</strong>؛ انقر نقرًا مزدوجًا على أي نص لتحريره في مكانه.',
59
- 'inspector.shortcuts': 'الاختصارات',
60
- 'shortcut.undoRedo': '⌘Z / ⌘⇧Z تراجع، إعادة',
61
- 'shortcut.duplicate': '⌘D — مضاعفة التحديد',
62
- 'shortcut.delete': 'حذف التحديد',
63
- 'shortcut.export': '⌘Eتصدير HTML',
64
- 'shortcut.escape': 'ESCإلغاء التحديد، إغلاق',
65
-
66
- 'blocks.dragHint': 'اسحب إلى اللوحة',
67
- 'blocks.count': '{count} كتلة',
68
-
69
- 'rows.sectionLayouts': 'تخطيطات الأقسام',
70
- 'rows.customMarkup': 'ترميز مخصص',
71
- 'rows.htmlRowHint': 'اسحب لإدراجه، أو انقر للإضافة — صف بعرض كامل تملأه بـ HTML خام',
72
- 'rows.rawHtmlSection': 'قسم HTML خام',
73
- 'rows.rawHtmlDesc': 'قسم بعرض كامل، ترميزك الخاص، وقابل للسحب أيضًا',
74
- 'rows.canvasModel': 'نموذج اللوحة',
75
- 'rows.modeRowBased': 'قائم على الصفوف',
76
- 'rows.modeFreeStack': 'تكديس حر',
77
- 'rows.hintRows':
78
- 'قائم على الأقسام: أسقط تخطيطًا أولًا، ثم أسقط الكتل داخل أعمدته — كل قسم يحمل خلفيته وحدوده وإعدادات flex أو grid الخاصة به.',
79
- 'rows.hintStack': 'تكديس حر: بدون تخطيطات — كل كتلة تسحبها تصبح قسمًا مستقلًا بعرض كامل، مرتبة بالتسلسل.',
80
-
81
-
82
- 'files.libraryCount': 'المكتبة — {count} ملفات',
83
- 'files.openManager': 'فتح مدير الملفات',
84
- 'files.dragToCanvas': 'اسحب أي ملف مباشرة إلى اللوحة لوضعه كصورة.',
85
-
86
- 'layers.structure': 'البنية',
87
- 'layers.sectionSingle': 'قسم',
88
- 'layers.sectionMulti': 'قسم · {count} أعمدة',
89
- 'layers.blockCount': '{count} كتلة',
90
-
91
- 'theme.globalStyles': 'الأنماط العامة',
92
-
93
- 'vars.title': 'المتغيرات',
94
- 'vars.fromCode': '{count} من برنامجك',
95
- 'vars.declaredNote': 'مُعرَّفة من قِبل تطبيقك — تعرض اللوحة دائمًا الرمز، وليس القيمة أبدًا.',
96
- 'vars.filterPlaceholder': 'تصفية المتغيرات…',
97
- 'vars.insertHint': 'انقر للإدراج في النص أو العنوان أو الزر المحدد',
98
- 'vars.insert': 'إدراج',
99
- 'vars.noMatch': 'لا يوجد متغير يطابق هذا الفلتر.',
100
- 'vars.noneDeclared': 'لم يُعرِّف تطبيقك أي متغيرات بعد.',
101
- 'vars.rteHint': 'أثناء تحرير النص يمكنك أيضًا اختيار متغير من القائمة المنسدلة في شريط الأدوات المضمّن.',
102
-
103
- 'modal.fileManager': 'مدير الملفات',
104
- 'modal.assetsTitle': 'الأصول',
105
- 'modal.replaceImage': 'استبدال الصورة',
106
- 'library.searchPlaceholder': 'بحث في الملفات…',
107
- 'action.upload': 'رفع',
108
- 'library.clickToPlace': 'انقر على ملف لوضعه · أو اسحب ملفًا إلى اللوحة',
109
- 'library.clickToReplace': 'انقر على ملف لاستبدال الصورة المحددة',
110
- 'library.storageLabel': '{count} ملفات · {size}',
111
- 'library.folders': 'المجلدات',
112
- 'library.dropHint': 'أسقط ملفات الصور هنا للرفع — أو استخدم زر الرفع.',
113
- 'library.deleteFileHint': 'حذف الملف',
114
- 'library.del': 'حذف',
115
- 'toast.assetDeleted': 'تم حذف {name}',
116
-
117
- 'modal.export': 'تصدير',
118
- 'modal.exportTitle': 'HTML بريد إلكتروني قائم على الجداول',
119
- 'export.copy': 'نسخ',
120
- 'export.copied': 'تم النسخ',
121
- 'action.download': 'تنزيل',
122
- 'export.meta': '{kb} كيلوبايت · جداول + أنماط مضمّنة · عروض آمنة لـ Outlook',
123
-
124
- 'modal.rawHtmlTitle': 'HTML خام، معاينة مباشرة',
125
- 'code.statusEdited': 'عرض الكود مُعدَّلالمعاينة مباشرة، لم يُطبَّق بعد',
126
- 'code.statusSynced': 'عرض الكود متزامن مع اللوحة',
127
- 'action.reload': 'إعادة تحميل',
128
- 'action.reloadHint': 'إعادة تحميل المصدر من اللوحة',
129
- 'action.applyToCanvas': 'تطبيق على اللوحة',
130
- 'action.applyToCanvasHint': 'تحليل المصدر مرة أخرى إلى صفوف قابلة للتحرير',
131
- 'action.closeWithoutApplyingHint': 'إغلاق دون تطبيق',
132
- 'code.source': 'المصدر',
133
- 'code.livePreview': 'معاينة مباشرة',
134
- 'code.liveHtmlPreviewTitle': 'معاينة HTML مباشرة',
135
- 'code.applyNote':
136
- 'يحلّل زر التطبيق كل صف جدول من المستوى الأعلى إلى صف لوحة يمكنك تحديده وإعادة ترتيبه وحذفه — الترميز المكتوب يدويًا يبقى سليمًا.',
137
- 'code.meta': '{kb} كيلوبايت · {lines} أسطر',
138
- 'toast.sourceReloaded': 'تمت إعادة تحميل المصدر من اللوحة',
139
- 'toast.sourceAppliedOne': 'تم تطبيق المصدر صف واحد على اللوحة',
140
- 'toast.sourceAppliedMany': 'تم تطبيق المصدر — {rows} صفوف على اللوحة',
141
- 'toast.parseError': 'تعذّر تحليل ذلك الـ HTML',
142
-
143
- 'modal.copyAssist': 'مساعد الصياغة',
144
- 'modal.draftCopyTitle': 'صياغة نص لهذه الحملة',
145
- 'ai.goal': 'الهدف',
146
- 'ai.tone': 'الأسلوب',
147
- 'ai.briefLabel': 'ما موضوع هذا البريد الإلكتروني؟',
148
- 'ai.briefPlaceholder': 'مثال: إطلاق ملابس الخريف، خصم 15% للمشتركين، شحن مجاني فوق 150$',
149
- 'ai.generate': 'إنشاء النص',
150
- 'ai.writing': 'جارٍ الكتابة…',
151
- 'ai.kindHeadline': 'عنوان رئيسي',
152
- 'ai.kindBody': 'نص أساسي',
153
- 'ai.kindButton': 'نص الزر',
154
- 'ai.actionInsertHeading': 'إدراج كعنوان',
155
- 'ai.actionInsertText': 'إدراج ككتلة نصية',
156
- 'ai.actionInsertButton': 'إدراج كزر',
157
- 'toast.headingAdded': 'تمت إضافة العنوان',
158
- 'toast.textBlockAdded': 'تمت إضافة الكتلة النصية',
159
- 'toast.buttonAdded': 'تمت إضافة الزر',
160
-
161
- 'preview.kickerMobile': 'معاينة جوال 375px',
162
- 'preview.kickerDark': 'معاينة — وارد داكن',
163
- 'preview.kickerDesktop': 'معاينة — سطح مكتب {width}px',
164
- 'action.close': 'إغلاق',
165
-
166
- 'toast.duplicated': 'تمت المضاعفة',
167
- 'toast.fileUploadedOne': 'تم رفع ملف واحد',
168
- 'toast.fileUploadedMany': 'تم رفع {count} ملفات',
169
- 'toast.imageReplaced': 'تم استبدال الصورة',
170
- 'toast.imageAdded': 'تمت إضافة الصورة إلى اللوحة',
171
- 'toast.htmlCopied': 'تم نسخ HTML إلى الحافظة',
172
- 'toast.templateLoaded': 'تم تحميل {name}',
173
- 'toast.snippetDefaultLabel': 'مقتطف',
174
- 'toast.snippetInserted': 'تم إدراج {name}',
175
- 'toast.snippetCopied': 'تم نسخ {name} — حدد كتلة نصية لإدراجه',
176
- };
177
-
1
+ /**
2
+ * Arabic (العربية) — `ar`. Right-to-left -- pair with `dir="rtl"` (the
3
+ * editor defaults `dir` from `isRtl(locale)` automatically unless the host
4
+ * sets `dir` explicitly).
5
+ *
6
+ * AI-drafted, not reviewed by a native speaker. Correctable one key at a
7
+ * time via `.messages` overrides.
8
+ */
9
+ export const AR = {
10
+ 'action.undoHint': 'تراجع — ⌘Z',
11
+ 'action.redoHint': 'إعادة — ⌘⇧Z',
12
+ 'action.chromeToDark': 'داكن',
13
+ 'action.chromeToLight': 'فاتح',
14
+ 'action.chromeHint': 'وضع المحرر فاتح / داكن',
15
+ 'action.chromeHintToDark': 'الوضع الداكن',
16
+ 'action.chromeHintToLight': 'الوضع الفاتح',
17
+ 'action.aiDraft': 'مسودة',
18
+ 'action.aiDraftHint': 'صياغة محتوى البريد بالذكاء الاصطناعي',
19
+ 'action.code': 'الكود',
20
+ 'action.codeHint': 'تحرير HTML الخام مع معاينة مباشرة',
21
+ 'action.preview': 'معاينة',
22
+ 'action.previewHint': 'معاينة البريد',
23
+ 'action.export': 'تصدير',
24
+ 'action.exportHint': 'تصدير بريدك',
25
+
26
+ 'device.desktop': 'سطح المكتب',
27
+ 'device.desktopHint': 'عرض سطح المكتب',
28
+ 'device.mobile': 'الجوال',
29
+ 'device.mobileHint': 'عرض الجوال',
30
+
31
+ 'status.autosaveOn': 'الحفظ التلقائي مفعّل',
32
+ 'status.saved': 'تم الحفظ {time}',
33
+ 'status.saveFailed': 'لم يتم الحفظ التخزين ممتلئ',
34
+
35
+ 'canvas.meta': '{rows} صفوف · {blocks} كتل · {width}px',
36
+
37
+ 'tab.design': 'النمط',
38
+ 'tab.designHint': 'تنسيق العنصر المحدد',
39
+ 'tab.blocks': 'الكتل',
40
+ 'tab.blocksHint': 'كتل المحتوى والمتغيرات',
41
+ 'tab.rows': 'الأقسام',
42
+ 'tab.rowsHint': 'تخطيطات الأقسام ونموذج اللوحة',
43
+ 'tab.files': 'الملفات',
44
+ 'tab.filesHint': 'مكتبة الأصول',
45
+ 'tab.layers': 'البنية',
46
+ 'tab.layersHint': 'بنية المستند',
47
+ 'tab.settings': 'الإعدادات',
48
+ 'tab.settingsHint': 'إعدادات البريد',
49
+ 'tab.data': 'المتغيرات',
50
+ 'tab.dataHint': 'المتغيرات المقدَّمة من برنامجك',
51
+
52
+ 'inspector.blockProperties': 'خصائص الكتلة',
53
+ 'inspector.sectionProperties': 'خصائص القسم',
54
+ 'inspector.title': 'المفتش',
55
+ 'inspector.sectionLabel': 'قسم',
56
+ 'inspector.nothingSelected': 'لا يوجد تحديد',
57
+ 'action.duplicateHint': 'مضاعفة — ⌘D',
58
+ 'action.deleteHint': 'حذف ',
59
+ 'inspector.emptyBody':
60
+ 'اختر صفًا أو كتلة على اللوحة لتنسيقه هنا. اسحب الكتل من تبويب <strong style="color: var(--ed-text); font-weight: 600;">الكتل</strong>؛ انقر نقرًا مزدوجًا على أي نص لتحريره في مكانه.',
61
+ 'inspector.shortcuts': 'الاختصارات',
62
+ 'shortcut.undoRedo': '⌘Z / ⌘⇧Z تراجع، إعادة',
63
+ 'shortcut.duplicate': '⌘Dمضاعفة التحديد',
64
+ 'shortcut.delete': 'حذف التحديد',
65
+ 'shortcut.export': '⌘E — تصدير HTML',
66
+ 'shortcut.escape': 'ESC إلغاء التحديد، إغلاق',
67
+
68
+ 'blocks.dragHint': 'اسحب إلى اللوحة',
69
+ 'blocks.count': '{count} كتلة',
70
+
71
+ 'rows.sectionLayouts': 'تخطيطات الأقسام',
72
+ 'rows.customMarkup': 'ترميز مخصص',
73
+ 'rows.htmlRowHint': 'اسحب لإدراجه، أو انقر للإضافة — صف بعرض كامل تملأه بـ HTML خام',
74
+ 'rows.rawHtmlSection': 'قسم HTML خام',
75
+ 'rows.rawHtmlDesc': 'قسم بعرض كامل، ترميزك الخاص، وقابل للسحب أيضًا',
76
+ 'rows.canvasModel': 'نموذج اللوحة',
77
+ 'rows.modeRowBased': 'قائم على الصفوف',
78
+ 'rows.modeFreeStack': 'تكديس حر',
79
+ 'rows.hintRows':
80
+ 'قائم على الأقسام: أسقط تخطيطًا أولًا، ثم أسقط الكتل داخل أعمدته — كل قسم يحمل خلفيته وحدوده وإعدادات flex أو grid الخاصة به.',
81
+ 'rows.hintStack': 'تكديس حر: بدون تخطيطات — كل كتلة تسحبها تصبح قسمًا مستقلًا بعرض كامل، مرتبة بالتسلسل.',
82
+
83
+ 'files.libraryCount': 'المكتبة {count} ملفات',
84
+ 'files.openManager': 'فتح مدير الملفات',
85
+ 'files.dragToCanvas': 'اسحب أي ملف مباشرة إلى اللوحة لوضعه كصورة.',
86
+
87
+ 'layers.structure': 'البنية',
88
+ 'layers.sectionSingle': 'قسم',
89
+ 'layers.sectionMulti': 'قسم · {count} أعمدة',
90
+ 'layers.column': 'العمود {index}',
91
+ 'layers.blockCount': '{count} كتلة',
92
+
93
+ 'vars.title': 'المتغيرات',
94
+ 'vars.fromCode': '{count} من برنامجك',
95
+ 'vars.declaredNote': 'مُعرَّفة من قِبل تطبيقك — تعرض اللوحة دائمًا الرمز، وليس القيمة أبدًا.',
96
+ 'vars.filterPlaceholder': 'تصفية المتغيرات…',
97
+ 'vars.insertHint': 'انقر للإدراج في النص أو العنوان أو الزر المحدد',
98
+ 'vars.insert': 'إدراج',
99
+ 'vars.noMatch': 'لا يوجد متغير يطابق هذا الفلتر.',
100
+ 'vars.noneDeclared': 'لم يُعرِّف تطبيقك أي متغيرات بعد.',
101
+ 'vars.rteHint': 'أثناء تحرير النص يمكنك أيضًا اختيار متغير من القائمة المنسدلة في شريط الأدوات المضمّن.',
102
+
103
+ 'modal.fileManager': 'مدير الملفات',
104
+ 'modal.assetsTitle': 'الأصول',
105
+ 'modal.replaceImage': 'استبدال الصورة',
106
+ 'library.searchPlaceholder': 'بحث في الملفات…',
107
+ 'action.upload': 'رفع',
108
+ 'library.clickToPlace': 'انقر على ملف لوضعه · أو اسحب ملفًا إلى اللوحة',
109
+ 'library.clickToReplace': 'انقر على ملف لاستبدال الصورة المحددة',
110
+ 'library.storageLabel': '{count} ملفات · {size}',
111
+ 'library.folders': 'المجلدات',
112
+ 'library.dropHint': 'أسقط ملفات الصور هنا للرفع — أو استخدم زر الرفع.',
113
+ 'library.deleteFileHint': 'حذف الملف',
114
+ 'library.del': 'حذف',
115
+ 'toast.assetDeleted': 'تم حذف {name}',
116
+ 'library.allFiles': 'كل الملفات',
117
+ 'library.loadMore': 'تحميل المزيد',
118
+ 'library.empty': 'لا توجد ملفات هنا بعد.',
119
+ 'storage.loading': 'جارٍ تحميل الملفات…',
120
+ 'storage.uploading': 'جارٍ رفع {count}…',
121
+ 'storage.errLoadFailed': 'تعذّر تحميل مكتبة الملفات — {reason}',
122
+ 'storage.errNoLimits': 'الرفع معطّل: لم يحدّد هذا التطبيق أي حدود للرفع.',
123
+ 'storage.errNoAccept': 'الرفع معطّل: لم يُسمح بأي صيغة ملفات.',
124
+ 'storage.errNoMaxBytes': 'الرفع معطّل: لم يُحدَّد حد أقصى لحجم الملف.',
125
+ 'storage.errTooLarge': 'حجم {name} هو {size}والحد هو {max}.',
126
+ 'storage.errFormat': '{name} ملف من نوع {type}، وهو غير مسموح به هنا.',
127
+ 'storage.errSvg': '{name} ملف SVG، وهذا التطبيق لا يقبله.',
128
+ 'storage.errDimensions': 'أبعاد {name} هي {w}×{ht}px — والحد هو {maxW}×{maxH}px.',
129
+ 'storage.errTooMany': 'يمكن رفع {max} ملفات فقط في المرة الواحدة.',
130
+ 'storage.errUnreadable': '{name} ليس صورة قابلة للقراءة.',
131
+ 'storage.errUploadFailed': 'تعذّر رفع {name} — {reason}',
132
+ 'storage.errDeleteFailed': 'تعذّر حذف {name} — {reason}',
133
+
134
+ 'modal.export': 'تصدير',
135
+ 'modal.exportTitle': 'HTML بريد إلكتروني قائم على الجداول',
136
+ 'export.copy': 'نسخ',
137
+ 'export.copied': 'تم النسخ',
138
+ 'action.download': 'تنزيل',
139
+ 'export.meta': '{kb} كيلوبايت · جداول + أنماط مضمّنة · عروض آمنة لـ Outlook',
140
+
141
+ 'modal.rawHtmlTitle': 'HTML خام، معاينة مباشرة',
142
+ 'code.statusEdited': 'عرض الكود — مُعدَّل — المعاينة مباشرة، لم يُطبَّق بعد',
143
+ 'code.statusSynced': 'عرض الكود — متزامن مع اللوحة',
144
+ 'action.reload': 'إعادة تحميل',
145
+ 'action.reloadHint': 'إعادة تحميل المصدر من اللوحة',
146
+ 'action.applyToCanvas': 'تطبيق على اللوحة',
147
+ 'action.applyToCanvasHint': 'تحليل المصدر مرة أخرى إلى صفوف قابلة للتحرير',
148
+ 'action.closeWithoutApplyingHint': 'إغلاق دون تطبيق',
149
+ 'code.source': 'المصدر',
150
+ 'code.livePreview': 'معاينة مباشرة',
151
+ 'code.liveHtmlPreviewTitle': 'معاينة HTML مباشرة',
152
+ 'code.applyNote':
153
+ 'يحلّل زر التطبيق كل صف جدول من المستوى الأعلى إلى صف لوحة يمكنك تحديده وإعادة ترتيبه وحذفه — الترميز المكتوب يدويًا يبقى سليمًا.',
154
+ 'code.meta': '{kb} كيلوبايت · {lines} أسطر',
155
+ 'toast.sourceReloaded': 'تمت إعادة تحميل المصدر من اللوحة',
156
+ 'toast.sourceAppliedOne': 'تم تطبيق المصدر — صف واحد على اللوحة',
157
+ 'toast.sourceAppliedMany': 'تم تطبيق المصدر — {rows} صفوف على اللوحة',
158
+ 'toast.parseError': 'تعذّر تحليل ذلك الـ HTML',
159
+ 'modal.aiDraft': 'مساعد الكتابة بالذكاء الاصطناعي',
160
+ 'modal.aiDraftTitle': 'اكتب مسودة بريدك بالذكاء الاصطناعي',
161
+ 'ai.disclosure': 'ينشئ الذكاء الاصطناعي اقتراحات من موجزك. راجع النتيجة وحرّرها قبل الإرسال.',
162
+
163
+ 'ai.goal': 'الهدف',
164
+ 'ai.tone': 'الأسلوب',
165
+ 'ai.briefLabel': 'ما موضوع هذا البريد الإلكتروني؟',
166
+ 'ai.briefPlaceholder': 'مثال: إطلاق ملابس الخريف، خصم 15% للمشتركين، شحن مجاني فوق 150$',
167
+ 'ai.generate': 'إنشاء النص',
168
+ 'ai.writing': 'جارٍ الكتابة…',
169
+ 'ai.kindHeadline': 'عنوان رئيسي',
170
+ 'ai.kindBody': 'نص أساسي',
171
+ 'ai.kindButton': 'نص الزر',
172
+ 'ai.actionInsertHeading': 'إدراج كعنوان',
173
+ 'ai.actionInsertText': 'إدراج ككتلة نصية',
174
+ 'ai.actionInsertButton': 'إدراج كزر',
175
+ 'toast.headingAdded': 'تمت إضافة العنوان',
176
+ 'toast.textBlockAdded': 'تمت إضافة الكتلة النصية',
177
+ 'toast.buttonAdded': 'تمت إضافة الزر',
178
+
179
+ 'preview.kickerMobile': 'معاينة — جوال 375px',
180
+ 'preview.kickerDesktop': 'معاينة — سطح مكتب {width}px',
181
+ 'action.close': 'إغلاق',
182
+
183
+ 'toast.duplicated': 'تمت المضاعفة',
184
+ 'toast.fileUploadedOne': 'تم رفع ملف واحد',
185
+ 'toast.fileUploadedMany': 'تم رفع {count} ملفات',
186
+ 'toast.imageReplaced': 'تم استبدال الصورة',
187
+ 'toast.imageAdded': 'تمت إضافة الصورة إلى اللوحة',
188
+ 'toast.htmlCopied': 'تم نسخ HTML إلى الحافظة',
189
+ 'toast.templateLoaded': 'تم تحميل {name}',
190
+ 'toast.snippetDefaultLabel': 'مقتطف',
191
+ 'toast.snippetInserted': 'تم إدراج {name}',
192
+ 'toast.snippetCopied': 'تم نسخ {name} — حدد كتلة نصية لإدراجه',
193
+ 'rte.textStyle': 'نمط النص',
194
+ 'rte.mergeTags': 'حقول الدمج',
195
+ 'rte.noMergeTags': 'لا توجد حقول دمج متاحة',
196
+ 'rte.textColor': 'لون النص',
197
+ 'rte.highlightColor': 'لون التمييز',
198
+ 'rte.removeHighlight': 'إزالة التمييز',
199
+ 'rte.clearFormatting': 'مسح التنسيق',
200
+ 'action.downloadPng': 'تنزيل PNG',
201
+ 'action.screenshot': 'لقطة شاشة',
202
+ 'action.screenshotHint': 'معاينة القالب كاملاً كصورة، ثم تنزيله',
203
+ 'toast.pngSaved': 'تم تنزيل لقطة الشاشة',
204
+ 'toast.pngFailed': 'فشلت لقطة الشاشة — تعذّر تحميل صورة خارجية',
205
+ 'toast.pngCopied': 'تم نسخ لقطة الشاشة إلى الحافظة',
206
+ 'toast.pngCopyFailed': 'لم يقبل هذا المتصفح نسخ صورة إلى الحافظة',
207
+ 'story.kicker': 'لقطة شاشة',
208
+ 'story.rendering': 'جارٍ إنشاء لقطة الشاشة',
209
+ 'story.renderingHint': 'يجري رسم كل كتلة بدقة 2× — يستغرق ذلك لحظة في القوالب الطويلة.',
210
+ 'story.failed': 'فشلت لقطة الشاشة',
211
+ 'story.failedHint': 'تعذّر تحميل إحدى صور القالب لالتقاطها.',
212
+ 'story.retry': 'أعد المحاولة',
213
+ 'story.play': 'تشغيل',
214
+ 'story.pause': 'إيقاف مؤقت',
215
+ 'story.replay': 'إعادة التشغيل',
216
+ 'story.copy': 'نسخ',
217
+ 'story.meta': '{w}×{h} · شاشة {i} من {n}',
218
+ 'footer.poweredBy': 'مدعوم من SELISE Blocks © 2026',
219
+ };