-
المساهمات
189 -
تاريخ الانضمام
-
تاريخ آخر زيارة
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو Ola Abbas
-
سنلقي في هذا المقال نظرة على مدير الحزم Package Manager بشيء من التفصيل لفهم كيفية استخدامه في مشاريعنا لتثبيت اعتماديات Dependencies أدوات المشروع وتحديثها وغير ذلك. المتطلبات الأساسية: الإلمام بأساسيات لغات HTML وCSS وجافاسكربت. الهدف: فهم مدراء ومستودعات الحزم، وسبب حاجتنا لها، وأساسيات استخدامها. اعتماديات المشروع تعدّ الاعتمادية Dependency جزءًا من برنامج تابع لجهة خارجية كتبه شخص ما غيرك لحل مشكلة نيابة عنك. يمكن أن يحتوي مشروع الويب على أي عدد من الاعتماديات، تتراوح من لا شيء إلى اعتماديات متعددة، ويمكن أن تتضمن اعتمادياتك اعتماديات فرعية لم تثبّتها صراحة، إذ يمكن لاعتمادياتك أن يكون لها اعتمادياتها الخاصة. من الأمثلة البسيطة على الاعتماديات المفيدة التي يمكن أن يحتاجها مشروعك الشيفرة البرمجية لحساب التواريخ النسبية بوصفها نصًا قابلًا للقراءة. يمكنك بالتأكيد كتابة هذه الشيفرة بنفسك، ولكن يمكن أن يحل شخص آخر هذه المشكلة بدلًا عنك، فلا داعي لنضيع الوقت في إعادة كتابة هذه الشيفرة (ليس علينا إعادة اختراع العجلة). يُحتمَل اختبار اعتمادية موثوقة لطرف ثالث في مواقف متعددة مختلفة، مما يجعلها أقوى وأكثر توافقًا من حلك مع المتصفحات. يمكن أن تكون اعتمادية المشروع عبارة عن مكتبة أو إطار عمل جافاسكربت كامل مثل React وVue أو أداة مساعدة صغيرة جدًا مثل مكتبة التاريخ القابلة للقراءة، أو يمكن أن تكون أداة سطر أوامر مثل Prettier أو Eslint التي تحدثنا عنها في المقال السابق. إن لم نستخدم أدوات البناء الحديثة، فيمكن تضمَّين مثل هذه الاعتماديات في مشروعك باستخدام عنصر <script> بسيط، ولكن يمكن ألا تعمل هذه الطريقة مباشرة، وبالتالي ستحتاج بعض الأدوات الحديثة لتجميع الشيفرة والاعتماديات مع بعضها بعضًا عند إصدارها على الويب. الحزمة Bundle هي المصطلح المُستخدَم للإشارة إلى ملف على خادم الويب الخاص بك الذي يحتوي على شيفرة جافاسكربت الخاصة ببرنامجك، وتُضغَطُ الحزمة قدر الإمكان للمساعدة في تقليل الوقت الذي يستغرقه تنزيل البرنامج وعرضه في متصفح زوار موقعك. لا يُعَد تتبّع بعض الاعتماديات أمرًا صعبًا إذا وجدت أداة أفضل تريد استخدامها بدلًا من الأداة الحالية، أو أُصدِر إصدار جديد من الاعتمادية تريد التحديث إليه، ولكن يمكن أن يصبح هذا النوع من الأشياء صعبًا في المشاريع الكبيرة التي تحتوي على اعتماديات متعددة، لذلك يمكنك استخدام مدير حزم Package Manager مثل npm، لأنه سيضمن إضافة الشيفرة وإزالتها بطريقة نظيفة، بالإضافة إلى مجموعة من المزايا الأخرى. مدير الحزم مدير الحزم هو نظام يدير اعتماديات مشروعك، ويوفّر طريقة لتثبيت اعتماديات جديدة يُشار إليها باسم "الحزم Packages"، وإدارة مكان تخزين الحزم على نظام ملفاتك، وتقديم إمكانيات لنشرها. يمكنك تنزيل اعتماديات مشروعك وتخزينها يدويًا دون استخدام مدير حزم، ولكن مدير الحزم سيتعامل بسلاسة مع تثبيت الحزم وإلغاء تثبيتها. إن لم تستخدم مدير حزم، فسيتعين عليك التعامل مع ما يلي يدويًا: العثور على كافة ملفات جافاسكربت الصحيحة الخاصة بالحزمة. التحقق منها للتأكد من عدم وجود أي ثغرات أمنية. تنزيلها ووضعها في الأماكن الصحيحة في مشروعك. كتابة الشيفرة لتضمين الحزمة أو الحزم في تطبيقك، إذ يمكن تطبيق ذلك باستخدام وحدات جافاسكربت. تطبيق الخطوات نفسها مع جميع اعتماديات الحزم الفرعية التي يُحتمَل وجود عشرات أو مئات منها. إزالة جميع الملفات مرة أخرى إذا أردت إزالة الحزم. كما يتعامل مدير الحزم مع الاعتماديات المكرَّرة، وهو أمر مهم وشائع في تطوير الواجهة الأمامية. لديك خياران لمكان تثبيت اعتمادياتك في حالة npm ومدير الحزم المستند إلى جافاسكربت وNode، ويمكن تثبيت الاعتماديات بطريقة عامة أي لكل المشاريع أو محليًا في مشروع معين فقط. بالرغم من وجود كثير من إيجابيات التثبيت العام، إلّا أن إيجابيات التثبيت المحلي لكل مشروع مهمة مثل قابلية نقل الشيفرة وقفل الإصدار. إذا اعتمد مشروعك مثلًا على Webpack مع إعداد معين، فيجب التأكد من عمل هذا الإعداد عند تثبيت المشروع على جهاز آخر أو العودة إليه لاحقًا. إذا ثُبِّت إصدار مختلف من Webpack، فيمكن ألّا يكون متوافقًا، لذلك يجب تثبيت الاعتماديات محليًا في المشروع. حاول تنزيل وتشغيل مشروع قائم، فإذا نجح وعملت جميع الاعتماديات مباشرة، فعندئذٍ لديك اعتماديات محلية يجب أن تشكرها على حقيقة أن الشيفرة قابلة للنقل. سجلات الحزم Package Registries يحتاج مدير الحزم ليعمل إلى معرفة المكان الذي نثبّت الحزم منه، وهو ما يدعَى بسجل الحزمة Package Registry. السجل هو مكان مركزي تُنشَر الحزمة عليه وبالتالي يمكن تثبيتها منه. يُعدُّ npm اسم سجل الحزم الأكثر استخدامًا لحزم جافاسكربت. ليس npm الخيار الوحيد لإدارة سجل حزمتك، إذ تتيح لك منتجات مثل Microsoft Azure إنشاء وكلاء لسجل npm إذ يمكنك تجاوز أو قفل حزم معينة، كما يقدم GitHub خدمة تسجيل حزمة، ويُحتمَل ظهور مزيد من الخيارات مع مرور الوقت. المهم هو التأكد من اختيارك لأفضل سجل مناسب لك، ولكن ستستخدم العديد من المشاريع مدير الحزم npm، وسنستخدمها في أمثلتنا. استخدام نظام الحزم المجتمعي لنعرض مثالًا باستخدام مدير وسجل الحزم لتثبيت أداة مساعدة لسطر الأوامر. Parcel هي أداة ذكية يستخدمها المطورون لمراقبة محتويات الشيفرة لاستدعاء الاعتماديات، وتثبّتها تلقائيًا أيّ اعتماديات ترى أن شيفرتنا بحاجة إليها، ويمكنها إنشاء الشيفرة تلقائيًا. ثبّتنا الأداة Prettier تثبيتًا عامًا لكل المشاريع في المقال السابق، ولكن سنستخدم الآن npm لتثبيت Parcel محليًا باستخدام أفضل الممارسات، وسنثبّتها بوصفها جزءًا من تطبيق تجريبي. إعداد التطبيق بوصفه حزمة npm أنشئ أولًا مجلدًا جديدًا لتخزين تطبيقنا التجريبي ضمنه في مكان يمكنك إيجاده بسهولة مرة أخرى، وسنسميه parcel-experiment، ولكن بالطبع يمكنك تسميته ما تشاء: mkdir parcel-experiment cd parcel-experiment لنهيّئ بعد ذلك تطبيقنا كحزمة npm التي تُنشئ ملف الإعداد package.json الذي يسمح بحفظ تفاصيل الإعداد الخاصة بنا في حال أردنا إعادة إنشاء هذه البيئة لاحقًا، أو نشر الحزمة على سجل npm بالرغم من أن ذلك إلى حد ما خارج نطاق هذا المقال. اكتب الأمر التالي، وتأكد من أنك داخل الدليل parcel-experiment: npm init ستُطرَح بعض الأسئلة عليك الآن، ثم سينشئ npm ملف package.json افتراضي بناءً على إجاباتك: name: الاسم الذي يعرّف التطبيق. اضغط على زر Enter لقبول الاسم parcel-experiment الافتراضي. version: رقم إصدار البداية الخاص بالتطبيق. اضغط على زر Enter لقبول الإصدار 1.0.0 الافتراضي. description: وصف سريع للغرض من التطبيق. اكتب شيئًا بسيطًا مثل "حزمة npm بسيطة للتعرف على كيفية استخدام npm"، ثم اضغط على زر Enter. entry point: يمثل ملف جافاسكربت ذي المستوى الأعلى في التطبيق. الملف index.js الافتراضي مناسب حاليًا، ثم اضغط على زر Enter. test command وgit repository وkeywords: اضغط على زر Enter لترك هذه الخيارات فارغة حاليًا. author: مؤلف المشروع. اكتب اسمك، ثم اضغط على زر Enter. license: ترخيص نشر الحزمة. اضغط على زر Enter لقبول الإعداد الافتراضي حاليًا. اضغط على زر Enter مرة أخرى لقبول هذه الإعدادات. انتقل إلى المجلد parcel-experiment وستجد أن لديك الملف package.json. افتحه ويجب أن يبدو كما يلي: { "name": "parcel-experiment", "version": "1.0.0", "description": "A simple npm package to learn about using npm", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Chris Mills", "license": "ISC" } إذ يمثل ملف الإعداد الذي يحدد حزمتك. تثبيت Parcel شغّل الأمر التالي لتثبيت Parcel محليًا: npm install parcel-bundler سنكون بعد ذلك جاهزين للتطوير الحديث من طرف العميل الذي يعني استخدام أدوات البناء لتسهيل العمل على المطور. ألقِ نظرة أخرى على ملف package.json أولًا، ستلاحظ أن npm أضاف حقلًا جديدًا وهو الاعتماديات dependencies: "dependencies": { "parcel-bundler": "^1.12.4" } إذا نقلتَ في المستقبل قاعدة شيفرتك إلى موقع آخر على جهاز آخر، فيمكنك إعادة إنشاء الإعداد نفسه عن طريق تشغيل الأمر npm install، وسينظر npm في الاعتماديات ثم يثبّتها لك. لكن أحد مساوئ npm هو أن Parcel متاح فقط ضمن التطبيق parcel-experiment، إذ لن تتمكن من تشغيله في مجلد مختلف. إعداد التطبيق يتوقّع Parcel أن يعمل ملف index.html وملف index.js، ولكن بخلاف ذلك ليست بنية مشروعك مُعلَنة. يمكن أن تكون الأدوات الأخرى مختلفة، ولكن تسهّل الأداة Parcel على الأقل من تجربتنا الأولية. يجب إضافة ملف index.html إلى دليل عملنا. أنشئ الملف index.html في دليل الاختبار الخاص بك، وضع فيه المحتويات التالية: <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8"> <title>My test page</title> </head> <body> <script src="./index.js"></script> </body> </html> يجب بعد ذلك إضافة ملف index.js في دليل الملف index.html نفسه. يمكن أن يكون الملف index.js فارغًا حاليًا، ولكن يجب أن يكون موجودًا لذلك أنشئه الآن. تطبيق Parcel سنشغّل الآن أداة Parcel المثبَّتة حديثًا. شغّل الأمر التالي في طرفيتك: parcel index.html يجب أن ترى شيئًا كالتالي مطبوعًا على طرفيتك: Server running at http://localhost:1234 ✨ Built in 193ms. إذا واجهتَ مشكلةً في الطرفية التي تعرض خطأ من النوع "الأمر غير موجود command not found"، فحاول تشغيل الأمر السابق باستخدام الأداة npx مثل الأمر npx parcel index.html. يمكننا الآن الاستفادة من نظام حزمة جافاسكربت المجتمعي الكامل. يوجد حاليًا خادم ويب محلي يعمل على العنوان http://localhost:1234، فإذا انتقلت إليه، فلن ترى أي شيء حاليًا، ولكن ستعيد Parcel بنائه وستعمل على تحديث الخادم تلقائيًا عند إجراء تعديلات على تطبيقك لتتمكن من رؤية تأثير التحديث مباشرة. لنفترض أننا نريد عرض التواريخ النسبية التي يمكن قراءتها، مثل "منذ ساعتين 2 hours ago" و"قبل 4 أيام 4 days ago" وما إلى ذلك. يُعَد التابع formatDistanceToNow() الخاص بالحزمة date-fns مفيدًا لذلك، وهناك حزم أخرى تطبّق الشي نفسه. أضف الشيفرة التالية في ملف index.js واحفظها: import { formatDistanceToNow } from 'date-fns' const date = '1996-09-13 10:00:00'; document.body.textContent = formatDistanceToNow(new Date(date)) + ' ago'; ارجع إلى http://localhost:1234 وسترى كم مضى منذ بلوغ المؤلف 18 عامًا. ما يميز الشيفرة السابقة هو أنها تستخدم الدالة formatDistanceToNow() من الحزمة date-fns التي لم نثبّتها. اكتشفت الأداة Parcel أنك بحاجة الوحدة، وبحثت عنها في سجل الحزمة npmjs.com، وثبّتتها محليًا تلقائيًا. يمكنك إثبات ذلك من خلال البحث في ملف package.json مرة أخرى، وسترى تحديث حقل الاعتماديات dependencies كما يلي: "dependencies": { "date-fns": "^2.12.0", "parcel-bundler": "^1.12.4" } كما أضافت Parcel الملفات المطلوبة لشخص آخر لأخذ هذا المشروع وتثبيت أي اعتماديات استخدمناها. إذا ألقيت نظرة على الدليل الذي شغّلتَ أمر parcel فيه، فستجد عددًا من الملفات الجديدة مثل: node_modules: ملفات اعتماديات Parcel وdate-fns. dist: دليل التوزيع distribution directory، وهو الملفات المُجمَّعة والمُصغَّرة تلقائيًا التي أنشتأها Parcel، والملفات المُخدَّمة على العنوان localhost:1234، وهي الملفات التي ستحمّلها إلى خادم الويب الخاص بك عند إطلاق الموقع عبر الإنترنت ليراه المستخدمين. طالما أننا نعرف اسم الحزمة، فيمكننا استخدامها في شيفرتنا وستوقِف Parcel تشغيل الحزمة -أو نسخة منها- وتجلبها وتثبّتها في دليلنا المحلي ضمن node_modules. بناء الشيفرة للإنتاج لا تعدّ الشيفرة السابقة جاهزة للإنتاج، إذ يكون لمعظم أنظمة أدوات البناء وضع تطوير Development Mode ووضع إنتاج Production Mode. الاختلاف المهم هو أن الكثير من الميزات المفيدة التي ستستخدمها في التطوير ليست ضرورية في الموقع النهائي، لذلك ستُستبعَد للإنتاج مثل استبدال الوحدة وإعادة التحميل المباشر والشيفرة المصدرية غير المضغوطة والمُعلَّقة. هذه بعض ميزات تطوير الويب الشائعة المفيدة جدًا في مرحلة التطوير، ولكنها ليست مفيدة في مرحلة الإنتاج. أوقِف أمر Parcel السابق باستخدام الاختصار Ctrl + C. يمكننا الآن تجهيز أساسات موقع لنشره وهميًا، إذ توفّر Parcel أمرًا إضافيًا لإنشاء ملفات مناسبة للنشر، وإنشاء حزم Bundles مع خيار البناء. شغّل الأمر التالي: parcel build index.html ويجب أن ترى الناتج التالي: ✨ Built in 9.35s. dist/my-project.fb76efcf.js.map 648.58 KB 64ms dist/my-project.fb76efcf.js 195.74 KB 8.43s dist/index.html 288 B 806ms وجهة ملفات الإنتاج هي الدليل dist. تقليل حجم ملف التطبيق حجم حزمة جافاسكربت my-project.fb76efcf.js هو 195K وهو حجم كبير جدًا، بالرغم من أن كل ما تفعله هو طباعة سطر نصي. هناك بالتأكيد بعض الحسابات، ولكننا لسنا بحاجة إلى 195K من شيفرة جافاسكربت لذلك. يجدر بك التساؤل عما إذا كانت أدوات التطوير تطبّق الشيء الصحيح عن استخدامها، إذ يبلغ حجم الحزمة 200K تقريبًا في مثالنا لأنها تضمّنت مكتبة date-fns الكاملة، وليس الدالة التي نستخدمها فقط. إذا تجنّبنا استخدام أي أدوات تطوير واستخدمنا العنصر <script src=""> مع إصدار مستضاف من date-fns، فسيحدث الشيء نفسه تقريبًا، وستُنزَّل المكتبة عند تحميل صفحة مثالنا في المتصفح. يمكننا أن نطلب من البرنامج أثناء وجود الأدوات على أجهزتنا فحص استخدامنا للشيفرة وتضمين الدوال التي نستخدمها في مرحلة الإنتاج فعليً فقط، وهي عملية تُعرف باسم هز الشجرة Tree Shaking. يُعَد ذلك منطقيًا لأننا نريد تقليل حجم الملف وبالتالي تحميل تطبيقنا في أسرع وقت ممكن، وتتيح الأدوات المختلفة تطبيق تقنية هز الشجرة بطرق مختلفة. هناك ثلاثة عروض رئيسية للأدوات التي تنشئ حزمًا من الشيفرة المصدرية هي: Webpack وRollup وParcel. سيكون هناك مزيد من الخيارات المتاحة، لكن تُعَد الأنواع التالية شائعة الاستخدام: تقدم أداة RollUp تقنية هز الشجرة وتقسيم الشيفرة. تتطلب أداة Webpack إعدادًا، بالرغم من أن البعض يقلل من تعقيد إعداد Webpack الخاص بالمطورين. هناك في حالة Parcel -قبل الإصدار Parcel 2- راية خاصة مطلوبة هي --experimental-scope-hoisting التي ستهز الشجرة أثناء البناء. لنستخدم Parcel حاليًا، بما أننا ثبّتناها سابقًا. لنشغّل الأمر التالي: parcel build index.html --experimental-scope-hoisting سترى أن هذا الأمر يحدث فرقًا كبيرًا: ✨ Built in 7.87s. dist/my-project.86f8a5fc.js 10.34 KB 7.17s dist/index.html 288 B 753ms أصبح حجم الحزمة حوالي 10K، وهذا أفضل بكثير. إذا أردنا إصدار هذا المشروع إلى خادم، فسنعدّل الملفات الموجودة في مجلد dist، إذ تتعامل Parcel تلقائيًا مع جميع تغييرات اسم الملف. نوصي بإلقاء نظرة على الشيفرة المصدرية في dist/index.html لتتمكن من رؤية التغييرات التي أجرتها Parcel تلقائيًا. توجد الكثير من الأدوات المتاحة، وينمو نظام حزمة جافاسكربت المجتمعي بمعدل غير مسبوق، وهو أمر له إيجابيات وسلبيات. كما تُجرَى تحسينات طوال الوقت، لكن يجب معرفة قدرة الأداة قبل اختيارها. دليل عملاء مدير الحزم ثبّتنا في مثالنا حزمة Parcel باستخدام npm، ولكن هناك بعض البدائل كما ذكرنا سابقًا، لذلك لنلقِ نظرة عليها. سنذكر بعض مدراء الحزم وهي: npm في npmjs.org. pnpm في pnpm.js.org. yarn في yarnpkg.com. يتشابه npm وpnpm من وجهة نظر سطر الأوامر، ويهدف pnpm إلى الحصول على تكافؤ كامل مع خيارات الوسطاء التي يقدمها npm، ولكنهما يختلفان إذ يستخدم pnpm طريقة مختلفة لتنزيل الحزم وتخزينها على حاسوبك بهدف تقليل المساحة الإجمالية المطلوبة على القرص الصلب. سنستخدم npm في الأمثلة التالية، ويمكنك استخدام pnpm وسيعمل الأمر بطريقة صحيحة. يُعتقَد أن yarn أسرع من npm من ناحية عملية التثبيت في أغلب الأحيان، وهذا مهم للمطورين بسبب وجود قدر كبير من الوقت الضائع في انتظار تثبيت الاعتماديات والنسخ إلى الحاسوب. لنراجع الآن الإجراءات الشائعة التي يجب تنفيذها مع مدير الحزم. بدء مشروع جديد npm init yarn init ستوجهك الأوامر السابقة وترشدك عبر سلسلة من الأسئلة لوصف مشروعك مثل الاسم والترخيص والوصف وما إلى ذلك، ثم إنشاء ملف package.json الذي يحتوي على معلومات وصفية حول مشروعك واعتمادياته. تثبيت الاعتماديات npm install date-fns yarn add date-fns رأينا أمر التثبيت install قيد التنفيذ أعلاه الذي سيؤدي إلى إضافة حزمة date-fns مباشرة إلى دليل العمل ضمن دليل فرعي يسمى node_modules مع اعتماديات date-fns. سيثبّت الأمر السابق افتراضيًا أحدث إصدار من date-fns، ولكن يمكنك التحكم في ذلك، إذ يمكنك استخدام الأمر date-fns@1 الذي يمنحك أحدث إصدار من 1.x وهو 1.30.1، أو يمكنك تجربة الأمر date-fns@^2.3.0 الذي يعطي أحدث إصدار يتضمن الإصدار 2.3.0 أو بعده (2.8.1 في وقت كتابة النسخة الأجنبية من هذا المقال). تحديث الاعتماديات npm update yarn upgrade سينظر الأمر السابق في الاعتماديات المثبَّتة حاليًا ويحدّثها عند وجود تحديث متاح ضمن المجال المحدّد في الحزمة. حُدِّد المجال في إصدار الاعتمادية في ملف package.json الخاص بك مثل date-fns^2.0.1، إذ يعني المحرف ^ جميع الإصدارات الثانوية وإصدارات تصحيح الأخطاء التي تتضمن الإصدار 2.0.1 والإصدارات التي بعدها باستثناء الإصدار 3.0.0. يُحدَّد الإصدار باستخدام نظام يسمى semver الذي يبدو معقدًا بعض الشيء في توثيقه، ولكن يمكن تبسيطه من خلال النظر فقط في المعلومات الموجزة، ويُمثّل الإصدار بالشكل MAJOR.MINOR.PATCH مثل 2.0.1، إذ يمثل الرقم 2 الإصدار الرئيسي Major Version ويمثل الرقم 1 إصدار تصحيح الأخطاء Patch Version. يمكنك تجربة قيم Semver باستخدام حاسبة semver. يجب أن نتذكر أن الأمر npm update لن يرقّي الاعتماديات خارج المجال المحدَّد في ملف package.json، وإنما يثبت الإصدار الموجود على وجه التحديد. تدقيق الثغرات npm audit yarn audit سيؤدي الأمر السابق إلى التحقق من كامل شجرة اعتمادية مشروعك وتشغيل الإصدارات المحدَّدة التي تستخدمها لتلافي ثغرات قاعدة البيانات وإعلامك إذا كانت هناك حزم ذات ثغرات محتمَلة في مشروعك. يُعَد مشروع Snyk نقطة انطلاق جيدة للتعرف على الثغرات، والذي يغطي كلًا من حزم جافاسكربت ولغات البرمجة الأخرى. التحقق من الاعتمادية npm ls date-fns yarn why date-fns يظهِر الأمر السابق إصدار الاعتمادية المُثبَّتة وكيفية تضمينها في مشروعك، ويُحتمَل سحب حزمة أخرى ذات مستوى أعلى في date-fns. كما يمكن أن يكون لديك إصدارات متعددة من حزمة معينة في مشروعك، ولوحظ هذا الأمر عدة مرات مع حزمة lodash أنها مفيدة جدًا لضمان عمل كافة الشيفرة البرمجية. يمكن أن ترغب في التحقق بالضبط من الإصدار المثبت، بالرغم من أن مدير الحزم سيبذل قصارى جهده لإزالة تكرار الحزم. إنشاء أوامرك الخاصة يدعم مدير الحزم إنشاء أوامرك الخاصة وتنفيذها من سطر الأوامر، إذ يمكننا استخدام الأمر التالي مثلًا: npm run dev # أو yarn run dev سيؤدي الأمر السابق إلى تشغيل سكربت مخصص لبدء مشروعنا في وضع التطوير، ويمكننا تضمينه بانتظام في جميع المشاريع إذ يميل إعداد التطوير المحلي إلى العمل بطريقة مختلفة عن كيفية تشغيله في عملية الإنتاج. إذا حاولت تشغيل هذا السكربت في مشروع اختبار Parcel الخاص بك، فيُحتمَل أن يدّعي أن السكربت dev مفقود، لأن npm وyarn يبحثان عن خاصية تسمى dev ضمن الخاصية scripts لملف package.json الخاص بك. يمكن أن تشغّل Parcel خادم تطوير باستخدام الأمر parcel serve filename.html، لأننا سنرغب في استخدامه كثيرًا أثناء عملية التطوير، لذلك لننشئ أمر مخصَّصًا مختصرًا هو "dev" في ملف package.json. يجب أن يكون لديك ملف package.json ضمن الدليل parcel-experiment. افتحه ويجب أن تبدو الخاصية scripts كما يلي: "scripts": { "test": "echo \"Error: no test specified\" && exit 1", }, حدّثها لتبدو كما يلي، ثم احفظ الملف: "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "parcel serve index.html" }, أضفنا الأمر dev المخصص بوصفه سكربت npm. حاول الآن تشغيل الأمر التالي في طرفيتك، وتأكد من أنك ضمن الدليل parcel-experiment: npm run dev يجب أن يبدأ الأمر السابق Parcel ويقدم ملف index.html الخاص بك على خادم التطوير المحلي كما رأينا سابقًا: Server running at http://localhost:1234 ✨ Built in 5.48s. كما تُعَد أوامر npm وyarn ذكية من لأنها ستبحث عن أدوات سطر الأوامر المثبَّتة محليًا للمشروع قبل محاولة العثور عليها من خلال الطرق التقليدية، ويخزّن حاسوبك عادةً البرامج ويسمح بإيجادها. يمكنك معرفة المزيد حول تعقيدات الأمر run، بالرغم من أن سكربتاتك ستعمل بصورة جيدة في معظم الحالات. يمكنك إضافة جميع الأنواع إلى الخاصية scripts التي تساعدك على أداء عملك. إلى هنا تنتهي جولتنا في التعرف على مدير الحزم، وخطوتنا التالية هي بناء نموذج لسلسلة أدوات، ووضع كل ما تعلمناه حتى الآن موضع التنفيذ. هذا المقال جزء من سلسلة مقالات بعنوان تعلم تطوير الويب والتي تشرح كامل عملية تطوير الويب من واجهات أمامية وخلفية بالكامل. ترجمة -وبتصرُّف- للمقال Package management basics. اقرأ أيضًا المقال التالي: بناء نموذج كامل لسلسلة أدوات تطوير الويب من طرف العميل المقال السابق: أدوات مطوري الويب المدمجة في المتصفحات فهم أدوات تطوير الويب من طرف العميل مدخل إلى Helm: مدير حزم Kubernetes نظام إدارة الحزم NuGet في dot NET كيف تدير الحزم على نظام FreeBSD 10.1 بواسطة Pkg
-
سنتعرّف في هذا المقال على الوضع التفاعلي REPL في Node.js الذي نستخدمه في الطرفية لتقييم تعبير برمجي مكتوب بلغة javascript، كما سنتعلّم كيفية التعامل مع سطر الأوامر في Node.js من تمرير وسائط منه وإرسال مخرجات إليه وقبول مدخلات منه. استخدام الوضع التفاعلي REPL يسمى الوضع التفاعلي في Node.js باسم REPL اختصارًا إلى اقرأ-قيّم-اطبع-كرر Read-Evaluate-Print-Loop، أي اقرأ وقدِّر قيمة التعبير البرمجي ثم اطبع الناتج وكرر العملية، وهو طريقة رائعة لاستكشاف ميزات Node.js بطريقة سريعة. استعملنا الأمر node سابقًا لتشغيل أحد السكربتات: node script.js أما إذا حذفنا اسم الملف، فسندخل في الوضع التفاعلي REPL: node وعندما تجرب الأمر السابق في الطرفية عندك، فسيحدث ما يلي وسيبقى الأمر في وضع السكون وينتظر منك إدخال تعبير ما: $ node Welcome to Node.js v14.15.0. Type ".help" for more information. > إذا أردنا أن نكون أكثر دقةً، فإن الوضع التفاعلي ينتظر منّا إدخال شيفرة JavaScript، لذا لنبدأ بسطر بسيط: > console.log('test') test undefined > القيمة الأولى المطبوعة test هي ناتج الأمر الذي طلبنا منه طباعة سلسلة نصية إلى الطرفية، ثم حصلنا على القيمة undefined وهي القيمة المعادة من تنفيذ console.log()، ويمكننا الآن إدخال سطر JavaScript جديد. استخدام الزر tab للإكمال التلقائي من أجمل مزايا الوضع التفاعلي REPL هو أنه تفاعلي، ففي أثناء كتابك للشيفرة إذا ضغطت على زر tab، فسيحاول الوضع التفاعلي الإكمال التلقائي لما كتبته ليوافق اسم متغير عرفته مسبقًا. استكشاف كائنات JavaScript جرِّب إدخال اسم كائن من كائنات JavaScript مثل Number وأضف إليه نقطةً ثم اضغط على tab، إذ سيعرض لك الوضع التفاعلي جميع الخاصيات والتوابع التي يمكنك الوصول إليها في ذاك الكائن. استكشاف الكائنات العامة يمكنك معاينة الكائنات العامة بكتابة global. ثم الضغط على الزر tab: المتغير الخاص _ إذا كتبت _ بعد شيفرة ما، فسيؤدي ذلك إلى طباعة ناتج آخر عملية. الأوامر ذوات النقط يملك الوضع التفاعلي REPL بعض الأوامر الخاصة وكلها تبدأ بنقطة . وهي: .help: يظهر المساعدة للأوامر ذوات النقط. .editor: تفعيل وضع المحرر، وذلك لكتابة شيفرة JavaScript متعددة الأسطر بسهولة، وبعد دخولك في هذا الوضع وكتابتك للشيفرة المطلوبة، فيمكنك إدخال Ctrl+D لتنفيذ الأمر الذي كتبت. .break: إذا كتبت الأمر .break عند كتابتك لتعبير متعدد الأسطر، فستلغي أي مدخلات قادمة، ومثله مثل الضغط على Ctrl+C. .clear: إعادة ضبط سياق الوضع التفاعلي إلى كائن فارغ وإزالة أي تعابير متعددة الأسطر جرت كتابتها. .load: تحميل ملف JavaScript بمسار نسبي إلى مجلد العمل الحالي. .save: حفظ ما أدخلته في الجلسة التفاعلية إلى ملف مع تمرير مسار الملف بعد كتابة .save. .exit: الخروج من الوضع التفاعلي وهو يماثل الضغط على Ctrl+C مرتين. يعرِف الوضع التفاعلي REPL متى تكتب تعبيرًا متعدد الأسطر دون الحاجة إلى تشغيل الأمر .editor، فإذا بدأت مثلًا بكتابة حلقة تكرار مثل هذه: [1, 2, 3].forEach(num => { ثم ضغطت على زر enter، فسيعرف الوضع التفاعلي أنك تكتب تعبيرًا متعدد الأسطر ويبدأ سطرًا جديدًا بثلاث نقط …، مما يشير إلى أنك ما زلت تعمل على القسم أو المقطع نفسه: ... console.log(num) ... }) إذا كتبت .break في آخر السطر، فسيتوقف وضع تعدد الأسطر ولن يُنفَّذ التعبير الذي كتبته. تمرير الوسائط من سطر الأوامر إلى Node.js سنشرح في هذا القسم كيفية استقبال وسائط arguments في برنامج Node.js مُمرَّرة من سطر الأوامر، إذ يمكنك تمرير أي عدد من الوسائط أثناء تشغيل برنامج Node.js باستخدام الأمر: node app.js يمكن أن تكون الوسائط بمفردها، أو على شكل زوج من المفاتيح والقيم مثل: node app.js ahmed أو node app.js name=ahmed يجعل هذا طريقة الحصول على القيمة مختلفةً في شيفرة Node.js. إذ أنّ طريقة الحصول على الوسائط هي استخدام الكائن process المبني في Node.js، ففيه الخاصية argv التي هي مصفوفة تحتوي على جميع الوسائط الممررة عبر سطر الأوامر؛ ويكون الوسيط الأول هو المسار الكامل للأمر node، بينما الوسيط الثاني هو مسار الملف المُنفَّذ كاملًا، وجميع الوسائط الإضافية ستكون موجودةً من الموضع الثالث إلى آخره، كما يمكنك المرور على جميع المعاملات بما في ذلك مسار node ومسار الملف المُنفَّذ باستخدام حلقة تكرار: process.argv.forEach((val, index) => { console.log(`${index}: ${val}`) }) يمكنك الحصول على الوسائط الإضافية من خلال إنشاء مصفوفة جديدة تستثني أول قيمتين: const args = process.argv.slice(2) إذا كان لديك معامل بمفرده دون مفتاح مثل: node app.js ahmed فيمكنك الوصول إليه كما يلي: const args = process.argv.slice(2) args[0] أما في حالة كان الوسيط هو مفتاح وقيمة كما في: node app.js name=ahmed فإن قيمة args[0] هي name=ahmed، وستحتاج إلى تفسيرها، وأفضل طريقة هي استخدام المكتبة minimist التي تساعدنا بالتعامل مع الوسائط: const args = require('minimist')(process.argv.slice(2)) args['name'] // ahmed إرسال تطبيق Node.js المخرجات إلى سطر الأوامر سنتعلم كيفية الطباعة إلى سطر الأوامر باستخدام Node.js بدءًا من الاستخدام الأساسي للتابع console.log حتى وصولنا إلى الأمور المعقدة. طباعة المخرجات باستخدام الوحدة console توفِّر Node.js الوحدة console التي توفر عددًا كبيرًا من الطرائق المفيدة في التعامل مع سطر الأوامر، وهي تشبه إلى حد ما الكائن console الموجود في المتصفحات، والتابع الأساسي الأكثر استخدامًا في هذه الوحدة هو التابع console.log()، الذي يطبع السلسلة النصية التي تمررها إليه إلى الطرفية، وإذا مررت كائنًا فسيعرضه على أساس سلسلة نصية، كما يمكنك تمرير قيمًا متعددةً إلى التابع console.log() كما يلي، إذ ستطبع Node.js القيمتين x وy معًا: const x = 'x' const y = 'y' console.log(x, y) يمكنك أيضًا تنسيق السلاسل النصية بتمرير القيم ومُحدِّد التنسيق كما في المثال التالي: console.log('My %s has %d years', 'cat', 2) إذ أنّ محددات التنسيق format specifiers هي: %s: تنسيق المتغير على أساس سلسلة نصية. %d أو %i: تنسيق المتغير على أساس عدد صحيح. %f: تنسيق المتغير على أساس عدد ذي فاصلة عشرية. %O: تنسيق المتغير على أساس كائن كما في المثال البسيط الآتي: console.log('%O', Number) مسح محتوى الطرفية يمسح التابع console.clear() محتوى الطرفية، لكن يختلف سلوكه اعتمادًا على الطرفية المستخدَمة. عد العناصر يُعَدّ التابع console.count() مفيدًا في بعض الحالات التي تريد فيها عدّ المرات التي طُبِعَت فيها السلسلة النصية وإظهار الرقم بجوارها، خذ هذا المثال: const x = 1 const y = 2 const z = 3 console.count( 'The value of x is ' + x + ' and has been checked .. how many times?' ) console.count( 'The value of x is ' + x + ' and has been checked .. how many times?' ) console.count( 'The value of y is ' + z + ' and has been checked .. how many times?' ) يمكننا إحصاء عدد البرتقالات والتفاحات التي لدينا: const oranges = ['orange', 'orange'] const apples = ['just one apple'] oranges.forEach(fruit => { console.count(fruit) }) apples.forEach(fruit => { console.count(fruit) }) طباعة تتبع مكدس الاستدعاء قد تكون هنالك حالات من المفيد فيها طباعة تتبع مكدس الاستدعاء call stack trace لإحدى الدوال، وذلك للإجابة مثلًا على السؤال التالي: كيف وصلنا إلى هذا الجزء من الشيفرة، إذ يمكنك استخدام التابع console.trace(): const function2 = () => console.trace() const function1 = () => function2() function1() سيطبع مكدس الاستدعاء ما يلي، وهذا هو الناتج إذا جربنا الشيفرة السابقة في النمط التفاعلي REPL في Node.js: Trace at function2 (repl:1:33) at function1 (repl:1:25) at repl:1:1 at ContextifyScript.Script.runInThisContext (vm.js:44:33) at REPLServer.defaultEval (repl.js:239:29) at bound (domain.js:301:14) at REPLServer.runBound [as eval] (domain.js:314:12) at REPLServer.onLine (repl.js:440:10) at emitOne (events.js:120:20) at REPLServer.emit (events.js:210:7) طباعة الزمن المستغرق يمكنك ببساطة حساب مقدار الوقت الذي أخذته الدالة للتنفيذ باستخدام التابعين time() وtimeEnd() كما في المثال التالي: const doSomething = () => console.log('test') const measureDoingSomething = () => { console.time('doSomething()') // افعل شيئًا وقس الوقت المستغرق لتنفيذه doSomething() console.timeEnd('doSomething()') } measureDoingSomething() مجرى الخرج القياسي stdout والخطأ القياسي stderr رأينا أنّ التابع console.log() رائع لطباعة الرسائل في الطرفية، وهذا ما يسمى مجرى الخرج القياسي standard output stream أو stdout؛ أما التابع console.error() فسيطبع الرسائل المرسَلة إلى مجرى الخطأ القياسي stderr والتي لن تظهر في الطرفية وإنما ستظهر في سجل الخطأ. طباعة المخرجات بألوان مختلفة يمكنك أن تغيير لون المخرجات النصية في الطرفية باستخدام تسلسلات التهريب escape sequences، وتسلسل التهريب هو مجموعة من المحارف التي تُعرِّف لونًا معينًا في الطرفية مثل: console.log('\x1b[33m%s\x1b[0m', 'hi!') يمكنك تجربة ذلك باستخدام النمط التفاعلي في Node.js وستُعرَض السلسلة النصية hi! باللون الأصفر، لكن هذه الطريقة ذات مستوى منخفض، فأبسط طريقة لتلوين المخرجات في الطرفية هي باستخدام مكتبة مثل Chalk، حيث يمكنها أيضًا إجراء عمليات التنسيق الأخرى إضافةً إلى تلوينها للنص مثل جعل النص غامقًا أو مائلًا أو مسطرًا تحته، كما يمكنك تثبيتها باستخدام npm install chalk ثم استخدامها: const chalk = require('chalk') console.log(chalk.yellow('hi!')) من المؤكد أن استخدام chalk.yellow أكثر راحةً من محاولة تذكُّر شيفرات التهريب وستكون قابلية قراءة الشيفرة أفضل. إنشاء شريط تقدم في الطرفية تُعَدّ حزمة Progress حزمةً رائعةً لإنشاء شريط تقدُّم في الطرفية، حيث يمكنك تثبيتها باستخدام npm install progress ببساطة. تُنشِئ الشيفرة التالية شريط تقدُّم بعشر خطوات، حيث ستكتمل خطوة كل 100 ميللي ثانية، وحين اكتمال الشريط سنصفِّر العداد: const ProgressBar = require('progress') const bar = new ProgressBar(':bar', { total: 10 }) const timer = setInterval(() => { bar.tick() if (bar.complete) { clearInterval(timer) } }, 100) قبول المدخلات من سطر الأوامر يمكننا جعل تطبيق Node.js الذي يعمل من سطر الأوامر تفاعليًا باستخدام وحدة readline المبنية في أساس Node.js. أصبحت Node.js بدءًا من الإصدار السابع توفِّر الوحدة readline التي تحصل على المدخلات من مجرى قابل للقراءة مثل process.stdin (مجرى الدخل القياسي stdin) سطرًا بسطر والذي يكون أثناء تنفيذ برنامج Node.js من سطر الأوامر هو الدخل المكتوب في الطرفية. const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }) readline.question(`What's your name?`, (name) => { console.log(`Hi ${name}!`) readline.close() }) تسأل الشيفرة السابقة المستخدِم عن اسمه، وبعد كتابة المستخدِم الاسم والضغط على enter سنرسل تحيةً له. يُظهِر التابع question() المعامل parameter الأول -أي السؤال- وينتظر مدخلات المستخدِم، ثم يستدعي دالة رد نداء عندما يضغط المستخدِم على زر enter. لاحظا أننا أغلقنا واجهة readline في دالة رد النداء، كما توفِّر الواجهة readline توابعًا كثيرةً متعددةً وسنتركك لاستكشافها من توثيقها؛ أما إذا احتجت إلى إدخال كلمة مرور، فمن الأفضل إظهار رمز * بدلًا منها، وأسهل طريقة لذلك هو استخدام الحزمة readline-sync التي تشبه readline في الواجهة البرمجية وتستطيع التعامل مع هذه الحالة دون عناء، والخيار الممتاز والمتكامل هو الحزمة inquirer.js، حيث يمكنك تثبيتها باستخدام npm install inquirer، كما يمكنك إعادة كتابة الشيفرة السابقة كما يلي: const inquirer = require('inquirer') var questions = [{ type: 'input', name: 'name', message: "What's your name?", }] inquirer.prompt(questions).then(answers => { console.log(`Hi ${answers['name']}!`) }) تسمح لك مكتبة inquirer.js بفعل أمور كثيرة مثل الأسئلة متعددة الخيارات وأزرار الانتقاء والتأكيدات وغير ذلك، كما من المفيد معرفة جميع الخيارات المتاحة أمامنا خصوصًا التي توفِّرها Node.js، لكن إذا أردت التعامل مع مدخلات سطر الأوامر كثيرًا، فالخيار الأمثل هو مكتبة inquirer.js. ترجمة -وبتصرّف- للفصل Command Line من كتاب The Node.js handbook لصاحبه Flavio Copes. اقرأ أيضًا المقال التالي: دليلك الشامل إلى مدير الحزم npm في Node.js المقال السابق: مقدمة إلى Node.js تأمين تطبيق Node.js يعمل على الحاويات باستخدام Nginx و Let’s Encrypt و Compose Docker نشر تطبيق Node.js على الويب: خدمة هيروكو (Heroku) مثالًا
-
سيُطلَب منك بلا شك خلال عملية التطوير تشغيل بعض الأوامر في الطرفية Terminal أو على سطر الأوامر Command Line، لذلك سنقدّم من خلال هذا المقال مقدمة عن الطرفية، والأوامر الأساسية التي ستحتاج إلى إدخالها، وكيفية ربط الأوامر مع بعضها بعضًا، وإضافة أدوات واجهة سطر الأوامر Command Line Interface -أو CLI اختصارًا- الخاصة بك. المتطلبات الأساسية: الإلمام بأساسيات لغات HTML وCSS وجافاسكربت. الهدف: فهم سطر الأوامر أو الطرفية، والأوامر الأساسية التي يجب تعلمها، وكيفية تثبيت أدوات سطر أوامر جديدة. الطرفية Terminal الطرفية هي واجهة نصية تُستخدَم لتنفيذ البرامج النصية. إذا شغّلتَ أدوات تطوير الويب، فهناك فرصة كبيرة لفتح سطر الأوامر وتشغيل بعض الأوامر لاستخدام الأدوات التي اخترتها، إذ سيُشار إلى هذه الأدوات باسم أو أدوات واجهة سطر الأوامر Command Line Interface أو أدوات CLI اختصارًا. يمكن استخدام عدد كبير من الأدوات عن طريق كتابة الأوامر في سطر الأوامر، ويكون العديد منها مثبتًا مسبقًا على نظامك، ويمكن تثبيت أدوات أخرى من سجلات الحزم التي تشبه متاجر التطبيقات، ولكن تُستخدَم غالبًا للأدوات والبرامج المستندة إلى سطر الأوامر. يفتقر سطر الأوامر إلى تجربة المستخدم، بل إن التجربة الأولى مع سطر الأوامر غالبًا ما تكون متعبة وصعبة الاستخدام نسبيًا، إذ يحتوي على شاشة فارغة ومؤشر وامض مع قليل من المساعدة الواضحة المتاحة بشأن ما يجب تطبيقه، لكننا نعدك أن استخدامه سيصبح أسهل مع قليل من التوجيه والممارسة، وسنُساعدك في هذا المقال للبدء في هذه البيئة. نشأت الطرفية في الخمسينات والستينات من القرن الماضي، ولكن شكلها الأصلي لا يشبه ما نستخدمه اليوم. بقيت الطرفية منذ ذلك الحين ميزة ثابتة في جميع أنظمة التشغيل من أجهزة سطح المكتب إلى خوادم السحابة إلى الحواسيب الصغيرة مثل Raspberry PI Zero وحتى الهواتف المحمولة. توفر الطرفية وصولًا مباشرًا إلى نظام ملفات الحاسوب الأساسي والميزات منخفضة المستوى، وبالتالي تُعَد مفيدة لأداء المهام المعقدة بسرعة. كما أنها مفيدة في عملية الأتمتة مثل كتابة أمر لتحديث أسماء مئات الملفات فوريًا كتعديل اسم الملف "ch01-xxxx.png" إلى "ch02-xxxx.png"، فإذا حدّثتَ أسماء الملفات باستخدام تطبيق Finder أو Explorer GUI، فسيستغرق الأمر وقتًا طويلًا. يمكنك من خلال الشكل الآتي رؤية بعض الأشكال المختلفة للبرامج المتوفرة التي يمكن أن تنقلك إلى الطرفية، وتظهَر موجِّهات الأوامر المتوفرة في ويندوز مثل برامج Cmd و Powershell التي يمكن تشغيلها من قائمة ابدأ عن طريق كتابة اسم البرنامج. كما يوضّح الشكل التالي تطبيق طرفية نظام ماك macOS: كيفية الوصول إلى الطرفية يستخدم العديد من المطورين حاليًا أدوات تستند إلى يونيكس مثل الطرفية والأدوات التي يمكنك الوصول إليها من خلالها، إذ تدعم العديد من الأدوات الموجودة على الويب الأنظمة التي تستند إلى يونيكس، ولكن لا داعي للقلق، فهي متوفرة في معظم الأنظمة. سنوضّح فيما يلي كيفية الوصول إلى الطرفية على النظام الذي تريده. لينكس أو يونيكس: تحتوي أنظمة لينكس أو يونيكس طرفية متاحة افتراضيًا مدرجَة ضمن تطبيقاتك. نظام ماك macOS: يحتوي نظامًا يسمى داروين Darwin يقع أسفل واجهة المستخدم الرسومية ويشبه نظام يونيكس، ويوفر الطرفية والوصول إلى الأدوات ذات المستوى المنخفض. الطرفية متاحة على نظام ماك من خلال المسار Applications/Utilities/Terminal. ويندوز: لم يكن استخدام الطرفية أو سطر الأوامر على ويندوز بسيطًا أو سهلًا كما هو الحال في أنظمة التشغيل الأخرى، ولكن الأمور تتحسن مع مرور الوقت. لطالما امتلك ويندوز برنامجًا شبيهًا بالطرفية يسمى Cmd أو موجه الأوامر، ولكنه ليس متكافئًا مع أوامر يونيكس، بل يكافئ موجه ويندوز دوز Windows DOS ذي النمط القديم. توجد برامج أفضل لتوفير طرفية على ويندوز مثل PowerShell وGitbash الذي يكون جزءًا من مجموعة أدوات git for Windows. لكن أفضل خيار لنظام ويندوز حاليًا هو نظام ويندوز الفرعي لنظام لينكس Windows Subsystem for Linux -أو WSL اختصارًا، وهو طبقة توافق لتشغيل أنظمة تشغيل لينكس مباشرة من داخل الإصدار رقم 10 من ويندوز، مما يتيح لك تشغيل طرفية حقيقية مباشرة على ويندوز دون الحاجة إلى آلة افتراضية، ويمكن تثبيت نظام WSL مباشرة من متجر ويندوز مجانًا. نوصي بشدة بتثبيت نظام WSL، ويمكنك التمسك باستخدام موجّه الأوامر الافتراضي cmd إذ ستعمل أدوات متعددة بطريقة صحيحة، ولكنك ستجد الأمور أسهل إذا كان لديك تكافؤ أفضل مع أدوات يونيكس. هناك فرق بين الطرفية وسطر الأوامر، فالطرفية تقنيًا هي برنامج يبدأ ويتصل بالصدفة Shell التي تُعَد بيئة جلستك إذ يمكنك تخصيص أشياء مثل الموجه والاختصارات، بينما سطر الأوامر هو السطر الحرفي الذي تكتب فيه الأوامر ويومض المؤشر. إذا استخدمت أدواتٍ مثل Visual Studio Code، فهناك مجموعة كبيرة من الامتدادات التي يمكن استخدامها كوكيل Proxy لاستخدام أوامر الطرفية دون الحاجة إلى استخدامها مباشرة، وبالرغم من وجود الكثير من الأدوات المتاحة في سطر الأوامر. لكنك لن تجد امتدادًا لمحرر الشيفرات لكل ما تريده، لذلك سيتعين عليك اكتساب خبرة في استخدام الطرفية في النهاية. أوامر المدمجة الأساسية في الطرفية إليك بعض الأشياء التي يمكن لسطر الأوامر تطبيقها، بالإضافة إلى أسماء الأدوات ذات الصلة بكل حالة: انقل نظام ملفات حاسوبك إلى جانب مهام المستوى الأساسي مثل الإنشاء والنسخ وإعادة التسمية والحذف: التنقل بين المجلدات باستخدام الأمر cd. إنشاء مجلد باستخدام الأمر mkdir. إنشاء ملفات وتعدّيل بياناتها الوصفية باستخدام الأمر touch. نسخ الملفات باستخدام الأمر cp. نقل الملفات باستخدام الأمرmv. حذف الملفات أو المجلدات باستخدام الأمر rm. تنزيل الملفات الموجودة في عناوين URL محدَّدة باستخدام الأمر curl. البحث عن أجزاء نصية ضمن مجموعات نصية أكبر باستخدام الأمر grep. عرض محتويات ملف بمقدار صفحة تلو الأخرى باستخدام الأمر less وcat. معالجة وتحويل مجاري النصوص مثل تغيير جميع وسوم <div> في ملف HTML إلى <article> باستخدام الأوامر awk وtr وsed. التنقل في سطر الأوامر ستحتاج حتمًا إلى الانتقال إلى مسار معين عندما تزور سطر الأوامر. تشغّل جميع أنظمة التشغيل برنامجها الطرفي في المسار الموجود فيه سطر الأوامر، وغالبًا سترغبُ بالانتقال إلى لمسار مختلف. يتيح لك الأمر cd تغيير الدليل Change Directory، وليس هذا الأمر برنامجًا وإنما مبني مسبقًا، إذ لا يمكنك حذفه عن طريق الخطأ. لا داعي للقلق كثيرًا بشأن ما إذا كان الأمر مبنيًا مسبقًا أم لا، ولكن ضع في بالك أن الأوامر المبنية مسبقًا تظهر في جميع الأنظمة القائمة على نظام يونيكس. يمكنك تغيير المسار من خلال كتابة الأمر cd في الطرفية متبوعًا بالمجلد الذي تريد الانتقال إليه. يمكنك استخدام الأمر cd Desktop بافتراض وجود المجلد ضمن المسار الرئيسي كما يلي: اكتب الأمر التالي في طرفية نظامك: cd Desktop إذا أردتَ الرجوع إلى المسار السابق، فيمكنك استخدام نقطتين كما يلي: cd.. هناك اختصار في الطرفية مفيد جدًا وهو استخدام مفتاح tab لإكمال الأسماء تلقائيًا التي تعرف أنها موجودة بدلًا من كتابة اسم المجلد بالكامل فمثلًا كتابة الأمر cd D ثم الضغط على مفتاح tab، سيكمل سطر الأوامر كتابة اسم المجلد Desktop نيابةً عنك، بشرط وجوده في المجلد الحالي. إذا كان المجلد الذي تريد الانتقال إليه متداخلًا، فيجب أن تعرف المسار للوصول إليه، إذ يصبح ذلك أسهل عندما تصبح أكثر دراية بمعمارية نظام ملفاتك، ولكن إن لم تكن متأكدًا من المسار، فيمكنك اكتشافه باستخدام الأمر ls، ومن خلال النقر في نافذة المستكشف Explorer أو Finder لمعرفة مكان المجلد بناءً على مكان وجودك حاليًا. إذا أردت الانتقال مثلًا إلى مجلد يسمى src يقع ضمن مجلد اسمه project موجود على سطح المكتب Desktop، فيمكنك كتابة هذه الأوامر الثلاثة للوصول إلى هناك من مجلدك الرئيسي كما يلي: cd Desktop cd project cd src ولكن يمكنك كتابة أمر واحد مع العناصر المختلفة في المسار مفصول بينها بشرطة مائلة للأمام، تمامًا كما تفعل عند تحديد مسارات للصور أو الأصول الأخرى في شيفرة CSS أو HTML أو جافاسكربت: cd Desktop/project/src لاحظ أن تضمين شرطة مائلة في المسار يجعله مسارًا مطلقًا مثل /Users/your-user-name/Desktop، إذ يؤدي حذف الشرطة المائلة في المقدمة كما فعلنا سابقًا إلى جعل المسار مسارًا نسبيًا متعلقًا بمجلد العمل الحالي، وهذا هو بالضبط ما تراه مع عناوين URL في متصفح الويب، إذ تعني الشرطة المائلة في البداية جذر موقع الويب، بينما يعني حذف الشرطة المائلة أن عنوان URL متعلق بصفحتي الحالية. يستخدم نظام ويندوز الشرطة المائلة للخلف بدلًا من الشرطة المائلة للأمام مثل الأمر التالي: cd Desktop\project\src سرد محتويات مجلد الأمر ls مبني مسبقًا في نظام التشغيل يونيكس وهو اختصار للكلمة الأجنبية List، ووظيفته سرد محتويات المجلد الذي تتواجد فيه حاليًا. لاحظ أن هذا الأمر لن ينجح إذا استخدمتَ موجّه أوامر ويندوز الافتراضي cmd، فالأمر المكافئ له هو dir. شغّل الأمر التالي في الطرفية: ls يمنحك الأمر ls قائمة بالملفات والمجلدات الموجودة في مجلد العمل الحالي، ولكنها معلومات أساسية، وستحصل فقط على اسم كل عنصر موجود دون معرفة نوعه. يمكن أن يمنحك تغيير بسيط في استخدام هذا الأمر كثيرًا من المعلومات. خيارات الأوامر تحتوي معظم أوامر الطرفية على خيارات، هي المعدّلات Modifiers التي تضيفها إلى نهاية الأمر، مما يجعله يتصرف بطريقة مختلفة. تتكون هذه الخيارات عادةً من مسافة بعد اسم الأمر، متبوعة بشرطة، متبوعة بحرف واحد أو أكثر. جرب الأمر التالي على سبيل المثال، وشاهد النتيجة: ls -l يمنحك الخيار -l في الأمر ls قائمة بملف أو مجلد واحد في كل سطر ومعلومات أخرى. يمكن التعرف على المجلدات من خلال البحث عن الحرف "d" على الجانب الأيسر من السطور، إذ يمكننا استخدام الأمر cd مع هذه المجلدات. يوضّح الشكل الآتي طرفية نظام ماك الصرفة في الجزء العلوي، وطرفية مخصّصة مع بعض الرموز والألوان الإضافية في الجزء السفلي، وكلاهما يعرض نتائج تشغيل الأمر ls -l: الإنشاء والنسخ والنقل والإزالة هناك عدد من الأوامر الأساسية الأخرى التي يُحتمَل أن تستخدمها كثيرًا أثناء عملك مع الطرفية. هذه الأوامر بسيطة جدًا، لذا لن نشرحها بقدر كبير من التفاصيل مثل الأمرين السابقين. استخدم أمثلة الأوامر التالية لفهمها: mkdir: يؤدي هذا الأمر إلى إنشاء مجلد جديد ضمن المجلد الحالي الذي تتواجد فيه، مع الاسم الذي تقدمه بعد الأمر، فمثلًا سينشئ الأمر mkdir my-awesome-website مجلدًا جديدًا اسمه my-awesome-website. rmdir: يزيل هذا الأمر المجلد المحدد إذا كان فارغًا فقط، فمثلًا سيزيل الأمر rmdir my-awesome-website المجلد الذي أنشأناه سابقًا. إذا أردتَ إزالة مجلد غير فارغ وإزالة كل ما يحتويه، فيمكنك استخدام الخيار -r وهو اختصار recursive تكراري، ولكن يجب الانتباه عند استخدامه، إذ يجب أن تتأكد من عدم وجود أيّ شيء يمكن أن تحتاجه داخل المجلد، إذ سيختفي إلى الأبد. touch: ينشئ هذا الأمر ملفًا فارغًا جديدًا ضمن المجلد الحالي، فمثلًا ينشئ الأمر touch mdn-example.md ملفًا فارغًا جديدًا اسمه mdn-example.md. mv: ينقل هذا الأمر ملفًا من موقع الملف الأول المحدَّد إلى موقع الملف المحدد الثاني، وينقل الأمر mv mdn-example.md mdn-example.txt الملف mdn-example.md في المجلد الحالي إلى الملف mdn-example.txt في المجلد الحالي (تُكتَب المواقع كمسارات ملفات)، إذ يُعَد الملف منقولًا، ولكن هذا الأمر يعيد تسمية الملف فعليًا. cp: يشبه الأمر mv في الاستخدام، إذ ينشئ الأمر cp نسخة من الملف الموجود ضمن الموقع الأول المحدد في الموقع الثاني المحدَّد، إذ يُنشئ الأمر cp mdn-example.txt mdn-example.txt.bak نسخة من الملف mdn-example.txt بالاسم mdn-example.txt.bak، ويمكنك بالطبع تسمية هذه النسخة باسم آخر إذا أدرتَ ذلك. rm: يزيل هذا الأمر الملف المحدَّد، فمثلًا يحذف الأمر rm mdn-example.txt ملفًا اسمه mdn-example.txt. لاحظ أن هذا الحذف نهائي ولا يمكن التراجع عنه عبر سلة المحذوفات الموجودة غالبًا على واجهة مستخدم سطح المكتب. تسمح لك العديد من أوامر الطرفية باستخدام العلامات النجمية بوصفها محارف بدل Wild Card مع أيّ تسلسل من المحارف، مما يسمح بتشغيل عملية على عدد كبير من الملفات في الوقت نفسه، وتتطابق جميعها مع النمط المحدد، إذ يحذف الأمر rm mdn-* جميع الملفات التي تبدأ بسلسلة المحارف mdn-، بينما يحذف الأمر rm mdn-*.bak جميع الملفات التي تبدأ بسلسلة المحارف mdn- وتنتهي بسلسلة المحارف .bak. هل تعد الطرفية خطيرة؟ عليك توخي الحذر عند استخدام الطرفية. لا تحمل الأوامر البسيطة الكثير من المخاطر، ولكن إذا جمّعتَ أوامرًا أكثر تعقيدًا، فعليك التفكير مليًا فيما ستفعله هذه الأوامر، ومحاولة اختبارها أولًا قبل تشغيلها في المجلد المحدَّد. لنفترض أن لديك 1000 ملف نصي في مجلد، وأردت الاطلاع عليها جميعًا وحذف الملفات التي يحتوي اسمها على سلسلة فرعية معينة. إن لم تكن حذرًا، يمكن أن ينتهي بك الأمر بحذف شيء مهم، وبالتالي تفقد عملك خلال هذه العملية. إحدى العادات الجيدة التي يجب عليك اتباعها هي كتابة الأمر ضمن محرر نصوص، ثم إنشاء نسخة احتياطية من مجلدك وتشغيل الأمر على هذه النسخة أولًا لاختباره. إن لم تكن مرتاحًا لتجربة أوامر الطرفية على جهازك الخاص، فيمكنك تجربتها في مكان آمن هو Glitch.com الذي يُعَد مكانًا رائعًا لتجربة شيفرة تطوير الويب، بالإضافة إلى إمكانية الوصول إلى طرفية، إذ يمكنك تشغيل كل هذه الأوامر مباشرة فيها. يُعَد tldr.sh من الموارد الرائعة للحصول على نظرة عامة وسريعة على أوامر طرفية معينة، وهي خدمة توثيق مقادَة من المجتمع على غرار MDN، ولكنها خاصة بالأوامر الطرفية. لنتعلّم الآن كيفية توصيل الأدوات مع بعضها في سطر الأوامر. ربط الأوامر باستخدام الأشرطة العمودية تعرّفنا سابقًا على الأمر ls الذي يعرض محتويات المجلد الحالي: ls ولكن إذا أردنا حساب عدد الملفات والمجلدات بسرعة ضمن المجلد الحالي، فلن يستطيع الأمر ls ذلك من تلقاء نفسه. هناك أداة أخرى متاحة من يونيكس تسمى wc تحسب عدد الكلمات أو الأسطر أو المحارف أو البايتات لكل ما يُوضَع فيها، إذ يمكن أن يكون ذلك ملفًا نصيًا، إذ ينتج عن تنفيذ الأمر التالي عدد الأسطر في الملف myfile.txt: wc -l myfile.txt كما يمكنها حساب عدد الأسطر لخرج أي أمر يُربَط معها من خلال رمز الشريط العمودي |، وسيحسبُ الأمر التالي عدد الأسطر الناتجة عن الأمر ls -أي ما سيطبعه إلى الطرفية إذا شُغِّل بمفرده- ويخرج عدد الأسطر في الطرفية: ls | wc -l بما أن الأمر ls يطبع كل ملف أو مجلد على سطر خاص به، فهذا يعطينا عدد الأدلة والملفات بفعالية. تطبع أدوات سطر أوامر يونيكس النص إلى الطرفية، ويشار إليها بالطباعة إلى الخرج المعياري Printing To Standard Output أو STDOUT اختصارًا، إذ يمكن لعدد كبير من الأوامر قراءة المحتوى من مجرى الدخل المعروف باسم الدخل المعياري Standard Input أو STDIN اختصارًا. يربط المعامل | هذه المدخلات والمخرجات مع بعضها، مما يسمح ببناء عمليات أكثر تعقيدًا لتناسب احتياجاتنا، إذ يمكن أن يصبح خرج أحد الأوامر دخلًا للأمر الذي بعده. يطبع الأمر ls عادةً خرجه إلى STDOUT، ولكن يُربَط خرجه مع الأمر wc من خلال الرمز | سيأخذ الأمر wc هذا الخرج بوصفه دخلًا له، ويحسب عدد الأسطر، ويطبعها إلى STDOUT. مثال أكثر تعقيدا سنحاول أولًا جلب محتويات صفحة "fetch" من MDN باستخدام الأمر curl الذي يمكن استخدامه لطلب المحتوى من عناوين URL مثل الرابط الآتي: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch كما يلي: curl https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch لن تحصل على خرج بسبب إعادة توجيه الصفحة إلى /Web/API/fetch، إذ يجب إعلام الأمر curl صراحةً باتباع عمليات إعادة التوجيه باستخدام الراية -L. لنلقِ نظرةً على الترويسات التي يعيدها developer.mozilla.org باستخدام الراية -I الخاصة بالأمر curl، ونطبع جميع عمليات إعادة التوجيه التي يرسلها الموقع إلى الطرفية عن طريق ربط خرج الأمر curl مع الأمر grep باستخدام الرمز |، وسنطلبُ من الأمر grep إعادة جميع الأسطر التي تحتوي على الكلمة "location". حاول تشغيل الأمر التالي (لاحظ أن هناك إعادة توجيه واحدة فقط قبل أن نصل إلى الصفحة الأخيرة): curl https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch -L -I | grep location يجب أن يبدو الخرج كما يلي، إذ سينتج الأمر curl أولًا بعض عدّادات التنزيل أو ما شابه ذلك: location: /en-US/docs/Web/API/fetch كما يمكننا تحويل محتويات سطور الموقع location:، وإضافة الأصل الأساسي إلى بداية كل منها لنحصل على عناوين URL كاملة مطبوعة، لذلك سنضيف الأمر awk، وهي لغة برمجة تشبه جافاسكربت أو روبي Ruby أو بايثون Python، ولكنها أقدم منها. شغّل الأمر التالي: curl https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch -L -I | grep location | awk '{ print "https://developer.mozilla.org" $2 }' ويجب أن يكون الخرج النهائي كما يلي: https://developer.mozilla.org/en-US/docs/Web/API/fetch خصّصنا الخرج من خلال دمج هذه الأوامر لإظهار عناوين URL الكاملة التي يعيد خادم Mozilla التوجيه من خلالها عندما نطلب العنوان /docs/Web/API/WindowOrWorkerGlobalScope/fetch. إضافة مزايا ألقينا نظرة على بعض الأوامر المبنية مسبقًا التي يأتي نظامك مزودًا بها، ولنلقِ نظرة الآن على كيفية تثبيت أداة CLI لجهة خارجية والاستفادة منها. يتوفر حاليًا النظام المجتمعي الواسع للأدوات القابلة للتثبيت لتطوير واجهة الويب الأمامية ضمن npm، وهي خدمة استضافة حزم يملكها القطاع الخاص، وتعمل بصورة وثيقة مع Node.js، ولكن يمكنك أن تتوقع رؤية مزيد من مزودي الحزم مع مرور الوقت. يؤدي تثبيت Node.js إلى تثبيت أداة سطر أوامر npm وأداة إضافية تعتمد على npm تسمى npx، وتوفر أداة npm بوابة لتثبيت أدوات سطر أوامر إضافية. يعمل Node.js وnpm بالطريقة نفسها في جميع الأنظمة: ماك macOS وويندوز Windows ولينكس Linux. ثبّت أداة npm على نظامك الآن مع تنزيل وتشغيل مثبّت Node.js المناسب لنظام تشغيلك. إذا طُلب منك ذلك، فتأكد من تضمين npm كجزء من عملية التثبيت. كما سنتعرّف على أداة Prettier، وهي أداة لتنسيق الشيفرات البرمجية وتحتوي على عدة خيارات بسيطة. مكان تثبيت أدوات CLI يمكننا تثبيت الأدوات بطريقة عامة باستخدام npm لنتمكن من الوصول إليها في أي مكان، أو محليًا في مجلد المشروع الحالي. هناك إيجابيات وسلبيات في كل طريقة، وهذه القائمة توضح إيجابيات وسلبيات التثبيت العام للأدوات: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } إيجابيات التثبيت العام سلبيات التثبيت العام يمكن الوصول إليها من أي مكان في الطرفية يمكن ألّا تكون متوافقة مع شيفرة مشروعك تُثبَّت مرة واحدة فقط لن يتمكن المطورون الآخرون في فريقك من الوصول إلى هذه الأدوات، مثل مشاركة قاعدة شيفرتك عبر أداة مثل git. يستهلك مساحة أقل على القرص الصلب تتعلق هذه النقطة بالنقطة السابقة، إذ يصعب نسخ شيفرة المشروع (إذا ثبّت أدواتك محليًا، فيمكن إعدادها كاعتماديات وتثبيتها باستخدام الأمر npm install). الإصدار نفسه دائمًا يبدو مثل أي أمر يونيكس آخر يُحتمَل أن يكون التأثير السلبي للتثبيت العام أكبر بكثير من الفوائد بالرغم من أن قائمة السلبيات أقصر، ولكننا سنثبّت الأدوات بطريقة عامة لإبقاء الأمور بسيطة. سنلقي نظرة أكثر على عمليات التثبيت المحلية وفوائدها في المقال التالي. تثبيت Prettier سنثبّت أداة Prettier بوصفها أداة مساعدة عامة لسطر الأوامر، وهي أداة تنسيق شيفرة لمطوري الواجهة الأمامية، وتركز على اللغات المستندة إلى لغة جافاسكربت بالإضافة إلى دعمها لغات HTML و CSS و SCSS و JSON وغير ذلك. يمكن أن تطبّق أداة Prettier ما يلي: حفظ العبء المعرفي المتمثل في جعل النمط متسقًا يدويًا عبر جميع ملفات شيفرتك، إذ يمكن أن تطبّق Prettier ذلك تلقائيًا. مساعدة المتعلمين الجدد في تطوير الويب على تنسيق شيفرتهم من خلال تطبيق أفضل الممارسات. يمكن تثبيتها على أي نظام تشغيل وكجزء مباشر من أدوات المشروع، مما يضمن لزملائك وأصدقائك الذين يعملون على شيفرتك أن يستخدموا نمط الشيفرة الذي تستخدمه. يمكن تهيئتها للتشغيل عند الحفظ، أو أثناء الكتابة، أو حتى قبل نشر الشيفرة. افتح الطرفية بعد تثبيت نود وشغّل الأمر التالي لتثبيت Prettier: npm install --global prettier تصبح بعد ذلك أداة Prettier متاحة في الطرفية وفي أيّ مكان في نظام ملفاتك. سيؤدي تشغيل الأمر بدون أي وسطاء -كما هو الحال مع العديد من الأوامر الأخرى- إلى تقديم معلومات حول كيفية الاستخدام والمساعدة. جرب الأمر التالي وشاهد النتيجة: prettier يجب أن يبدو الخرج كما يلي: Usage: prettier [options] [file/glob ...] By default, output is written to stdout. Stdin is read if it is piped to Prettier and no files are given. … يجب دائمًا الاطلاع على معلومات الاستخدام على الأقل، حتى لو كانت طويلة، لأنها ستساعدك في فهم كيفية استخدام الأداة بطريقة أفضل. لنجرب استخدام الأداة Prettier لنتمكن من معرفة كيفية عملها. أنشئ أولًا مجلدًا جديدًا في مكان ما على نظام ملفاتك يسهل العثور عليه مثل مجلد اسمه prettier-test على سطح المكتب Desktop، ثم احفظ الشيفرة التالية في ملف جديد يسمى index.js ضمن مجلد الاختبار: const myObj = { a:1,b:{c:2}} function printMe(obj){console.log(obj.b.c)} printMe(myObj) يمكننا أن نشغّل prettier في قاعدة الشيفرة للتحقق من حاجة شيفرتنا لتعديلٍ ما. شغّل الأمر cd للانتقال إلى مجلدك، وشغّل الأمر التالي: prettier --check index.js ويجب أن تحصل على الخرج التالي: Checking formatting... index.js Code style issues found in the above file(s). Forgot to run Prettier? لذلك هناك بعض أنماط الشيفرات التي يمكن إصلاحها، سيؤدي إضافة الخيار --write إلى الأمر prettier إلى إصلاح هذه المشاكل، مما يجعلنا نركز على كتابة شيفرة مفيدة فقط. شغّل إصدار الأمر التالي: prettier --write index.js وستحصل على الخرج التالي: Checking formatting... index.js Code style issues fixed in the above file(s). ولكن إذا نظرت إلى ملف جافاسكربت الخاص بك، فستجد أنه منسَّق مثل الشيفرة التالية: const myObj = { a: 1, b: { c: 2 }, }; function printMe(obj) { console.log(obj.b.c); } printMe(myObj); يمكنك جعل هذا التنسيق جزءًا تلقائيًا من عمليتك بناءً على طريقة سير عملك. الأتمتة هي المكان الذي تتفوق فيه الأدوات، وأفضل أتمتة هي الأتمتة الذي "يحدث على الفور" دون الحاجة إلى إعداد أي شيء. هناك عدد من الطرق التي يمكن من خلالها تحقيق الأتمتة مع أداة Prettier. هناك بعض الموارد الممتازة عبر الإنترنت للمساعدة، على الرغم من أن ذلك خارج نطاق هذا المقال. يمكنك استدعاء أداة Prettier: قبل تأكيد شيفرتك في مستودع git باستخدام Husky. عندما تضغط على "حفظ" في محرر الشيفرة، سواء أكان محرر VS Code أو Atom أو Sublime Text. بوصفها جزءًا من فحوصات التكامل المستمرة باستخدام أدوات مثل Github Actions. تفضيلنا الشخصي هو الخيار الثاني -أثناء استخدام محرر VS Code، وتعمل Prettier على تشغيل وتنظيف أي تنسيق تحتاجه في كل عملية حفظ. أدوات أخرى إليك قائمة مختصرة ممتعة من الأدوات لتجربتها: bat: النسخة الأفضل من الأداة cat (تُستخدم cat لطباعة محتويات الملفات). prettyping: نفّذ الأمر ping على سطر الأوامر. تُعَد أداة ping مفيدة للتحقق مما إذا كان الخادم يستجيب. htop: عارض للعمليات، مفيد عندما يكون هناك شيء ما يجعل مروحة وحدة المعالجة المركزية الخاصة بك تتصرف مثل محرك نفاث وتريد تحديد البرنامج المخالف. tldr: متاح بوصفه أداة لسطر الأوامر. لاحظ أن بعض الاقتراحات السابقة يمكن أن تحتاج إلى التثبيت باستخدام npm، كما فعلنا مع Prettier. هذا المقال جزء من سلسلة مقالات بعنوان تعلم تطوير الويب والتي تشرح كامل عملية تطوير الويب من واجهات أمامية وخلفية بالكامل. ترجمة -وبتصرُّف- للمقال Command line crash course. اقرأ أيضًا المقال التالي: أدوات مطوري الويب المدمجة في المتصفحات المقال السابق: فهم أدوات تطوير الويب من طرف العميل كيف تستخدم أدوات المطوِّر في المتصفحات الحديثة الفرق بين صفحة الويب وموقع الويب وخادم الويب ومحرك البحث
-
يمكن أن تكون أدوات تطوير الويب من طرف العميل غير مفهومة بالنسبة لكثير من المطورين، لذلك سنوضّح من خلال سلسلة من المقالات الغرض من بعض أدوات تطوير الويب الأكثر شيوعًا من طرف العميل، وسنشرح أيضًا الأدوات التي يمكنك ربطها مع بعضها بعضًا، وكيفية تثبيتها باستخدام مدير الحزم، والتحكم فيها باستخدام سطر الأوامر، وسنقّدّم مثالًا كاملًا عن سلسلة أدوات يوضح كيفية زيادة الإنتاجية، ولكن في البداية وقبل محاولة استخدام هذه الأدوات يجب أن تتعلم أساسيات لغات HTML وCSS وجافاسكربت JavaScript. وفّرنا من خلال موسوعة حسوب مرجعًا لكل من لغات HTML وCSS وJavaScript يمكنك البدء منه. سنوضح في هذه السلسلة من المقالات المواضيع التالية لفهم أدوات تطوير الويب من طرف العميل: نظرة عامة على أدوات تطوير الويب من طرف العميل: نقدّم في هذا المقال نظرة عامة على أدوات الويب الحديثة، وأنواع الأدوات المتاحة وأين ستصادفها في دورة حياة تطوير تطبيقات الويب، وكيفية العثور على المساعدة باستخدام هذه الأدوات. دورة مكثفة لفهم سطر الأوامر: سيُطلب منك بلا شك تشغيل بعض الأوامر في الطرفية Terminal أو في سطر الأوامر خلال عملية التطوير، حيث يقدم هذا المقال مقدمة إلى الطرفية والأوامر الأساسية التي ستحتاج إلى إدخالها، وكيفية ربط الأوامر مع بعضها بعضًا، وكيفية إضافة أدوات واجهة سطر الأوامر Command Line Interface -أو CLI اختصارًا. أساسيات إدارة الحزم: سنلقي نظرة على مدراء الحزم بشيء من التفصيل لفهم كيفية استخدامها في مشاريعك لتثبيت اعتماديات Dependencies أدوات المشروع وتحديثها وغير ذلك. سلسلة أدوات كاملة: سنعمل في المقالين الأخيرين من السلسلة على ترسيخ معرفتك بالأدوات من خلال إرشادك خلال عملية بناء نموذج لسلسلة أدوات عن طريق إعداد بيئة تطوير ووضع أدوات التحويل في مكانها لنشر تطبيقك فعليًا على Netlify. كما سنقدم دراسة حالة مع إعداد بيئة التطوير الخاصة بنا وإعداد أدوات تحويل شيفرتنا. نشر التطبيق: سنأخذ في المقال الأخير من هذه السلسلة مثالًا عن سلسلة الأدوات التي أنشأناها في المقال السابق ونضيفها لنتمكن من نشر التطبيق، إذ سنرفع الشيفرة البرمجية للمشروع على موقع مشاركة الشيفرات جيت هب GitHub، وننشرها باستخدام نيتليفاي Netlify، وسنوضّح كيفية إضافة اختبار بسيط لهذه العملية. لنبدأ بمقالنا الأول من هذه السلسلة من خلال إلقاء نظرة سريعة على أدوات تطوير الويب من طرف العميل. المتطلبات الأساسية: الإلمام بمفاهيم لغات HTML و CSS وجافاسكربت الأساسية. الهدف: فهم أنواع الأدوات من طرف العميل وكيفية العثور عليها والحصول على المساعدة بشأنها. استخدام الأدوات الحديثة أصبحت كتابة برمجيات الويب أكثر تعقيدًا بمرور الوقت، وبالرغم من ذلك لا يزال كتابة برمجيات الويب يدويًا بلغة HTML و CSS وجافاسكربت أمرًا ممكنًا إلا أنه يوجد الآن مجموعة كبيرة من الأدوات التي يمكن للمطورين استخدامها لتسريع عملية إنشاء موقع ويب أو تطبيق. توجد بعض الأدوات المستقرة التي أصبحت أسماء مألوفة وشائعة في مجتمع تطوير الويب، بالإضافة إلى الأدوات الجديدة التي نراها تصدر كل يوم لحل مشكلات معينة، فيمكن أن تكتب برنامجًا للمساعدة في عملية التطوير الخاصة بك ولحل مشكلة معينة لا يمكن أن تحلها الأدوات الحالية. يمكنك استخدام عدد هائل من الأدوات وتضمينها في مشروع واحد، كما يمكنك استخدام أداة واحدة مثل Webpack وإعداد ملف تكوينها من مئات الأسطر، وغالبًا ما ينظر المبرمجين المبتدئين لهذه الشيفرة وكأنها تعويذات تؤدي المهمة بطريقة سحرية ولن يفهمها إلا المهندسون الخبراء. إلا أنه في الواقع غالبية الخبراء يواجهون مشاكلًا في استخدام الأدوات من وقت لآخر، إذ يمكن إضاعة ساعات في محاولة تشغيل مسار أدوات قبل لمس سطر واحد من شيفرة التطبيق. لذلك لا داعي للقلق، فأنت لست وحدك. سنزودك من خلال هذا المقال بنقطة بداية مفيدة لفهم أساسيات استخدام أدوات الويب، إذ يُفضَّل أن تبدأ على نطاق صغير، ثم تشق طريقك تدريجيًا إلى الاستخدامات أكثر تقدمًا. نظام أدوات المطورين الحديث يعدّ النظام البيئي Ecosystem الحديث لأدوات المطورين في يومنا الحالي ضخم نسبيًا، لذا يجب من الأفضل تكوين فكرة عامة عن المشاكل الرئيسية التي تحلها هذه الأدوات. إذا انتقلت إلى محرك البحث المفضل لديك وبحثت عن "أدوات مطور الواجهة الأمامية"، فستصل لمجموعة كبيرة من النتائج تتراوح من محرّرات النصوص والمتصفحات وحتى نوع الأقلام التي يمكنك استخدامها لتدوين الملاحظات. وبالرغم من أن اختيارك لمحرّر الشيفرة هو بالتأكيد جزء من خيارات الأدوات، ولكن في هذه السلسلة من المقالات سنتجاوز ذلك من خلال التركيز على أدوات المطور التي تساعدك على إنتاج شيفرة ويب ذات كفاءة عالية. يمكنك تصنيف الأدوات من طرف العميل ضمن الفئات الثلاث التالية: شبكة الأمان Safety Net: أدوات مفيدة أثناء تطوير شيفرتك. التحويل Transformation: الأدوات التي تحول الشيفرة بطريقة ما مثل تحويل لغة وسيطة إلى لغة جافاسكربت التي يمكن أن يفهمها المتصفح. أدوات ما بعد التطوير Post-development: الأدوات المفيدة بعد كتابة شيفرتك مثل أدوات الاختبار والنشر. لنلقِ نظرة على كل واحدة من هذه الفئات بمزيد من التفصيل. شبكة الأمان هي الأدوات التي تحسّن شيفرتك البرمجية التي تكتبها، ويجب أن تكون هذه الأدوات خاصةً ببيئة التطوير الخاصة بك، بالرغم من ذلك من غير المألوف أن يكون لدى الشركات سياسة أو إعدادات جاهزة للتثبيت لكي تضمن أن يستخدم جميع مطوري هذه الشركات العمليات نفسها. تتضمن هذه الأدوات أيّ شيء يسهّل عملية التطوير فيما يتعلق بإنشاء شيفرة مستقرة وموثوقة. كما يجب أن تساعدك أدوات شبكة الأمان في منع حدوث الأخطاء أو تصحيحها تلقائيًا دون الحاجة إلى إنشاء شيفرة من نقطة الصفر في كل مرة. سنوضّح فيما يلي بعض أنواع أدوات شبكة الأمان الشائعة التي يستخدمها المطورون. منقحات الصياغة Linters منقحات الصياغة هي أدوات تتحقق من شيفرتك وتخبرك بوجود أخطاء وبأنواعها وسطور الشيفرة التي توجد فيها. يمكن ضبط منقحات الصياغة للإبلاغ عن الأخطاء، وللإبلاغ عن أيّ انتهاكات لدليل النمط المحدَّد الذي يستخدمه فريقك مثل الشيفرة التي تستخدم عددًا خاطئًا من المسافات البادئة، أو استخدام صياغة قالب Template Literals بدلًا من صياغة سلسلة نصية عادية String Literals. يعدّ Eslint منقّح أخطاء معياري خاص بلغة جافاسكربت ويمكن ضبط هذه الأداة لاكتشاف أخطاء الصياغة المحتملة وتشجيعك لاستخدام أفضل الممارسات ضمن شيفرتك البرمجية. شاركت بعض الشركات والمشاريع إعدادات Eslint الخاصة بها، ويمكنك العثور على أدوات اكتشاف أخطاء للغات أخرى مثل Csslint. كما يمكنك استخدام Webhint وهو منقح أخطاء مفتوح المصدر يمكن ضبطه للويب، ويعرض أفضل الممارسات لاستخدامها بما في ذلك أساليب الوصول والأداء والتوافق مع المتصفحات باستخدام بيانات توافق متصفح MDN والأمان واختبار تطبيقات الويب ذات الصفحة الواحدة PWA وغير ذلك. كما يتوفر كأداة سطر أوامر Node.js وكامتداد VS Code. التحكم بالشيفرة البرمجية يُعرَف أيضًا باسم أنظمة التحكم بالإصدارات Version Control Systems أو VCS اختصارًا، ويُعَد التحكم بالشيفرة البرمجية ضروريًا لدعم العمل الفردي أو ضمن فريق. يتضمن نظام VCS إصدارًا محليًا من الشيفرة التي تجري تغييرات عليها، ثم ترفع التغييرات إلى إصدار رئيسي من الشيفرة داخل مستودع بعيد مُخزَّن على خادم في مكان ما. هناك عادةً طريقة للتحكم في التعديلات التي تُطبَّق على النسخة الرئيسية من الشيفرة وتنسيقها ومتى تطبَّق، وبالتالي لا يكتب فريق المطورين فوق عمل بعضهم بعضًا. يعد نظام جيت هاب Git من أشهر نظم التحكم بالشيفرة البرمجية الذي يستخدمه معظم المطورين حاليًا، إذ يمكن الوصول إليه عبر سطر الأوامر أو عبر واجهات سهلة الاستخدام. كما يمكنك رفع نسخة من المشروع إلى الخادم الخاص بك باستخدام شيفرتك في مستودع جيت، أو يمكنك استخدام موقع ويب مستضاف للتحكم بالشيفرة المصدرية مثل جيت هب GitHub أو جيت لاب GitLab أو بيت باكيت BitBucket، ولكن سنستخدم GitHub في مثالنا. مُنسِّقات الشيفرة Code Formatters ترتبط مُنسِّقات الشيفرة إلى حد ما بمنقّحات الصياغة، باستثناء أنه بدلًا من الإشارة إلى الأخطاء في شيفرتك، فإنها عادةً ما تميل إلى التأكد من تنسيق شيفرتك الصحيح وفقًا لقواعد النمط الخاصة بك، وتعمل تلقائيًا على إصلاح الأخطاء التي تعثر عليها. أحد الأمثلة الشائعة لمنسقات الشيفرة البرمجية هو Prettier، والذي سنستخدمه لاحقًا في مثالنا. الحزم Bundlers أو Packagers هي الأدوات التي تجعل شيفرتك جاهزةً لعملية الإنتاج عن طريق تقنية هز الشجرة Tree-Shaking مثلًا للتأكّد من إدراج أجزاء مكتبات الشيفرة التي تستخدمها فعليًا فقط في شيفرة الإنتاج النهائي، أو التصغير Minifying لإزالة كل مسافة فارغة في شيفرة الإنتاج، مما يصغّرها قدر الإمكان قبل رفعها إلى الخادم. تعد أداة Parcel من الأدوات الذكية التي يمكنها تطبيق المهام المذكورة السابقة، كما أنها تساعد أيضًا في حزم الملفات أو الملحقات assets مثل HTML وCSS وملفات الصور ضمن حزم ملائمة يمكنك نشرها لاحقًا، وتضيف اعتماديات تلقائيًا كلما حاولت استخدامها. كما يمكن لهذه الأداة التعامل مع بعض مهام تحويل الشيفرة نيابة عنك. يذكر أن أداة ويب باك Webpack هي أشهر أداة حزم تطبّق مهامًا مماثلة. التحويل Transformation تتيح هذه المرحلة من دورة حياة تطبيق الويب كتابة شيفرة برمجية إما في شيفرة مستقبلية مثل تحويل الشيفرة البرمجية لأحدث ميزات لغة CSS أو جافاسكربت التي يمكن ألّا تدعمها بعض المتصفحات حتى الآن، أو إنشاء شيفرة برمجية مكافئة لشيفرة برمجية مكتوبة بلغة معينة مثل لغة TypeScript، لتتوافق الشيفرة التي أنشأتها الأداة المطلوبة مع المتصفح لاستخدامها في عملية الإنتاج. يُنظَر إلى تطوير الويب على أنه مؤلَّف من ثلاث لغات هي HTML وCSS وجافاسكربت، وهناك أدوات تحويل لجميع هذه اللغات. يقدّم التحويل فائدتين رئيسيتين هما: القدرة على كتابة شيفرة برمجية باستخدام أحدث ميزات اللغة وتحويلها إلى شيفرة تعمل على جميع الأجهزة، فيمكن أن ترغب مثلًا في كتابة شيفرة بلغة جافاسكربت باستخدام ميزات لغة جديدة متطورة، ولكن لا يزال لديك شيفرة الإنتاج النهائي التي تعمل على المتصفحات القديمة التي لا تدعم هذه الميزات. تشمل الأمثلة التالية: Babel: مصرّف جافاسكربت JavaScript الذي يسمح للمطورين بكتابة شيفرة باستخدام أحدث إصدارات جافاسكربت، والتي يأخذها Babel ويحوّلها إلى إصدار جافاسكربت قديم يمكن لمزيد من المتصفحات فهمه. كما يمكن للمطورين كتابة ونشر إضافات Babel. PostCSS: تطبّق هذه الأداة الشيء نفسه الذي يطبّقه Babel، ولكن مع ميزات CSS المتطورة. إذا لم تكن هناك طريقة مكافئة لتطبيق شيء ما باستخدام ميزات CSS القديمة، فسيثبّت PostCSS تعويض نقص دعم المتصفحات Polyfill بلغة جافاسكربت لمحاكاة تأثير CSS الذي تريده. خيار كتابة الشيفرة بلغة مختلفة تمامًا وتحويلها إلى لغة متوافقة مع الويب مثل: Sass / SCSS: يتيح لك هذا الامتداد من لغة CSS استخدام المتغيرات والقواعد المتداخلة والمزج والدوال والعديد من الميزات الأخرى، إذ يُعَد بعضها متاحًا في لغة CSS الأصلية مثل المتغيرات، وبعضها ليس كذلك. TypeScript: هي مجموعة شاملة من لغة جافاسكربت التي تقدم مجموعة من الميزات الإضافية. يحوّل مصرّف TypeScript شيفرة TypeScript إلى جافاسكربت عند البناء بهدف الإنتاج. توفّر أطر العمل مثل React وEmber وVue الكثير من الوظائف مجانًا وتسمح لك باستخدامها عبر صيغة مخصَّصة مبنية على لغة جافاسكربت الصرفة Vanilla JavaScript. تعمل شيفرة جافاسكربت الخاصة بإطار العمل في الخلفية لتفسير هذه البنية المخصَّصة وتقديمها بوصفها تطبيق ويب نهائي. أدوات ما بعد التطوير Post Development تضمن أدوات ما بعد التطوير أن يصل برنامجك إلى الويب ويستمر في عمله، إذ تتضمن مرحلة ما بعد التطوير عمليات النشر وأطر عمل الاختبار وأدوات التدقيق وغير ذلك. تُعَد هذه المرحلة بأنها المرحلة التي تحتاج أقل قدر من التفاعل النشط بحيث تُشغَّل تلقائيًا بمجرد تهيئتها، وتخبرك بحدوث خطأ ما. أدوات الاختبار Testing Tools تأخذ هذه الأدوات شكل أداة تختبر تلقائيًا شيفرت البرمجية للتأكد من صحتها قبل المضي قدمًا مثل رفع تعديلات إلى مستودع جيب هب GitHub Repo. يمكن أن يشمل ذلك الكشف عن الأخطاء Linting، ويشمل إجراءات أكثر تعقيدًا مثل اختبارات الوحدة إذ تشغّل جزءًا من شيفرتك، مع التأكد من أنها تتصرف كما ينبغي. تشمل أطر عمل اختبارات الكتابة Jest وMocha وJasmine. تتضمن أنظمة التشغيل والاختبارات الآلية Travis CI وJenkins وCircle CI وغيرها. أدوات النشر Deployment Tools تسمح أنظمة النشر بنشر موقع الويب الخاص بك، وهي متاحة لكل من المواقع الثابتة والديناميكية، وتميل للعمل جنبًا إلى جنب مع أنظمة الاختبار، إذ ستنتظرك سلسلة الأدوات إلى أن ترفع التغييرات إلى المستودع البعيد، وتجري بعض الاختبارات لمعرفة ما إذا كانت التغييرات مناسبة، وإذا نجحت الاختبارات، فستنشر تطبيقك تلقائيًا على موقع إنتاج. تعد Netlify واحدة من أكثر أدوات النشر شيوعًا في الوقت الحالي، ولكن هناك أدوات أخرى مثل Vercel وGithub Pages. أدوات ما بعد التطوير الأخرى هناك عدد من أنواع الأدوات الأخرى المتاحة للاستخدام في مرحلة ما بعد التطوير، بما في ذلك Code Climate لجمع مقاييس جودة الشيفرة، وامتداد متصفح Webhint لإجراء تحليل وقت التشغيل للتوافق مع المتصفحات وعمليات التحقق الأخرى، وGithub bots لتوفير المزيد من ميزات GitHub القوية، وUpdown لتوفير مراقبة وقت تشغيل التطبيق وغير ذلك الكثير. أنواع الأدوات تُطبَّق أنواع الأدوات المختلفة في دورة حياة التطوير وفق ترتيب معين، ولكن كن مطمئنًا أنك لست مضطرًا إلى أن يكون لديك كل هذه الأدوات لإصدار موقع ويب، فلن لا تحتاج لأيٍّ منها. لكن سيؤدي تضمين بعض هذه الأدوات في عملياتك إلى تحسين تجربة التطوير، ويُحتمَل أن يؤدي إلى تحسين جودة شيفرتك الإجمالية. يستغرق استقرار أدوات المطور الجديدة بعض الوقت حسب تعقيدها. تشتهر إحدى أشهر الأدوات وهي Webpack بكونها معقدة للغاية للتعامل معها، ولكن كان هناك ضغط كبير لتبسيط الاستخدام في أحدث إصدار رئيسي، لذا قُلٍّل الإعداد المطلوب إلى الحد الأدنى. ليس هناك حل سحري يضمن النجاح باستخدام الأدوات، ولكن ستجد تدفقات عمل تناسبك أو تناسب فريقك ومشاريعك مع زيادة خبرتك، ويجب أن تكون سلسلة الأدوات شيئًا يمكنك نسيانه وأن تركّز على العمل فقط، بمجرد تسوية جميع مكامن الخلل في العملية. كيفية اختيار أداة معينة والحصول عليها تميل معظم الأدوات إلى كتابتها وإصدارها بصورة منفصلة، لذلك لا تتوفر أبدًا في المكان أو التنسيق نفسه، على الرغم من وجود مساعدة شبه مؤكدة، فيمكن أن يكون العثور على مساعدة في استخدام أداة أو حتى اختيار الأداة التي تريد استخدامها أمرًا صعبًا. المعرفة حول أفضل الأدوات لاستخدامها هي معرفة مجتمعية إلى حد ما، مما يعني أنه إن لم تكن بالفعل في مجتمع الويب، فستكون معرفة الأدوات التي تريدها بالضبط أمرًا صعبًا، وهذا هو أحد الأسباب التي دفعتنا إلى كتابة هذه السلسلة من المقالات، ونأمل أن نقدم تلك الخطوة الأولى التي يصعب إيجادها بطريقة أخرى. ستحتاج على الأرجح إلى مجموعة الأشياء التالية: نجح المدرسون أو الموجهون أو الزملاء الطلاب ذوو الخبرة أو الزملاء الذين لديهم بعض الخبرة في حل هذه المشكلات من قبل، ويمكنهم تقديم المشورة. مكان محدد مفيد للبحث، إذ تكون عمليات البحث العامة على الويب عن أدوات مطور الواجهة الأمامية عديمة الفائدة إلا إن عرفتَ اسم الأداة التي تبحث عنها. إذا استخدمتَ مدير الحزم NPM لإدارة اعتمادياتك على سبيل المثال، فيُفضَّل الانتقال إلى صفحة npm الرئيسية والبحث عن نوع الأداة التي تبحث عنها. حاول مثلًا البحث عن "التاريخ date" إن أردتَ أداة تنسيق التاريخ، أو "المُنسِّق formatter" إذا كنت تبحث عن مُنسق شيفرة عام. انتبه إلى درجات الشعبية والجودة والصيانة، وآخر تحديث للحزمة. انقر على صفحات الأداة لمعرفة عدد تنزيلات الحزمة الشهرية، واحتوائها على توثيق جيد يمكنك استخدامه للتأكد من أنها تطبّق ما تريده، وبالتالي تُعَد مكتبة date-fns أداة تنسيق تاريخ جيدة لاستخدامها. إذا أردت البحث عن إضافة Plugin لدمج وظائف الأدوات في محرّر الشيفرة، فألقِ نظرة على صفحة الإضافات / الامتدادات لمحرر الشيفرة، وراجع حزم Atom وامتدادات VSCode على سبيل المثال. ألقِ نظرة على الامتدادات المميزة في الصفحة الأولى، وحاول مرة أخرى البحث عن نوع الامتداد الذي تريده (أو اسم الأداة مثل البحث عن "eslint" في صفحة امتدادات VSCode). إذا حصلتَ على نتائج، فألقِ نظرة على معلومات عدد النجوم أو التنزيلات التي يحتويها الامتداد، إذ يُعَد ذلك مؤشرًا على جودته. المنتديات المتعلقة بالتنمية لطرح أسئلة حول الأدوات التي يجب استخدامها مثل قسم الأسئلة والأجوبة البرمجية في أكاديمية حسوب. إذا اخترت أداة لاستخدامها، فيجب أن يكون طريقة فهم الأداة هو الصفحة الرئيسية لمشروع الأداة والذي يكون غالبًا موقع ويب كامل أو يكون مستندًا تمهيديًا واحدًا في مستودع الشيفرة. يمكن أن ترغب في العثور على بعض البرامج التعليمية المخصصة لبدء استخدام أنواع معينة من الأدوات، لذا تعد المقالات البرمجية ومقالات DevOps في أكاديمية حسوب أماكن الانطلاق الرائعة للبحث. يُحتمَل أن تمر عبر العديد من الأدوات المختلفة أثناء البحث عن الأدوات المناسبة لك، وأن تجربها لمعرفة ما إذا كانت منطقية ومدعومة جيدًا وتطبّق ما تريده منها. يُعَد كل ذلك مناسبًا للتعلم، وسيصبح الطريق أسلس كلما اكتسبت مزيدًا من الخبرة. الخلاصة قدّمنا من خلال هذا المقال مقدمة بسيطة عن أدوات الويب من طرف العميل، وسنقدّم في المقال القادم دورة مكثفة عن سطر الأوامر، إذ تُستدعَى كثير من الأدوات منه، وسنلقي نظرة على ما يمكن أن يفعله سطر الأوامر ثم نحاول تثبيت الأداة الأولى ونستخدمها. هذا المقال جزء من سلسلة مقالات بعنوان تعلم تطوير الويب والتي تشرح كامل عملية تطوير الويب من واجهات أمامية وخلفية بالكامل. ترجمة -وبتصرُّف- للمقالين Understanding client-side web development tools وClient-side tooling overview. اقرأ أيضًا مدخل إلى أدوات التطوير في متصفح الويب DevTools كيف تستخدم أدوات المطوِّر في المتصفحات الحديثة الفرق بين مصمم الويب ومطور الويب وكيفية معرفة الأنسب بينهما الأدوات المستخدمة في بناء مواقع ويب
-
بدأنا بالحديث عن شبكات التراكب ثم تطرقنا إلى شبكات الند للند ثم بروتوكول البت تورنت وسنكمل في هذا القسم الأخير في الحديث عن شبكات توزيع المحتوى. رأينا بالفعل كيف يسمح تشغيل بروتوكول HTTP عبر بروتوكول TCP لمتصفحات الويب باسترداد الصفحات من خوادم الويب، ولكن يعرف أي شخصٍ ينتظر إلى الأبد لاسترداد صفحة ويب أن النظام بعيدٌ عن الكمال. تُنشَأ شبكة الإنترنت الرئيسية backbone الآن من روابطٍ ذات 40 جيجابت في الثانية، لذلك ليس واضحًا سبب حدوث ذلك. هناك أربع نقاط اختناقٍ محتملة في النظام عندما يتعلق الأمر بتنزيل صفحات الويب هي: الميل الأول The first mile، حيث قد يحتوي الإنترنت على روابطٍ ذات سعةٍ عالية، ولكن هذا لا يساعدك على تنزيل صفحة ويب بصورةٍ أسرع عندما تكون متصلًا بخط DSL بسرعة 1.5 ميجابت في الثانية أو رابطٍ لاسلكي سيء الأداء. الميل الأخير The last mile، حيث يمكن أن يُحمَّل الرابط الذي يربط الخادم بالإنترنت بصورةٍ كبيرة عن طريق طلباتٍ كثيرة جدًا، حتى إذا كان حيز النطاق التراسلي bandwidth الإجمالي لذلك الرابط مرتفعًا جدًا. الخادم نفسه The server itself، حيث يحتوي الخادم على كميةٍ محدودةٍ من الموارد مثل وحدة المعالجة المركزية، والذاكرة، وحيز نطاق القرص الصلب وغير ذلك، ويمكن تحميله بصورةٍ كبيرة overload بسبب العديد من الطلبات المتزامنة. نقاط التناظر Peering points، حيث قد يكون لدى عددٍ من مزودي خدمة الإنترنت الذين يطبّقون جميعًا شبكة الإنترنت الرئيسية backbone أنابيبًا ذات حيز نطاقٍ تراسلي عالٍ، لكن لديهم القليل من الحافز لتوفير اتصالٍ عالي السعة لأندادهم؛ فإذا كنت متصلًا بمزود خدمة الإنترنت A وكان الخادم متصلًا بمزود خدمة الإنترنت B، فقد تُسقَط الصفحة التي تطلبها عند النقطة التي يتقابل فيها المزوّدان A وB مع بعضهما بعضًا. ليس هناك الكثير من الأشياء الممكن فعلها بشأن المشكلة الأولى، ولكن يمكن استخدام النسخ أو التضاعف لمعالجة المشكلات المتبقية، وتُسمّى الأنظمة المسؤولة عن ذلك بشبكات توزيع المحتوى Content Distribution Networks -أو اختصارًا CDNs-، حيث تدير أكاماي Akamai أشهر شبكة CDN. تتمثل فكرة شبكة CDN في توزيع مجموعةٍ من بدائل الخادم server surrogates جغرافيًا، والتي تضع الصفحات ضمن الذاكرة المخبئية في مجموعةٍ معينةٍ من خوادم الواجهة الخلفية backend servers. وبالتالي يمكن نشر الحِمل على عدة خوادم، بدلًا من أن ينتظر الملايين من المستخدمين إلى الأبد للاتصال عند ظهور قصةٍ إخباريةٍ كبيرة، حيث يُعرَف مثل هذا الموقف بالتجمّع المفاجئ flash crowd. وبدلًا من الاضطرار إلى عبور عددٍ من مزودي خدمة الإنترنت للوصول إلى الموقع www.cnn.com، فيجب أن يكون ممكنًا الوصول إلى خادمٍ بديلٍ دون الحاجة إلى عبور نقطة تناظر، إذا كانت هذه الخوادم البديلة منتشرةً عبر جميع مزودي خدمة الإنترنت الأساسيين. صيانةُ آلاف الخوادم البديلة في أنحاء شبكة الإنترنت مكلفٌ للغاية لأي موقعٍ يريد توفير وصولٍ أفضل إلى صفحات الويب الخاصة به. توفّر شبكات CDN التجارية هذه الخدمة للعديد من المواقع، وهذا يؤدي إلى تسديد التكلفة عبر العديد من العملاء. نسمّي هذه الخوادم خوادمًا بديلة، لكن يمكن عدّها ذواكرًا مخبئية caches. فإذا لم يكن لدى هذه الخوادم البديلة الصفحة التي طلبها العميل، فإنها تطلبها من خادم الواجهة الخلفية، ولكن عمليًا تنسخ خوادم الواجهة الخلفية بياناتها مسبقًا إلى الخوادم البديلة عوضًا عن انتظار الخوادم البديلة لطلبها عند الضرورة، وهذه نفس حالة توزيع الصفحات الثابتة فقط، التي لا تحوي محتوىً ديناميكيًا عبر الخوادم البديلة. يجب على العملاء الانتقال إلى خادم الواجهة الخلفية لأي محتوىً يتغير بصورةٍ متكررة، مثل نتائج الألعاب الرياضية وأسعار الأسهم، أو لأي محتوىً ينتج عن بعض العمليات الحسابية، مثل استعلام قاعدة البيانات. لا يحلّ وجودُ مجموعةٍ كبيرة من الخوادم الموزّعة جغرافيًا المشكلة تمامًا، حيث تحتاج شبكات CDN أيضًا إلى توفير مجموعةٍ من مُعيدات التوجيه redirectors التي تمرر طلبات العميل إلى الخادم الأنسب، كما هو موضحٌ في الشكل السابق. يتمثل الهدف الأساسي من معيدات التوجيه بتحديد الخادم لكل طلبٍ ينتج عنه أفضل وقت استجابةٍ response time للعميل؛ أما الهدف الثانوي فهو معالجة النظام عددًا من الطلبات في الثانية والتي يستطيع العتاد الأساسي مثل روابط الشبكة وخوادم الويب دعمها. يُعَد متوسط عدد الطلبات الممكن تلبيتها في فترةٍ زمنيةٍ معينة، والمعروفة باسم إنتاجية النظام system throughput، مشكلةً أساسيةً عندما يكون النظام تحت عبءٍ ثقيل، مثل وصول تجمّعٍ مفاجئ إلى مجموعةٍ صغيرةٍ من الصفحات أو هجماتٍ موزَّعة لحجب الخدمة Distributed Denial of Service -أو اختصارًا DDoS- على موقعٍ ما، كما حدث لمواقع CNN وYahoo والعديد من المواقع البارزة الأخرى في فبراير (شباط) عام 2000. تستخدم شبكات CDN عدة عواملٍ لتحديد كيفية توزيع طلبات العملاء، كأن يختار معيد التوجيه خادمًا بناءً على قرب شبكته لتقليل وقت الاستجابة، ولكن يُستحسَن موازنة الحمل بالتساوي عبر مجموعة من الخوادم لتحسين إنتاجية النظام الإجمالية، حيث يمكن تحسين كلٍّ من الإنتاجية ووقت الاستجابة إذا أخذت آلية التوزيع المكان ضمن حساباتها؛ أي تختار خادمًا يُحتمَل أن يكون لديه بالفعل الصفحة المطلوبة في ذاكرته المخبئية. سنشرح فيما يلي تركيبة العوامل التي يجب أن تستخدمها شبكة CDN. الآليات Mechanisms معيد التوجيه هو وظيفةٌ مجردة، على الرغم من أنه يظهر مثل شيءٍ قد يُطلَب من الموجّه فعله لأنه يمرر منطقيًا رسالة طلبٍ كما يمرر الموجّه الرزم. هناك العديد من الآليات الممكن استخدامها لتطبيق إعادة التوجيه redirection التي سنشرحها الآن؛ والتي سنفترض فيها لغرض هذه المناقشة معرفة كل معيد توجيه عنوان كل خادمٍ متاح، كما سنتخلى عن مصطلح بديل surrogate ونتحدث ببساطةٍ من حيث مجموعة من الخوادم. الآلية الأولى هي تطبيق إعادة التوجيه عن طريق تعزيز نظام DNS لإرجاع عناوين خوادم مختلفة للعملاء، حيث يمكن لخادم DNS إرجاع عنوان IP للخادم الذي يستضيف صفحات الويب الخاصة بموقع CNN والمعروف عنه أنه يحتوي على أخف حِمل، عندما يطلب أحد العملاء تحليل resolve الاسم www.cnn.com على سبيل المثال؛ بينما قد ترجع مجموعةٌ معينةٌ من الخوادم العناوين فقط بطريقة جولة روبن round robin الدورية. لاحظ أن دقة إعادة التوجيه المستندة إلى نظام DNS تكون عادةً على مستوى الموقع، مثل cnn.com عوضًا عن عنوان URL محدد، مثل: https://www.cnn.com/2020/11/12/politics Biden-wins-arizona index.html لكن يمكن للخادم إعادة كتابة عنوان URL عند إرجاع رابطٍ مضمَّن، وبالتالي توجيه العميل بفعالية إلى الخادم الأنسب لهذا الكائن المحدد. تستخدم شبكات CDN التجارية تركيبةً من إعادة كتابة عناوين URL مع إعادة التوجيه المستندة إلى نظام DNS، حيث يشير خادم DNS عالي المستوى أولًا ولأسبابٍ تتعلق بقابلية التوسع، إلى خادم DNS على المستوى الإقليمي، الذي يرد بعنوان الخادم الفعلي. تعدّل خوادم DNS فترات TTL لسجلات الموارد التي تعود إلى فترةٍ قصيرة جدًا مثل 20 ثانية، بهدف الاستجابة للتغيرات بسرعة، ويُعَد هذا ضروريًا حتى لا يضع العملاء النتائج في ذاكرةٍ مخبئية وبالتالي يفشلون في الرجوع إلى خادم DNS للحصول على أحدث ربطٍ بين عنوان URL والخادم. الآلية الثانية هي استخدام ميزة إعادة توجيه بروتوكول HTTP، حيث يرسل العميل رسالة طلبٍ إلى الخادم، الذي يستجيب بخادمٍ جديدٍ أفضل يتوجب على العميل الاتصال به للحصول على الصفحة. تتطلب إعادة التوجيه المستندة إلى الخادم وقتًا إضافيًا ذهابًا وإيابًا عبر الإنترنت، ويمكن أيضًا أن تكون الخوادم عرضةً للحِمل الزائد بسبب مهمة إعادة التوجيه redirection نفسها. بدلًا من ذلك، إذا كانت هناك عقدةٌ قريبةٌ من العميل، مثل وكيل ويب محلي local Web proxy على درايةٍ بالخوادم المتاحة، فيمكنها اعتراض رسالة الطلب وإرشاد العميل لطلب الصفحة من خادمٍ آخر مناسب. إما أن يكون معيد التوجيه في هذه الحالة ضمن نقطة اختناقٍ بحيث تمر جميع الطلبات التي تغادر الموقع من خلالها، أو سيتعيّن على العميل التعاون من خلال معالجة الوكيل صراحةً، كما هو الحال مع الوكيل الكلاسيكي وليس الوكيل الشفّاف transparent proxy؛ الذي هو خادمٌ يقع بين حاسوبك والإنترنت ويعيد توجيه طلباتك واستجاباتك دون تعديلها. قد تتساءل عن علاقة شبكات CDN بشبكات التراكب، حيث يتخذ معيد التوجيه المستند إلى الوكيل قرار توجيهٍ على مستوى التطبيق مثل عقدة التراكب، ويمرر طلبات HTTP بناءً على عنوان URL وعلى معرفته بموقع ومدى حِمل مجموعةٍ من الخوادم بدلًا من تمرير رزمة استنادًا إلى عنوانٍ ما address وبناءً على معرفته بمخطط الشبكة. لا تدعم معمارية الإنترنت الحالية إعادة التوجيه مباشرةً، حيث نعني بكلمة "مباشرةً" أن العميل يرسل طلب HTTP إلى معيد التوجيه، الذي يمرره إلى الوِجهة، بدلًا من تطبيق إعادة التوجيه بصورةٍ غير مباشرة عن طريق معيد التوجيه الذي يرجع عنوان الوجهة المناسب والعميل الذي يتصل بالخادم ذاته. السياسات Policies نستعرض الآن بعض الأمثلة عن السياسات التي قد يستخدمها مُعيدو التوجيه لتمرير الطلبات، حيث اقترحنا بالفعل سياسةً واحدةً بسيطةً وهي جولة روبن round-robin، وسيكون المثال الآخر هو اختيار أحد الخوادم المتاحة عشوائيًا. يوزع كلا الأسلوبين الحِمل بالتساوي عبر شبكة توصيل المحتوى، لكنهما لا يقلّلان من وقت الاستجابة المتوقَّع للعميل. من الواضح عدم أخذ هذين الأسلوبين قُرب الشبكة في حساباتهما، وتجاهلهما أيضًا للمنطقة المحلية؛ أي يُعاد توجيه الطلبات الخاصة بعنوان URL نفسه إلى خوادم مختلفة، مما يقلل من احتمالية تخديم الصفحة من الذاكرة المخبئية الموجودة ضمن الخادم المحدد. هذا يفرض على الخادم استرداد الصفحة من قرصه الصلب، أو ربما من خادم الواجهة الخلفية. كيف يمكن لمجموعةٍ موزعةٍ من معيدات التوجيه أن تتسبب في انتقال الطلبات لنفس الصفحة إلى نفس الخادم أو إلى مجموعةٍ صغيرةٍ من الخوادم دون تنسيقٍ عالمي؟ الإجابة بسيطةٌ وهي: تستخدم جميع مُعيدات التوجيه شكلًا من أشكال تطبيق التعمية hashing لربط عناوين URL بمجالٍ صغير من القيم. الفائدة الأساسية من هذا النهج هي أنه لا حاجة لوجود اتصالٍ بين معيدي التوجيه لتحقيق عمليةٍ منسقة؛ فإن عملية التعمية تنتج نفس الخرج بغض النظر عن معيد التوجيه الذي يتلقى عنوان URL. إذًا ما الذي يجعل مخطط التعمية جيدًا؟ مخطط تعمية النموذج الكلاسيكي، الذي يجري تعميةً على كل وحدة URL مع عددٍ من الخوادم، غير مناسبٍ لهذه البيئة، لأن حساب النموذج في حالة تغيير عدد الخوادم سيؤدي إلى تناقص الصفحات التي تحتفظ بتخصيصات الخادوم نفسها. لا نتوقع حدوث تغييراتٍ متكررةٍ في مجموعة الخوادم، إلا أن حقيقة إضافة خوادمٍ جديدة إلى المجموعة ستؤدي إلى إعادة تخصيص ضخمة أمرٌ غير مرغوبِ فيه. البديل هو استخدام نفس خوارزمية التعمية المستقرة التي ناقشناها سابقًا، حيث يجري كل معيد توجيه أولًا تعميةً على كل خادمٍ ضمن الدائرة، ثم يجري أيضًا تعميةً إلى قيمةٍ على الدائرة لكل عنوان URL واصل، ويُعيَّن عنوان URL للخادم الأقرب في الدائرة مع قيمة التعمية الخاصة به. فإذا فشلت العقدة في هذا المخطط، فسينتقل حِملُها إلى جيرانها على الدائرة، وبالتالي فإن إضافة أو إزالة خادمٍ يؤدي فقط إلى تغييراتٍ محلية في تخصيصات الطلب. يعرف كل معيد توجيه كيفية ربط مجموعة الخوادم مع الدائرة، لذلك يمكن لكل معيد توجيه اختيار الخادم الأقرب بصورةٍ مستقلة، على عكس حالة ند لند؛ حيث توجَّه الرسالة من عقدةٍ إلى أخرى من أجل العثور على الخادم الذي يكون معرّفه هو الأقرب إلى الكائنات. يمكن توسيع هذه الاستراتيجية بسهولة لأخذ حِمل الخادم ضمن حساباتنا، حيث نفترض معرفة معيد التوجيه الحِمل الحالي لكلٍ من الخوادم المتاحة. قد لا تكون هذه المعلومات محدَّثة تمامًا، ولكن يمكننا تخيل معيد التوجيه يحسب ببساطة عدد المرات التي مرر فيها طلبًا إلى كل خادمٍ في الثواني القليلة الماضية ويستخدم هذا العدد مثل تقديرٍ لحِمل هذا الخادم الحالي. يجري معيد التوجيه تعميةً على عنوان URL المُستقبَل مع كلٍ من الخوادم المتاحة ويرتّب القيم الناتجة، حيث تحدّد هذه القائمة المرتَّبة بفعالية الترتيب الذي سينظر فيه معيد التوجيه في الخوادم المتاحة، ثم يتحرّك معيد التوجيه في هذه القائمة حتى يعثر على خادمٍ يكون الحِمل عليه أقل من حدٍ معين. تتمثل فائدة هذا الأسلوب في أن ترتيب الخادم يختلف باختلاف عنوان URL، لذلك إذا فشل خادمٌ ما، فسيُوزَّع حِمله بالتساوي بين الأجهزة الأخرى. يُعَد هذا النهج أساس بروتوكول توجيه ذاكرة المصفوفة المخبئية Cache Array Routing Protocol -أو اختصارًا CARP- الموضّح في الشيفرة التالية: SelectServer(URL, S) for each server s in server set S weight[s] = hash(URL, address[s]) sort weight for each server s in decreasing order of weight if Load(s) < threshold then return s return server with highest weight يتغير هذا المخطط مع زيادة الحِمل من استخدام الخادم الأول فقط في القائمة المُرتَّبة إلى نشر الطلبات على عدة خوادم. ستعالج خوادمٌ أقل انشغالًا أيضًا بعضَ الصفحات التي تتعامل معها الخوادم المشغولة. بما أن هذه العملية تستند إلى حِمل الخادم الكلي عوضًا عن الطلب على كل صفحةٍ مفردة، فقد تجد الخوادمُ التي تستضيف بعض الصفحات المطلوبة المزيدَ من الخوادم التي تتشارك معها حِملها، أكثر من الخوادم التي تستضيف بصورةٍ جماعية صفحاتٍ غير مطلوبة. ستُنسَخ بعض الصفحات غير المطلوبة ضمن النظام لمجرد أنها مُستضافة على خوادمٍ مشغولة، وإذا أصبحت بعض الصفحات مطلوبةً للغاية، فيمكن أن تكون جميع الخوادم في النظام مسؤولةً عن خدمة هذه الصفحات. أخيرًا، يمكن إدخال تقارب الشبكة network proximity في المعادلة بطريقتين مختلفتين على الأقل. الطريقة الأولى هي إخفاء التمييز بين حِمل الخادم وتقارب الشبكة من خلال مراقبة المدة التي يستغرقها الخادم للاستجابة للطلبات واستخدام القياس الناتج مثل معاملٍ لحِمل الخادم في الخوارزمية السابقة. تميل هذه الإستراتيجية إلى تفضيل الخوادم القريبة / غير المحمَّلة كثيرًا على الخوادم البعيدة / المحمَّلة بصورةٍ كبيرة. تتمثل الطريقة الثانية في إدخال عامل التقارب في القرار في مرحلةٍ مبكرة عن طريق قَصر مجموعة الخوادم المرشَّحة التي رأيناها ضمن الخوارزميات المذكورة أعلاه على تلك الخوادم القريبة فقط. المشكلة الأصعب هي اختيار الخوادم التي يُحتمَل أن تكون قريبةً بصورةٍ مناسبة، حيث تتمثل إحدى الطرق في اختيار تلك الخوادم المتوفّرة فقط على نفس مزود خدمة الإنترنت مثل عملاء. تتمثل الطريقة الأعقد في النظر إلى خارطة الأنظمة المستقلة التي ينتجها بروتوكول BGP واختيار تلك الخوادم فقط التي تبعد عددًا معينًا من القفزات عن العميل على أنها خوادم مرشَّحة. البحث عن التوازن الصحيح بين تقارب الشبكة ومحلية ذاكرة الخادم المخبئية هو موضوع بحثٍ مستمر. منظور الفصل التاسع: السحابة هي شبكة الإنترنت الجديدة كما رأينا سابقًا، كان هناك انتقالٌ لتطبيقات الإنترنت التقليدية، مثل البريد الإلكتروني وخوادم الويب، من الأجهزة التي تعمل محليًا إلى الآلات الافتراضية التي تعمل ضمن سحاباتٍ سلعية. يتوافق هذا مع تحوُّلٍ في المصطلحات من خدمات الويب إلى الخدمات السحابية وتحولٍ أيضًا في العديد من التقنيات الأساسية المستخدمة من الآلات الافتراضية إلى الخدمات الصغيرة السحابية الأصلية. لكن تأثير السحابة على كيفية تطبيق تطبيقات الشبكة اليوم أكبر مما يوحي به هذا الانتقال، فهو مزيجٌ من السحابات السلعية وشبكات التراكب المشابهة لتلك الموضحة أعلاه، التي قد يكون لها التأثير الأكبر في النهاية. يحتاج التطبيق المستند إلى التراكب وجود بصمةٍ واسعةٍ ليكون فعالًا، أي وجود عدة نقاط تواجد حول العالم. تُنشَر موجهات IP على نطاقٍ واسع، لذلك إذا كان لديك إذنٌ لاستخدام مجموعةٍ منها مثل عقدٍ أساسية في شبكة التراكب الخاصة بك، فأنت جاهزٌ للعمل. لكن هذا لن يحدث، حيث لا يوجد مشغلو شبكات أو مسؤولو مؤسسةٍ على استعدادٍ للسماح للأشخاص العشوائيين بتحميل برمجيات التراكب على الموجهات الخاصة بهم. قد يكون خيارك التالي هو حشد موارد مواقع الاستضافة لبرمجيات التراكب الخاصة بك، حيث سينجح ذلك إذا اشتركت مع أشخاصٍ آخرين على هدفٍ واحد، مثل تنزيل الموسيقى المجانية. لكن انتشار تطبيق التراكب الجديد أمرٌ صعب، وحتى إذا حدث ذلك، فقد يكون التأكدُ من وجود سعةٍ كافيةٍ في أي وقتٍ لحمل كل حركة المرور التي يولدها تطبيقك مشكلةً، حيث ينجح ذلك أحيانًا مع الخدمات المجانية، ولكنه لن ينجح مع تطبيقٍ تأمل في تحقيق الربح منه. توجد طريقةٌ للدفع لشخصٍ ما مقابل حقوق تحميل وتشغيل برنامجك على خوادمٍ منتشرةٍ في جميع أنحاء العالم؛ وهذا هو بالضبط ما توفره السحابات السلعية مثل Amazon AWS و Microsoft Azure و Google Cloud Platform، حيث توفّر السحابة عددًا غير محدودٍ من الخوادم ظاهريًا، ولكنها لا تقل أهميةً، إن لم تكن الأهم، عن مكان وجود هذه الخوادم، حيث تُوزَّع على نطاقٍ واسع عبر أكثر من 150 موقعًا متصلًا بصورةٍ جيدة. لنفترض مثلًا أنك تريد بث مجموعةٍ من قنوات الفيديو أو الصوت الحية لملايين المستخدمين، أو أنك تريد دعم الآلاف من جلسات مؤتمرات الفيديو التي يربط كل منها عشرات المشاركين المُوزعين على نطاقٍ واسع. ستنشئ في كلتا الحالتين شجرة تراكب متعدد البث (شجرةٌ لكل قناة فيديو في المثال الأول، وشجرةٌ لكل جلسة مؤتمر في المثال الثاني)، مع وجود عقد التراكب في الشجرة في مجموعةٍ من تلك المواقع السحابية البالغ عددها 150 موقعًا. ثم تسمح للمستخدمين النهائيين، من متصفحات الويب ذات الأغراض العامة أو تطبيقات الهواتف الذكية المصممة لهذا الغرض، بالاتصال بشجرةٍ أو مجموعة شجرات البث المتعدد التي يختارونها. إذا كنت بحاجةٍ إلى تخزين قدرٍ من محتوى الفيديو أو الصوت لتشغيله في وقتٍ لاحق، لدعم تحويل الوقت time shifting؛ فيمكنك أيضًا شراء سعة تخزينٍ في بعض أو كل هذه المواقع السحابية، وبناء شبكة توزيع المحتوى الخاصة بك بفعالية. عُدَّ الإنترنت في الأصل مثل خدمة اتصالٍ بحتة، مع السماح لتطبيقات الحوسبة والتخزين بالتطور على أطراف الشبكة، لكن برمجيات التطبيقات اليوم هي لجميع الأغراض العملية المضمَّنة داخل الشبكة أو الموزَّعة عبرها، حيث تُعَد معرفة مكان نهاية الإنترنت وبداية السحابة أمرًا صعبًا، وسيستمر هذا المزج في التعمق حتى اقتراب السحابة من طرف الشبكة، مثل الاقتراب من آلاف المواقع التي ترتبط بها شبكات الوصول، وستقود تكاليفُ التوسّع الأجهزةَ العتادية المستخدَمة في بناء مواقع الإنترنت أو السحابة إلى أن تصبح عمومية. ترجمة -وبتصرّف- للقسم Overlay Networks من فصل Applications من كتاب Computer Networks: A Systems Approach. اقرأ أيضًا المتطلبات اللازمة لبناء شبكة حاسوبية البرمجيات المستخدمة في بناء الشبكات الحاسوبية معمارية الشبكة الحاسوبية وشبكة الإنترنت (Network Architecture) الشبكات الحاسوبية متعددة الوصول (Multi-Access Networks)
-
سنتعلّم من خلال هذا المقال كيفية إنشاء مذياع في برنامج الإليستريتور Adobe Illustrator باستخدام الأشكال الأساسية مثل المستطيلات والمستطيلات ذات الزوايا المستديرة والدوائر، بالإضافة إلى تقنيات رسم الأشكال المتجهة vector، بعد ذلك سنضيف الظلال والإضاءات إلى المذياع لجعله أكثر لمعانًا وثلاثي الأبعاد. إنشاء مستند جديد شغّل برنامج الإليستريتور Illustrator ثم اضغط على الاختصار Ctrl + N لإنشاء مستند جديد. حدّد خيار البكسلات Pixels من قائمة الوحدات Units، وأدخِل القيمة 834 في خانة العرض width والقيمة 700 في خانة الارتفاع height، ثم انقر على خيارات متقدمة Advanced. حدّد نمط الألوان RGB والخيار Screen (72ppi)، وتأكّد من إلغاء تحديد مربع اختيار محاذاة الكائنات الجديدة إلى شبكة البكسلات Align New Objects to Pixel Grid قبل النقر على موافق OK. إنشاء جسم المذياع استخدم أداة المستطيل Rectangle Tool (باستخدام الاختصار M) لإنشاء مستطيل أبعاده 518×333 بكسل، ثم أنشئ نسخةً منه باستخدام الاختصار Ctrl + C ثم Ctrl + F، واستبدل لون حدّ stroke هذه النسخة الحالي باللون الأحمر. حدّد المستطيل الأحمر وانتقل إلى قائمة تأثير Effect ثم Stylize ثم زوايا مستديرة Round Corners، ثم أدخِل نصف قطر Radius مقداره 105 بكسلات وانقر على موافق، ثم انتقل إلى قائمة كائن Object ثم توسيع المظهر Expand Appearance. استخدم أداة التحديد المباشر Direct Selection Tool باستخدام الاختصار A، لتحديد نقطة ارتكاز الكائن الأحمر المميزة باللون الأزرق ثم أزِلها. حدّد بعد ذلك نقطة الارتكاز العلوية اليمنى وحرّكها بمقدار 7 بكسلات إلى اليسار، ثم حدّد نقطة الارتكاز السفلية اليمنى وحرّكها بمقدار 50 بكسلًا إلى اليسار. حدّد نقطة الارتكاز المميزة باللون الأسود وانقر على أيقونة "تحويل نقاط الارتكاز المحدَّدة إلى سلِسة Convert selected anchor points to smooth" من شريط خصائص Properties، ثم انقر على مقبض هذه النقطة العلوي، واضغط على الفأرة واسحبه للأعلى. حدّد بعد ذلك نقطتي الارتكاز المميزتين باللون الأزرق وأزِلهما، ثم حدّد نقطتي الارتكاز المميزتين باللون الأرجواني وحرّكهما بمقدار 100 بكسل إلى اليمين. حدّد الكائن الأحمر وانتقل إلى قائمة كائن Object ثم تحويل Transform ثم انعكاس Reflect، واضبط المحور Axis على الخيار رأسي Vertical، ثم انقر على نسخ Copy. حدّد هذه النسخة واستمر في الضغط على مفتاح Shift، ثم انقر على المستطيل الأسود الذي أنشأناه في الخطوة رقم 2، ثم حرّر مفتاح Shift وانقر على المستطيل الأسود مرةً أخرى (لتثبيت موضعه). افتح لوحة المحاذاة Align (من قائمة Window ثم Align) وانقر على زر المحاذاة اليسرى أفقيًا Horizontal Align Left. أعِد تحديد الكائنين الملوّنين باللون الأحمر، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر دمج Unite، ثم حدّد المستطيل الأسود وأزِله. حدّد الكائن الأحمر وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار غير موحّد Non-Uniform، وأدخِل القيمة 95 في خانة أفقي Horizontal، ثم انقر على نسخ Copy. استبدل لون حدّ هذه النسخة الحالي باللون الأسود ثم حرّكه بمقدار 57 بكسلًا للأعلى. استخدم أداة التحديد المباشر A لتحديد نقطة ارتكاز الكائن الأسود العلوية اليسرى وحرّكها بمقدار 5 بكسلات إلى اليمين، ثم حدّد نقطة الارتكاز العلوية اليمنى وحرّكها بمقدار 5 بكسلات إلى اليسار. حدّد الكائن الأحمر، وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، حدّد هذه النسخة واستمر في الضغط على مفتاح Shift ثم انقر على الكائن الأسود، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر Minus Back. حدد الكائن الأحمر وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم استبدل لون حدّ هذه النسخة الحالي باللون الأزرق واجلبه إلى الأمام باستخدام الاختصار Ctrl + Shift + Right Square Bracket. اختر أداة إضافة نقطة ارتكاز Add Anchor Point Tool (+)، وانقر على النقطتين المميزتين باللون الأحمر في الكائن الأزرق، مما يؤدي إلى إضافة نقطتي ارتكاز جديدتين إليه. استخدم أداة التحديد المباشر (A) مع مفتاح Shift لتحديد نقاط الارتكاز العلوية الأربع من الكائن الأزرق وحرّكها بمقدار 112 بكسلًا للأسفل. اختر أداة تحويل نقاط الارتكاز Convert Anchor Point Tool باستخدام الاختصار Shift + C، ثم انقر على المقبض العلوي لنقطة الارتكاز العلوية اليسرى من الكائن الأزرق واضغط على الفأرة، ثم اسحب هذا المقبض إلى الجهة السفلية اليمنى. انقر بعد ذلك على المقبض العلوي لنقطة الارتكاز العلوية اليمنى، واضغط على الفأرة، ثم اسحب هذا المقبض إلى الجهة السفلية اليسرى. حدّد الكائن الأحمر الذي أنشأناه في الخطوة رقم 4 ثم أزِل حدّه واملأه بالتدرج اللوني الخطي linear gradient الموضّح أدناه. أنشئ نسخةً من الشكل الناتج بالضغط على Ctrl + C ثم Ctrl + F، ثم استبدل لون تعبئة هذه النسخة الحالي باللون الرمادي الفاتح (# e7dfd0). حدّد الشكل الناتج وانتقل إلى قائمة تأثير Effect ثم Stylize ثم Feather، وأدخِل نصف قطر مقداره 20 بكسلًا وانقر على موافق. حدّد الكائن الأسود الذي أنشأناه في الخطوة رقم 5، ثم أزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه. حدّد الكائن الأزرق الذي أنشأناه في الخطوة رقم 6 وأنشئ نسخةً منه باستخدام الاختصار Ctrl + C ثم Ctrl + F، ثم اضغط على الاختصار Ctrl +3 لإخفاء هذه النسخة. أخيرًا، أعِد تحديد الكائن الأزرق الأصلي، وأزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه. اضغط على الاختصار Ctrl + Alt +3 لإظهار الكائن الذي أخفيناه في الخطوة رقم 7. حدّد هذا الكائن واستبدل لون حدّه الحالي باللون الأزرق الفاتح (# 0074bd) وغيّر ثُخن هذا الحد إلى 1.5 بكسل. استخدم أداة التحديد المباشر (A) ومفتاح Shift لتحديد نقطتي الارتكاز المميزتين باللون الأحمر، ثم انقر على أيقونة "قص المسارات عند نقاط الارتكاز المحدَّدة Cut paths at selected anchor points" من شريط خصائص Properties، مما يجعل الكائن مؤلفًا من مسارين. أعِد تحديد المسار العلوي وأنشئ نسخة منه بالضغط على Ctrl + C ثم Ctrl + F، بعد ذلك حرّك هذه النسخة بمقدار 2 بكسل للأسفل. حدّد هذا المسار، واستبدل لون حدّه الحالي باللون السماوي (# 41b8bd). حدد المسار السفلي الذي أنشأناه في الخطوة رقم 8، وغيّر ثُخن حدّه إلى 3 بكسلات واستبدل لون الحدّ الحالي باللون الأزرق الزاهي (# 239ef1)، ثم طبّق الخيار Width Profile 1 على المسار الناتج. حدّد المسار الناتج، واستخدم أداة إضافة نقطة ارتكاز Add Anchor Point (+) لإضافة نقطتي ارتكاز عند النقاط المميّزة باللون الأحمر. أعِد تحديد نقطتي الارتكاز اللتين أنشأناهما للتو وانقر على أيقونة "قص المسارات عند نقاط الارتكاز المحدَّدة Cut paths at selected anchor points" من شريط خصائص Properties، مما يجعل المسار مؤلفًا من ثلاثة مسارات، ثم حدّد المسارين الأقصر وأزِلهما. أعِد تحديد المسار المتبقي وحرّكه بمقدار 1 بكسل للأسفل، ثم طبّق عليه تأثير Gaussian Blur بمقدار 3 بكسلات. حدّد الآن الشكل الأزرق الذي أنشأناه في الخطوة رقم 7 وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام Ctrl + Shift + Right Square Bracket. أبقِ هذه النسخة محدَّدةً واستمر في الضغط على مفتاح Shift، ثم انقر على المسار الذي طبّقنا عليه تأثير الضبابية blur في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة. حدّد الشكل الرمادي الفاتح الذي طبّقنا عليه تأثير Feather في الخطوة رقم 7 وأنشئ نسخةً منه، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). حدّد هذه النسخة، وافتح لوحة Appearance من قائمة Window ثم Appearance، وأزِل تأثير feather. أزِل لون تعبئة الشكل الناتج، ثم أضِف له حدًا باللون الأحمر مقداره 1 بكسل. حدّد الكائن الأحمر وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Non-Uniform، ثم أدخِل القيمة 98 في خانة أفقي Horizontal والقيمة 94 في خانة رأسي Vertical، ثم انقر على موافق. حدّد الكائن الناتج وافتح نافذة Scale مرةً أخرى، ثم حدّد الخيار موحّد Uniform، وأدخِل القيمة 95 في قسم Scale وانقر على نسخ Copy، ثم حرّك هذه النسخة بمقدار 1 بكسل للأعلى و5 بكسلات إلى اليسار. أعِد تحديد الكائنين الملونين باللون الأحمر اللذين أنشأناهما في الخطوة الحالية، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر Minus Front. حدّد الكائن الناتج، ثم أزِل حدّه واملأه باللون الرمادي الداكن (# 7a7b80). طبّق تأثير Gaussian Blur بمقدار 3 بكسلات على الشكل الناتج، ثم اضبط نمط المزج Blending Mode على الخيار Multiply وقلّل التعتيم Opacity إلى 40%. حدّد الشكل الرمادي الفاتح الذي طبّقنا عليه تأثير Feather في الخطوة رقم 7 مرةً أخرى وأنشئ نسخةً منه، ثم أحضِر هذه النسخة إلى الأمام عن طريق الاختصار Ctrl + Shift + Right Square Bracket. حدّد هذه النسخة، واستمر في الضغط على مفتاح Shift وانقر على الشكل الذي طبّقنا عليه تأثير blur في الخطوة الحالية، ثم انقر بزر الفأرة الأيمن على لوحة الرسم، وحدّد الخيار إنشاء قناع قطع Make Clipping Mask من القائمة. استخدم أداة القلم Pen Tool (باستخدام الاختصار P) لإنشاء شكل أبيض (# ffffff) كما هو موضّح أدناه، ثم طبّق تأثير Gaussian Blur بمقدار 6 بكسلات، مع ضبط نمط المزج على الخيار Lighten. حدّد الشكل الناتج واضغط على الاختصار Ctrl + X لقصه، ثم اختر أداة التحديد Selection Tool (باستخدام الاختصار V)، وانقر نقرًا مزدوجًا على مجموعة القطع التي أنشأناها في الخطوة رقم 10 واضغط على الاختصار Ctrl + F للصق الشكل الذي قصصناه في الخطوة الحالية، ثم انقر نقرًا مزدوجًا في أيّ مكان خارج مجموعة القطع. حدّد الشكل العلوي الذي أنشأناه في الخطوة رقم 7 وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محدَّدةً، ثم أزِل لون التعبئة، وأضِف حدًا بمقدار 2 بكسل باللون الأسود (# 160000)، ثم طبّق الخيار Width Profile 1 على الكائن الناتج. استخدم أداة التحديد المباشر (A) ومفتاح Shift لتحديد نقطتي ارتكاز الكائن الناتج المميزتين باللون الأحمر، ثم انقر على أيقونة "قص المسارات عند نقاط الارتكاز المحدَّدة Cut paths at selected anchor points" من شريط خصائص Properties، مما يجعل هذا الكائن مؤلفًا من مسارين، ثم حدد المسار العلوي وأزِله. حدّد المسار الآخر وأنشئ نسخةً منه، ثم استبدل لون الحدّ الحالي باللون الرمادي الداكن (# 8e8871). أبقِ هذا المسار محدَّدًا، واستخدم أداة إضافة نقاط ارتكاز Add Anchor Point Tool (+) لإضافة نقطتي ارتكاز عند النقاط المميزة باللون الأزرق. أعِد تحديد هاتين النقطتين وانقر على أيقونة "قص المسارات عند نقاط الارتكاز المحدَّدة Cut paths at selected anchor points" من شريط خصائص Properties، مما يجعل هذا المسار مؤلفًا من ثلاثة مسارات. حدّد المسارين الأقصر وأزِلهما، ثم أعِد تحديد المسار المتبقي وحرّكه بمقدار 2 بكسل للأعلى. استخدم أداة القلم (P) لإنشاء شكلين كما هو موضّح أدناه. حدّد هذين الشكلين وطبّق عليهما تأثير Gaussian Blur بمقدار 5 بكسلات، ثم انتقل إلى قائمة كائن Object ثم Transform ثم انعكاس Reflect. اضبط المحور Axis على الخيار رأسي Vertical ثم انقر على نسخ Copy. اسحب هذه النُسخ إلى اليمين، ولا تنسَ الاستمرار في الضغط على مفتاح Shift من لوحة المفاتيح للسحب السويّ. حدد الآن الشكل العلوي الذي أنشأناه في الخطوة رقم 7 وأنشئ نسخةً منه، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). حدّد هذه النسخة ثم استمر في الضغط على مفتاح Shift وانقر على الأشكال الأربعة التي طبّقنا عليها تأثير الضبابية blur في الخطوة الحالية، ثم انقر بزر الفأرة الأيمن على لوحة الرسم وحدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة. يجب أن يبدو مذياعك الآن كما في الشكل التالي: إنشاء مكبر الصوت استخدم أداة الدائرة Ellipse Tool (باستخدام الاختصار L) لإنشاء دائرة أبعادها 192×192 بكسل، ثم ضع هذا الكائن في الموضع الذي تراه في الشكل الأول أدناه. حدّد هذه الدائرة وأنشئ نسخةً منها بالضغط على Ctrl + C ثم Ctrl + F، ثم اضغط على الاختصار Ctrl +3 لإخفاء هذه النسخة. أعِد تحديد الدائرة الحمراء الأصلية وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Uniform، ثم أدخِل القيمة 87 في نافذة Scale وانقر على نسخ Copy. حرّك هذه النسخة بمقدار 4 بكسلات إلى اليمين، ثم استبدل لون الحدّ الحالي باللون الأسود. استخدم أداة القلم (P) لإنشاء مسارين باللون الأزرق كما هو موضّح في الشكل الأول أدناه. حدّد هذين المسارين بعد رسمهما، ثم انقر بزر الفأرة الأيمن على لوحة الرسم وحدد خيار ضم Join من القائمة، ثم انقر بزر الفأرة الأيمن على لوحة الرسم وحدّد خيار ضم Join مرةً أخرى. حدّد الآن الشكل الأزرق الذي أنشأناه في الخطوة رقم 7 وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة واستمر في الضغط على مفتاح Shift، ثم انقر على الكائن الأزرق الذي أنشأناه في الخطوة الحالية، ثم افتح لوحة مستكشف المسار Pathfinder من قائمة Window ثم Pathfinder، وانقر على زر التقاطع Intersect. حدّد الكائن الناتج واستمر في الضغط على مفتاح Shift، ثم انقر على الدائرة الحمراء التي أنشأناها في الخطوة رقم 15، ثم انقر على زر الدمج Unite من لوحة مستكشف المسار Pathfinder. استخدم أداة القلم (P) لإنشاء مسارين باللون الأحمر كما هو موضّح في الشكل الأول أدناه. حدّد هذين المسارين بعد رسمهما، ثم انقر بزر الفأرة الأيمن على لوحة الرسم وحدد خيار الضم Join من القائمة، ثم انقر بزر الفأرة الأيمن على لوحة الرسم وحدّد خيار الضم Join مرةً أخرى. حدّد الآن الشكل الأزرق الذي أنشأناه في الخطوة رقم 7 وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة واستمر في الضغط على مفتاح Shift، ثم انقر على الكائن الأحمر الذي أنشأناه في الخطوة الحالية، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر التقاطع Intersect. حدّد الكائن الناتج واستمر في الضغط على مفتاح Shift، ثم انقر على الدائرة السوداء التي أنشأناها في الخطوة رقم 15، ثم انقر على زر الدمج Unite من لوحة مستكشف المسار Pathfinder. حدّد الكائنين اللذين أنشأناهما من بداية الخطوة رقم 16 حتى الآن، ثم أزِل حدّهما واملأهما بالتدرجات اللونية الخطية الموضّحة أدناه. أعِد تحديد الشكل الأصغر وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه وانقر على موافق. حدّد الشكل الأكبر وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام باعتماد الاختثار Ctrl + Shift + Right Square Bracket. حدّد هذه النسخة، واستمر في الضغط على مفتاح Shift ثم انقر على الشكل الذي طبّقنا عليه تأثير الظل في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة. اضغط على الاختصار Ctrl + Alt +3 لإظهار الدائرة الحمراء التي أخفيناها في الخطوة رقم 15، ثم أحضِرها إلى الأمام (Ctrl + Shift + Right Square Bracket). حدّد هذه الدائرة وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Uniform، ثم أدخِل القيمة 73 في نافذة Scale وانقر على موافق. أبقِ الدائرة الناتجة محدّدةً وافتح نافذة Scale مرةً أخرى، وحدّد الخيار Uniform، ثم أدخِل القيمة 92 في قسم Scale وانقر على نسخ Copy. حدّد الآن الشكل الدائري الأكبر، ثم أزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه، ثم انتقل إلى قائمة تأثير Effect ثم Stylize ثم إضاءة خارجية Outer Glow، واتبع البيانات الموضّحة أدناه وانقر على موافق. أخيرًا، حدّد الدائرة الحمراء المتبقية، ثم أزِل حدّها واملأها باللون الأحمر الداكن (# 1d0500). اختر أداة المضلع Polygon Tool من شريط الأدوات وانقر على لوحة الرسم، ثم أدخِل القيمة 5 بكسلات في خانة نصف القطر Radius والقيمة 6 في خانة الأضلاع Sides، ثم انقر على موافق. اختر أداة التحديد (V) واستمر في الضغط على مفتاح Alt، وانقر على الشكل السداسي الذي أنشأناه للتو، واضغط على الفأرة واسحبه للأسفل إلى الموضع الموضّح أدناه، ولا تنسَ الاستمرار في الضغط على مفتاح Shift من لوحة المفاتيح للسحب السويّ، مما يؤدي إلى إنشاء نسخة من الشكل السداسي. استخدم أداة التحديد (V) لتحديد هذين الشكلين السداسيين، ثم استمر في الضغط على مفتاح Alt وانقر على الشكلين السداسيين المحددّين واسحبهما للأسفل أثناء الضغط على مفتاح Shift. اضغط بعد ذلك على الاختصار Ctrl + D سبع مرات للحصول على النتائج الموضّحة أدناه. أخيرًا، حدّد وجمّع (بالضغط على الاختصار Ctrl + G) جميع الأشكال السداسية التي أنشأناها في الخطوة الحالية. اختر أداة التحديد (V) واستمر في الضغط على مفتاح Alt، ثم انقر على المجموعة التي أنشأناها في الخطوة رقم 20، واضغط على الفأرة مع سحبها إلى الجهة اليمنى السفلية. استخدم أداة التحديد (V) لتحديد المجموعتين اللتين أنشأناهما أخيرًا، ثم استمر في الضغط على مفتاح Alt، وانقر على المجموعتين المحدَّدتين واسحبهما إلى اليمين إلى الموضع الموضّح أدناه أثناء الضغط على مفتاح Shift. اضغط بعد ذلك على الاختصار Ctrl + D ثماني مرات للحصول على النتائج الموضحة أدناه. أخيرًا، حدد وجمّع (Ctrl + G) جميع المجموعات التي أنشأناها من بداية الخطوة رقم 20 إلى الخطوة الحالية. ضع المجموعة التي أنشأناها في الخطوة رقم 21 في الموضع الذي تراه في الشكل الأول أدناه. حدّد الآن الدائرة ذات اللون الأحمر الداكن التي أنشأناها في الخطوة رقم 19 وأنشئ نسخةً منها بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محدَّدةً، واستمر في الضغط على مفتاح Shift، ثم انقر على المجموعة التي أنشأناها في الخطوة رقم 21. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة. استخدم أداة القلم (P) لإنشاء الكائن الموضّح في الشكل الأول أدناه، ثم أنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، بعد ذلك استبدل لون حدّ هذه النسخة الحالي باللون الأحمر. اختر أداة إضافة نقطة ارتكاز Add Anchor Point (+)، ثم انقر على النقطتين المميزتين باللون الأصفر من الكائن الأحمر، مما يؤدي إلى إضافة نقطتي ارتكاز جديدتين إلى هذا الكائن الأحمر. حدّد نقطتي الارتكاز المميزتين باللون الأزرق وحرّكهما بمقدار 2 بكسل للأسفل، ثم حدّد نقطتي الارتكاز المميزتين باللون الأصفر وحرّكهما بمقدار 3 بكسلات للأعلى. أخيرًا، أعِد تحديد الكائن الأخضر الذي أنشأناه في الخطوة الحالية، وأزِل حدّه ثم املأه بالتدرج اللوني الخطي الموضّح أدناه. حدّد الكائن الأحمر الذي أنشأناه في الخطوة رقم 23 وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم استبدل لون الحدّ الحالي باللون الأصفر، ثم كرّر العملية نفسها التي طبّقناها في الخطوة رقم 23 لضبط شكل الكائن الأصفر، إذ يجب أن يبدو هذا الكائن تقريبًا مثل الشكل الأول أدناه. أعِد تحديد الكائن الأحمر، وأزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح في الشكل الثاني أدناه. حدّد الكائن الأصفر الذي أنشأناه في الخطوة الحالية، وأزِل حدّه واملأه باللون الأبيض (# f6fdff). بعد ذلك حدّد الشكل الناتج وطبّق عليه تأثير Feather بمقدار 2 بكسل. استخدم أداة القلم (P) لإنشاء الكائنات الستة الموضّحة في الشكل الأول أدناه. حدّد هذه الكائنات بعد إنشائها، ثم أزِل حدّها واملأها بالتدرج اللوني الخطي الموضّح في الشكل الثاني أدناه. استخدم أداة القلم (P) لإنشاء ستة أشكال رمادية داكنة (# 607278) كما هو موضّح في الشكل الثالث أدناه، ثم أنشئ ستة أشكال سوداء (# 020000). استخدم أداة القلم (P) لإنشاء ستة أشكال بيضاء (# f6fdff) كما هو موضّح في الشكلين الأول والثاني أدناه. حدّد هذه الأشكال الستة البيضاء وطبّق عليها تأثير Feather بمقدار 3 بكسلات، واستخدم أداة القلم (P) لإنشاء سبعة أشكال باللون الأزرق الفاتح (# 7599e2)، ثم طبّق عليها تأثير Gaussian Blur بمقدار 2 بكسل. يجب أن يبدو مذياعك الآن كما يلي: إنشاء مقبض التحكم بالصوت استخدم أداة الدائرة (L) لإنشاء دائرة أبعادها 156×156 بكسل، ثم انتقل إلى قائمة كائن Object ثم Transform ثم Scale، ثم حدّد الخيار Uniform، وأدخِل القيمة 90 في قسم Scale وانقر على نسخ Copy، ثم استبدل لون حدّ هذه النسخة الحالي باللون الأحمر. أعِد تحديد الدائرة السوداء التي أنشأناها في الخطوة الحالية، ثم أزِل حدّها واملأها بالتدرج اللوني الخطي الموضّح أدناه، ثم طبّق تأثير Feather بمقدار 5 بكسلات على الشكل الناتج. حدّد الدائرة الحمراء التي أنشأناها في الخطوة رقم 28 واملأها بالتدرج اللوني الشعاعي radial gradient الموضّح أدناه. حدّد الدائرة الناتجة، ثم افتح لوحة Stroke من قائمة Window ثم Stroke، وغيّر ثُخن هذا الحدّ إلى 2.5 بكسل وانقر على أيقونة محاذاة الحدّ إلى الخارج Align Stroke to Outside، ثم استبدل لون الحد الحالي بالتدرج اللوني الخطي المطبّق على الحدّ والموضّح أدناه. أبقِ هذه الدائرة محدّدةً، ثم افتح لوحة Appearance من قائمة Window ثم Appearance، وانقر على زر إضافة حدٍّ جديد Add New Stroke (في الزاوية السفلية اليسرى من لوحة Appearance)، مما يؤدي إلى إضافة حدّ ثانٍ. املأ هذا الحدّ بالتدرج اللوني الخطي الموضّح أدناه وغيّر ثُخنه إلى 2 بكسل. حدّد الدائرة التي أنشأناها في الخطوة رقم 29 وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، ثم حدّد الخيار Uniform، وأدخِل القيمة 71 في قسم Scale وانقر على نسخ Copy. حدّد هذه النسخة، وافتح لوحة Appearance (من قائمة Window ثم Appearance)، ثم طبّق الخطوات الموضّحة أدناه. استخدم أداة القلم (P) لإنشاء الشكلين الموضّحين أدناه باللون الرمادي الداكن (# 4e5661)، ثم طبّق عليهما تأثير Gaussian Blur بمقدار 2 بكسل. حدّد الآن الدائرة التي أنشأناها في الخطوة رقم 29 وأنشئ نسخةً منها (بالضغط على Ctrl + C ثم Ctrl + F)، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محدّدةً، واستمر في الضغط على مفتاح Shift، ثم انقر على الشكلين اللذين طبّقنا عليهما تأثير الضبابية blur في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الدائرة التي أنشأناها في الخطوة رقم 30. حدّد الدائرة التي أنشأناها في الخطوة رقم 30 وأنشئ نسخةً منها بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة، وافتح لوحة Appearance (من قائمة Window ثم Appearance) وأزِل حدّها، ثم انتقل إلى قائمة كائن كائن Object ثم Transform ثم Scale، وحدّد الخيار Uniform، بعد ذلك أدخِل القيمة 97 في قسم Scale وانقر على موافق، ثم حرّك الدائرة الناتجة بمقدار 11 بكسلًا للأسفل. أنشئ نسخةً من الدائرة التي حرّكناها للتو، ثم أزِل لون تعبئة هذه النسخة وأضِف إليها حدًّا مقداره 1 بكسل باللون الأحمر. استخدم أداة القلم (P) لإنشاء الأشكال الأربعة الموضّحة أدناه، ثم حدّدها وطبّق عليها تأثير Gaussian Blur بمقدار 5 بكسلات. حدّد الآن الدائرة الحمراء التي أنشأناها في الخطوة الحالية وأنشئ نسخةً منها بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). حدّد هذه النسخة، ثم استمر في الضغط على مفتاح Shift وانقر على الأشكال الأربعة التي طبّقنا عليها تأثير الضبابية blur في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، وحدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الدائرة الحمراء. حدّد جميع الكائنات التي أنشأناها في الخطوة رقم 32، وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، بعد ذلك حدّد الخيار Uniform، وأدخِل القيمة 72 في قسم Scale ثم انقر على نسخ Copy. استخدم أداة القلم (P) لإنشاء الأشكال الثلاثة الموضّحة أدناه باللون الرمادي الداكن (# 5f6775)، ثم طبّق عليها تأثير Gaussian Blur بمقدار 2 بكسل. حدّد الأشكال الناتجة، ثم اضغط على الاختصار Ctrl + X لقصها، ثم اختر أداة التحديد Selection Tool (باستخدام الاختصار V) وانقر نقرًا مزدوجًا على مجموعة القطع التي أنشأناها في الخطوة الحالية، وبعد ذلك اضغط على الاختصار Ctrl + F للصق الأشكال التي قصصناها للتو، ثم انقر نقرًا مزدوجًا في أيّ مكان خارج مجموعة القطع. حدّد مجموعة القطع والدائرة الحمراء الصغيرة، ثم اضغط على الاختصار Ctrl +2 لقفلهما، ثم حدّد الدائرة الأخرى التي أنشأناها في الخطوة الحالية واستبدل لون التعبئة الحالي بتدرج لوني شعاعي جديد كما هو موضّح أدناه. أخيرًا، اضغط على الاختصار Ctrl + Alt +2 لفك قفل جميع الكائنات التي قفلناها في الخطوة الحالية. حدّد الدائرة الحمراء الكبيرة، ثم غيّر ثُخن حدّها إلى 1.5 بكسل، واستبدل لون الحد الحالي بالتدرج اللوني الخطي الموضّح أدناه ضمن الحد. حدّد الدائرة الحمراء الأخرى، وغيّر ثُخن الحدّ إلى 5 بكسلات، ثم استبدل لون الحدّ الحالي باللون الرمادي الداكن (# 9e9ea3). أنشئ نسخةً من الدائرة الناتجة (بالضغط على Ctrl + C ثم Ctrl + F)، ثم غيّر ثُخن حدّ هذه النسخة إلى 4 بكسلات واستبدل لون الحدّ الحالي باللون الأزرق الفاتح (# b7d6ff). حدّد الآن الدائرة الأولى التي أنشأناها في الخطوة رقم 32 وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه، ثم انقر على موافق. استخدم أداة القلم (P) لإنشاء الشكلين الموضحين أدناه باللون الرمادي الداكن (# 656b77)، ثم طبّق عليهما تأثير Gaussian Blur بمقدار 2 بكسل. حدّد الآن الدائرة التي أنشأناها في الخطوة رقم 30 وأنشئ نسخةً منها بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محدَّدةً واستمر في الضغط على مفتاح Shift، ثم انقر على الشكلين اللذين طبّقنا عليهما تأثير الضبابية blur في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع هذه خلف الدائرة الأولى التي أنشأناها في الخطوة رقم 32. حدّد جميع الكائنات التي أنشأناها من بداية الخطوة رقم 28 وحتى الآن وجمّعها (Ctrl + G)، ثم ضع هذه المجموعة في الموضع الموضّح في الشكل التالي: إنشاء ضابط المذياع استخدم أداة المستطيل (M) لإنشاء مستطيل أحمر أبعاده 296×54 بكسل، ثم انتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Non-Uniform، ثم أدخِل القيمة 97 في خانة أفقي Horizontal والقيمة 86 في خانة رأسي Vertical، ثم انقر على نسخ Copy. أعِد تحديد هذين المستطيلين وأنشئ نسخةً منهما بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النُسخ، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر Minus Front. حدّد الكائن الناتج، ثم أزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه، ثم انتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضحة أدناه ثم انقر على موافق. حدّد المستطيل الأحمر الأكبر الذي أنشأناه في الخطوة الحالية وأنشئ نسخةً منه، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). تأكّد من أن هذه النسخة لا تزال محدَّدةً واستمر في الضغط على مفتاح Shift، ثم انقر على الشكل الذي طبّقنا عليه تأثير الظل Shadow في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة. حدّد المستطيل الأحمر الأكبر الذي أنشأناه في الخطوة رقم 37، واجلبه إلى الأمام عن طريق الاختصار Ctrl + Shift + Right Square Bracket. استخدم أداة التحديد المباشر (A) مع مفتاح Shift لتحديد نقطتي ارتكاز هذا المستطيل الأحمر السفليتين، ثم انقر على أيقونة "قص المسارات عند نقاط الارتكاز المحدَّدة Cut paths at selected anchor points" من شريط خصائص Properties، مما يجعل هذا المستطيل الأحمر مؤلفًا من مسارين. حدّد المسار العلوي وأزِله، ثم أعِد تحديد المسار الآخر واستبدل لون حدّه الحالي باللون السماوي الفاتح (# d7f0f5). أخيرًا، حدّد المستطيل الأحمر الآخر، وأزِل حدّه واملأه باللون البني الداكن (# 231f18). استخدم أداة الخط Line Segment Tool () لإنشاء خط رأسي بطول 46 بكسلًا، وبحدٍّ مقداره 2 بكسل باللون الأسود (# 2b2820) وبلا تعبئة. حدّد هذا الخط وانتقل إلى قائمة كائن Object ثم Transform ثم Move، ثم أدخِل القيمة 3 بكسلات في خانة أفقي Horizontal وانقر على نسخ Copy، ثم اضغط على الاختصار Ctrl + D إلى أن تحصل على النتائج الموضّحة أدناه. أخيرًا، حدّد جميع الخطوط التي أنشأناها في الخطوة الحالية وجمّعها (Ctrl + G)، ثم ضع هذه المجموعة في الموضع الموضّح أدناه. استخدم أداة الخط Line Segment Tool () لإنشاء خط أفقي بطول 260 بكسلًا، وبحدّ مقداره 1.5 بكسل باللون الأزرق المائل إلى الرمادي (# d1d3d4) وبلا تعبئة. أنشئ خطًا رأسيًا بطول 9 بكسلات، وبحدٍّ مقداره 1.5 بكسل باللون الأزرق المائل إلى الرمادي وبلا تعبئة، ثم ضع هذين الخطين في المواضع الموضّحة أدناه. أعِد تحديد الخط الرأسي وانتقل إلى قائمة كائن Object ثم Transform ثم Move، وأدخِل القيمة -3 بكسل في خانة أفقي Horizontal وانقر على نسخ Copy، ثم اضغط على الاختصار Ctrl + D إلى أن تحصل على النتائج الموضّحة أدناه. استخدم أداة التحديد (V) مع مفتاح Shift لتحديد الخطوط الرأسية التسعة الموضّحة أدناه، ثم افتح لوحة Transform من قائمة Window ثم Transform، وغيّر قيمة الخيار H إلى 17 بكسلًا. أخيرًا، حدّد جميع الخطوط التي أنشأناها في الخطوة الحالية وجمّعها (Ctrl + G)، ثم ضع هذه المجموعة في الموضع الموضّح أدناه. اختر أداة الكتابة Type Tool باستخدام الاختصار T، ثم افتح لوحة Character من قائمة Window ثم Type ثم Character، واتبع البيانات الموضّحة أدناه. انقر بعد ذلك على لوحة الرسم واكتب النص "AM" و "FM"، ثم ضع هذه النصوص في الموضع الموضّح أدناه. استخدم أداة الخط Line Segment Tool () لإنشاء خط رأسي بطول 46 بكسلًا، وبحدٍّ مقداره 2 بكسل باللون الأحمر (# ed1c24) وبلا تعبئة. استخدم الآن أداة المستطيل (M) وأداة التدرج (G) لإنشاء مستطيل أبعاده 276×40 بكسل كما هو موضّح أدناه، ثم طبّق عليه تأثير Gaussian Blur بمقدار 2 بكسل. يجب أن يبدو مذياعك الآن كما يلي: إنشاء الأزرار انتقل إلى القسم العلوي من المذياع، ثم اختر أداة المستطيل ذي الزوايا المستديرة Rounded Rectangle Tool من شريط الأدوات، وانقر على لوحة الرسم. بعد ذلك أدخِل البيانات الموضّحة في الشكل الأول أدناه، ثم ضع هذا المستطيل في الموضع الموضّح أدناه. استخدم أداة التحديد المباشر (A) مع مفتاح Shift لتحديد نقطتي ارتكاز المستطيل الأصفر المميزتين باللون الأخضر وحرّكهما بمقدار 2 بكسل للأسفل. حدّد الآن نقطة الارتكاز العلوية اليسرى وحرّكها بمقدار 2 بكسل إلى اليمين، ثم حدّد نقطة الارتكاز العلوية اليمنى وحرّكها بمقدار 2 بكسل إلى اليسار. أنشئ نسخةً (بالضغط على Ctrl + C ثم Ctrl + F) من المستطيل الأصفر الذي أنشأناه في الخطوة رقم 43، ثم استبدل لون حدّ هذه النسخة باللون الأخضر. حدّد نقطتي ارتكاز هذا المستطيل الأخضر المميزتين باللون الأزرق وأزِلهما، ثم حدّد نقطة ارتكاز الكائن الناتج العلوية اليسرى، وحرّكها بمقدار 8 بكسلات للأسفل و 2 بكسل إلى اليسار، ثم حدّد نقطة الارتكاز العلوية اليمنى وحرّكها بمقدار 8 بكسلات للأسفل، ثم 2 بكسل إلى اليمين. أخيرًا، استخدم أداة التحديد المباشر (A) مع مفتاح Shift لتمديد مقابض نقطتي الارتكاز العلويتين كما هو موضّح أدناه. حدّد الكائن الأصفر الذي أنشأناه في الخطوة رقم 43، ثم أزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه، ثم حدّد الكائن الأخضر، وأزِل حده واملأه باللون الأسود (# 1a1a1a). حدّد الشكل الناتج وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، بعد ذلك استبدل لون تعبئة هذه النسخة الحالي بالتدرج اللوني الخطي الموضّح أدناه. حدّد الآن نقطة ارتكاز هذه النسخة العلوية اليسرى، وحرّكها بمقدار 3 بكسلات للأسفل و 1 بكسل إلى اليمين، ثم حدّد نقطة الارتكاز العلوية اليمنى، وحرّكها بمقدار 3 بكسلات للأسفل و1 بكسل إلى اليسار، ثم حدّد الشكل الأول الذي أنشأناه في الخطوة الحالية وأنشئ نسخةً منه. بعد ذلك أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أخيرًا، أزِل لون تعبئة هذه النسخة، ثم أضِف حدًا مقداره 1 بكسل باللون الأزرق المائل إلى الرمادي (# bcbec0). استخدم أداة المستطيل ذي الزوايا المستديرة Rounded Rectangle Tool لإنشاء مستطيل أبيض (# f2f2f2) كما هو موضّح أدناه، ثم أنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة، ثم أزِل لون تعبئتها وأضف حدًا مقداره 1 بكسل باللون الأبيض (# fcfcfc). أعِد تحديد المستطيل الأول الذي أنشأناه في الخطوة الحالية وأنشئ نسخةً منه، ثم حرّك هذه النسخة بمقدار 10 بكسلات للأسفل، ثم استبدل لون تعبئة هذه النسخة الحالي بالتدرج اللوني الخطي الموضّح أدناه، ثم أرسِل المستطيل الناتج إلى الخلف (Ctrl + Shift + Left Square Bracket). حدّد المستطيل الأخير الذي أنشأناه في الخطوة رقم 46 وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Non-Uniform، وأدخِل القيمة 103 في خانة أفقي Horizontal ثم انقر على نسخ Copy. استبدل لون تعبئة هذه النسخة الحالي باللون الأسود (# 000000)، وحرّك المستطيل الناتج بمقدار 2 بكسل للأسفل، ثم أرسله للخلف (Ctrl + Left Square Bracket). حدّد الآن جميع الكائنات التي أنشأناها من بداية الخطوة رقم 46 إلى الخطوة الحالية، ثم انتقل إلى قائمة كائن Object ثم Transform ثم Move، وأدخِل القيمة 71 في خانة أفقي Horizontal وانقر على نسخ Copy، ثم اضغط على الاختصار Ctrl + D مرةً واحدة للحصول على النتائج الموضّحة أدناه. حدد وجمّع (Ctrl + G) جميع الكائنات التي أنشأناها من بداية الخطوة رقم 46 حتى الآن، ثم ضع هذه المجموعة في الموضع الموضّح أدناه. إنشاء الهوائي استخدم أداة المستطيل (M) وأداة الدائرة (L) لإنشاء مستطيل أبعاده 16×55 بكسل ودائرة أبعادها 16×5 بكسل، ثم ضع هذين الكائنين في الموضع الموضّح أدناه. اختر أداة إضافة نقطة ارتكاز Add Anchor Point (+) وانقر على النقطة المميزة باللون الأرجواني من المستطيل الذي أنشأناه في الخطوة الحالية، مما يؤدي إلى إضافة نقطة ارتكاز جديدة لهذا الكائن. حدّد نقطة الارتكاز المضافَة حديثًا، ثم حرّكها بمقدار 4 بكسلات للأسفل. اختر أداة تحويل نقاط الارتكاز Convert Anchor Point Tool (باستخدام الاختصار Shift + C)، ثم انقر على نقطة الارتكاز التي حرّكتها للتو، واضغط على الفأرة واسحبها إلى اليسار أثناء الضغط على مفتاح Shift. أعِد تحديد الكائنين اللذين أنشأناهما في الخطوة الحالية وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، ثم حدّد الخيار Uniform، وأدخِل القيمة 87 في قسم Scale وانقر على نسخ Copy، ثم حرّك هذه النُسخ بمقدار 54 بكسلًا للأعلى. حدد آخر كائنين أنشأناهما في الخطوة رقم 49 وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Uniform، ثم أدخِل القيمة 87 في قسم Scale وانقر على نسخ Copy، ثم حرّك هذه النُسخ بمقدار 46 بكسلًا للأعلى. حدّد الكائنين الناتجين وافتح نافذة Scale مرةً أخرى، ثم حدّد الخيار Uniform وأدخِل القيمة 138 في قسم Scale، ثم انقر على نسخ Copy. حدّد نقاط ارتكاز الكائن الأرزق الثلاثة السفلية وحرّكها بمقدار 49 بكسلًا للأعلى. حدّد الكائن الأزرق العلوي الذي أنشأناه في الخطوة رقم 50، ثم أزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه. حدّد الكائنين الزرقاويين المتبقيين، ثم اختر أداة القطارة Eyedropper Tool (باستخدام الاختصار I) وانقر على الشكل الأول الذي أنشأناه في الخطوة الحالية. حدّد الدائرة العلوية التي أنشأناها في الخطوة رقم 49، ثم أزِل حدّه واملأه بالتدرج اللوني الخطي الموضّح أدناه. أخيرًا، أعِد تحديد الدائرتين الحمراوتين المتبقيتين، ثم اختر أداة القطارة Eyedropper Tool (باستخدام الاختصار I) وانقر على الدائرة العلوية التي ملأتها بالتدرج اللوني الخطي في الخطوة الحالية. حدّد الشكل الأول الذي ملأته بالتدرج اللوني الخطي في الخطوة رقم 51، وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة في الشكل الأول أدناه وانقر على موافق. حدّد الآن الشكل الموضّح في الشكل الثاني أدناه وأنشئ نسخة منه، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). حدّد هذه النسخة واستمر في الضغط على مفتاح Shift، ثم انقر على الشكل الذي طبّقنا عليه تأثير الظل Shadow المطبق في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الشكل الأول الذي ملأناه بالتدرج اللوني الخطي في الخطوة رقم 51. حدّد وجمّع (Ctrl + G) جميع الكائنات التي أنشأناها من بداية الخطوة رقم 49 حتى الآن، ثم ضع هذه المجموعة في الموضع الموضّح أدناه. استخدم أداة الدائرة (L) لإنشاء دائرة أبعادها 21×12 بكسل باللون الأسود (# 130000) كما هو موضّح أدناه، ثم اخفِ هذه الدائرة خلف المجموعة التي أنشأناها في الخطوة الحالية. حدّد جميع الكائنات التي أنشأناها من بداية الخطوة رقم 2 حتى الآن وجمّعها (Ctrl + G). أصبح المذياع جاهزًا ويجب أن يبدو مثل الشكل التالي: إنشاء الخلفية استخدم أداة المستطيل (M) لإنشاء مستطيلين أبعادهما 834×700 بكسل و 882×284 بكسل، ثم ضع هذين المستطيلين في الموضع الموضّح أدناه. أعِد تحديد هذين المستطيلين، ثم أزِل حدّهما واملأهما بالتدرجات اللونية الشعاعية الموضّحة أدناه. أخيرًا، أعِد تحديد المستطيل الأصغر وطبّق عليه تأثير Gaussian Blur بمقدار 11 بكسلًا. ضع المذياع في هذه الخلفية، ثم أضف ظلًا له لإعطائه مظهرًا أكثر واقعية، وذلك من خلال استخدام أداة القلم (P) وأداة التدرج (G) لإنشاء الشكل الموضّح أدناه، ثم طبّق عليه تأثير Gaussian Blur بمقدار 5 بكسلات، ثم اخفِ الشكل الناتج خلف المذياع. وبذلك أصبح كل شيء جاهزًا، حيث يُفترض أن ينتج معك الشكل النهائي الآتي: ترجمة -وبتصرّف- للمقال Learn to create a Vector Radio in Adobe Illustrator لصاحبه Bao Nguyen. اقرأ أيضًا كيفية إنشاء تلفاز قديم باستخدام إليستريتور كيفية إنشاء الدواليب الهوائية الملونة باستخدام الإليستريتور كيفية إنشاء مصباح كهربائي في برنامج إليستريتور إنشاء ساعة كاسيو Casio في الإليستريتور
-
تحدثنا في مقال سابق عن شبكات التراكب ثم تطرقنا إلى شبكات الند للند وسنكمل في هذا المقال الحديث عن بروتوكول البت تورنت، وهو بروتوكول مشاركة ملفات ند لند ابتكره برام كوهين Bram Cohen، ويعتمد على نسخ الملف أو نسخ أجزاءٍ منه والتي تُسمى قِطعًا pieces، حيث يمكن تحميل أية قطعةٍ معينة من عدة أنداد، حتى لو كان هناك ندٌ فقط لديه الملف بأكمله. الفائدة الأساسية لعملية النسخ التي يفعلها بروتوكول بت تورنت هي تجنب الاختناق المتمثل في وجود مصدرٍ واحد فقط للملف، حيث يكون هذا مفيدًا عندما تفكر في أن أي حاسوبٍ لديه سرعةٌ محدودةٌ يمكنه من خلالها خدمة الملفات عبر رابطٍ صاعدٍ خاصٍ به إلى الإنترنت، ويكون حد هذه السرعة منخفضًا غالبًا بسبب الطبيعة غير المتماثلة لمعظم شبكات النطاق العريض. تكمن أهمية بروتوكول بت تورنت في أن النَّسخ replication هو أحد الآثار الجانبية الطبيعية لعملية التنزيل downloading، فبمجرد تنزيل أحد الأنداد لقطعةٍ معينة، يصبح هذا الند مصدرًا آخر لتلك القطعة، وكلما زاد عدد الأنداد الذين ينزّلون قطعًا من الملف كلما حدث المزيد من النَّسخ للقطعة، مع توزيع التحميل بصورةٍ متناسبة، وزيادة حيز النطاق التراسلي الإجمالي المتاح لمشاركة الملف مع الآخرين. تُنزَّل القطع بترتيبٍ عشوائي لتجنب الموقف الذي يجد فيه الأنداد أنفسهم مفتقرين لنفس مجموعة القطع. تجري مشاركة كل ملفٍ عبر شبكة بت تورنت المستقلة الخاصة به، والتي تُسمى سربًا swarm، ويمكن أن يشارك السرب مجموعةً من الملفات، لكننا نصف حالة ملفٍ فقط للبساطة. تكون دورة حياة السرب النموذجية كما يلي: يبدأ السرب ندًا يملك نسخةً كاملةً من الملف، ثم تنضم العقدة التي تريد تنزيل الملف إلى السرب لتصبح العضو الثاني، وتبدأ بتنزيل أجزاءٍ من الملف من الند الأصلي، وبذلك تصبح مصدرًا آخر للِقطع التي نزّلتها، حتى لو لم تنزّل الملف بالكامل بعد. من الشائع أن يترك الأنداد السرب بمجرد الانتهاء من تنزيلاتهم، على الرغم من تشجيعهم للبقاء لفترة أطول. تنضم العقد الأخرى إلى السرب وتبدأ بتنزيل القطع من أندادٍ متعددين، وليس فقط من الند الأصلي، كما هو موضّحٌ في الشكل السابق. إذا بقي الطلب مرتفعًا على الملف، مع وجود مجرىً من الأنداد الجدد الذين يحلّون محل أولئك الذين غادروا السرب، فيمكن أن يظل السرب نشطًا إلى أجلٍ غير مسمى؛ وإذا لم يكن الأمر كذلك، فقد يتقلص السرب ليشمل الند الأصلي فقط حتى ينضم أندادٌ جدد إلى السرب. يمكننا، بعد أن أصبح لدينا نظرةً عامةً لبروتوكول بت تورنت، أن نسأل كيف توجَّه الطلبات إلى الأنداد الذين لديهم قطعةً معينة. يجب أن ينضم المنزِّل downloader المحتمل أولًا إلى السرب لتقديم الطلبات، فيبدأ بتنزيل ملفٍ يحتوي على معلوماتٍ تعريفيةٍ حول الملف والسرب، حيث يُنزَّل عادةً الملف الذي يمكن نسخه بسهولة من خادم ويب ويمكن اكتشافه باتباع الروابط من صفحات الويب. يحتوي هذا الملف على ما يلي: حجم الملف الهدف. حجم القطعة. القيم المعمَّاة SHA-1 المحسوبة مسبقًا من كل قطعة؟ عنوان URL لمتتبّع tracker السرب. المتتبّع هو خادمٌ يتتبع عضوية السرب الحالية. سنرى لاحقًا أنه يمكن توسيع بروتوكول بت تورنت للتخلص من هذه النقطة المركزية التي قد تؤدي إلى حدوث اختناقٍ أو فشل. ينضم المنزِّل المحتمل بعد ذلك إلى السرب، ليصبح ندًا، عن طريق إرسال رسالةٍ إلى المتتبّع تحتوي على عنوان شبكته ومعرّف الند الذي أنشأه عشوائيًا لنفسه. تحمل الرسالة أيضًا القيمة المُعمَّاة SHA-1 للجزء الرئيسي من الملف، والتي تُستخدَم مثل معرّف سرب. افترض أن الند الجديد يُدعَى P. يرد المتتبّع على الند P بقائمةٍ جزئيةٍ من الأنداد الذين يقدمون معرفاتهم وعناوين الشبكة الخاصة بهم، وينشئ الند P اتصالاتٍ عبر بروتوكول TCP مع بعض هؤلاء الأنداد. لاحظ أن الند P متصلٌ مباشرةً بمجموعةٍ فرعيةٍ فقط من السرب، على الرغم من أنه قد يقرر الاتصال بأندادٍ إضافيين أو طلب المزيد من الأنداد من المتتبّع. يرسل الند P معرّف السرب الخاص به ومعرّفَ الند لإنشاء اتصال بت تورنت بندٍ معين بعد إنشاء اتصال TCP الخاص به، ويرد الند بمعرّفه ومعرّف السرب؛ فإذا لم تتطابق معرّفات السرب، أو لم يكن معرّف الند الذي أجرى الرد هو ما يتوقعه الند P، فسيُلغى الاتصال. اتصال بت تورنت الناتج هو اتصالٌ متماثل نظرًا لإمكانية كل طرفٍ التنزيل من الطرف الآخر، حيث يبدأ كل طرفٍ بإرسال خارطةٍ نقطية bitmap تعلن فيها للطرف الآخر عن الأجزاء الموجودة به، بحيث يعرف كل ندٍ الحالة الأولية للند الآخر. يرسل المنزِّل D عندما ينتهي من تنزيل قطعةٍ أخرى رسالةً تحدد تلك القطعة إلى كل من أنداده المتصلين مباشرةً، حتى يتمكن هؤلاء الأنداد من تحديث تمثيلهم الداخلي لحالة المنزِّل D، ويكون هذا بمثابة إجابةٍ للسؤال حول كيفية توجيه طلب تنزيل لقطعةٍ ما إلى ندٍ لديه القطعة، لأنه يعني أن كل ندٍ يعرف الند المتصل مباشرةً به والذي يملك القطعة. إذا احتاج المنزِّل D إلى قطعةٍ لا تمتلكها أيٌّ من اتصالاته، فيمكنه الاتصال بأندادٍ أكثر أو أندادٍ مختلفين؛ حيث يمكنه الحصول على المزيد من الأنداد من المتتبّع، أو يشغُل نفسه بقطعٍ أخرى على أمل أن تحصل بعض اتصالاته على القطعة من اتصالاتها. كيف تُربَط الكائنات، أو القطع في هذه الحالة مع العقد الأنداد؟ سيحصل كل ندٍ في النهاية على جميع القطع، لذا فإن السؤال يتعلق بالقطع التي يمتلكها الند في وقتٍ معين قبل أن يحتوي على كل القطع أو حول الترتيب الذي ينزِّل به الندُ القطعَ. الإجابة هي أنهم ينزّلون القطع بترتيبٍ عشوائي، وذلك لمنعهم من الحصول على مجموعةٍ فرعيةٍ صارمةٍ أو مجموعةٍ شاملةٍ من القطع الخاصة بأيٍ من أندادهم. يستخدم بروتوكول بت تورنت الموصوف حتى الآن متتبّعًا مركزيًا يشكل نقطة فشل واحدة للسرب ويمكن أن يكون نقطة اختناق للأداء. كما يمكن أن يكون أيضًا توفير متتبّعٍ مصدر إزعاجٍ لمن يرغب في إتاحة ملفٍ عبر بروتوكول بت تورنت. تدعم الإصدارات الأحدث من بروتوكول بت تورنت أيضًا الأسراب التي لا تحتوي متتبّعًا trackerless، والتي تستخدِم تطبيقًا يعتمد على جدول التعمية الموزَّع DHT؛ حيث لا يطبّق برنامج عميل بت تورنت الذي لا يحتوي متتبّعًا ند بت تورنت فحسب، بل يطبّق أيضًا ما نُطلق عليه أداة البحث عن الأنداد peer finder، التي تُسمَّى عقدة node باستخدام مصطلحات بت تورنت، والتي يستخدمها الند للعثور على أنداده. تشكّل أدوات البحث عن الأنداد شبكةَ التراكب الخاصة بها باستخدام بروتوكولها الخاص عبر بروتوكول UDP لتطبيق جدول DHT، حيث تتضمّن شبكة أداة البحث أدوات بحثٍ عن الأنداد الذين ينتمي أندادهم المرتبطين بهم إلى أسرابٍ مختلفة؛ أي يشكّل كل سربٍ شبكةً مميزةً من أنداد بت تورنت، لكن تمتد شبكة أدوات البحث عن الأنداد عبر الأسراب بدلًا من ذلك. تنشئ أدوات البحث عن الأنداد معرّفات أدوات البحث الخاصة بها عشوائيًا، والتي تكون بنفس حجم معرّفات السرب؛ أي 160 بتًا. وتحتفظ كل أداة بحث بجدولٍ متواضع يحتوي بصورةٍ أساسية على أدوات البحث عن الأنداد والأنداد المرتبطين بها، التي تكون معرّفاتها قريبةً من معرّف هذه الأداة، بالإضافة إلى بعض أدوات البحث التي تكون معرّفاتها أبعد. تضَمن الخوارزمية التالية إمكانية معرفة أدوات البحث، التي تكون معرّفاتها قريبةً من معرّف سربٍ معين، أندادها من هذا السرب؛ حيث توفر الخوارزمية في الوقت نفسه طريقةً للبحث عنهم. عندما تحتاج أداة البحث F إلى العثور على أندادٍ من سرب معين، فإنها ترسل طلبًا إلى أدوات البحث في جدولها التي تكون معرّفاتها قريبةً من معرّف ذلك السرب، فإذا عرفت أداة البحث المتصلة أندادًا من هذا السرب، فإنها ترد بمعلومات الاتصال الخاصة بها؛ وإلا فإنها ترد بمعلومات الاتصال الخاصة بأدوات البحث في جدولها القريبة من السرب، بحيث يمكن لأداة البحث F الاستعلام بصورةٍ متكررةٍ عن أدوات البحث تلك. إذا وصل البحث إلى طريقٍ مسدود، نظرًا لعدم وجود أدوات بحثٍ أقرب إلى السرب، تُدخِل أداة البحث F معلومات الاتصال الخاصة بها والند المرتبط بها ضمن أدوات البحث الأقرب إلى السرب، وبالنتيجة يحدث إدخال أنداد سربٍ معين في جداول أدوات البحث القريبة من هذا السرب. تفترض المناقشة أعلاه أن أداة البحث F هي بالفعل جزءٌ من شبكة أداة البحث، وتفترض أن هذه الأداة تعرف بالفعل كيفية الاتصال ببعض أدوات البحث الأخرى. هذا الافتراض صحيحٌ بالنسبة لعمليات تثبيت أداة البحث المُشغَّلة سابقًا، لأنها تحفظ المعلومات حول أدوات البحث الأخرى، حتى عبر عمليات التنفيذ. إذا كان السرب يستخدم متتبّعًا، فسيكون أنداد هذا السرب قادرين على إخبار أدوات البحث الخاصة بهم عن أدوات البحث الأخرى (على عكس الدور الذي يلعبه الأنداد وأدوات البحث) بسبب توسّع بروتوكول أنداد بت تورنت لتبادل معلومات اتصال أداة البحث. ولكن كيف يمكن لأداة بحث مثبَّتة مؤخرًا اكتشاف أدواة بحثٍ أخرى؟ تتضمن ملفات الأسراب التي لا تحوي متتبّعًا معلومات الاتصال الخاصة بأداةٍ أو عددٍ قليلٍ من أدوات البحث، بدلًا من عنوان URL الخاص بالمتتبّع، لهذه الحالة فقط. أحد الجوانب غير الاعتيادية في بروتوكول بت تورنت هو أنه يتعامل مباشرةً مع مسألة العدالة أو المواطنة الجيدة على الشبكة، حيث تعتمد البروتوكولات غالبًا على السلوك الجيد للأنداد دون القدرة على فرض هذا السلوك، فيمكن مثلًا أن يحصل الند صاحب السلوك السيء في شبكة إيثرنت على أداءٍ أفضل باستخدام خوارزمية التراجع التي تكون أكثر قوةً من التراجع الأسي، أو يمكن لند TCP صاحب السلوك السيء الحصول على أداءٍ أفضل من خلال عدم التعاون في التحكم في الازدحام. السلوك الجيد الذي يعتمد عليه بروتوكول بت تورنت هو رفع uploading الأنداد القطعَ إلى أندادٍ آخرين. نظرًا لحاجة مستخدم بت تورنت العادي لتنزيل الملف فقط بأسرع ما يمكن، فهناك إغراءٌ لتطبيق ندٍ يحاول تنزيل جميع القطع مع أقل قدرٍ ممكنٍ من الرفع،ويُعد هذا ندًا سيئَا. يشتمل بروتوكول بت تورنت على آلياتٍ تسمح للأنداد بمكافأة أو معاقبة بعضهم بعضًا بهدف التقليل من هذا السلوك السيء؛ فإذا أساء أحد الأنداد التصرفَ بعدم الرفع بصورةٍ جيدة إلى ندٍ آخر، فيمكن للند الثاني أن يخنق choke الند السيء، حيث يمكنه أن يقرر إيقاف الرفع إلى الند السيء، مؤقتًا على الأقل، ويرسل إليه رسالةً تفيد بذلك، وهناك أيضًا نوع من الرسائل لإخبار الند بإلغاء الاختناق. يستخدم الند آليةَ الاختناق أيضًا للحد من عدد اتصالات بت تورنت النشطة، للحفاظ على أداءٍ جيد لبروتوكول TCP. هناك العديد من خوارزميات الاختناق المحتملة، لكن ابتكار خوارزميةٍ جيدةٍ هو فنٌ بحد ذاته. ترجمة -وبتصرّف- للقسم Overlay Networks من فصل Applications من كتاب Computer Networks: A Systems Approach. اقرأ أيضًا المتطلبات اللازمة لبناء شبكة حاسوبية البرمجيات المستخدمة في بناء الشبكات الحاسوبية بروتوكولات طرف إلى طرف End-to-End Protocols في الشبكات الحاسوبية
-
سنشرح في هذا المقال كيفية التصدير أو الحفظ بتنسيق PDF سواءً لكامل الملف أو لمجال محدَّد من أوراق ليبر أوفيس كالك باستخدام الماكرو. هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبر أوفيس كالك، فهرس السلسلة: مدخل إلى كتابة ماكرو Macro في ليبر أوفيس كالك LibreOffice Calc معالجة محتويات خلايا ليبر أوفيس كالك باستخدام الماكرو معالجة مجال من الخلايا باستخدام الماكرو في ليبر أوفيس كالك استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبر أوفيس التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبر أوفيس كالك أتمتة حفظ أوراق ليبر أوفيس كالك بتنسيق PDF باستعمال الماكرو التصدير أو الحفظ بتنسيق PDF في أوراق ليبر أوفيس كالك باستخدام الماكرو سنوضح فيما يلي كيفية حفظ ورقة ليبر أوفيس كالك LibreOffice Calc مباشرة كملف pdf باستخدام الماكرو، إذ تُستخدَم هذه الميزة البسيطة في العديد من مهام الأتمتة. كتابة الماكرو لنطلق على الدالة التي ستجري هذه العملية الاسم exportToPDF(). عرّف أولًا كائنين يحتفظ أحدهما بمستند كالك ويُستخدَم الكائن الآخر لتنفيذ الإجراءات. dim document as object dim dispatcher as object document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") أنشئ ملفًا فارغًا باستخدام الدالة Open. لاحظ أن المسار هو مسار نظام الملفات، بسبب وجود البادئة file://، ثم أغلق الملف بعد إنشائه. path ="file:///home/arindam/sheet1.pdf" Open path For Append As #1 Close #1 أنشئ الآن مصفوفة بالحجم 1 للاحتفاظ بقيمة خاصية التصدير بتنسيق pdf، ثم املأ هذه الخاصية بمصفوفة الاسم "URL" مع مسار الملف الذي أنشأناه للتو. dim args1(0) as new com.sun.star.beans.PropertyValue args1(0).Name = "URL" args1(0).Value = "file:///home/arindam/sheet1.pdf" أخيرًا، استدعِ التابع executeDispatch لوضع محتوى الورقة 1 في ملف pdf واحفظه. dispatcher.executeDispatch(document, ".uno:ExportDirectToPDF", "", 0, args1()) الدالة الكاملة موضَّحة أدناه: Sub ExportToPDF() dim document as object dim dispatcher as object document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") ' غيّر المسار حسب احتياجاتك path ="file:///home/arindam/sheet1.pdf" Open path For Append As #1 Close #1 dim args1(0) as new com.sun.star.beans.PropertyValue args1(0).Name = "URL" args1(0).Value = "file:///home/arindam/sheet1.pdf" ' غيّر المسار حسب احتياجاتك dispatcher.executeDispatch(document, ".uno:ExportDirectToPDF", "", 0, args1()) End Sub تشغيل دالة الحفظ بتنسيق pdf افتح ليبر أوفيس كالك وأنشئ ماكرو وضَع فيه الدالة السابقة، ثم اكتب أي شيء في الورقة 1 كما يلي: تشغيل الماكرو يمكنك رؤية محتوى الورقة 1 محفوظًا في المجلد المحدَّد المذكور في الماكرو السابق، حيث يوضّح الشكل التالي محتوى ملف pdf الذي أنشأناه باستخدام هذا الماكرو: التصدير أو الحفظ بتنسيق PDF لمجال محدَّد من أوراق ليبر أوفيس كالك باستخدام الماكرو يُعَد تصدير محتوى ورقة ليبر أوفيس إلى PDF ضروريًا بسبب الاستخدام الواسع لملفات PDF لتوزيعها ولإعداد التقارير وما إلى ذلك. أوضحنا سابقًا كيفية تصدير محتوى ورقة إلى ملف pdf، وسنوضّح الآن كيفية تصدير مجال معين (مثل A1: B2) إلى ملف pdf. يجب أن يحتوي ملف pdf على لون وقيم مجال الخلايا من A1 إلى I3 الموضَّحة أدناه، ويجب أن يحتوي اسم ملف pdf على التاريخ الحالي واسم الورقة (أي "mySheet" في هذا المثال) وقيمة ثابتة من خلية (أي الخلية B5 في مثالنا). تفاصيل الماكرو يحضّرهذا الماكرو أولًا اسم ملف pdf ديناميكيًا بناءً على قيمة معينة كما هو موضّح أدناه، حيث يتكون اسم ملف pdf من اسم الورقة وقيمة من الخلية B5 والتاريخ. dim fileName fileName = ThisComponent.Sheets(0).Name & _ "_ratie_" & ThisComponent.Sheets(0).getCellRangebyName("B5").String & _ "_" & Replace(Date,"/","-") & ".pdf" إذا أردت الحصول على اسم الورقة النشطة أو تحديد اسم ورقة كالك الحالية، فاستخدم ما يلي: fileName = ThisComponent.getCurrentController.getActiveSheet.Name & _ أنشئ كائن Frame والكائن المرسِل dispatcher إلى الخدمة com.sun.star.frame.DispatchHelper التي تساعد في تصدير ملف pdf عبر الدالة. أنشئ ملفًا فارغًا في أيّ مسار ثم أغلق الملف. ' غيّر المسار حسب احتياجاتك path ="file:///home/arindam/" & fileName Open path For Append As #1 Close #1 يجب الآن وضع المحتوى ضمن ملف pdf، حيث سنحتاج إلى استخدام المرشّحات Filters التي هي أزواج الأنواع والقيم التي يمكن وضعها في مصفوفة ويمكن تمريرها إلى الدالة executeDispatch كوسيط. الأنواع مُعرَّفة مسبقًا وستُعالَج عند تمريرها، حيث يجب تمرير اسم الملف ومجال الأوراق التي تريد طباعتها فقط في ملف pdf، إذ سنستخدم في مثالنا الخاصية FilterData المبنية مسبقًا. document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") oSheet = ThisComponent.CurrentController.getActiveSheet() oCellRange = oSheet.getCellRangeByName("A1:I3") dim aFilterData(0) as new com.sun.star.beans.PropertyValue aFilterData(0).Name = "Selection" aFilterData(0).Value = oCellRange dim args1(1) as new com.sun.star.beans.PropertyValue args1(0).Name = "URL" args1(0).Value = "file:///home/arindam/" & fileName ' غيّر المسار حسب احتياجاتك args1(1).Name = "FilterData" args1(1).Value = aFilterData() مرّر الآن هذا الوسيط إلى الدالة executeDispatch كوسيط لها كما يلي: dispatcher.executeDispatch(document, ".uno:ExportDirectToPDF", "", 0, args1()) تشغيل الماكرو إليك ملف pdf الذي أنشاناه مع محتويات مجال الأوراق: ملف PDF المُنشَأ بعد التشغيل محتويات ملف pdf شيفرة الماكرو الكاملة Sub ExportRangeToPDF() dim document as object dim dispatcher as object dim fileName fileName = ThisComponent.Sheets(0).Name & _ "_ratie_" & ThisComponent.Sheets(0).getCellRangebyName("B5").String & _ "_" & Replace(Date,"/","-") & ".pdf" document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") oSheet = ThisComponent.CurrentController.getActiveSheet() oCellRange = oSheet.getCellRangeByName("A1:I3") dim aFilterData(0) as new com.sun.star.beans.PropertyValue aFilterData(0).Name = "Selection" aFilterData(0).Value = oCellRange ' غيّر المسار حسب احتياجاتك path ="file:///home/arindam/" & fileName Open path For Append As #1 Close #1 dim args1(1) as new com.sun.star.beans.PropertyValue args1(0).Name = "URL" args1(0).Value = "file:///home/arindam/" & fileName ' غيّر المسار حسب احتياجاتك args1(1).Name = "FilterData" args1(1).Value = aFilterData() dispatcher.executeDispatch(document, ".uno:ExportDirectToPDF", "", 0, args1()) End Sub ترجمة -وبتصرُّف- للمقالان Export or Save As PDF in LibreOffice Calc Sheets using Macro و Export or Save As PDF A Specific Range in LibreOffice Calc Sheets using Macro لصاحبها Arindam. اقرأ أيضًا تعرّف على معالج جداول البيانات LibreOffice Calc كيفية التحكّم في طرق عرض جداول بيانات LibreOffice Calc كيفية تحرير البيانات في LibreOffice Calc
-
يحتوي برنامج كريتا Krita على رسوم متحركة نقطية إطارًا تلو الآخر بفضل كيك ستارتر 2015 Kickstarter، وأسهل طريقة للوصول إلى ميزات التحريك في كريتا هي تغيير مساحة العمل إلى خيار التحريك Animation، مما يؤدي إلى ظهور لوحات التحريك وسير العمل. سير العمل يجب إنشاء إطارات رئيسية Keyframes في سير عمل الرسوم المتحركة التقليدي، حيث تحتوي هذه الإطارات الرئيسية على المواضع المهمة، ثم يجب رسم إطارات بينها أو ما يسمى الرسوم البينية Tweening بلغة الرسوم المتحركة المتطورة جدًا. هناك ثلاثة لوحات مهمة لسير عمل الرسوم المتحركة هي: لوحة خط الرسوم المتحركة الزمني Animation Timeline Docker: تُستخدَم لعرض جميع الإطارات في رسومك المتحركة والتحكم بها. تحتوي لوحة الخط الزمني Timeline على وظائف لإدارة طبقاتك، حيث تظهر الطبقات المُنشَأة في لوحة الخط الزمني على لوحة الطبقات العادية. لوحة سلخ البصل Onion Skin Docker: تُستخدَم للتحكم بمظهر تقنية سلخ البصل التي تفيد في رؤية الإطار السابق. لوحة منحنيات الرسوم المتحركة Animation Curves Docker: تسمح بتطبيق حركة بسيطة على منحنيات الرسوم المتحركة. لوحة مخطط القصة Storyboard Docker: تساعد في إنشاء وتتبّع مخططات القصص. إذا أردت إنشاء رسوم متحركة كبيرة، أي التي تكون أطول من 3 ثوانٍ، فيجب عليك التفكير في كيفية التعامل مع ذلك. كريتا متخصص في تحريك الإطارات واحدًا تلوَ الآخر frame by frame animation، لذلك يحتفظ بجميع الإطارات في الذاكرة، وبالتالي ستستهلك ملفات الرسوم المتحركة كل ذاكرة الحاسوب العاملة RAM. إن لم تعرف ما هي الذاكرة العاملة، فيُحتَمل أن تطبّق شيئًا إضافيًا بسيطًا لإنشاء تسلسل طويل في كريتا، لذلك تحتاج إلى أن تأخذ صفحة من الرسوم المتحركة الاحترافية وتستخدم بعض التخطيط. يمكن أن تساعدك لوحة مخطط القصة في تخطيط لقطات المشهد تبدأ معظم مشاريع الرسوم المتحركة بنص أو على الأقل بمخطط للحركات التي ستحدث باستخدام أيّ نوع من محرّرات النصوص الذي تريدها. الخطوة التالية هي إنشاء مخطط قصة وهي رسومات تخطيطية لتكوين المشهد الأساسي، مع بعض الملاحظات الإضافية عن الأشياء المتحركة مثل حركة الكاميرا وحركة الشخصية، وملاحظات عن الصوت، وملاحظات عن اللون، إذ يبدو ذلك أقرب إلى الرسوم الهزلية منه إلى الرسوم المتحركة، ولكن الاختلاف الرئيسي بينهما هو أن تكوين الرسوم الهزلية يساعد القارئ على تحريك عينيه على الصفحة، بينما تبقى عيون المشاهد في الرسوم المتحركة في نفس المكان تقريبًا، لذلك ستحتوي إطارات مخطط القصة المتتالية على أهم عناصرها في المكان نفسه نسبيًا. يمكنك إنشاء مخطط قصة باستخدام وظائف الرسوم المتحركة، ولكن المفتاح هنا هو أنك تستخدم أقل عدد ممكن من الإطارات، كما يمكنك تصدير مخطط القصة باستخدام خيار تصيير الحركة Render Animation. الخطوة التالية هي تطبيق التحريك Animatic الذي هو عبارة عن تطبيق التحريك على مخطط قصة Storyboard، حيث يُفضَّل تطبيق ذلك في محرر فيديو مثل Kdenlive أو OpenShot أو Olive أو Windows Movie Maker. إذا أردت تجميع كل شيء في رسم متحرك واحد كبير، فيجب أن تتعلم كيفية استخدام مثل هذه البرامج، إذ لا يحتوي كريتا على وظائف خاصة بمونتاج الفيديو والصوت. يسمح تطبيق التحريك بمعرفة كيفية تقسيم الرسوم المتحركة إلى مقاطع صغيرة. إذا كنت مبتدئًا، فيُفضَّل أن تعتمد على معدّل 12 إطارًا في الثانية، وبالتالي سيتكوّن مقطع مدته 10 ثوانٍ من 120 إطارًا، لذلك حاول أن تقسّم رسومك المتحركة إلى مقاطع مدتها 10 ثوانٍ أو أقصر. يمكنك استيراد إطارات مخطط القصة المرتبطة بمقطع معين بالانتقال إلى قائمة ملف File ثم استيراد إطارات حركة Import Animation Frames، لتبدأ بإنشاء رسومك المتحركة. قد يساعدك العمل بدقة Resolution منخفضة أثناء مرحلة الرسم مثل الدقة 800×450 بكسل، وتبدأ الدقة العالية في التأثير فقط عندما تنشئ رسومات خطية، وسيكون الوصول إلى هذه النقطة أمرًا صعبًا، إن لم يكن لديك مخطط تقريبي. راقب استهلاك الذاكرة دائمًا، إذ يمكنك رؤية استهلاك الذاكرة في شريط الحالة بالنقر على عنوان الدقة Resolution الذي يجب أن يحتوي على شريط تقدم صغير يوضّح مقدار الذاكرة التي يستخدمها كريتا حاليًا. لا تدع شريط الذاكرة يمتلئ، لأن ذلك سيؤدي إلى بطء كريتا، وبالتالي لن يكون قادرًا على تصدير الرسوم المتحركة على جهازك في بعض الأحيان. يمكنك تقليل استهلاك الذاكرة من خلال: دمج الطبقات معًا، إذ لا يُفضَّل وجود طبقة لكل تغيير، فكلما قلّ عدد الطبقات، كان ذلك أفضل. سيؤدي الانتقال إلى قائمة صورة Image ثم قص الطبقات إلى مقاس الصورة Crop Layers to Image Size في بعض الحالات إلى اقتصاص كل الطبقات لإزالة الأقسام الموجودة خارج رقعة الرسم. ليس ضروريًا أن تكون طبقات معينة بالألوان الكاملة، خاصة إن كانت باللونين الأبيض والأسود فقط. انتقل إلى قائمة طبقات Layers ثم تحويل Convert ثم تحويل فضاء ألوان الطبقة Convert Layer Color Space وحوّل الطبقة إلى طبقة رمادية، مما يؤدي إلى تقليل كمية ذاكرة RAM التي ستستهلكها هذه الطبقة إلى النصف. يجب أن تقبل أن حاسوبك لا يمكنه التعامل مع إنشاء رسوم متحركة بدقة 4K، لذلك جرّب أن تخفّض الرسوم المتحركة ولو بنسبة قليلة، إذ يمكن أن يحدِث التخفيض بنسبة 20% فرقًا كبيرًا في استهلاك الذاكرة، لكنه لا يحدِث فرقًا كبيرًا في الدقة. راقب أيضًا أن البرامج الأخرى الموجودة على حاسوبك لا تستهلك ذاكرة RAM الكاملة مثل متصفحات الويب وبرامج الدردشة خاصةً عند بث الموسيقى أو مقاطع الفيديو، لذلك إن عانيت من الذاكرة، فحاول أن تشغّل هذه الوظائف على جهاز منفصل مثل هاتفك. كما يجب أن تنشئ الكثير من النسخ الاحتياطية، إذ سترغب في الانتقال إلى قائمة ملف File ثم نسخة احتياطية تزايدية Incremental Backup لإنشاء نسخة منفصلة من الملف الحالي في كل مرة تنشئ فيها قسمًا مهمًا من رسمك المتحرك مثل إنهاء رسم خطي أو إنجاز قسم صعب، وبالتالي إذا تعرّض ملف الرسوم المتحركة للتلف الذي قد يحدث بسبب انقطاع التيار الكهربائي، فسيظل لديك نسخة من آخر قسم مهم. كما يوصَى بشدة باستخدام تقنيات النسخ الاحتياطي الأخرى مثل نسخ الملفات إلى خدمة سحابية أو إلى قرص صلب احتياطي. يمكنك استخدام خيار تصيير الحركة Render Animation مرة أخرى عند الانتهاء، ثم تصدير سلسلة إطارات أو ملف فيديو صغير، ويمكنك بعد ذلك تكوين جميع سلاسل الإطارات وملفات الفيديو معًا في محرّر الفيديو، ويمكنك تصييرها إلى WebM، وتحميلها على موقع استضافات الفيديو المفضل لديك. قد يبدو كل ذلك أمرًا معقدًا بعض الشيء، حيث يجب أن تتصرف بذكاء إن لم يتمتّع حاسوبك بالموارد المناسبة. كيفية إنشاء دورة مشي Walk Cycle تُعَد دورات المشي أكثر الأشكال الأساسية في عملية إنشاء الرسوم المتحركة الكاملة، نظرًا لوجود جميع الأجزاء المختلفة المرتبطة بها، لذلك فإن مراجعة كيفية إنشاء دورة المشي يجب أن تكون بمثابة مقدمة جيدة. الإعداد سننشئ ملفًا جديدًا أولًا، ونكتب في التبويب الأول نسبة مناسبة مثل 1280×1024، ونضبط عدد النقاط في الإنش dpi على القيمة 72 (خاص بالشاشات)، ونطلق على هذا المستند الاسم "walk cycle". نختار في التبويب الثاني لونًا مناسبًا للخلفية، ونضبط الخلفية على لون رقعة الرسم، وبالتالي سيملأ كريتا تلقائيًا أي أجزاء شفافة بلون الخلفية، ولكن يمكنك تغيير ذلك من قائمة صورة Image ثم خصائص الصورة Image Properties. يُعَد ذلك مفيدًا جدًا للرسوم المتحركة، حيث يجب أن تكون الطبقة التي تنشئ عليها الرسوم المتحركة شبه شفافة لتستخدم تقنية سلخ البصل Onion Skinning. اضغط بعد ذلك على زر إنشاء Create، ثم حدد مساحة عمل الرسوم المتحركة من قائمة نافذة Window ثم مساحة عمل Workspace ثم رسوم متحركة Animation للحصول على جميع الأدوات اللازمة للرسوم المتحركة، مما يؤدي إلى ظهور ما يلي: تضيف مساحة عمل الرسوم المتحركة لوحة الخط الزمني للرسوم المتحركة Animation Timeline Docker في الأسفل التحريك Animating تأكد من إعداد طبقتين شفافتين في لوحة الطبقات Layers، حيث يمكنك إضافة طبقة جديدة بالضغط على زر + أو بالضغط على مفتاح ins. نسمّي الطبقة السفلية environment والطبقة العلوية walkcycle عن طريق النقر المزدوج على اسم الطبقة في لوحة الطبقات. استخدم أداة الخط المستقيم لرسم خط أفقي واحد يمثّل الأرض كما يلي: ثم حدّد طبقة walkcycle وارسم رأس وجسم الشخصية (يمكنك استخدام أي فرشاة لهذا الغرض). لن يؤدي تحديد إطار جديد إلى إنشائه تلقائيًا، ولا يرى كريتا طبقة walkcycle كطبقة متحركة على الإطلاق، ولكن يمكننا جعلها طبقة متحركة عن طريق إضافة إطار إلى الخط الزمني. حدّد خيار إنشاء إطار مكرر Create Duplicate Frame للحصول على قائمة سياق لإطار في الخط الزمني. يمكنك أن ترى أن الطبقة أصبحت طبقة متحركة بسبب ظهور أيقونة سلخ البصل في لوحة الخط الزمني. استخدم زر إنشاء إطار مكرّر Create Duplicate Frame لنسخ الإطار الأول إلى الإطار الثاني، ثم انتقل إلى أداة التحريك Move باستخدام الاختصار T ثم استخدم الاختصار Shift + ↑ لتحريك محتويات الإطار للأعلى. يمكننا أن نرى الفرق من خلال تشغيل زر سلخ البصل (اضغط على لتصبح ): يجب أن ترى الإطار السابق باللون الأحمر. تُرسَم الإطارات المستقبلية باللون الأخضر، ويمكن ضبط كلا اللونين في لوحة سلخ البصل. سنرسم الآن طرفي دورة المشي، حيث سنرسم الوضع الذي تكون فيه كلتا الساقين متباعدتين قدر الإمكان، والوضع الذي تكون فيه إحدى الساقين متمددة بالكامل والأخرى مسحوبة للداخل، بحيث تكون جاهزة للخطوة التالية. تُظهِر الصورة السابقة طرفي نقيض هما: ساقان متباعدتان، وساق مستقيمة والأخرى مثنية تستعد للخطوة التالية، إذ يوضّح ذلك قوة تقنية سلخ البصل، حيث يمكننا أن نرى كلا الوضعين في وقت واحد. لاحظ أن الأرجل شبه شفافة، وهذا ليس ضروريًا مع شكل الثابت، ولكنه مفيد في هذه الحالة عندما نبدأ في النسخ. لننسخ هذين الوضعين عن طريق الضغط بزر الفأرة الأيمن على الإطار، ثم تحديد خيار نسخ الإطارات الرئيسية Copy Keyframes، ثم حدّد الموضع الجديد في الخط الزمني، واضغط بزر الفأرة الأيمن مرة أخرى، ثم اضغط على خيار لصق الإطارات الرئيسية Paste Keyframes، ثم طبّق الخطوات التالية: انسخ الإطار رقم 0 إلى الإطار رقم 2. انسخ الإطار رقم 1 إلى الإطار رقم 3. امسح الخطوط شبه الشفافة لتوضيح أيّ ساق أمام الأخرى، حيث لدينا الساق الأقرب إلى اليمين هي التي تنحني في الإطارين رقم 0 و 1، ولدينا الساق الأبعد عن اليمين هي التي تنحني في الإطارين 2 و 3. اضبط معدّل الإطارات Frame Rate على القيمة 4 في إعدادات الرسوم المتحركة كما يلي: حدّد جميع الإطارات في لوحة الخط الزمني عن طريق سحبها وتحديدها. اضغط زر تشغيل Play في الأعلى، واستمتع برسومك المتحركة. توسيع دورة المشي يمكنك توفير بعض المساحة بسرعة عن طريق الضغط بمفتاح Alt مع السحب على أيّ إطار، مما يؤدي إلى تحريك هذا الإطار وكل الإطارات التي بعده دفعة واحدة، ولكن الطريقة الأكثر فعالية هي تحديد جميع الإطارات، ثم الضغط على زر الفأرة الأيمن، وتحدّيد خيار إطارات التجميد Hold Frames ثم إدراج إطار تجميد Insert Hold Frame الذي سيدرج مساحة فارغة أو إطار تجميد بين الإطارات الرئيسية. أنشئ إطارات جديدة بين الإطارات الرئيسية، وحاول إنشاء إطارات بينية بين الإطارات التي تضيفها. ستجد أنه كلما زاد عدد الإطارات التي تضيفها، زادت صعوبة تتبع عملية التحريك. لكن يمكنك تسهيل هذا الأمر من خلال تطبيق شيئين أحدهما هو تلوين لصاقات الإطارات، حيث يمكنك الضغط بزر الفأرة الأيمن على الإطارات الرئيسية، وتحديد اللون الذي تريده في الأسفل. تكون الإطارات الجوهرية باللون الأزرق في هذا المثال، والإطارات البينية باللون الأخضر والإطارات البينية الأقل أهمية باللونين الأصفر والبرتقالي الشيء الآخر الذي يمكنك تطبيقه هو ضبط تقنية سلخ البصل، حيث يمكنك تعديلها باستخدام لوحة سلخ البصل Onion Skin، ويمكنك تغيير عدد الإطارات المرئية مرة واحدة عن طريق تبديلها في الصف العلوي. الصف السفلي مخصص للتحكم في الشفافية، بينما يمكنك في الأسفل تعديل الألوان وكثافة التلوين. أوقفنا هنا تشغيل جميع إطارات سلخ البصل باستثناء الإطارات التالية والسابقة تحريك طبقات متعددة تفتقد دورة المشي التي أنشأناها إلى الأيدي، إذًا لنضفها في طبقة منفصلة، لذلك سننشئ طبقة جديدة، ونسميها hands. اختفت دورة المشي من لوحة الخط الزمني، حيث يُعَد ذلك ميزةً. يمكن أن تحتوي الرسوم المتحركة الكاملة على العديد من الأجزاء الصغيرة التي قد يرغب صانعها في إزالة الطبقات التي لا يعمل عليها من لوحة الخط الزمني. تُثبَّت جميع الطبقات الجديدة في الخط الزمني افتراضيًا في الإصدار رقم 4.3.0 من كريتا والإصدارات الأحدث. يمكنك إظهار طبقة لمعرفة إذا كانت نشطة أم لا من خلال تثبيتها في الخط الزمني عن طريق النقر على أيقونة أثناء تحديد الطبقة التي تريد تثبيتها في لوحة الطبقات، إذ نوصيك بتثبيت أيّ طبقات تطبّق تحريكًا عليها حاليًا. التصدير انتقل إلى قائمة ملف File ثم تصيير الحركة Render Animation عند الانتهاء، ولكن ستحتاج إلى برنامج يسمَّى FFmpeg للتصيير إلى ملف فيديو. تحريك أقنعة التحويل (جديد في الإصدار رقم 5.0) إذا أردت تحريك دورة المشي، فيمكنك استخدام أقنعة التحويل Transform Masks لتحريك الإطارات من اليسار إلى اليمين دون تعديل البكسلات. افتح أولًا لوحة منحنيات الرسوم المتحركة Animation Curves Docker إن لم تكن مفتوحة مسبقًا من قائمة إعدادات Setting ثم لوحات (أرصفة) Dockers ثم منحنيات الرسوم المتحركة Animation Curves. جمّع بعد ذلك الطبقات التي تريد تحويلها وهي في مثالنا الطبقتان hands و walkcycle، ثم اضغط بزر الفأرة الأيمن على المجموعة، ثم اضغط إضافة قناع تحويل Transform mask. انتقل بعد ذلك إلى لوحة منحنيات الرسوم المتحركة، وحدّد الإطار الأول، وحدّد خيار إضافة إطار رئيسي للتحكم في الخاصية القياسية Adds keyframe to control scalar property، حيث ستُميَّز الإطارات القياسية Scalar Frames بشكل المعيَّن في لوحة الخط الزمني. حدّد أداة التحويل Transform Tool، واضغط على الشاشة وانقل المجموعة إلى نقطة البداية، ثم اضغط على مفتاح Enter للتأكيد. حدّد الإطار الأخير في اللوحة، ثم اضغط على الشاشة مرة أخرى، وانقل كل شيء إلى نقطة النهاية. اضغط على خيار تقريب العرض لملاءمة نطاق القناة Zoom view to fit channel range لعرض الإطار بالكامل. إذا ضغطتَ على زر تشغيل Play، فستتحرك محتويات الطبقة، لكن يُحتمَل أن تتحرك بسرعة كبيرة. يمكنك تقليل السرعة من خلال نسخ ولصق إطارات دورة المشي بتكرار 3 أو 4 مرات، ثم نقل الإطار القياسي إلى الإطار الأخير. لكن لا تتزامن دورة المشي مباشرة مع السرعة التي تتحرك بها، لذلك انتقل إلى الإطار الأول حيث تلامس إحدى القدمين الأرض، ثم حدّد هذا القسم (باستخدام الأدلة مثلًا)، ثم استخدم أداة التحويل على كل إطار لتحريكه في الإطارات اللاحقة بحيث تبقى القدم في المكان نفسه طالما أنها تلامس الأرض. طبّق الشيء نفسه بالنسبة للجزء التالي حيث تلمس القدم الأرض وهكذا. يُميَّز كل مكان تلامس فيه القدم الأرض باستخدام أدلة رأسية، مما يسمح بضبط كل إطار بحيث تبقى القدم في مكانها لوحة منحنى الرسوم المتحركة بعد ضبط كل إطار ليكون في المكان الصحيح. يمكن لكريتا إنشاء منحنيات من النوع ease-in و ease-out، ولكن يكون التعديل لكل إطار أسرع في مثل هذا الموقف. ستتحرك دورة المشي بسلاسة بعد تطبيق كل ما سبق كما يلي: ترجمة -وبتصرّف- للمقال Animation with Krita من موقع Krita. اقرأ أيضًا تحميل وحفظ الفرش في كريتا Krita تحبير مسودة الرسم في كريتا رسم أزهار الأزاليا باستخدام أقنعة التحول في برنامج كريتا معاينة الطباعة وأقنعة التدرج اللوني في كريتا
-
أدخلت تطبيقات مشاركة الموسيقى مثل Napster و KaZaA مصطلح الند للند في اللغة العامية الشعبية، ولكن ما الذي يعنيه بالضبط أن يكون النظام ندًا لند أو نظيرًا لنظير؟ يعني ذلك، ضمن سياق مشاركة ملفات MP3، عدم الاضطرار إلى تحميل الموسيقى من موقعٍ مركزي، ولكن القدرة على الوصول إلى ملفات الموسيقى مباشرةً من أي شخصٍ على الإنترنت لديه نسخةٌ مخزنةٌ على حاسوبه. يمكننا القول أن شبكة الند للند تسمح لمجتمع المستخدمين بتجميع مواردهم، مثل المحتوى والتخزين وحيز النطاق التراسلي للشبكة وحيز نطاق القرص الصلب ووحدة المعالجة المركزية، وبالتالي توفير الوصول إلى متجرٍ مؤرشَف أكبر، ومؤتمرات فيديو أو صوت أكبر، وعمليات بحثٍ وحوسبةٍ أعقد مما يستطيع أي مستخدمٍ تحمل تكاليفه بمفرده. تُذكَر سماتٌ مثل اللامركزية والتنظيم الذاتي عند مناقشة شبكات الند للند في كثيرٍ من الأحيان، مما يعني أن العُقد تنظّم نفسها في شبكةٍ دون أي تنسيقٍ مركزي. إذا فكرت في الأمر، فيمكنك استخدام مصطلحات مثلها لوصف الإنترنت نفسه، ولكن من المفارقات أن تطبيق نابستر Napster لم يكن نظام ندٍ لند حقيقيًا بهذا التعريف بسبب اعتماده على سجلٍ مركزيٍ للملفات المعروفة، وكان على المستخدمين البحث في هذا الدليل للعثور على الجهاز الذي يقدم ملفًا معينًا. الخطوة الأخيرة المتمثلة بتحميل الملف فعليًا هي فقط التي حدثت بين الأجهزة التي تنتمي إلى مستخدمين اثنين، ولكن هذا ليس أكثر من معاملةٍ تقليديةٍ بين العميل والخادم؛ حيث أن الفارق الوحيد هو أن الخادم مملوكٌ لشخصٍ مثلك تمامًا وليس لشركةٍ كبيرة. إذا عدنا إلى السؤال الأصلي: ما المثير للاهتمام في شبكات الند للند؟ تتمثل إحدى الإجابات في أن كلًا من عملية تحديد موقع كائن وعملية تحميل هذا الكائن على جهازك المحلي تحدث دون الحاجة إلى الاتصال بسلطةٍ مركزية، وفي نفس الوقت يكون النظام قادرًا على توسيع نطاقه ليشمل ملايين العقد. يتضح أن نظام الند للند الذي يمكنه إنجاز هاتين المهمتين بطريقةٍ لامركزية هو شبكة تراكب overlay network، حيث تكون العقد هي هؤلاء المضفين الذين يرغبون في مشاركة الكائنات، مثل الموسيقى والملفات المتنوعة الأخرى، وتمثل الروابط (أو الأنفاق) التي تربط هذه العقد تسلسل الأجهزة التي يجب عليك زيارتها لتعقب الكائن الذي تريده. سيصبح كل شيءٍ أوضح بعد أن نشرح المثالين التاليين. شبكة جنوتيلا Gnutella وهي إحدى شبكات الند للند الأولى التي حاولت التمييز بين تبادل الموسيقى، الذي يمكن أن ينتهك حقوق الطبع والنشر لشخصٍ ما، والمشاركة العامة للملفات والتي يجب أن تكون جيدة لأننا تعلّمنا المشاركة منذ نعومة أظفارنا. كانت شبكة جنوتيلا Gnutella من أوائل الأنظمة التي لم تعتمد على سجلٍ مركزي للكائنات، حيث يرتّب المشاركون أنفسهم في شبكة تراكبٍ مشابهةٍ للشبكة الموضحة في الشكل الآتي؛ أي أن كل عقدةٍ تشغّل برمجيات شبكة جنوتيلا (أي تطبّق بروتوكول شبكة Gnutella) تعرّف مجموعةً من الأجهزة الأخرى التي تشغّل برمجيات هذه الشبكة أيضًا. تتوافق العلاقة "تعرف العقدتان A وB بعضهما بعضًا" مع أضلاع الرسم البياني التالي. إذا أراد المستخدم في عقدةٍ معينة العثور على كائنٍ ما، ترسل شبكة جنوتيلا رسالة استعلام QUERY عن هذا الكائن (مثل تحديد اسم الملف) إلى جيران العقدة في الرسم البياني؛ فإذا كان لدى أحد الجيران هذا الكائن، فإنه يستجيب للعقدة التي أرسلت إليه الاستعلام برسالة استجابة QUERY RESPONSE، مع تحديد مكان تحميل الكائن، مثل عنوان IP ورقم منفذ TCP، ويمكن لهذه العقدة فيما بعد استخدام رسائل GET أو PUT للوصول إلى الكائن؛ وفي حال لم تتمكن العقدة من تحليل الاستعلام، فإنها تعيد توجيه رسالة QUERY إلى كل جيرانها باستثناء العقدة التي أرسلت لها الاستعلام، وتتكرر العملية، أي يغمر بروتوكول جنوتيلا شبكة التراكب لتحديد موقع الكائن المطلوب. يضبط بروتوكول شبكة جنوتيلا مدة البقاء أو العُمر TTL على كل استعلامٍ حتى لا يستمر هذا الغمر إلى أجلٍ غير مسمى. تحتوي كل رسالةٍ من رسائل QUERY على معرف استعلام فريد query identifier -أو اختصارًا QID- بالإضافة إلى مدة TTL وسلسلة الاستعلامات، ولكنها لا تحتوي على هوية مصدر الرسالة الأصلي، حيث تحتفظ كل عقدةٍ بدلًا من ذلك بسجلٍ لرسائل QUERY التي شاهدتها مؤخرًا، والذي يحتوي على كلٍ من معرّف QID والجار الذي أرسل رسالة QUERY إلى هذه العقدة. يُستخدم هذا السجل بطريقتين. أولًا، إذا استلمت العقدة في أي وقت استعلامًا بمعرف QID يطابق معرّفًا رأته مؤخرًا، فلن تمرر رسالة QUERY. يعمل هذا على قطع حلقات التمرير بسرعةٍ أكبر مما قد تفعله مدة TTL. ثانيًا، عندما تتلقى العقدة استجابة QUERY RESPONSE من جارٍ يقع تحتها في الشجرة، فإنها تمرر الاستجابة إلى الجار الرئيسي الذي أرسل إليها رسالة QUERY في الأصل. تعود الاستجابة في طريقها باستخدام هذه الطريقة إلى العقدة الأصلية دون أن تعرف أيًّا من العقد الوسيطة هي العقدة التي أرادت تحديد موقع هذا الكائن المحدد في المقام الأول. يجب أن تعرف العقدة عقدةً أخرى على الأقل عندما تنضم إلى شبكة تراكب جنوتيلا، حيث تُضاف العقدة الجديدة إلى شبكة التراكب بواسطة هذا الرابط على الأقل، ثم تتعرف عقدةٌ معينةٌ على العقد الأخرى نتيجة لرسائل QUERY RESPONSE، سواء بالنسبة للكائنات التي طلبتها أو للاستجابات التي تمر عبرها. العقدة حرةٌ في تحديد العقد التي تُكتشف بهذه الطريقة والتي تريد الاحتفاظ بها مثل جار، حيث يوفر بروتوكول جنوتيلا رسائل PING و PONG التي تتحرى العقدة بواسطتها ما إذا كان جارٌ معين لا يزال موجودًا أم لا وأن هذا الحار يستجيب، على التوالي. يجب أن يكون واضحًا أن بروتوكول شبكة جنوتيلا كما هو موصوف هنا ليس بروتوكولًا ذكيًا، وقد حاولت الأنظمة اللاحقة تحسينه. أحد أبعاد التحسينات الممكنة هو كيفية نشر الاستعلامات، حيث تحتوي طريقة الغمر Flooding على خاصيةٍ لطيفةٍ وهي ضمان العثور على الكائن المطلوب في أقل عددٍ ممكنٍ من القفزات، ولكنها لا تتوسّع جيدًا. يمكن تمرير الاستعلامات عشوائيًا، أو وفقًا لاحتمالية النجاح بناءً على النتائج السابقة. البعد الثاني هو استنساخ الكائنات استباقيًا، نظرًا لأنه كلما زاد عدد نسخ كائنٍ معين، كان من الأسهل العثور على نسخة. يمكن بدلًا من ذلك تطوير استراتيجيةٍ مختلفةٍ تمامًا، وهو الموضوع الذي سنشرحه الآن. شبكات التراكب المهيكلة Structured Overlays في نفس الوقت الذي بدأت فيه أنظمة مشاركة الملفات الصراع لملء الفراغ الذي تركه تطبيق Napster، بدأ مجتمع البحث في استكشاف تصميمٍ بديلٍ لشبكات الند للند. نشير إلى هذه الشبكات على أنها مهيكلة structured، على عكس الطريقة العشوائية غير المهيكلة أساسًا التي تتطوّر بها شبكة جنوتيلا، حيث تستخدم شبكات التراكب غير المهيكلة مثل شبكة جنوتيلا خوارزميات بناء وصيانة تراكب بسيطة، ولكن أفضل ما يمكن أن تقدمه هو البحث العشوائي غير الموثوق به؛ بينما صُمِّمت شبكات التراكب المهيكلة لتتوافق مع بنية رسمٍ بيانيٍ معينة تتيح موقعًا موثوقًا وفعالًا وبتأخير محدود احتماليًا، في مقابل تعقيدٍ إضافي أثناء إنشاء التراكب وصيانته. هناك سؤالان يجب مراعاتهما، هما: كيف يمكننا ربط الكائنات مع العقد، وكيف نوجه طلبًا إلى العقدة المسؤولة عن كائن معين؟ نبدأ بالسؤال الأول، الذي يحتوي على عبارةٍ بسيطة: كيف يمكننا ربط كائنٍ x مع عنوان بعض العقد n التي يمكنها خدمة هذا الكائن؟ لا تتحكم شبكات الند للند التقليدية في تحديد العقدة التي تستضيف الكائن x، فإذا تمكنا من التحكم في كيفية توزيع الكائنات عبر الشبكة، فقد نتمكن من فعل أمرٍ أفضل للعثور على هذه الكائنات في وقتٍ لاحق. من الأساليب المعروفة لربط الأسماء مع عنوان هي استخدام جدول التعمية hash كما يلي: hash(x) → n حيث يُوضَع الكائن x أولًا على العقدة n، وسيتعين في وقتٍ لاحق على العميل الذي يحاول تحديد موقع x، تنفيذ تعمية x لتحديد أنه موجود على العقدة n. يتميز النهج القائم على التعمية بخاصيةٍ تتمثل في ميله إلى نشر الكائنات بالتساوي عبر مجموعة العقد، لكن خوارزميات التعمية المباشرة تعاني من عيبٍ هو: ماهو عدد القيم n الممكنة التي يجب أن نسمح بها؟ أو باستخدام مصطلحات التعمية، كم عدد المجموعات buckets التي يجب أن تكون موجودة؟ يمكننا أن نقرر ببساطةٍ أن هناك 101 قيمةً معمَّاةً محتملةً على سبيل المثال، ونستخدم دالة تعميةٍ نمطيةٍ هي: hash(x) return x % 101 إذا كان هناك أكثر من 101 عقدةٍ على استعدادٍ لاستضافة كائنات، فلا يمكننا الاستفادة منها جميعًا. وإذا حددنا عددًا أكبر من أكبر عددٍ ممكنٍ من العقد، فستكون هناك بعض قيم x التي ستُطبَّق عليها التعمية في عنوان عقدةٍ غير موجودة. وهناك أيضًا مشكلةٌ صغيرةٌ تتمثل في ترجمة القيمة التي تعيدها دالة التعمية إلى عنوان IP فعلي. تستخدم شبكات الند للند المهيكلة، لمعالجة هذه المشكلات خوارزميةً تُعرف باسم إجراء التعمية المستقرة consistent hashing، والتي تطبّق تعميةً على مجموعة من الكائنات بصورةٍ موحدة عبر حيز معرّفاتٍ كبير. يوضح الشكل السابق حيز معرّفات ذا 128 بت على شكل دائرة، حيث نستخدم الخوارزمية لوضع كلٍ من الكائنات: hash(ObjectName) → ObjectID والعقد: hash(IPAddr) → NodeID على هذه الدائرة. بما أن حيز المعرّفات ذا 128 بت هائل، فليس مرجحًا تعمية الكائن لنفس المعرّف تمامًا مثل تعمية عنوان IP الخاص بالجهاز. لحساب هذا الاحتمال، يُحتفَظ بكل كائنٍ على العقدة التي يكون معرّفها أقرب، في حيز 128 بت هذا، إلى معرّف هذا الكائن. تكمن الفكرة في استخدام دالة تعمية عالية الجودة لربط كلٍ من العقد والكائنات في نفس حيز المعرّفات الكبير والمبعثر؛ حيث يمكنك بعد ذلك ربط الكائنات مع العقد عن طريق التقريب العددي من معرّفات كل منها، وهذا يوزّع الكائنات بالتساوي إلى حدٍ ما عبر العقد، ولكن وعلى عكس التعمية العادية، يجب أن يتحرك عددٌ قليلٌ فقط من الكائنات عندما تنضم العقدة إلى مجموعة التعمية أو تغادر. ننتقل الآن إلى السؤال الثاني الذي يدور حول كيفية معرفة المستخدم الذي يريد الوصول إلى الكائن x العقدةَ الأقرب في معرّف x ضمن هذا الحيّز. تتمثل إحدى الإجابات المحتملة في احتفاظ كل عقدةٍ بجدولٍ كامل لمعرّفات العقد وعناوين IP المرتبطة بها، ولكن هذا لن يكون عمليًا لشبكةٍ كبيرة، والبديل هو توجيه رسالةٍ إلى هذه العقدة، وهو النهج الذي تستخدمه شبكات ند لند المهيكلة. فإذا أنشأنا شبكة التراكب بطريقةٍ ذكية، والذي يعني أننا بحاجةٍ إلى اختيار مدخلات لجدول توجيه العقدة بطريقةٍ ذكية، فسنجد عقدةً ببساطة عن طريق التوجيه نحوها، ويُطلَق على هذا النهج أحيانًا جدول التعمية الموزَّع distributed hash table -أو اختصارًا DHT-، نظرًا لأنه نظريًا يُوزَّع جدول التعمية على جميع العقد في الشبكة. يوضّح الشكل السابق ما يحدث لحيز معرّف بسيطٍ ذي 28 بت، حيث افترضنا تسمية النهج الذي تستخدمه شبكة ند لندٍ معينة باسم Pastry للحفاظ على طبيعة المناقشة محددةً، وتعمل الأنظمة الأخرى بطريقةٍ مماثلة. افترض أنك في العقدة ذات المعرّف 65a1fc (عدد ست عشري) وتحاول تحديد موقع locate الكائن ذي المعرّف d46a1c، حيث تدرك أن معرّفك لا يتشارك شيئًا مع الكائن، لكنك تعرف عقدةً تشترك في البادئة d على الأقل، وهذه العقدة أقرب منك في حيز المعرّفات ذي 128 بت، لذلك تمرر الرسالة إلى هذه العقدة. لا نعطي صيغة الرسالة المُمررة، ولكن يمكنك التفكير في الأمر مثل تحديد موقع الكائن d46a1c. افترض أن العقدة d13da3 تعرف عقدةً أخرى تشترك في بادئةٍ أطول مع الكائن، لذلك تمرر الرسالة إليها. تستمر عملية الاقتراب في حيز المعرّفات حتى تصل إلى عقدةٍ لا تعرف أي عقدةٍ أقرب؛ هذه العقدة، بحكم التعريف، هي التي تستضيف الكائن. ضع في بالك أنه تُمرر الرسالة بالفعل من عقدةٍ إلى أخرى عبر شبكة الإنترنت الأساسية، بينما نتحرك منطقيًا عبر حيز المعرّفات. تحتفظ كل عقدةٍ بجدول توجيه وعناوين IP لمجموعةٍ صغيرة من معرّفات العقد الأكبر والأصغر عددًا، وهذا ما يُسمى مجموعة أوراق leaf set العقدة؛ وتكمن أهمية مجموعة الأوراق في أنه بمجرد توجيه الرسالة إلى أية عقدةٍ في نفس مجموعة الأوراق مثل العقدة التي تستضيف الكائن، يمكن لهذه العقدة تمرير الرسالة مباشرةً إلى الوجهة النهائية؛ كما تسهّل مجموعة الأوراق التسليم الصحيح والفعال للرسالة إلى العقدة الأقرب عدديًا، على الرغم من وجود عدة عقدٍ تشترك في بادئةٍ ذات أقصى طول مع معرّف الكائن؛ وتقوّي أيضًا مجموعةُ الأوراق التوجيهَ لأن أيًا من العقد في مجموعة الأوراق يمكنها توجيه رسالة تمامًا مثل أية عقدةٍ أخرى في نفس المجموعة، وبالتالي إذا كانت إحدى العقد غير قادرةٍ على إحراز تقدمٍ في توجيه رسالة، فقد يتمكن أحد جيرانها في مجموعة الأوراق من ذلك، حيث يمكن تعريف إجراء التوجيه على النحو التالي: Route(D) if D is within range of my leaf set forward to numerically closest member in leaf set else let l = length of shared prefix let d = value of l-th digit in D's address if RouteTab[l,d] exists forward to RouteTab[l,d] else forward to known node with at least as long a shared prefix and numerically closer than this node جدول التوجيه المشار إليه باسم RouteTab، هو مصفوفةٌ ثنائية الأبعاد، ويحتوي على سطرٍ لكل رقمٍ ست عشري في المعرّف (يوجد 32 رقمًا في معرّف 128 بت) وعمودٍ لكل قيمةٍ ست عشرية (هناك 16 قيمة)، حيث تشترك كل مدخلةٍ في السطر i ببادئة طولها i مع هذه العقدة، وتكون للمُدخلة في العمود j في هذا السطر القيمة الست عشرية j في الموضع i + 1. يوضح الشكل الآتي السطور الثلاثة الأولى من جدول توجيه العقدة 65a1fcx، حيث تشير x إلى لاحقةٍ غير محددة. يوضّح هذا الشكل أيضًا بادئة المعرّف المطابقة لكل مدخلةٍ في الجدول، ولكنه لا يُظهر القيمة الفعلية المضمَّنة في هذه المدخلة، والتي هي عنوان IP للعقدة التالية للتوجيه إليها. تعمل إضافة عقدةٍ إلى شبكة التراكب إلى حدٍ كبير مثل توجيه رسالة تحديد موقع locate object message إلى كائن، حيث يجب أن تعرف العقدة الجديدة عضوًا حاليًا واحدًا على الأقل، وتطلب من هذا العضو توجيه رسالة إضافة عقدة add node message إلى العقدة الأقرب عدديًا لمعرّف عقدة الانضمام، كما هو موضح في الشكل الآتي. تتعرّف العقدة الجديدة على العقد الأخرى ذات البادئة المشتركة من خلال عملية التوجيه، وتستطيع بدء ملء جدول التوجيه الخاص بها. تمتلك العقد الحالية أيضًا بمرور الوقت وانضمام العقد الإضافية إلى شبكة التراكب، خيارَ تضمين معلوماتٍ حول العقدة المنضمَّة حديثًا في جداول التوجيه الخاصة بها، حيث تقوم بذلك عندما تضيف العقدة الجديدة بادئةً أطول مما هو موجود حاليًا في جداولها. كما تتبادل العقد الجيران في مجموعات الأوراق جداول التوجيه مع بعضها بعضًا، مما يعني أنه بمرور الوقت تنتشر معلومات التوجيه عبر شبكة التراكب. من المُلاحظ أن شبكات التراكب المهيكلة توفر حدًا محتمَلًا لعدد قفزات التوجيه المطلوبة لتحديد موقع كائنٍ معين، لكن عدد القفزات في آلية Pastry محددٌ بالقيمة log<sub>16</sub>N، حيث تمثل N عدد العقد في شبكة التراكب. قد تساهم كل قفزةٍ في تأخيرٍ كبير، لأن كل عقدةٍ وسيطة قد تكون في موقعٍ عشوائيٍ على الإنترنت، وقد تكون كل عقدةٍ في قارةٍ مختلفة في أسوأ الأحوال. التأخير المتوقَع لكل قفزة هو متوسط التأخير بين جميع أزواج العقد في الإنترنت في شبكة تراكبٍ عالمية باستخدام الخوارزمية كما هو موضح أعلاه، ولكن يمكن فعل شيءٍ أفضل بكثير عمليًا؛ حيث تكمن الفكرة في اختيار كل مدخلةٍ في جدول التوجيه بحيث تشير إلى عقدةٍ قريبةٍ في الشبكة الفيزيائية الأساسية، من بين جميع العقد ذات بادئة المعرّف المناسبة للمدخلة. اتضح أن فعل ذلك يؤدي إلى تأخيراتٍ في التوجيه من طرفٍ إلى طرف بمعامل تأثيرٍ صغير من إجمالي التأخير بين عقدة المصدر والوجهة. أخيرًا، ركّزت المناقشة حتى الآن على المشكلة العامة المتمثلة في تحديد موقع الكائنات في شبكة ندٍ لند، حيث يمكن بناء خدماتٍ مختلفة بالنظر إلى مثل هذه البنية التحتية للتوجيه. قد تستخدم خدمة مشاركة الملفات أسماء الملفات مثل أسماء كائنات، حيث يجب أولًا تطبيق تعميةٍ على اسم ملفٍ لتحديد موقعه في معرّف الكائن المقابل ثم توجيه رسالة تحديد موقع إلى هذا المعرّف. وقد ينسخ النظام أيضًا كل ملفٍ عبر عقدٍ متعددةٍ لتحسين التوافرية، وتتمثل أحد الطرق لتحقيق ذلك بتخزين عدة نُسخٍ على مجموعة أوراق العقدة التي يُوجَّه إليها ملفٌ معين. ضع في بالك أنه على الرغم من أن هذه العقد هي جيران في حيز المعرّفات، فيُحتمَل أن توزَّع فعليًا عبر الإنترنت، وبالتالي فإن انقطاع التيار الكهربائي في مدينةٍ بأكملها قد يؤدي إلى إزالة النسخ المتماثلة القريبة فعليًا من ملفٍ في نظام ملفاتٍ تقليدي، لكن يمكن أن تنجو نسخةً متماثلةً واحدةً أو أكثر من هذا الفشل في شبكة ند لند. يمكن أيضًا إنشاء خدمات أخرى غير مشاركة الملفات على جداول التعمية الموزعة. فمثلًا من أجل تطبيقات البث المتعدد وبدلًا من إنشاء شجرة متعددة البث من شبكة، يمكن إنشاء الشجرة من أضلاع شبكة التراكب المهيكلة، ويؤدي ذلك إلى استهلاك تكلفة إنشاء شبكة التراكب وصيانتها عبر العديد من التطبيقات ومجموعات البث المتعدد. ترجمة -وبتصرّف- للقسم Overlay Networks من فصل Applications من كتاب Computer Networks: A Systems Approach. اقرأ أيضًا بيانات شبكات طرف إلى طرف الحاسوبية بروتوكولات تدفق البايتات الموثوقة في الشبكات الحاسوبية: آلية الإرسال والبدائل استدعاء إجراء عن بعد Remote Procedure Call في الشبكات الحاسوبية
-
سنوضَح في هذا المقال كيفية إضافة عناصر التحكم بمربع الحوار Dialog في ليبر أوفيس كالك LibreOffice Calc والتعامل مع عناصر التحكم المختلفة في نموذج باستخدام الماكرو Macro. هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبر أوفيس كالك، فهرس السلسلة: مدخل إلى كتابة ماكرو Macro في ليبر أوفيس كالك LibreOffice Calc. معالجة محتويات خلايا ليبر أوفيس كالك باستخدام الماكرو. معالجة مجال من الخلايا باستخدام الماكرو في ليبر أوفيس كالك. استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبر أوفيس. التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبر أوفيس كالك. أتمتة حفظ أوراق ليبر أوفيس كالك بتنسيق PDF باستعمال الماكرو. التعامل مع عناصر التحكم بمربع الحوار باستخدام الماكرو سنوضّح كيفية إنشاء مربع حوار Dialog في ليبر أوفيس LibreOffice وإضافة عناصر تحكم متنوعة إليه مثل مربع النص TextBox وقراءة قيم عناصر التحكم باستخدام الماكرو. إضافة مربع حوار يمكنك إضافة مربع حوار في ليبر أوفيس كالك من قائمة أدوات Tools ثم ماكرو Macros ثم تنظيم المربعات الحوارية Organize Dialogs. إنشاء مربع حوار من القائمة ستفتح بعد ذلك نافذة منظم الماكروهات الأساسية Basic Macro Organizer الموضَحة أدناه. انقر على زر جديد New في تبويب "الحواريات Dialogs". إنشاء مربع حوار جديد سمِّ مربع الحوار في نافذة حواري جديد New Dialog المنبثقة. استخدم الاسم الافتراضي Dialog1، ثم اضغط موافق OK. مربع حوار جديد يمكنك رؤية مربع الحوار Dialog1 ضمن حواراتي My Dialogs ثم Standard ثم Dialog1. إضافة عنصر التحكم بمربع نص TextBox انقر على تحرير Edit مع تحديد Dialog1 في نافذة منظم الماكروهات الأساسية. تحرير مربع الحوار سيفتح محرّر مربع الحوار، ثم يجب إضافة بعض عناصر التحكم، حيث سنضيف مربع نص وزر. تُوضَع عناصر التحكم في الجزء السفلي من الشاشة. حدد عنصر تحكم واسحب الفأرة إلى داخل مربع الحوار لوضع عنصر التحكم المطلوب ضمنه. إذا كنت غير قادر على رؤية مربع الأدوات أسفل الشاشة، فانتقل إلى قائمة عرض View ثم أشرطة الأدوات Toolbars ثم مربع الأدوات Toolbox. يجب أن يبدو مربع الحوار كما يلي: يمكنك ضبط خصائص كل عنصر تحكم من خلال تحديده، ثم يمكنك مشاهدة نافذة الخصائص المفتوحة في الجانب السفلي الأيمن من المحرّر، حيث تُستخدَم قيمة "الاسم name" في تبويب "عام General" لتحديد الكائنات ضمن الماكرو. اسم مربع النص الافتراضي هو TextField1، بينما اسم الزر الافتراضي هو CommandButton1. أصبح مربع الحوار جاهزًا، إذًا لنكتب الماكرو. شيفرة الماكرو سنعرض كيفية فتح مربع الحوار باستخدام ماكرو ليبر أوفيس كالك، وقراءة محتويات مربع النص ومحتوى خلية من الورقة 1، ثم سنعرض محتوى مربع النص ومحتويات الخلية في مربع رسالة بعد النقر على الزر. انتقل إلى محرّر الماكرو (انقر على تبويب Module1) وأنشئ دالتين على النحو التالي: Dim oDialog1 As Object Sub StartDialog1() ' Code for initiating and showing the dialog End Sub Sub readDialog1() ' Read the content End Sub عرّف كائن oDialog1 على أنه نوع كائن خارج نطاق الدوال، لأننا نحتاج إلى الوصول إلى مربع الحوار Dialog في دالة مختلفة. سنحمّل مكتبة الأدوات Tools في الدالة StartDialog1(). تُنفَّذ المكتبات كواجهات UNO وليس كخدمات UNO وفقًا لتصميم ليبر أوفيس وأوبن أوفيس الحالي، ولا تُحمَّل جميع المكتبات الأساسية عند بدء تشغيل ليبر أوفيس / أوبن أوفيس لتوفير الوقت. إذا أنشأت مكتبتك الخاصة مثل Library1، فيجب تحميل المكتبة صراحةً لتحديد الدوال التي يعرّفها المستخدم، حيث يمكنك استخدام الخصائص المبنية مسبقًا BasicLibraries.LoadLibrary لتحميل أيّ مكتبة. سنستخدم مكتبة ليبر أوفيس / أوبن أوفيس المُعرَّفة مسبقًا "Tools" مع الشيفرة الآتية، حيث ستحمِّل الخاصية LoadLibrary مكتبة الأدوات "Tools" ثم سنعرض مربع الحوار المُنشَأ باستخدام الدالة LoadDialog() والدالة Execute(). Sub StartDialog1() BasicLibraries.LoadLibrary("Tools") oDialog1 = LoadDialog("Standard", "Dialog1") oDialog1.Execute() End Sub كما يمكنك استخدام طريقة أخرى مثل جزء الشيفرة التالية الذي يمكنه فتح مربع حوار: DialogLibraries.LoadLibrary("Standard") oDialog = CreateUnoDialog(DialogLibraries.Standard.Dialog1) سنقرأ الآن محتوى مربع نص TextBox ومحتوى الخلية الأولى من الورقة 1 في كالك أي الخلية A1. للحصول على عنصر تحكم. استخدم الدالة (اسم عنصر التحكم) GetControl الخاصة بكائن مربع الحوار، ثم يمكنك استخدام الخاصيات المتاحة المتعددة، مثل استخدام خاصية النص Text() الخاصة بعنصر التحكم لإدخال نص في مربع نص Textbox. Sub readDialog1() Dim cell_val oT1 = oDialog1.GetControl("TextField1") cell_val = ThisComponent.Sheets(0).getCellByPosition(0,0) msgbox cell_val.String & chr(13) & "Value from controls: " & oT1.Text End Sub يجب إسناد الدالة readDialog1() إلى حدث النقر على الزر قبل تشغيل الماكرو من خلال الرجوع إلى محرّر مربع الحوار وتحديد الزر، ثم حدّد تبويب الأحداث Events في نافذة الخاصيات. أسنِد الدالة readDialog1() من خلال النقر على زر "تنفيذ إجراء Execute Action" واختيار الماكرو. تشغيل الماكرو ضع أيّ نص في الخلية A1 في ورقة كالك وضع النص "Hello World". افتح محرّر الماكرو وشغّل الدالة StartDialog1() بحيث يُنفَّذ مربع الحوار، ثم ضع نصًا في مربع النص وانقر على الزر. يجب أن تشاهد النص الموجود في مربع النص من مربع الحوار وكذلك النص الموجود في الخلية A1 من الورقة 1. تشغيل الماكرو يمكنك العمل بهذه الطريقة مع مربعات الحوار وعناصر التحكم باستخدام الماكرو في ليبر أوفيس / أوبن أوفيس. شيفرة الماكرو الكاملة انسخ والصق الشيفرة التالية في محرّر الماكرو في ليبر أوفيس: Dim oDialog1 As Object Sub StartDialog1() BasicLibraries.LoadLibrary("Tools") oDialog1 = LoadDialog("Standard", "Dialog1") oDialog1.Execute() End Sub Sub readDialog1() Dim cell_val oT1 = oDialog1.GetControl("TextField1") cell_val = ThisComponent.Sheets(0).getCellByPosition(0,0) msgbox cell_val.String & chr(13) & "Value from controls: " & oT1.Text End Sub معالجة النماذج باستخدام الماكرو في ليبر أوفيس كالك سنشرح فيما يلي كيفية الوصول إلى قيم عناصر تحكم حقل التسمية Label وخانة الاختيار Check Box وزر الخيار Option Box ومربع التحرير والسرد Combo Box ومربع القائمة List Box، وكيفية التعرف على القيم التي يحدّدها المستخدم في عناصر التحكم هذه. افتح برنامج ليبر أوفيس وأنشئ مربع حوار، ثم أضِف حقل تسمية وثلاث خانات اختيار وزرَّي خيار ومربع قائمة واحد ومربع تحرير وسرد واحد وزر. يمكن إضافة كل عناصر التحكم هذه من مربع الأدوات ToolBox، حيث يمكنك الوصول إليه من قائمة عرض View ثم أشرطة الأدوات Toolbars ثم مربع الأدوات ToolBox. مربع الأدوات في ليبر أوفيس حدّد عناصر التحكم بعد إضافتها واسحبها ضمن النموذج حسب الحاجة. كما يمكن الوصول إلى القيم أو الخيارات المحددة في عناصر التحكم هذه ووضعها في خلايا كالك. مربع الاختيار Checkbox مربعات الاختيار هي وسيلة ليختار المستخدم من بين خيارات متعددة. يمكن معرفة ما إذا كان مربع الاختيار محددًا أم لا من خلال استخدام الدالة getState. إذا كان مربع الاختيار محدَّدًا، فستعيد الدالة القيمة 1، وإلّا فستعيد القيمة 0. يمكنك تغيير النص المعروض بجانب كل خانة اختيار أثناء التصميم باستخدام حقل "التسمية Label" في تبويب عام من نافذة الخصائص. chkBox1 = oDialog1.GetControl("CheckBox1") chkBox2 = oDialog1.GetControl("CheckBox2") chkBox3 = oDialog1.GetControl("CheckBox3") if chkBox1.State = 1 then oCell = ThisComponent.Sheets(0).getCellByPosition(1,1) oCell.String = "Debian" end if if chkBox2.State = 1 then oCell = ThisComponent.Sheets(0).getCellByPosition(1,2) oCell.String = "Ubuntu" end if if chkBox3.State = 1 then oCell = ThisComponent.Sheets(0).getCellByPosition(1,3) oCell.String = "elementary" end if مربع القائمة List Box ومربع التحرير والسرد Combo box يمنح مربع القائمة List Box ومربع التحرير والسرد Combo Box المستخدم القدرة على الاختيار من قائمة العناصر، ولكن الفرق الوحيد بينهما هو طريقة عرض العناصر، حيث يحتوي مربع التحرير والسرد على قائمة منسدلة بينما يحتوي مربع القائمة على قائمة بالعناصر المعروضة. استخدم الدالة getSelectedItem() للحصول على تحديد مربع القائمة، واستخدم الدالة SelectedText() للحصول على العنصر المحدد من مربع التحرير والسرد. استخدم الدالة addItem(,) أثناء تحميل النموذج لأول مرة لملء مربع القائمة ومربع التحرير السرد مسبقًا. lstBox1 = oDialog1.GetControl("ListBox1") if lstBox1.getItemCount = 0 then lstBox1.addItem("Mango",1) lstBox1.addItem("Apple",2) lstBox1.addItem("Orange",3) end if cmbBox1 = oDialog1.GetControl("ComboBox1") if cmbBox1.getItemCount = 0 then cmbBox1.addItem("500",1) cmbBox1.addItem("1000",2) cmbBox1.addItem("10000",3) end if oCell = ThisComponent.Sheets(0).getCellByPosition(1,5) oCell.String = lstBox1.getSelectedItem() oCell = ThisComponent.Sheets(0).getCellByPosition(1,6) oCell.String = cmbBox1.SelectedText() زر الخيار Option Box يمثل زر الخيار الخيارات المُقدَّمة للمستخدم بحيث يمكن تحديد خيار واحد فقط. تُجمَّع كل أزرار الخيارات المُضافَة في النموذج معًا افتراضيًا في ليبر أوفيس على عكس التطبيقات الأخرى. تعيد الخاصية State() الخاصة بزر الخيار القيمة True إذا كان الخيار محدَّدًا، وإلا فإنها تعيد القيمة False. if optBtn1.State = True then oCell = ThisComponent.Sheets(0).getCellByPosition(1,7) oCell.String = "No" end if if optBtn2.State = True then oCell = ThisComponent.Sheets(0).getCellByPosition(1,8) oCell.String = "Yes" end if تشغيل شيفرة الماكرو سنعرض القيم التي اختارها المستخدم في نموذج كالك بعد اكتمال تصميمه، ثم نشغّل الدالة StartDialog1() لتنفيذ النموذج. حدّد بعض الخيارات من المكونات الموجودة في النموذج وانقر على الزر وانتقل إلى ليبر أوفيس كالك المفتوح، ثم يمكنك أن ترى أن القيم قد قُرأت ووُضِعت في خلايا كالك. النموذج مع تحديد القيم الخرج شيفرة الماكرو الكاملة انسخ والصق الشيفرة التالية في محرّر الماكرو في ليبر أوفيس: Dim oDialog1 As Object Sub StartDialog1() BasicLibraries.LoadLibrary("Tools") oDialog1 = LoadDialog("Standard", "Dialog1") lstBox1 = oDialog1.GetControl("ListBox1") if lstBox1.getItemCount = 0 then lstBox1.addItem("Mango",1) lstBox1.addItem("Apple",2) lstBox1.addItem("Orange",3) end if cmbBox1 = oDialog1.GetControl("ComboBox1") if cmbBox1.getItemCount = 0 then cmbBox1.addItem("500",1) cmbBox1.addItem("1000",2) cmbBox1.addItem("10000",3) end if oDialog1.Execute() End Sub Sub readDialog1() Dim oCell chkBox1 = oDialog1.GetControl("CheckBox1") chkBox2 = oDialog1.GetControl("CheckBox2") chkBox3 = oDialog1.GetControl("CheckBox3") optBtn1 = oDialog1.GetControl("OptionButton1") optBtn2 = oDialog1.GetControl("OptionButton2") lstBox1 = oDialog1.GetControl("ListBox1") cmbBox1 = oDialog1.GetControl("ComboBox1") if chkBox1.State = 1 then oCell = ThisComponent.Sheets(0).getCellByPosition(1,1) oCell.String = "Debian" end if if chkBox2.State = 1 then oCell = ThisComponent.Sheets(0).getCellByPosition(1,2) oCell.String = "Ubuntu" end if if chkBox3.State = 1 then oCell = ThisComponent.Sheets(0).getCellByPosition(1,3) oCell.String = "elementary" end if oCell = ThisComponent.Sheets(0).getCellByPosition(1,5) oCell.String = lstBox1.getSelectedItem() oCell = ThisComponent.Sheets(0).getCellByPosition(1,6) oCell.String = cmbBox1.SelectedText() if optBtn1.State = True then oCell = ThisComponent.Sheets(0).getCellByPosition(1,7) oCell.String = "No" end if if optBtn2.State = True then oCell = ThisComponent.Sheets(0).getCellByPosition(1,8) oCell.String = "Yes" end if End Sub ترجمة -وبتصرُّف- للمقالين Working with Dialog Controls in LibreOffice Calc using Macro – Part 1 و Form Processing with LibreOffice Calc Macro – Part 2 لصاحبهما Arindam. اقرأ أيضًا كيفية تحرير البيانات في LibreOffice Calc كيفية التحكّم في طرق عرض جداول بيانات LibreOffice Calc تعرّف على معالج جداول البيانات LibreOffice Calc
-
سنستخدم عناصر تحكم بالنماذج Controls -مثل الأزرار ومربعات النصوص- ونافذة فتح الملفات ضمن جدول بيانات ليبر أوفيس كالك LibreOffice Calc، وسنسند لها ماكرو، حيث سنعطي أمثلة بسيطة توضّح الأساسيات ولكن يمكنك تطويرها لتشمل احتياجاتك المختلفة. هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبر أوفيس كالك، فهرس السلسلة: مدخل إلى كتابة ماكرو Macro في ليبر أوفيس كالك LibreOffice Calc معالجة محتويات خلايا ليبر أوفيس كالك باستخدام الماكرو معالجة مجال من الخلايا باستخدام الماكرو في ليبر أوفيس كالك استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبر أوفيس التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبر أوفيس كالك أتمتة حفظ أوراق ليبر أوفيس كالك بتنسيق PDF باستعمال الماكرو إضافة زر إلى جدول بيانات كالك انتقل إلى قائمة عرض View ثم أشرطة الأدوات Toolbars ثم عناصر التحكم بالنموذج Form Controls، حيث يتكون عنصر التحكم بالنموذج من عناصر تحكم متعددة وزر تبديل لوضع التصميم وغير ذلك. سنضيف الآن زرًا إلى جدول بيانات كالك باستخدام عنصر تحكم الزر. لنكتب برنامجًا بسيطًا بلغة بيسك Basic قبل أن نسند أيّ ماكرو له، حيث سيُنفَّذ هذا البرنامج البسيط عند الضغط على الزر. إليك البرنامج المُنفَّذ عند النقر على الزر: Sub hello_world Dim my_doc as object Dim my_sheets as object Dim my_cell as object my_doc = ThisComponent my_sheets = my_doc.Sheets my_cell = ThisComponent.Sheets(0).getCellByPosition(2,2) my_cell.String = "A string populated by a button!" Msgbox "~~~ Welcome ~~~" & chr(13) & "LibreOffice Form Controls Demo",,"DebugPoint.com" End Sub ارجع إلى جدول بيانات كالك وحدّد الزر بعد أن يصبح البرنامج جاهزًا. انقر على زر "عناصر التحكم Controls" في شريط أدوات عناصر التحكم بالنموذج، أو يمكنك النقر بزر الفأرة الأيمن على الزر ثم النقر على عناصر التحكم Controls من قائمة السياق، ثم ستفتح نافذة خصائص الزر. إسناد ماكرو إلى الزر انقر على الزر الصغير بجوار العنوان "تنفيذ الإجراء Execute action"، حيث ستفتح نافذة جديدة هي "إسناد الإجراء Assign Action". اختر "تنفيذ الإجراء" وانقر على الزر "ماكرو Macro" لتحديد ماكرو. اختر الآن الماكرو الذي تريد تنفيذه (وهو "hello world" في مثالنا) وانقر على "موافق". سيظهر الماكرو المختار في نافذة "إسناد الإجراء" عند تحديده، ثم انقر على "موافق" للعودة إلى جدول البيانات. تشغيل الماكرو حان الوقت الآن لتشغيل شيفرة الماكرو، ولكن يجب قبل ذلك إيقاف تشغيل وضع التصميم Design Mode بالنقر على زر "تشغيل / إيقاف تشغيل وضع التصميم Design Mode On/Off" في شريط أدوات عناصر تحكم النموذج، ثم انقر على الزر وشاهد النتيجة. يمكنك باستخدام هذه الطريقة إسناد ماكرو بسرعة إلى عناصر التحكم وأتمتة المهام المختلفة في ليبر أوفيس. إدراج وقراءة النص في عنصر تحكم مربع النص TextField سنوضّح كيفية تهيئة سلسلة نصية وإدراجها في وقت التشغيل، وقراءتها من عنصر التحكم TextField باستخدام ماكرو مكتوب بلغة بيسك Basic. كيفية إضافة عنصر TextField إلى نافذة انقر على الرمز التالي واسحبه إلى نافذة جديدة لإضافة عنصر TextField: كيفية قراءة نص من عنصر TextField استخدم الدالة getText() لقراءة نص من عنصر TextField، حيث ستعيد هذه الدالة النص المُدخَل كسلسلة نصية من عنصر TextField. إليك المثال التالي: oTextField = oDialog1.getControl("TextField1") Msgbox oTextField.getText() كيفية إدراج أو تحديث نص في عنصر TextField استخدم الدالة setText() لتحديث محتويات عنصر TextField أثناء وقت التشغيل. إليك المثال التالي: oTextField = oDialog1.getControl("TextField1") oTextField.setText("Hello World!!!") كيفية تهيئة نص افتراضيًا في عنصر TextField هناك طريقتان يمكنك استخدامهما لتهيئة نص افتراضيًا في عنصر TextField. يمكنك تهيئة أي نص افتراضيًا لعنصر TextField أثناء التصميم باستخدام الخاصية Text، حيث يمكنك كتابة أيّ شيء تريده في الخاصية Text وستُملَأ في TextBox. الخيار الثاني هو استخدام الدالة setText() أثناء تحميل النافذة باستخدام عناصر التحكم الخاصة بها. خاصية TextField الافتراضية Text شيفرة الماكرو الكاملة انسخ والصق الشيفرة التالية في محرّر الماكرو ضمن ليبر أوفيس، وأنشئ نافذة بها زر ومربع نص، ثم أسند الدالة test() إلى حدث نقر الزر. قراءة النص: Dim oDialog1 As Object Sub StartDialog1() BasicLibraries.LoadLibrary("Tools") oDialog1 = LoadDialog("Standard", "Dialog1") oDialog1.Execute() End Sub Sub test() oTextField = oDialog1.getControl("TextField1") Msgbox oTextField.getText() End Sub ضبط النص: Dim oDialog1 As Object Sub StartDialog1() BasicLibraries.LoadLibrary("Tools") oDialog1 = LoadDialog("Standard", "Dialog1") oDialog1.Execute() End Sub Sub test() oTextField = oDialog1.getControl("TextField1") oTextField.setText("Hello World!!!") End Sub استخدام نافذة فتح ملف من خلال ماكرو سنوضّح فيما يلي كيفية فتح نافذة اختيار ملف في ليبر أوفيس LibreOffice وأوبن أوفيس OpenOffice باستخدام ماكرو. تُستخَدم نافذة اختيار ملف لتحديد ملف أو ملفات في عمليات الأتمتة المختلفة مثل فتح مصنف أوبن أوفيس OpenOffice أو ليبر أوفيس LibreOffice أو مثل استيراد ملف نصي أو ملف csv وما إلى ذلك. إنشاء الكائنات لنعرّف دالة يمكن أن يستخدمها أيّ ماكرو لفتح نافذة منتقي الملفات. Function open_file() As String ' open file picker dialog here and return the path of the chosen file End Function استخدم خدمة FilePicker الخاصة بوحدة com.sun.star.ui.dialogs وخدمة SimpleFileAccess الخاصة بالوحدة com.sun.star.ucb لفتح نافذة اختيار ملف، حيث ستوفر هاتان الخدمتان المقابض اللازمة لفتحها. صرّح وأنشئ كائنين لهذه الخدمات كما يلي: Dim file_dialog as Object Dim ucb as object GlobalScope.BasicLibraries.LoadLibrary("Tools") file_dialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker") ucb = createUnoService("com.sun.star.ucb.SimpleFileAccess") يوفر الكائن ucb -اختصارًا إلى Universal Content Broker- طريقة للوصول إلى محتويات متنوعة عبر UCP (مزوّدو المحتوى العالمي Universal Content Providers). تنسيق النافذة يجب تقديم بعض المعلومات قبل فتح نافذة منتقي الملفات مثل أنواع الملفات أو الامتدادات (.jpg و .png وغير ذلك) التي ستكون متاحة بوصفها مرشّحات Filters، ويجب ضبط المجلد الافتراضي لتحديده عند تنفيذ النافذة. عرّف مصفوفة تحتوي على امتدادات الملفات التي يجب تحميلها في قائمة النوع المنسدلة، ثم مرّرها إلى الدالة AddFiltersToDialog باستخدام كائن dialog. Dim filterNames(3) as String filterNames(0) = "*.*" filterNames(1) = "*.png" filterNames(2) = "*.jpg" AddFiltersToDialog(FilterNames(), file_dialog) استخدم الدالة SetDisplayDirectory مع كائن dialog لضبط المجلد الافتراضي الذي ستفتحه النافذة. تحوّل الدالة ConvertToUrl مسار لينكس إلى مسار نظام ملفات مثل المسار /usr الذي يُحوَّل إلى file:///usr. init_path = ConvertToUrl("/usr") If ucb.Exists(init_path) Then file_dialog.SetDisplayDirectory(init_path) End If فتح النافذة افتح نافذة اختيار الملف لإعادة اسم الملف، حيث ستفتح نافذة اختيار الملف عند تنفيذ الدالة Execute الخاصة بنافذة الملف، حيث تعيد هذه الدالة قيمتين هما 0 و 1 بناءً على إجراءات المستخدم. إذا اخترتَ ملفًا وضغطت على "موافق OK"، فستُعاد القيمة 1، وإذا ضغطت على "إلغاء CANCEL"، فستُعاد القيمة 0، وإذا حدّد المستخدم ملفًا أو ملفات متعددة، فستُعاد مصفوفة. لنحدّد في مثالنا ملفًا واحدًا ونعيد اسم الملف. أخيرًا، نفّذ الدالة Dispose لتحرير جميع الموارد. open_status = file_dialog.Execute() If open_status = 1 Then file_path = file_dialog.Files(0) open_file = file_path End If file_dialog.Dispose() استدعِ بعد ذلك الدالة open_file() من إجراء آخر، ولنعرض مسار الملف الُمحدَّد في مربع رسالة. Sub pick_a_file() Dim fName As String fName = open_file() MsgBox fName & chr(10) & ConvertFromUrl(fName) End Sub تشغيل الشيفرة إذا شغّلت الدالة pick_a_file()، فيمكنك رؤية النافذة ومربع الرسالة مع مسار الملف المُحدَّد. فتح نافذة تحديد ملف باستخدام ماكرو خرج فتح ملف شيفرة الماكرو الكاملة Sub pick_a_file() Dim fName As String fName = open_file() MsgBox fName & chr(10) & ConvertFromUrl(fName) End Sub Function open_file() as String Dim file_dialog as Object Dim status as Integer Dim file_path as String Dim init_path as String Dim ucb as object Dim filterNames(3) as String filterNames(0) = "*.*" filterNames(1) = "*.png" filterNames(2) = "*.jpg" GlobalScope.BasicLibraries.LoadLibrary("Tools") file_dialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker") ucb = createUnoService("com.sun.star.ucb.SimpleFileAccess") AddFiltersToDialog(FilterNames(), file_dialog) 'Set your initial path here! init_path = ConvertToUrl("/usr") If ucb.Exists(init_path) Then file_dialog.SetDisplayDirectory(init_path) End If status = file_dialog.Execute() If status = 1 Then file_path = file_dialog.Files(0) open_file = file_path End If file_dialog.Dispose() End Function اختيار ملفات متعددة لنعدّل الماكرو السابق قليلًا بحيث يعيد قائمة أسماء الملفات (المسار الكامل) المُحدَّدة. الاختلاف الوحيد هو أن الدالة معرَّفة بوصفها متغيرًا Variant واستخدام خاصية نافذة الملف file_dialog.setMultiSelectionMode(True) والدالة file_dialog.getSelectedFiles(). توضّح الشيفرة التالية شيفرة ماكرو كاملة لاختيار ملفات متعددة والحصول على أسمائها: Sub pick_a_file() Dim fName() As Variant fName = open_file() for i = 0 to Ubound(fName) str1 = str1 & fName(i) & chr(10) next MsgBox str1 End Sub Function open_file() as Variant Dim file_dialog as Object Dim status as Integer Dim init_path as String Dim ucb as object Dim filterNames(3) as String filterNames(0) = "*.*" filterNames(1) = "*.png" filterNames(2) = "*.jpg" GlobalScope.BasicLibraries.LoadLibrary("Tools") file_dialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker") ucb = createUnoService("com.sun.star.ucb.SimpleFileAccess") AddFiltersToDialog(FilterNames(), file_dialog) 'Set your initial path here! init_path = ConvertToUrl("/usr") file_dialog.setMultiSelectionMode(True) If ucb.Exists(init_path) Then file_dialog.SetDisplayDirectory(init_path) End If status = file_dialog.Execute() If status = 1 Then file_path = file_dialog.getSelectedFiles() open_file = file_path End If file_dialog.Dispose() End Function ترجمة -وبتصرُّف- للمقالات Using Form Controls in LibreOffice Macro و Use Open File Dialog using Macro in LibreOffice/OpenOffice و Insert and Read Text in TextField Control Using LibreOffice Basic Macro لصاحبها Arindam. اقرأ أيضًا كيفية تحرير البيانات في LibreOffice Calc كيفية التحكّم في طرق عرض جداول بيانات LibreOffice Calc تعرّف على معالج جداول البيانات LibreOffice Calc
-
سنوضّح من خلال هذا المقال كيفية معالجة تحديد خلية ومجموعة من الخلايا التي تشكل مجالًا باستخدام الماكرو Macro في ليبرأوفيس كالك LibreOffice Calc. هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبرأوفيس كالك، فهرس السلسلة: مدخل إلى كتابة ماكرو Macro في ليبرأوفيس كالك LibreOffice Calc معالجة محتويات خلايا ليبرأوفيس كالك باستخدام الماكرو معالجة مجال من الخلايا باستخدام الماكرو في ليبرأوفيس كالك. استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبرأوفيس التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبرأوفيس كالك أتمتة حفظ أوراق ليبرأوفيس كالك بتنسيق PDF باستعمال الماكرو معالجة خلايا محددة في كالك باستخدام الماكرو سنوضّح آلية التحديد في خلايا ليبرأوفيس كالك LibreOffice Calc باستخدام الماكرو Macro. الدالة getCurrentSelection() يجب أولًا الحصول على مصنف Workbook كالك مفتوح باستخدام عبارة ThisComponent وإسناد الكائن المُعاد إلى متغير. يمكنك معرفة التحديدات التي أجراها المستخدم في ورقة كالك باستخدام الدالة getCurrentSelection() الخاصة بواجهة Xcomponent، حيث توفّر هذه الدالة وصولًا لقراءة التحديد الحالي إلى وحدة التحكم، وتعيد التحديد الحالي من وحدة التحكم الحالية. Dim oDoc, oSel oDoc = ThisComponent oSel = oDoc.getCurrentSelection() إن لم يكن هناك تحديد، فستعيد الدالة getCurrentSelection() القيمة NULL. كما يمكنك استخدام الدالة IsNull لمعرفة إذا كان هناك شيء ما محدَّد أم لا. لا نستطيع معرفة التحديدات باستخدام oSel فقط، حيث يجب استخدام الدالة supportService الخاصة بواجهة XServiceInfo التي تختبر ما إذا كانت الخدمة المحددة مدعومة أي يمكن تنفيذها، بحيث تعيد القيمة TRUE إذا كانت مدعومة، وإلّا فإنها تعيد القيمة FALSE. توجد قائمة بالخدمات المتاحة التي يمكن اختبارها باستخدام هذه الدالة مثل الخدمات التالية: com.sun.star.sheet.SheetCell com.sun.star.sheet.SheetCellRange com.sun.star.sheet.SheetCellRanges ويمكنك العثور على قائمة كاملة بالخدمات من مرجع ليبرأوفيس com.sun.star.sheet. تحديد خلية واحدة استخدم خدمة com.sun.star.sheet.SheetCell للتحقق من تحديد خلية واحدة. كما يمكنك الحصول على قيمة تلك الخلية المحددة باستخدام الدالة getString() مع كائن التحديد. If oSel.supportsService("com.sun.star.sheet.SheetCell") Then MsgBox "One Cell selected and it contains: " & oSel.getString() End If تحديد مجال واحد استخدم الخدمة com.sun.star.sheet.SheetCellRange لتحديد مجال من الخلايا مثل C5:F7. If oSel.supportsService("com.sun.star.sheet.SheetCellrange") Then MsgBox "One Cell Range selected" End If تحديد مجالات متعددة استخدم خدمة com.sun.star.sheet.SheetCellRanges لتحديد مجالات متعددة من الخلايا. If oSel.supportsService("com.sun.star.sheet.SheetCellRanges") Then MsgBox "Multiple Cell Ranges selected. Total=" & oSel.getCount() End If تشغيل الماكرو أولًا، تحديد خلية واحد: الخرج: ثانيًا، تحديد مجال من الخلايا: الخرج: ثالثًا، تحديد مجالات متعددة من الخلايا: الخرج: شيفرة الماكرو الكاملة Sub Main Dim oDoc, oSel oDoc = ThisComponent oSel = oDoc.getCurrentSelection() If oSel.supportsService("com.sun.star.sheet.SheetCell") Then MsgBox "One Cell selected and it contains: " & oSel.getString() Else If oSel.supportsService("com.sun.star.sheet.SheetCellRange") Then MsgBox "One Cell Range selected" Else If oSel.supportsService("com.sun.star.sheet.SheetCellRanges") Then Msgbox "Multiple Cell Ranges selected. Total=" & oSel.getCount() Else Print "Somethine else is selected." End If End If End If End Sub معالجة مجال من الخلايا باستخدام الماكرو في ليبرأوفيس كالك نحتاج في العديد من مهام الأتمتة إلى الوصول إلى جدول البيانات باستخدام مجال Range من الخلايا لتقليل وقت المعالجة، حيث يمكن الوصول إلى كل خلية باستخدام طريقة "صف، عمود row, column" التي تُعَد طريقة مكلفة من حيث وقت المعالجة والتعقيد، وبالتالي يُفضَّل استخدام المجال على معالجة الخلية المفردة. سنتحدث فيما يلي عن كيفية معالجة "مجال Range" في تطبيق جداول البيانات ليبرأوفيس كالك من خلال الكتابة ضمن مجالات جداول البيانات. تحديد المجال يُحدَّد المجال باستخدام "عنوان خلية البداية: عنوان خلية النهاية startcelladdress: stopcelladdress"، حيث تُحدَّد الأعمدة في كالك باستخدام الأحرف مثل "A" و "B" و "C"، وتُحدَّد الصفوف باستخدام أرقام تبدأ من الرقم 1، وبالتالي يشير المجال "A1: D5" إلى جميع الخلايا التي تبدأ من الخلية (1,1) إلى الخلية (4,5) كما يلي: مجال بسيط إنشاء الماكرو أنشئ ماكرو جديدًا في ليبرأوفيس كالك، ثم أضف دالة مثل rang_processing_demo() التي تشير إلى جدول بيانات قبل أن نبدأ في معالجة المجال. Sub range_processing_demo dim my_doc as object Dim my_sheets as object Dim my_range as object my_doc = ThisComponent my_sheets = my_doc.Sheets End Sub سنبدأ بتعبئة خلية واحدة باستخدام مجال، ثم ننتقل إلى معالجة مجال أكثر تعقيدًا. ضبط خلية واحدة باستخدام مجال يمكن ضبط المجالات باستخدام الدالة setDataArray(array)، فوسيط هذه الدالة هو مصفوفة ثنائية الأبعاد لها حجم المجال نفسه. إذا اخترت المجال "A1" الذي لا يمثل سوى خلية واحدة، فيجب أن يكون للمصفوفة المقابلة قيمة واحدة فقط، وبالتالي يجب تحديد مصفوفة تحتوي على عنصر واحد فقط وضبط قيمتها كما يلي: Dim my_data(0,0) my_data(0,0) = "Apple" حدّد بعد ذلك مجالًا من خلية واحدة مثل "A1"، وضع المصفوفة المحدَّدة ضمن الدالة setDataArray(). my_range = ThisComponent.Sheets(0).getCellRangebyName("A1") my_range.setDataArray(my_data) إذا شغّلت الشيفرة السابقة، فستكون النتيجة كما يلي: تعبئة خلية واحدة باستخدام مجال ضبط صف من الخلايا باستخدام مجال نريد تعبئة صف الخلايا من A3 إلى C3 باستخدام مجال، لذلك نحتاج إلى تحديد مصفوفة أبعادها (0,2)، حيث يمثل الرقم 0 عدد الصفوف ويمثل الرقم 2 عدد الأعمدة. لاحظ أن الأعمدة تبدأ من 0، وبالتالي نريد تعبئة 3 أعمدة من 0 إلى 2. ' Set a row of cells using range ReDim my_data(0,2) my_data(0,0) = "Apple" my_data(0,1) = "1000" my_data(0,2) = "Red" my_range = ThisComponent.Sheets(0).getCellRangebyName("A3:C3") my_range.setDataArray(my_data) وتكون نتيجة الشيفرة السابقة كما يلي: تعبئة الصفوف باستخدام مجال ضبط أعمدة من الخلايا باستخدام مجال نريد تعبئة عمود واحد بعدة صفوف من خلال تحديد مصفوفة أبعادها (2,0) وكتابة الشيفرة التالية: ' Set a column of cells using range ReDim my_data(2,0) my_data(0,0) = "Apple" my_data(1,0) = "1000" my_data(2,0) = "Red" my_range = ThisComponent.Sheets(0).getCellRangebyName("C1:C3") my_range.setDataArray(my_data) وتكون النتيجة كما يلي: تعبئة الأعمدة باستخدام مجال ضبط صف وعمود من الخلايا بالحجم نفسه باستخدام مجال نريد تعبئة مجالات الصفوف والأعمدة باستخدام الحجم نفسه، لذلك لنحدّد مصفوفة أبعادها (2,2) كما يلي: ' Set row and column of same size using range ReDim my_data(2,2) my_data(0,0) = "Apple" my_data(0,1) = "1000" my_data(0,2) = "Red" my_data(1,0) = "Apple-1" my_data(1,1) = "1000-1" my_data(1,2) = "Red-1" my_data(2,0) = "Apple-2" my_data(2,1) = "1000-2" my_data(2,2) = "Red-2" my_range = ThisComponent.Sheets(0).getCellRangebyName("B2:D4") my_range.setDataArray(my_data) ويكون الخرج كما يلي: تعبئة الصفوف والأعمدة من الحجم نفسه باستخدام مجال ضبط صف وعمود من الخلايا ذات أبعاد مختلفة باستخدام مجال نريد تعبئة مجال بأبعاد مختلفة من خلال تحديد مصفوفة ذات أبعاد مختلفة كما يلي: ' Set row and column of different size using range ReDim my_data(3,1) my_data(0,0) = "Apple" my_data(0,1) = "1000" my_data(1,0) = "Apple-1" my_data(1,1) = "1000-1" my_data(2,0) = "Apple-2" my_data(2,1) = "1000-2" my_data(3,0) = "Apple-3" my_data(3,1) = "1000-3" my_range = ThisComponent.Sheets(0).getCellRangebyName("B2:C5") my_range.setDataArray(my_data) ويكون الخرج كما يلي: تعبئة الصفوف والأعمدة ذات القيم المختلفة باستخدام مجال حدّد حجم المصفوفة الخاص بك باستخدام (row, col) واستخدم الدالة setDataArray() لتعبئة المجال باستخدام الماكرو. الحصول على عنوان الخلية والمجال المحدد باستخدام الماكرو سنوضّح كيفية الحصول على العنوان الذي يمكن قراءته الخاص بالخلايا والمجالات المحدَّدة باستخدام الماكرو. التحديدات يمكن تحديد خلية واحدة أو خلايا متعددة -أي مجالات- في كالك. عرّف بعض المتغيرات للاحتفاظ بنسخ من الخلية الفعّالة activeCell والتحويل Conversion كما يلي: Dim oActiveCell Dim oConv استخدم الدالة getCurrentSelection للحصول على التحديد الحالي من وحدة التحكم. oActiveCell = ThisComponent.getCurrentSelection() يمكنك الحصول على عنوان الخلية المحدَّدة والمجال المحدَّد من خلال استخدام خدمتين مختلفتين هما: com.sun.star.table.CellRangeAddressConversion com.sun.star.table.CellAddressConversion أنشئ نسخًا من هذه الخدمات باستخدام الدالة createInstance كما يلي: oConv = ThisComponent.createInstance("com.sun.star.table.CellRangeAddressConversion") oConv = ThisComponent.createInstance("com.sun.star.table.CellAddressConversion") يمكنك بعد ذلك تعبئة خاصية العنوان Address من عنوان الخلية أو المجال المحدَّد باستخدام الشيفرة التالية: oConv.Address = oActiveCell.getRangeAddress oConv.Address = oActiveCell.getCellAddress ستعيد دالتان مهمتان خاصتان بكائن التحويل عنوان الخلية أو المجال الذي يمكن قراءته هما: UserInterfaceRepresentation: تعيد عمود وصف الخلية، مثل A1 و B3 عند تحديد خلية واحدة، وتعيد مجالًا مثل A1: C3 و B1: E4 عند تحديد مجال PersistentRepresentation: تعيد الشيء نفسه مع اسم ورقة العمل الحالية مثل Sheet1.A1 و Sheet1.B3 و Sheet1.A1:Sheet1.C3 و Sheet1.B1:Sheet1.E4، حيث تكون جميع القيم المُعادة سلسلة نصية String ويمكن معالجتها وفقًا لذلك. msgbox oConv.UserInterfaceRepresentation & _ " " & oConv.PersistentRepresentation تشغيل الماكرو خرج تحديد خلية واحدة: getCellAddress Demo خرج تحديد مجال من الخلايا: getRangeAddress Demo شيفرة الماكرو الكاملة الشيفرة الخاصة بالخلايا: Sub get_cell_address oActiveCell = ThisComponent.getCurrentSelection() oConv = ThisComponent.createInstance("com.sun.star.table.CellAddressConversion") oConv.Address = oActiveCell.getCellAddress msgbox oConv.UserInterfaceRepresentation & _ " " & oConv.PersistentRepresentation End Sub الشيفرة الخاصة بالمجالات: Sub get_range_address oActiveCell = ThisComponent.getCurrentSelection() oConv = ThisComponent.createInstance("com.sun.star.table.CellRangeAddressConversion") oConv.Address = oActiveCell.getRangeAddress msgbox oConv.UserInterfaceRepresentation & _ " " & oConv.PersistentRepresentation End Sub ترجمة -وبتصرُّف- للمقالات Calc Cell Selection Processing Using Macro و Range Processing using Macro in LibreOffice Calc – Part 1 و Get the Selection Cell and Range Address using Macro in LibreOffice لصاحبها Arindam. اقرأ أيضًا كيفية إدخال البيانات في LibreOffice Calc كيفية تنسيق البيانات في LibreOffice Calc كيفية التحكّم في طرق عرض جداول بيانات LibreOffice Calc كيفية تحرير البيانات في LibreOffice Calc
-
سنتعلّم من خلال هذا المقال كيفية إنشاء تلفاز قديم باستخدام بعض التقنيات الأساسية في برنامج الإليستريتور Adobe Illustrator، كما سنتعرّف على حيل متعددة مفيدة لتسريع عملية الرسم. إنشاء مستند جديد شغّل برنامج الإليستريتور Illustrator ثم اضغط على الاختصار Ctrl + N لإنشاء مستند جديد. حدّد خيار البكسلات Pixels من قائمة الوحدات Units، وأدخِل القيمة 1000 في خانة العرض width والقيمة 992 في خانة الارتفاع height، ثم انقر على خيارات متقدمة Advanced. حدّد نمط الألوان RGB والخيار Screen (72ppi)، وتأكّد من إلغاء تحديد مربع اختيار محاذاة الكائنات الجديدة إلى شبكة البكسلات Align New Objects to Pixel Grid قبل النقر على موافق OK. إنشاء الإطار الأساسي استخدم أداة المستطيل Rectangle Tool (باستخدام الاختصار M) لإنشاء مستطيل أصفر مائل إلى اللون الرمادي (# 4c4c43) أبعاده 549×354 بكسل. حدّد هذا المستطيل وانتقل إلى قائمة تأثير Effect ثم Stylize ثم زوايا مستديرة Round Corners، وأدخِل نصف قطر Radius مقداره 30 بكسلًا وانقر على موافق. حدّد المستطيل الناتج وانتقل إلى قائمة كائن Object ثم مسار Path ثم إزاحة المسار Offset Path، وأدخِل إزاحة بمقدار -8 بكسل وانقر على موافق، ثم استبدل لون تعبئة هذا المستطيل الحالي باللون الأخضر الداكن (# 20231c). حدّد المستطيل الأكبر الذي أنشأناه في الخطوة رقم 2، وأنشئ نسخةً منه (بالضغط على الاختصار Ctrl + C ثم Ctrl + F). ابقِ هذه النسخة محدَّدةً ثم بدّل بين لوني التعبئة والحدّ، عن طريق النقر على السهم المنحني ذي الرأسين بجوار حاملَي ألوان التعبئة والحدّ في لوحة الأدوات Toolbox. غيّر ثُخن حدّ الكائن الناتج إلى 2 بكسل وبدّل لون الحد الحالي باللون البرتقالي الفاتح (# ffd888)، ثم طبّق الخيار Width Profile 1 على هذا الكائن. حدّد نقطتي الارتكاز الملوّنتين باللون الأخضر، وانقر على أيقونة "قص المسار عند نقاط الارتكاز المُحدَّدة Cut path at selected anchor points" من شريط خصائص Properties، مما يجعل الكائن البرتقالي الفاتح مؤلفًا من مسارين، ثم حدّد وأزِل المسار العلوي. حدّد المستطيل الأصغر الذي أنشأناه في الخطوة رقم 2 وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F). حرّك هذه النسخة بمقدار 16 بكسلًا للأسفل ثم أرسلها للخلف (باستخدام الاختصار Ctrl + Shift + Left Square Bracket). حدّد المستطيل الأصغر الذي أنشأناه في الخطوة رقم 2 مرةً أخرى وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، وأدخِل إزاحة بمقدار -7 بكسل، ثم انقر على موافق، واستبدل لون تعبئة المستطيل الناتج الحالي باللون الأخضر المائل إلى اللون الرمادي الداكن (# 353e31). حدّد المستطيل الأخير الذي أنشأناه في الخطوة رقم 3، وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، وأدخِل إزاحةً بمقدار 3 بكسلات وانقر على موافق، ثم استبدل لون تعبئة المستطيل الحالي باللون الأصفر الفاتح (# fae67a). أبقِ المستطيل الناتج محدَّدًا، وافتح نافذة إزاحة المسار Offset Path مرةً أخرى، ثم أدخِل إزاحة بمقدار 3 بكسلات وانقر على موافق. أعِد تحديد المستطيلين الملوَّنين باللون الأصفر الفاتح، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر Minus Front، ثم طبّق تأثير Feather بمقدار 2 بكسل على المسار المركّب الناتج. إنشاء الشاشة استخدم أداة المستطيل (M) لإنشاء مستطيل أبعاده 408×293 بكسل باللون الأخضر المائل إلى الرمادي الداكن (# 475343)، ثم ضعه في الموضع الموضَّح في الشكل الأول الآتي. حدّد هذا المستطيل وانتقل إلى قائمة تأثير Effect ثم Stylize ثم زوايا مستديرة Round Corners، وأدخِل نصف قطر مقداره 17 بكسلًا وانقر على موافق. أبقِ المستطيل الناتج محدَّدًا وانتقل إلى قائمة كائن Object، ثم Path، ثم Offset Path، ثم أدخِل إزاحة بمقدار -2 بكسل وانقر على موافق، ثم استبدل لون تعبئة المستطيل الحالي باللون الأخضر الليموني المائل إلى الرمادي الداكن (# 869682). تأكّد من أن المستطيل الناتج لا يزال محدَّدًا وافتح نافذة Offset Path، ثم أدخِل إزاحة بمقدار -4 بكسل وانقر على موافق، ثم استبدل لون تعبئة المستطيل الحالي بالتدرج اللوني الخطي linear gradient الموضّح أدناه. أبقِ المستطيل الناتج محدّدًا، وافتح لوحة Appearance (من قائمة Window ثم Appearance) وانقر على خيار زوايا مستديرة Round Corners، ثم أدخِل نصف قطر بمقدار 15 بكسلًا وانقر على موافق. حدّد المستطيل الأخير الذي أنشأناه في الخطوة رقم 5 وانتقل إلى قائمة كائن Object ثم تحويل Transform ثم Scale، ثم حدّد الخيار غير موحّد Non-Uniform، وأدخِل القيمة 89% في خانة أفقي Horizontal والقيمة 85% في خانة رأسي Vertical، بعد ذلك انقر على نسخ Copy. استبدل لون تعبئة هذا المستطيل الحالي بتدرج لوني خطي جديد كما هو موضّح في الشكل الأول الآتي، واستخدم أداة إضافة نقاط ارتكاز Add Anchor Point (+) لإضافة أربع نقاط ارتكاز جديدة عند النقاط المميزة باللون الأصفر. استخدم أداة التحديد المباشر Direct Selection Tool (باستخدام الاختصار A) لتحديد نقطة الارتكاز العلوية الوسطى التي أضفتها للتو وحرّكها بمقدار 8 بكسلات للأعلى، ثم حدّد نقطة الارتكاز السفلية الوسطى وحرّكها بمقدار 8 بكسلات للأسفل، ثم حدّد نقطة الارتكاز اليسرى الوسطى وحرّكها بمقدار 6 بكسلات إلى اليسار. أخيرًا، حدّد نقطة الارتكاز اليمنى الوسطى ثم حرّكها بمقدار 6 بكسلات إلى اليمين. استخدم أداة المستطيل (M) لإنشاء مستطيل أسود أبعاده 200×670 بكسل، واختر أداة تحويل نقطة الارتكاز Convert Anchor Point Tool (بالضغط على الاختصار Shift + C)، وانقر على نقطة الارتكاز العلوية الوسطى التي حرّكتها في الخطوة رقم 6، ثم اضغط على الفأرة واسحبها إلى اليمين أثناء الضغط على مفتاح Shift. انقر بعد ذلك على نقطة الارتكاز السفلية الوسطى، واضغط على الفأرة واسحبها إلى اليسار، ثم انقر على نقطة الارتكاز اليسرى الوسطى، واضغط على الفأرة واسحبها للأعلى، ولا تنسَ الاستمرار في الضغط على مفتاح Shift من لوحة المفاتيح للسحب السويّ. أخيرًا، انقر على نقطة الارتكاز اليمنى الوسطى، ثم اضغط على الفأرة واسحبها للأسفل. حدّد الشكل الذي أنشأناه في الخطوة رقم 7 وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، وأدخِل إزاحةً بمقدار -7 بكسل وانقر على موافق، ثم استبدل لون تعبئة هذا الشكل الحالي باللون السماوي الداكن (# 1c4b46). حدّد الشكل الناتج وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار موحّد Uniform، ثم أدخِل القيمة 90% في نافذة Scale وانقر على نسخ Copy، بعد ذلك استبدل لون تعبئة الشكل الحالي باللون السماوي الفاتح (# 81afbb). أبقِ الشكل الناتج محدَّدًا، ثم طبّق تأثير Gaussian Blur بمقدار 15 بكسلًا عليه. حدّد الشكل الأول الذي أنشأناه في الخطوة رقم 8 وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). استخدم أداة الدائرة Ellipse Tool (باستخدام الاختصار L) لإنشاء دائرة حمراء أبعادها 760×109 بكسل، ثم ضعها في الموضع الموضّح في الشكل الثاني أدناه. أبقِ هذه الدائرة محدَّدةً واستمر في الضغط على مفتاح Shift، وانقر على الشكل الأول الذي أنشأناه في الخطوة الحالية، ثم افتح لوحة مستكشف المسار Pathfinder (من قائمة Window ثم Pathfinder) وانقر على زر التقاطع Intersect. أزِل حدّ هذا الكائن ثم أملأه باللون السماوي الداكن (# 67969f)، ثم غيّر نمط مزج Blending Mode الشكل الناتج إلى النمط Multiply وقلّل التعتيم Opacity إلى 10%. استخدم أداة القلم Pen Tool (باستخدام الاختصار P) لإنشاء شكل باللون السماوي المائل إلى الرمادي (# 9cbac0) كما هو موضَّح في الشكل الأول أدناه. أعِد تحديد هذا الشكل بعد رسمه، ثم طبّق تأثير Gaussian Blur بمقدار 7 بكسلات عليه. استخدم أداة الدائرة (L) لإنشاء دائرة باللون السماوي المائل إلى الرمادي الفاتح (# d4e1e2) كما هو موضّح أدناه، ثم طبّق عليها تأثير Gaussian Blur بمقدار 3 بكسلات. حدّد الآن الشكلين اللذين أنشأناهما في الخطوة الحالية، وانتقل إلى قائمة كائن Object ثم تحويل Transform ثم انعكاس Reflect، وحدّد الخيار رأسي Vertical وانقر على نسخ Copy. اسحب هذه النُسخ إلى اليمين، ولا تنسَ الاستمرار في الضغط على مفتاح Shift من لوحة المفاتيح للسحب السويّ. استخدم أداة الدائرة (L) لإنشاء دائرة باللون السماوي المائل إلى الرمادي (# 9cbac0)، وضعه في الموضع الموضّح في الشكل الأول الآتي. طبّق تأثير Gaussian Blur بمقدار 7 بكسلات على هذه الدائرة، ثم اضبط نمط المزج على الخيار Lighten وقلّل التعتيم Opacity إلى 50%. أنشئ دائرةً أخرى باللون السماوي المائل إلى الرمادي الفاتح (# d4e1e2)، وضعه في الموضع الموضّح أدناه، ثم طبّق عليها تأثير Gaussian Blur بمقدار 5 بكسلات. أخيرًا، حدّد وجمّع (باستخدام الاختصار Ctrl + G) جميع الكائنات التي أنشأناها من بداية الخطوة رقم 10 إلى الخطوة الحالية. حدّد الشكل الذي طبّقنا عليه تأثير الضبابية blur في الخطوة رقم 8 وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محدَّدةً وافتح لوحة Appearance (من قائمة Window ثم Appearance)، وأزِل تأثير Gaussian Blur. حدّد نقاط الارتكاز الأربع المميزة باللون الأسود وانقر على أيقونة "تحويل نقاط الارتكاز المحدَّدة إلى سلِسة Convert selected anchor point to smooth" من شريط خصائص Properties. أعِد تحديد الشكل الناتج وانتقل إلى قائمة كائن Object ثم توسيع المظهر Expand Appearance، حيث يجب أن يبدو الشكل الناتج كما في الشكل الثالث أدناه. أبقِ هذا الشكل محدَّدًا، واستمر في الضغط على مفتاح Shift ثم انقر على المجموعة التي أنشأناها في الخطوة رقم 11. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة. إنشاء زر محدد القنوات التلفزيونية استخدم أداة الدائرة (L) لإنشاء دائرة أبعادها 85×85 بكسل باللون الأخضر الداكن (# 060a08). حدّد هذه الدائرة وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، ثم أدخِل إزاحة بمقدار -2 بكسل وانقر على موافق، ثم استبدل لون تعبئة الدائرة الناتجة الحالي بالتدرج اللوني الشعاعي radial gradient الموضّح في الشكل الثاني أدناه. استخدم أداة القلم (P) وأداة التدرّج Gradient Tool (باستخدام الاختصار G) لإنشاء الشكل الموضّح أدناه، ثم ارسم مسارًا منحنيًا باستخدام أداة القلم (P) وامنحه حدًا باللون الأزرق الداكن (# 20282f) بمقدار 3 بكسلات. حدّد هذا المسار، ثم افتح لوحة Stroke (من قائمة Window ثم Stroke) وانقر على أيقونة زوايا مستديرة Round Cap. حدّد الدائرة كما هو موضّح في الشكل الأول الآتي وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، وأدخِل إزاحةً بمقدار -8 بكسل وانقر على موافق. أبقِ هذه الدائرة محدَّدةً ثم بدّل بين لوني التعبئة والحدّ عن طريق النقر على السهم المنحني ذي الرأسين بجوار حاملَي ألوان التعبئة، والحدّ في لوحة الأدوات. استبدل لون حدّ الدائرة الناتجة الحالي باللون الأزرق المائل إلى الرمادي الفاتح (# dae0e3)، وغيّر ثُخن الحدّ إلى 2 بكسل. أبقِ الدائرة الناتجة محدَّدة، ثم افتح لوحة Stroke (من قائمة Window ثم Stroke) وانقر على أيقونة Round Cap، ثم حدّد خيار الخط المتقطع Dashed Line، وأدخِل القيمة 8 بكسلات في خانة dash والقيمة 9 بكسلات في خانة الفجوة gap. حدّد الدائرة الناتجة وانتقل إلى قائمة كائن Object ثم تحويل Transform ثم تدوير Rotate، وأدخِل زاويةً مقدارها -8 درجة وانقر على موافق. استخدم أداة الدائرة (L) لإنشاء دائرة أبعادها 3×3 بكسل باللون الأصفر الفاتح (# fffff7)، ثم ضعها في الموضع الموضّح أدناه. أعِد تحديد هذه الدائرة واختر أداة التدوير Rotate Tool (باستخدام الاختصار R)، ثم استمر في الضغط على مفتاح Alt، وانقر في مركز أول دائرة أنشأناها في الخطوة الحالية. بعد ذلك أدخِل زاويةً مقدارها 30 درجة وانقر على نسخ Copy. كرّر ذلك بالضغط على الاختصار Ctrl + D إلى أن تحصل على النتائج الموضّحة أدناه. افتح لوحة Character (من قائمة Window ثم Type ثم Character)، وحدّد الخط Myriad Pro مع جعله متوسط الثخانة Semibold، ثم اضبط حجم الخط على 6 بكسلات. اختر أداة الكتابة Type Tool (باستخدام الاختصار T)، ثم انقر على لوحة الرسم واكتب النص "1" واضبط لونه على اللون الأبيض (# ffffff). أبقِ هذا الرقم محدّدًا، وافتح لوحة فقرة Paragraph (من قائمة Window ثم Type ثم Paragraph) وانقر على أيقونة محاذاة مركزية Align Center. أبقِ الرقم "1" محدَّدًا، ثم اختر أداة التدوير (R)، واستمر في الضغط على مفتاح Alt ثم انقر في مركز أول دائرة أنشأناها في الخطوة رقم 14، ثم أدخِل زاوية مقدارها 30 درجة وانقر على نسخ Copy. كرّر ذلك بالضغط على الاختصار Ctrl + D إلى أن تحصل على النتائج الموضّحة أدناه، ثم استخدم أداة الكتابة (T) لتغيير الواحدات التي عددها 11 واحدًا إلى الأرقام الصحيحة الموضّحة أدناه. حدّد الدائرة الموضَّحة في الشكل الأول أدناه وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، وأدخِل إزاحةً قدرها -15 بكسل مع النقر على موافق، ثم استبدل لون تعبئة هذه الدائرة الحالي بلون سماوي داكن (# 151b1b). أبقِ الدائرة الناتجة محدَّدًا، وانتقل إلى قائمة كائن Object ثم Path ثم Offset Path، وأدخِل إزاحةً قدرها -1 بكسل مع النقر على موافق، ثم استبدل لون تعبئة هذه الدائرة الحالي بالتدرج اللوني الخطي الموضّح أدناه. حدّد الدائرة الناتجة وافتح نافذة Offset Path، ثم أدخِل إزاحةً قدرها -1 بكسل وانقر على موافق، ثم استبدل لون تعبئة الدائرة الحالي باللون البرتقالي المائل إلى الرمادي (# c4bfba). تأكّد من أن الدائرة الناتجة لا تزال محددة، وافتح نافذة Offset Path مرةً أخرى، ثم أدخِل إزاحةً قدرها -8 بكسل وانقر على موافق. استبدل لون تعبئة هذه الدائرة الحالي باللون البرتقالي الداكن (# 1d1b19)، ثم أضف لها حدًا قدره 1 بكسل بلون برتقالي داكن (# 050402). ارسم مسارًا منحنيًا باستخدام أداة القلم (P)، وامنحه حدًا بمقدار 1 بكسل باللون البرتقالي المائل إلى الرمادي الداكن (# 94918f)، ثم طبّق الخيار Width Profile 1 على المسار الناتج. استخدم أداة المستطيل (M) وأداة التدرج (G) لإنشاء مستطيل أبعاده 53×7 بكسل كما هو موضّح في الشكل الأول أدناه. أبقِ هذا المستطيل محدَّدًا، وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F). حدّد هذه النسخة وافتح لوحة تحويل Transform (من نافذة Window ثم Transform)، واضبط الخيار H على 5 بكسلات، ثم استبدل لون تعبئة المستطيل الناتج الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. استخدم أداة الدائرة (L) لإنشاء دائرة أبعادها 4×4 بكسل باللون الأبيض (# fffff7)، وضعها في الموضع الموضّح أدناه. حدّد وجمّع (Ctrl + G) جميع الكائنات الثلاثة التي أنشأناها في الخطوة الحالية، ثم حدّد هذه المجموعة، وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه وانقر على موافق. حدّد المجموعة الناتجة وانتقل إلى قائمة كائن Object ثم تحويل Transform ثم تدوير Rotate، وأدخِل زاويةً مقدارها -30 درجة وانقر على موافق. حدّد وجمّع عن طريق Ctrl + G، جميع الكائنات التي أنشأناها من بداية الخطوة رقم 13 حتى الآن، ثم ضع هذه المجموعة في الموضع الموضّح في الشكل الأول أدناه. استخدم أداة المستطيل ذي الزوايا المستديرة Rounded Rectangle Tool لإنشاء مستطيل أحمر اللون وضَعه في الموضع الموضّح في الشكل الثاني أدناه، ثم أزِل حدّ هذا المستطيل واملأه باللون الأخضر الليموني الداكن (# 252d24). حدّد المستطيل الناتج وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم أزِل لون تعبئة هذه النسخة وأضف لها حدًا مقداره 2 بكسل باللون البرتقالي المائل إلى الرمادي الداكن (# 504f4d)، بعد ذلك طبّق الخيار Width Profile 1 على المستطيل الناتج. حدّد نقاط الارتكاز الأربعة الملوّنة باللون الأخضر، وانقر على أيقونة "قص المسار عند نقاط الارتكاز المحدّدة Cut path at selected anchor points" من شريط خصائص Properties، مما يجعل المستطيل البرتقالي المائل إلى الرمادي الداكن مؤلفًا من أربعة مسارات، ثم حدّد وأزِل المسارين الرأسيين. إنشاء مكبر الصوت استخدم أداة المستطيل ذي الزوايا المستديرة Rounded Rectangle Tool لإنشاء مستطيل أسود كما هو موضّح في الشكل الأول أدناه، ثم أنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم استبدل لون حدّ هذه النسخة باللون الأحمر. حدّد نقطة الارتكاز اليمنى المميزة باللون الأسود، وحرّكها بمقدار 2 بكسل إلى اليسار و7 بكسلات للأسفل، ثم حدّد نقطة الارتكاز اليسرى المميزة باللون الأسود، وحرّكها بمقدار 2 بكسل إلى اليمين و7 بكسلات للأسفل. اختر أداة تحويل نقطة الارتكاز Convert Anchor Point Tool (بالضغط على الاختصار Shift + C)، وانقر على المقبض العلوي لنقطة الارتكاز اليسرى المميزة باللون الأزرق، ثم استمر في الضغط على الفأرة واسحب المقبض إلى الجهة اليمنى السفلية، ثم انقر على المقبض العلوي لنقطة الارتكاز اليمنى المميزة باللون الأزرق، واستمر في الضغط على الفأرة واسحب المقبض إلى الجهة اليسرى السفلية. حدّد المستطيل الأسود ذو الزوايا المستديرة الذي أنشأناه في الخطوة رقم 19، وأزِل حدّه واملأه باللون الأخضر الداكن (# 060907)، ثم حدّد الكائن الأحمر وأزِل حدّه واملأه باللون الأزرق الداكن (# 252729). حدّد المستطيل الذي ملأته للتو بلون أخضر داكن وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم أحضر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محدَّدةً وبدّل بين لوني التعبئة والحدّ عن طريق النقر على السهم المنحني ذي الرأسين بجوار حاملَي ألوان التعبئة والحدّ في لوحة الأدوات. استبدل لون حدّ الكائن الناتج الحالي باللون الأحمر المائل إلى الرمادي الداكن (# 7b7776)، ثم طبّق عليه الخيار Width Profile 1. حدّد نقطتي الارتكاز المميزتين باللون الأحمر، وانقر على أيقونة "قص المسار عند نقاط الارتكاز المحدَّدة Cut path at selected anchor points" من شريط خصائص Properties، مما يجعل هذا الكائن الأحمر المائل إلى الرمادي الداكن مؤلفًا من مسارين، ثم حدّد وأزِل المسار العلوي. في الأخير، حدّد وجمّع (Ctrl + G) جميع الكائنات الثلاثة التي أنشأناها من بداية الخطوة رقم 19 إلى الخطوة الحالية، ثم سمِّ هذه المجموعة بالاسم "Speaker" أي مكبر الصوت. ضع مجموعة "Speaker" التي أنشأناها في الخطوة رقم 20 في الموضع الموضح في الشكل الأول أدناه. حدّد هذه المجموعة وانتقل إلى قائمة كائن Object ثم Transform ثم Move، ثم أدخِل القيمة 47 بكسلًا في خانة أفقي Horizontal، ثم انقر على نسخ Copy. أعِد تحديد مجموعتي "Speaker" وافتح نافذة Move مرةً أخرى، ثم أدخِل القيمة 15 بكسلًا في خانة رأسي Vertical وانقر على نسخ Copy، ثم اضغط على الاختصار Ctrl + D ثلاث مرات للحصول على النتائج كما تراها في الشكل الثالث أدناه. حدّد جميع مجموعات "Speaker" وجمّعها (Ctrl + G)، ثم أنشئ نسخةً منها (بالضغط على Ctrl + C ثم Ctrl + F)، ثم اسحب هذه النسخة للأسفل وضعها في المكان الموضّح أدناه. يجب أن يبدو تلفازك الآن كما يلي: إنشاء هوائي التلفاز استخدم أداة المستطيل (M) لإنشاء مستطيل أسود أبعاده 12×57 بكسل، ثم استخدم أداة الدائرة (L) لإنشاء دائرة حمراء أبعادها 12×1 بكسل ثم ضعها في الموضع الموضّح في الشكل الأول أدناه. حدّد المستطيل الأسود الذي أنشأناه في الخطوة الحالية، وأزِل حدّه واملأه بالتدرج اللوني الخطي الموضح أدناه. حدّد الدائرة الحمراء، وأزِل حدّها ثم املأها بالتدرج اللوني الخطي كما هو موضح أدناه. أخيرًا، حدّد وجمّع (Ctrl + G) هذين الكائنين اللذين أنشأناهما في الخطوة الحالية. حدّد المجموعة التي أنشأناها في الخطوة رقم 23 وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Uniform، ثم أدخِل القيمة 77% في قسم Scale وانقر على نسخ Copy، ثم ضع هذه النسخة في الموضع الموضّح في الشكل الأول أدناه. اختر أداة التحديد المباشر (A)، واسحب الفأرة باتجاه السهم الأزرق الموضّح أدناه، مما يسمح لك بتحديد جميع النقاط في تلك المنطقة، ثم حرّك جميع نقاط الارتكاز المحدّدة بمقدار 24 بكسلًا للأعلى. حدّد المجموعة التي أنشأناها في الخطوة رقم 24 وانتقل إلى قائمة كائن Object ثم Transform ثم Scale، وحدّد الخيار Uniform، وأدخِل القيمة 52% في قسم Scale وانقر على نسخ Copy، ثم ضع هذه النسخة في الموضع االموضّح في الشكل الأول أدناه. اختر أداة التحديد المباشر (A)، واسحب الفأرة باتجاه السهم الأزرق كما هو موضّح في الشكل الثاني أدناه، مما يسمح لك بتحديد جميع النقاط في تلك المنطقة، ثم حرّك جميع نقاط الارتكاز المحدَّدة بمقدار 26 بكسلًا للأسفل. أعِد تحديد المجموعة التي أنشأناها حديثًا وافتح نافذة Scale مرةً أخرى، ثم حدّد خيار Uniform، وأدخِل القيمة 310% في قسم Scale وانقر على نسخ Copy، ثم ضع هذه النسخة في الموضع الموضّح أدناه. اختر أداة التحديد المباشر (A)، ثم اسحب الفأرة باتجاه السهم الأزرق الموضّح أدناه، ثم حرّك جميع نقاط الارتكاز المحدَّدة بمقدار 49 بكسلًا للأسفل. أخيرًا، حدّد وجمّع (Ctrl + G) جميع المجموعات التي أنشأناها من بداية الخطوة رقم 23 إلى الخطوة الحالية، وبذلك أصبح أول هوائي جاهزًا. حدّد الهوائي الأول وأنشئ نسخة منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم ضع هذه النسخة في موضع جديد. اختر أداة التحديد المباشر (A)، واسحب الفأرة باتجاه السهم الأزرق الموضّح أدناه، مما يسمح لك بتحديد جميع نقاط الارتكاز في تلك المنطقة، ثم حرّك جميع هذه النقاط المحددة بمقدار 32 بكسلًا للأعلى. كرّر العملية نفسها على قسم آخر كما هو موضّح أدناه، ثم حرّك جميع نقاط الارتكاز المحدَّدة بمقدار 24 بكسلًا للأعلى، ثم كرّر العملية نفسها وحرّك جميع نقاط الارتكاز المحدّدة بمقدار 16 بكسلًا للأعلى كما هو موضّح أدناه، وبذلك يكون الهوائي الثاني قد أصبح جاهزًا. يجب أن يبدو هوائيا تلفازك كما في الشكل الأول أدناه. حدّد الهوائي الأقصر، وانتقل إلى قائمة كائن Object ثم Transform ثم Rotate، وأدخِل زاويةً مقدارها 20 درجة وانقر على موافق، ثم ضع هذا الهوائي في الموضع الموضّح في الشكل الثاني أدناه. حدّد الهوائي الثاني ودوّره بزاوية مقدارها -30 درجة، ثم ضع هذا الهوائي في الموضع الموضح في الشكل الثالث أدناه. أخيرًا، حدّد الهوائيين ثم أرسلهما للخلف (Ctrl + Shift + Left Square Bracket). سننشئ الآن أرجل التلفاز. استخدم أداة المستطيل (M) لإنشاء مستطيل أبعاده 21×12 بكسل باللون الأصفر الداكن (# 201f1c)، ثم ضعه في الموضع الموضّح في الشكل الأول أدناه، ثم أنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، وضع هذه النسخة في الموضع الموضّح في الشكل الثاني أدناه. إنشاء طاولة التلفاز الخشبية استخدم أداة المستطيل (M) وأداة التدرّج (G) لإنشاء مستطيل أبعاده 583×19 بكسل باللون البرتقالي الداكن كما هو موضّح أدناه. أبقِ هذا المستطيل محدّدًا، وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F). حدّد هذه النسخة، ثم بدّل بين لوني التعبئة والحد عن طريق النقر على السهم المنحني ذي الرأسين بجوار حاملَي ألوان التعبئة والحدّ في لوحة الأدوات، ثم استبدل لون حدّ المستطيل الحالي باللون الأحمر الفاتح (# dfb2a9). حدّد نقطتي الارتكاز المميزتين باللون الأخضر وانقر على أيقونة "قص المسار عند نقاط الارتكاز المحدّدة Cut path at selected anchor points" من شريط خصائص Properties، مما يجعل هذا المستطيل الأحمر الفاتح مؤلفًا من مسارين، ثم حدّد وأزَل المسار السفلي. استخدم أداة المستطيل (M) وأداة التدرج (G) لإنشاء مستطيل أبعاده 539×31 بكسل باللون البرتقالي الداكن، ثم ضعه في الموضع الموضّح أدناه. استخدم أداة المستطيل (M) لإنشاء مستطيل أحمر أبعاده 57×13 بكسل، ثم ضعه في الموضع الموضّح أدناه، وأزِل حدّ هذا المستطيل ثم املأه بالتدرج اللوني الخطي الموضّح أدناه كما ترى في الصورة الثانية. استخدم أداة القلم (P) وأداة التدرج (G) لإنشاء شكل برتقالي داكن كما هو موضح أدناه، ثم حدّد هذا الشكل وانتقل إلى قائمة كائن Object ثم Transform ثم Move، وأدخِل القيمة 31 بكسلًا في خانة أفقي Horizontal والقيمة -37 بكسل في خانة رأسي Vertical، ثم انقر على نسخ Copy. أخيرًا، أرسِل الشكل الناتج للخلف (Ctrl + Shift + Left Square Bracket). حدّد الكائنات الثلاثة التي أنشأناها في الخطوة رقم 30، وانتقل إلى قائمة كائن Object ثم تحويل Transform ثم انعكاس Reflect، ثم حدّد الخيار رأسي Vertical وانقر على نسخ Copy، بعد ذلك اسحب هذه النسخ إلى اليمين، ولا تنسَ الاستمرار في الضغط على مفتاح Shift من لوحة المفاتيح للسحب السويّ. سنضيف بعض الظلال على بعض الأماكن الرئيسية لإعطاء مظهر أكثر واقعية. استخدم أداة القلم (P) لإنشاء شكل أحمر كما هو موضّح في الشكل الأول أدناه، ثم أزِل حدّه واملأه باللون الأصفر الداكن (# 201f1c). طبّق تأثير Gaussian Blur بمقدار 15 بكسلًا على الشكل الناتج، ثم اضبط نمط المزج Blending Mode على الخيار Multiply وقلّل التعتيم Opacity إلى 40%. أخيرًا، أرسِل الشكل الناتج للخلف (Ctrl + Shift + Left Square Bracket). استخدم أداة القلم (P) وأداة التدرج (G) لإنشاء الشكلين الموضّحين في الشكل الأول أدناه، ثم طبّق تأثير Gaussian Blur بمقدار 5 بكسلات على هذين الشكلين، واضبط نمط المزج على الخيار Multiply، ثم ضع الشكلين الناتجين خلف الطاولة. حدّد هذين الشكلين وانتقل إلى قائمة كائن Object ثم Transform ثم Reflect، ثم حدّد الخيار رأسي Vertical وانقر على نسخ Copy، اسحب هذه النُسخ إلى اليمين، ولا تنسَ الاستمرار في الضغط على مفتاح Shift من لوحة المفاتيح للسحب السويّ. حدّد وجمّع (Ctrl + G) جميع الكائنات التي أنشأناها من بداية الخطوة رقم 2 حتى الآن، حيث يجب أن يبدو تلفازك كما يلي: إنشاء الخلفية استخدم أداة المستطيل (M) وأداة التدرج (G) لإنشاء مستطيل أبعاده 1000×992 بكسل باللون البرتقالي المائل إلى الرمادي الفاتح، ثم ضع المجموعة التي أنشأناها في الخطوة رقم 34 في الخلفية. وبذلك يكون كل شيء قد أصبح جاهزًا. ترجمة -وبتصرّف- للمقال Create a Vintage Television لصاحبه Bao Nguyen. اقرأ أيضًا أدوات عديدة لانتقاء الألوان تفيدك في عملية التصميم دليلك لاختيار تركيبات الألوان عند تصميم مواقع للعملاء كيفية إنشاء مصباح كهربائي في برنامج إليستريتور كيفية إنشاء الدواليب الهوائية الملونة باستخدام الإليستريتور رسم مروحة ورقية قابلة للطي في إليستريتور
-
تتكون تطبيقات جداول البيانات مثل كالك Calc من مصنفات workbooks وأوراق عمل worksheets وخلايا Cells يجب معالجتها باستخدام ماكرو Macro لأتمتة المهام المختلفة. سنشرح فيما يلي المعالجة الأساسية لأوراق العمل والخلايا ومحتوياتها التي تُعَد أساسًا للعديد من الماكرو المعقّد. هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبرأوفيس كالك، فهرس السلسلة: مدخل إلى كتابة ماكرو Macro في ليبرأوفيس كالك LibreOffice Calc معالجة محتويات خلايا ليبرأوفيس كالك باستخدام الماكرو معالجة مجال من الخلايا باستخدام الماكرو في ليبرأوفيس كالك استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبرأوفيس التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبرأوفيس كالك أتمتة حفظ أوراق ليبرأوفيس كالك بتنسيق PDF باستعمال الماكرو أوراق عمل مصنفات ليبرأوفيس LibreOffice ومعالجة الخلايا باستخدام الماكرو سنقرأ جدول بيانات كالك مكوَّن من 3 أوراق وسنقرأ محتوياته، ثم سنعرض محتويات القراءة المنسَّقة في نافذة الرسالة. تحتوي الورقة 1 و الورقة 2 و الورقة 3 على البيانات التالية: تفاصيل الشيفرة سنصرّح أولًا عن 3 كائنات لتعريف مصنف كالك ومجموعة الأوراق والخلية. لمعرفة كيفية البدء بالعمل وكتابة شيفرات الماكرو منذ البداية راجع المقال السابق، المشار إليه ببداية المقال. dim my_doc as object Dim my_sheets as object Dim my_cell as object اضبط my_doc باستخدام ThisComponent الذي يشير إلى أن مصنف كالك الحالي مفتوح، ثم يمكنك إسناد مجموعة الأوراق إلى كائن my_sheets للوصول إلى جميع أوراق المصنف، وتُسنَد جميع الأوراق إلى كائن my_sheets بوصفها مصفوفة، حيث يمكن الوصول إليها من خلال استخدام الدليل السفلي subscript مثل Sheets(0) و Sheets(1) وما إلى ذلك (لاحظ أن الدليل السفلي subscript يبدأ من الصفر). my_doc = ThisComponent my_sheets = my_doc.Sheets sheet_count = my_sheets.Count يمكننا الوصول إلى كل خلية باستخدام التابع getCellByPosition بمجرد أن نحصل على مقبض إلى الورقة باستخدام Sheets(subscript). الطريقة النموذجية للوصول إلى خلية هي على النحو التالي: my_cell = ThisComponent.Sheets(i).getCellByPosition(col,row) لاحظ أن وسطاء التابع getCellByPosition هي عمود column ثم صف row. يجب الوصول إلى محتويات كائن الخلية my_cell بعد ضبطه، ولكن لدى ليبرأوفيس نظرة مختلفة إليها، حيث تُعرَّف كل خلية بنوع محتواها. إذا وضعت عددًا في خلية، فسيصبح نوع هذه الخلية عدديًا، وإذا وضعت محارفًا فيه، فسيصبح من النوع النصي. يوفّر ليبرأوفيس قائمة تعدادية enums لنوع الخلية Cell.Type كما يلي: com.sun.star.table.CellContentType.VALUE ' Used for cells containing numbers com.sun.star.table.CellContentType.TEXT ' Used for cells containing characters com.sun.star.table.CellContentType.EMPTY ' Used for empty cells com.sun.star.table.CellContentType.FORMULA ' Used for cells containing formula استخدم جزء الشيفرة التالي للوصول إلى قيم الخلية في مثالنا: Select Case my_cell.Type Case com.sun.star.table.CellContentType.VALUE cell_value = my_cell.Value Case com.sun.star.table.CellContentType.TEXT cell_value = my_cell.String End Select تشغيل الشيفرة سنربط قيم كل خلية بطريقة منسَّقة ونعرضها في مربع رسالة، ثم تظهر جميع قيم الخلايا من جميع الأوراق على النحو التالي بعد تشغيل الشيفرة (راجع فقرة "الشيفرة الكاملة" أدناه): الشيفرة الكاملة Sub processing_sheets_cells dim my_doc as object Dim my_sheets as object Dim my_cell as object Dim sheet_count, i, row, col, cell_value, str my_doc = ThisComponent my_sheets = my_doc.Sheets sheet_count = my_sheets.Count for i = 0 to sheet_count - 1 str = str & chr(13) & "--------" & chr(13) for row=1 to 4 for col=0 to 1 my_cell = ThisComponent.Sheets(i).getCellByPosition(col,row) Select Case my_cell.Type Case com.sun.star.table.CellContentType.VALUE cell_value = my_cell.Value Case com.sun.star.table.CellContentType.TEXT cell_value = my_cell.String End Select str = str & " " & cell_value next col str = str & Chr(13) next row next i msgbox str End Sub معالجة السلاسل النصية String في ماكرو ليبرأوفيس كالك مع أمثلة عنها سنوضّح كيفية معالجة سلسلة نصية مشتركة باستخدام الماكرو في ليبرأوفيس LibreOffice، حيث سنستخدم خلايا ليبرأوفيس كالك لاستخدام السلاسل النصية، فعمليات المعالجة هذه ضرورية لتطوير أيّ ماكرو. لنضع 3 سلاسل نصية في ورقة ليبرأوفيس كالك ونضمّها كما هو موضّح أدناه: ضم Joining السلاسل في كالك استخدم المعامل "&" لضم سلسلتين أو نصين، حيث سنستخدم هذا المعامل لضم ثلاثة أعمدة من السلاسل النصية ووضع النتائج في عمود آخر كما يلي: Sub String_join() part1 = ThisComponent.Sheets(0).getCellByPosition(0,1) part2 = ThisComponent.Sheets(0).getCellByPosition(1,1) part3 = ThisComponent.Sheets(0).getCellByPosition(2,1) result_cell = ThisComponent.Sheets(0).getCellByPosition(3,1) result_cell.String = part1.String & "." & part2.String & "." & part3.String End Sub ماكرو ليبرأوفيس كالك - الضم Join لنضع بعض السلاسل النصية في العمود A كما هو موضّح أدناه في ليبرأوفيس، حيث سنستخدم هذه السلاسل الثلاثة لعمليات المعالجة المتبقية في مثالنا. الدالة Left تعيد الدالة Left عدد المحارف من جانب السلسلة النصية الأيسر، حيث يمكن تحديد عدد المحارف في وسيط الدالة. ضع السلسلة "www.google.com" في الخلية A1 وشغّل الدالة على الخلية A1 على النحو التالي، حيث ستعيد هذه الدالة السلسلة الفرعية "www". Sub left_demo() part1 = ThisComponent.Sheets(0).getCellByPosition(0,0) result = ThisComponent.Sheets(0).getCellByPosition(2,0) result.String = left(part1.String,3) End Sub ماكرو ليبرأوفيس كالك - مثال Left الدالة Right تعيد الدالة Right عدد المحارف المُعطَى من الجانب الأيمن، حيث ستعيد هذه الدالة أدناه السلسلة النصية "com" مع المثال السابق نفسه. Sub right_demo() part1 = ThisComponent.Sheets(0).getCellByPosition(0,0) result = ThisComponent.Sheets(0).getCellByPosition(2,0) result.String = right(part1.String,3) End Sub ماكرو ليبرأوفيس كالك - مثال Right الدالة Mid تعيد الدالة Mid حجم سلسلة فرعية من سلسلة نصية معينة. وسطاء الدالة Mid هي (السلسلة النصية string، وموضع البداية start position، وطول السلسلة الفرعية length of the sub-string). ضع سلاسلًا نصية في عمود ضمن ليبرأوفيس كالك، ثم شغّل الدالة Mid، حيث تُحوَّل السلاسل من العمود A إلى سلسلة فرعية موجودة في العمود B في المثال أدناه، إذ تبدأ السلسلة الفرعية من المحرف رقم 4 من السلسلة ويبلغ الطول 6 محارف. Sub mid_demo() part1 = ThisComponent.Sheets(0).getCellByPosition(0,1) result = ThisComponent.Sheets(0).getCellByPosition(1,1) result.String = mid(part1.String,5,6) part2 = ThisComponent.Sheets(0).getCellByPosition(0,2) result = ThisComponent.Sheets(0).getCellByPosition(1,2) result.String= mid(part2.String,5,6) part3 = ThisComponent.Sheets(0).getCellByPosition(0,3) result = ThisComponent.Sheets(0).getCellByPosition(1,3) result.String = mid(part3.String,5,6) End Sub ماكرو ليبرأوفيس كالك - مثال Mid الدالة Trim تُستخدَم الدالة Trim لإزالة المسافات البادئة واللاحقة من سلسلة نصية، حيث يمكن استخدام هذه الدالة كما يلي: Trim(your_string_here). الدالة Len تعيد الدالة Len عدد محارف السلسلة، أي طول السلسلة، حيث تُستخدَم كما يلي: Len(string). الدالة Instr تُستخدَم الدالة Instr للبحث عن سلسلة ضمن سلسلة أخرى. إذا عُثِر على تطابق، فستعيد الدالة Instr رقم موضع بداية السلسلة التي يجري البحث عنها، وإن لم يُعثَر عليها، فستُعاد القيمة 0. Sub instr_demo() part1 = ThisComponent.Sheets(0).getCellByPosition(0,1) result = ThisComponent.Sheets(0).getCellByPosition(1,1) result.Value = instr(part1.String,"oogl") part2 = ThisComponent.Sheets(0).getCellByPosition(0,2) result = ThisComponent.Sheets(0).getCellByPosition(1,2) result.Value = instr(part2.String,"dd") part3 = ThisComponent.Sheets(0).getCellByPosition(0,3) result = ThisComponent.Sheets(0).getCellByPosition(1,3) result.Value = instr(part3.String,"untu") End Sub ماكرو ليبرأوفيس كالك - مثال Instr معالجة التاريخ والوقت في ليبرأوفيس كالك باستخدام الماكرو التاريخ هو نوع بيانات يُستخدم لتخزين قيم التاريخ والوقت، ويحتفظ بقيمة منتصف الليل من 1 يناير عام 0001 افتراضيًا، ولكن يمكن أن نختار أيّ تاريخ نريده ونعالجه بطرق مختلفة. إضافة أيام وشهور إلى تاريخ يمكن التصريح عن متغير التاريخ كما يلي: Dim my_date As Date سنستخدم بعد ذلك الدالة DateValue التي تساعد في تحويل التاريخ من تنسيق نص إلى تنسيق تاريخ، حيث سنضع هذا التاريخ في خلية ليبرأوفيس كالك. my_date = DateValue("Nov 20, 2014") my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,1) my_cell.String = my_date يمكن إضافة 3 أيام إلى التاريخ السابق باستخدم الدالة DateAdd(). يحدّد وسيط هذه الدالة الأول أيّ جزء من التاريخ يجب زيادته. إذا مرّرت الحرف "d"، فسيُزاد جزء اليوم من التاريخ، وإذا استخدمتَ الحرف "m"، فسيؤدي ذلك إلى زيادة جزء الأشهر في التاريخ. يمكن زيادة التاريخ بمقدار 3 أيام كما يلي: my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,3) my_cell.String = DateAdd("d", 3, my_date) يمكن زيادة التاريخ بمقدار 3 أشهر كما يلي: my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,5) my_cell.String = DateAdd("m", 3, my_date) تنسيق التاريخ يكون تنسيق التاريخ ضروريًا دائمًا لعمليات حسابية مختلفة ومعالجات ماكرو خاصة عندما تحتاج إلى استخراج اليوم والشهر والسنة ويوم الأسبوع وغير ذلك من أجزاء التاريخ. سنستخدم فيما يلي طرقًا مختلفة لتنسيق التاريخ، حيث يمكن استخدام كل من هذه الطرق مع تاريخ صالح بوصفه وسيطًا. الخرج: 20 – 11 – 14 my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,7) my_cell.String = Format(my_date, "d - m - yy") ' 20 - 11 - 14 الخرج: 20 Nov 2014 my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,9) my_cell.String = Format(my_date, "d MMM yyyy") '20 Nov 2014 الخرج: 20 November 2014 my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,11) my_cell.String = Format(my_date, "d MMMM yyyy") '20 November 2014 الخرج: Thursday, 20 Nov 2014 my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,13) my_cell.String = Format(my_date, "dddd, d MMM yyyy") 'Thursday, 20 Nov 2014 الخرج: Thursday, 20 November 2014 my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,15) my_cell.String = Format(my_date, "dddd, d MMMM yyyy") 'Thursday, 20 November 2014 معالجة الوقت يمكن استخراج وقت النظام باستخدام الماكرو، حيث سنعرض فيما يلي بعض دوال الوقت وخصائصها. Now: تعرض التاريخ الحالي ووقت النظام متضمنًا الساعات والدقائق والثواني. my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,17) my_cell.String = Now Hour: تعرض جزء الساعات. my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,19) my_cell.String = Hour(Now) Minute: تعرض جزء الدقائق. my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,21) my_cell.String = Minute(Now) Second: تعرض جزء الثواني. my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,23) my_cell.String = Second(Now) الخرج النهائي إذا وضعنا جميع شيفرات معالجة التاريخ والوقت السابقة في ماكرو، فسيكون الخرج كما يلي في كالك: خرج مثال معالجة الوقت والتاريخ حذف محتويات مجال من الخلايا في كالك باستخدام الماكرو يمكنك مسح محتويات خلية أو مجال من الخلايا باستخدام الماكرو، حيث سنمسح كل نوع من أنواع المحتويات من هذا المجال. لنعرّف دالة باستخدام Sub تمسح محتويات مجال من الخلايا كما يلي: Sub ClearRangeContents() End Sub لنحصل على مجال من الخلايا في الورقة 1. تعيد الدالة getCellRangeByName كائن المجال المقابل للمجال المُمرَّر عبر الوسيط. Dim oDoc As Object Dim oSheet As Object Dim oCell As Object Dim oRange As Object oDoc = ThisComponent oSheet = oDoc.Sheets(0) ' Refers to Sheet1 as in 0, 1, 2 etc oRange = oSheet.getCellRangeByName("A3:B10") المجال A3:B10 مع أنواع مختلفة من القيم يمكن استخدام دالة المجال clearContents(flags) لمسح محتويات هذا المجال، فالرايات flags هي أنواع القيم التي يمكن أن توجد في خلية، حيث يمكن أن تكون عبارة عن سلسلة نصية أو أرقام أو صيغ أو أنماط وغير ذلك، إذ يمكنك تحديد الأنواع التي تريد مسحها من هذا المجال. تُعَد رايات وسيط الدالة ClearContents من نوع البيانات long، ويمكن أن تأخذ رايات متعددة كدخل. توجد الرايات في مجموعة أوبن أوفيس / ليبرأوفيس الثابتة CellFlags التي تُعَد جزءًا من com.sun.star.sheet. قائمة الرايات الموجودة ضمن com.sun.star.sheet.CellFlags table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } الراية وصفها قيمتها VALUE تحدد القيم العددية الثابتة التي ليس تنسيقها تاريخ أو وقت. 1 DATETIME تحدد القيم العددية الثابتة التي لها تنسيق التاريخ أو الوقت. 2 STRING تحدد سلاسلًا نصية ثابتة. 4 ANNOTATION تحدد تعليقات الخلايا التوضيحية. 8 FORMULA تحدّد الصيغ. 16 HARDATTR تحدد كل التنسيقات الصريحة، لكنها لا تحدد التنسيق المطبق ضمنيًا من خلال نمط الأوراق. 32 STYLES تحدد أنماط الخلية. 64 OBJECTS تحدد الكائنات الرسومية. 128 EDITATTR تحدد التنسيق ضمن أجزاء من محتويات الخلية. 256 FORMATTED تحدد الخلايا ذات التنسيق ضمن الخلايا أو الخلايا التي تحتوي على أكثر من فقرة واحدة في الخلايا. 512 ضع كل الثوابت السابقة ضمن متغير ومرّره إلى الدالة clearContents كما يلي: Dim oFlags As Long oFlags = com.sun.star.sheet.CellFlags.VALUE + _ com.sun.star.sheet.CellFlags.DATETIME + _ com.sun.star.sheet.CellFlags.STRING + _ com.sun.star.sheet.CellFlags.ANNOTATION + _ com.sun.star.sheet.CellFlags.FORMULA + _ com.sun.star.sheet.CellFlags.HARDATTR + _ com.sun.star.sheet.CellFlags.STYLES + _ com.sun.star.sheet.CellFlags.OBJECTS + _ com.sun.star.sheet.CellFlags.EDITATTR oRange.clearContents(oFlags) تشغيل الشيفرة ضع الشيفرة الكاملة الآتية في جدول بيانات كالك الذي يحتوي على قيم مختلفة ضمن مجال، وشغّل الماكرو عن طريق استدعاء الدالة. قد يكون الخرج هو مسح جميع القيم والتنسيق وغير ذلك. شيفرة الماكرو الكاملة Sub ClearRangeContents() Dim oDoc As Object Dim oSheet As Object Dim oCell As Object Dim oRange As Object Dim oFlags As Long oDoc = ThisComponent oSheet = oDoc.Sheets(0) ' Refers to Sheet1 as in 0, 1, 2 etc oRange = oSheet.getCellRangeByName("A3:B10") oFlags = com.sun.star.sheet.CellFlags.VALUE + _ com.sun.star.sheet.CellFlags.DATETIME + _ com.sun.star.sheet.CellFlags.STRING + _ com.sun.star.sheet.CellFlags.ANNOTATION + _ com.sun.star.sheet.CellFlags.FORMULA + _ com.sun.star.sheet.CellFlags.HARDATTR + _ com.sun.star.sheet.CellFlags.STYLES + _ com.sun.star.sheet.CellFlags.OBJECTS + _ com.sun.star.sheet.CellFlags.EDITATTR oRange.clearContents(oFlags) End Sub معالجة الملفات والمجلدات باستخدام ماكرو ليبرأوفيس كالك سنوضّح كيفية معالجة أو قراءة الملفات والمجلدات في نظام ملفات يونيكس باستخدام لغة بيسيك Basic وماكرو ليبرأوفيس كالك، ووضع أسماء الملفات أو المجلدات في خلايا ليبرأوفيس كالك. يجب معرفة معالجات نظام الملفات والمجلدات، حيث سنعتمد على نظام ملفات يونيكس الذي يختلف عن نظام ويندوز، إذ سيقرأ الماكرو محتويات مجلد ويستخرج الملفات والمجلدات ويدرجها في خلايا كالك. لنفترض أن بنية نظام الملفات تشبه ما يلي في نظام أبونتو Ubuntu المعياري في المسار /usr/include: هناك الكثير من المجلدات والملفات، حيث نريد أن ندرج هذه المحتويات الكاملة ضمن خلايا كالك. توفّر لغة بيسيك Basic الدالة Dir التي يمكن استخدامها لقراءة محتويات مجلد، وتكون هذه الدالة بالشكل التالي: Dir (path, attributes) As String وسيط دالة Dir الأول هو سلسلة المسار النصية المراد قراءتها، ويخبر الوسيط الثاني الدالة Dir بنوع عناصر هذا المسار المراد إعادتها. مرّر القيمة "0" للملف والقيمة "16" للمجلدات في الوسيط الثاني، حيث يكون الوسيطان اختياريين. إذا استدعيت الدالة Dir لأول مرة بنجاح، فاستدعِ الدالة مرة أخرى بدون وسيط داخل حلقة للحصول على نفس العناصر من الدالة الناتجة عن إدراج محتويات المجلد الكامل. شيفرة الماكرو الكاملة أنشئ ملف كالك جديد وانسخ والصق الشيفرة التالية في محرّر الماكرو Macro Editor ضمن ليبرأوفيس وشغّلها: Sub list_files() Dim i, strFile path ="/usr/include/" strFile = Dir(path,0) i = 1 while strFile <> "" my_cell = ThisComponent.Sheets(0).getCellbyPosition(1,i) my_cell.String = strFile strFile = Dir ' returns next entry i = i + 1 wend End Sub Sub list_directory() Dim i, strDir path ="/usr/include/" strDir = Dir(path, 16) i = 1 while strDir <> "" my_cell = ThisComponent.Sheets(0).getCellbyPosition(2,i) my_cell.String = strDir strDir = Dir ' returns next entry i = i + 1 wend End Sub الخرج ستظهر محتويات المسار /usr/include في كالك بعد تشغيل الشيفرة، حيث سيحتوي العمود الأول على الملفات وسيحتوي العمود الثاني على المجلدات. قائمة الملفات والمجلدات باستخدام ماكرو كالك مرجع الدالة Dir Dir (path, attributes) المسار path: وسيط اختياري. السمات attributes: وسيط اختياري. القيمة المعادة: سلسلة نصية String. قائمة أنواع السمات السمة وصفها عادية (القيمة الافتراضية) 1 للقراءة فقط 2 مخفية 4 ملف نظام 8 تسمية قرص Volume label 16 مجلد أو دليل 64 اسم الملف هو اسم بديل alias ترجمة -وبتصرُّف- لمجموعة المقالات LibreOffice Workbook Worksheet and Cell Processing using Macro String Processing in LibreOffice Calc Macro with Examples Date and Time Processing in LibreOffice Calc using Macro Deleting All Types of Contents from Calc Range using Macro Files and Directory Processing Using LibreOffice Calc Macro using Basic لصاحبها Arindam. اقرأ أيضًا تعلّم أساسيات التعامل مع جداول بيانات LibreOffice Calc كيفية تحرير البيانات في LibreOffice Calc كيفية التحكّم في طرق عرض جداول بيانات LibreOffice Calc
-
تختلف الصورة عند إنشائها في كريتا Krita عن الصورة الناتجة بعد طباعتها باستخدام طابعة، إذ قد تصبح الألوان أكثر أو أقل قتامة مما هو متوقع، أو قد يكون اللون الأحمر أقوى أو قد يختفي التباين من الصورة. لا يمثل ذلك مشكلة كبيرة بالنسبة للمستندات البسيطة، ولكنه قد يكون سيئًا للغاية بالنسبة للمطبوعات الاحترافية، لأنه يمكن أن يغير شكل ومظهر الصورة كثيرًا. سبب هذا الاختلاف هو أن الطابعة تستخدم نمط ألوان مختلف هو CMYK، وبالتالي لديها إمكانية وصول إلى مجال أقل من الألوان (يسمى التدرج اللوني Gamut). قد يقترح الشخص المبتدئ الحل التالي: اعمل ضمن نمط ألوان CMYK، ولكن هذا الحل ينطوي على ثلاث مشاكل هي: لا يضمن الرسم في فضاء CMYK بقاء الألوان نفسها على طابعتك، فلكل مجموعة من الأحبار والأوراق وأجهزة الطباعة تدرج لوني ناتج مختلف يمكنك استخدامه، مما يعني أن لكل تدرج لوني ملف تعريف Profile مختلف مرتبط به. فضاء ألوان CMYK غير منتظم حتى إن كان لديك ملف تعريف وعملت في فضاء اللون الدقيق الذي يمكن للطابعة إخراجه، وبالتالي ليست حساباته اللونية جميلة كما في الفضاءات الأخرى، وتختلف أوضاع المزج في CMYK أيضًا. أخيرًا، يعني العمل في فضاء CMYK المحدَّد أن الصورة عالقة في ذلك الفضاء. إذا ضبطتَ عملك على ملف تعريف CMYK مختلف، فقد يكون لديك تدرج لوني أكبر بألوان أزهى يمكنك الاستفادة منه نظرًا لاختلاف الورق أو الطابعة أو الحبر. لذلك يمكنك من الناحية النظرية إنشاء الصورة باستخدام نمط ألوان RGB واستخدام جميع أدواته المفضلة لديك، ثم السماح للحاسوب بإجراء تحويل إلى فضاء CMYK معين بسرعة للمعاينة فقط، وهذا ما نسميه "بمعاينة الطباعة Soft Proofing". تمثل الصورة اليسارية الصورة الأصلية، وتمثل الصورة اليمينية عرض تشغيل معاينة الطباعة. الاختلاف دقيق بسبب عدم وجود ألوان زاهية، ولكن النسخة المطبَّق عليها معاينة الطباعة تكون أقل زرقة قليلًا في اللون الأبيض من الزهور وأقل تشبعًا في اللون الأخضر من الأوراق. يمكنك تطبيق معاينة الطباعة على أيّ صورة باستخدام الاختصار Ctrl + Y، حيث يمكن استخدام ذلك لكل معاينة على عكس البرامج الأخرى، إذ يمكنك معاينة صورتك الأصلية بجانب الصورة المطبَّق عليها معاينة الطباعة، وكما تطبَّق الإعدادات على كل صورة وتُحفَظ في ملف .kra. يمكنك ضبط خيارات معاينة الطباعة من قائمة صورة Image ثم خصائص Image Properties ثم معاينة الطباعة Soft Proofing. كما يمكنك ضبط الخيارات التالية: ملف التعريف Profile والعمق Depth والفضاء Space: ملف التعريف هو المهم فقط، حيث سيكون بمثابة ملف التعريف الذي تطبّق معاينة الطباعة عليه، إذ يجب أن تحدّد المطبعة ملف التعريف في عملية الطباعة الاحترافية. الهدف Intent: يضبط هذا الخيار هدف معاينة الطباعة، حيث يستخدم أهداف سير العمل المُدار بالألوان نفسها. تمثل الصورة اليسارية الصورة المطبَّق عليها معاينة الطباعة مع ضبط شريط تمرير حالة التكيف Adaptation state على الحد الأقصى. تمثل الصورة اليمينية الصورة المطبَّق عليها معاينة الطباعة مع ضبط حالة التكيف على الحد الأدنى. حالة التكيف Adaptation State: ميزة تسمح لك بضبط خيار مقياس الألوان المطلق Absolute Colorimetric لجعل اللون الأبيض في الصورة على الشاشة مثل اللون الأبيض أثناء عملية معاينة الطباعة (يُضبَط شريط التمرير على الحد الأقصى)، أو بهدف استخدام درجة اللون الأبيض في ملف التعريف (يُضبَط شريط التمرير على الحد الأدنى). تحتوي ملفات تعريف CMYK على لون أبيض مختلف عن اللون الأبيض الموجود على الشاشة في أغلب الأحيان بسبب اختلاف لون الورق. إصلاح درجة اللون الأسود Black Point Compensation: يؤدي تعطيل هذا الخيار إلى تقليل قيم الظل إلى الحد الأدنى الذي يمكن أن تتعامل معه الشاشة ويمكن لملف تعريف معاينة الطباعة معالجته، بينما يؤدي تفعيل هذا الخيار إلى تغيير مجال اللون الأسود إلى مجال الشاشة، مما يؤدي إلى عرض مجال اللون الرمادي الكامل في الصورة. تنبيه التدرج اللوني Gamut Warning: يضبط هذا الخيار لون تنبيه الخروج عن التدرج اللوني. كما يمكنك ضبط الإعدادات الافتراضية التي يستخدمها كريتا من قائمة إعدادات Settings ثم ضبط كريتا Configure Krita ثم إدارة الألوان Color Management. يوصَى بإنشاء صور لاختبار الطباعة مع طباعتها باستخدام طابعة مضبوطة ضبطًا صحيحًا والموازنة بينها، ثم تقريب خيارات معاينة الطباعة إلى الصورة التي تكون الأقرب من النسخة الواقعية. تنبيه الخروج عن التدرج اللوني يُعَد تنبيه الخروج عن التدرج اللوني أو منبه التدرج اللوني خيارًا إضافيًا لمعاينة الطباعة، إذ يسمح لك بمعرفة الألوان المقصوصة عن طريق استبدال اللون الناتج بلون التنبيه المضبوط. قد يكون هذا الخيار مفيدًا لتحديد مكان فقد بعض التباينات، وللسماح بتعديل الصورة ببطء إلى صورة أقل تباينًا. تمثل الصورة اليسارية عرض الصورة الأصلية. تمثل الصورة اليمينية عرض الصورة مع تشغيل معاينة الطباعة وتنبيهات التدرج اللوني. سيحفظ كريتا لون تنبيه التدرج اللوني مع خيارات معاينة الطباعة في ملف KRA، لذا اختر لونًا تعتقد أنه سيكون بارزًا في صورتك الحالية. يمكنك تنشيط تنبيهات التدرج اللوني باستخدام الاختصار Ctrl + Shift + Y، ولكنه يحتاج إلى تنشيط معاينة الطباعة ليعمل بكامل قدراته. أقنعة التدرج اللوني Gamut Masks قناع التدرج اللوني هو طريقة للتلوين وحّدها جيمس جورني James Gurney بناءً على فكرة أن أيّ نظام ألوان يمكن التعبير عنه بأشكال مقتطعة من عجلة الألوان. نشأت هذه الطريقة في عالم الرسم التقليدي كشكل من أشكال التخطيط ولوحات المزج المسبق، ولكن يمكن أن يُترجَم إلى فن رقمي، مما يتيح لك استكشاف الألوان وتحليلها وتخطيط أنظمة الألوان وتوجيه اختياراتك لها، وقد ظهرت هذه الميزة في الإصدار رقم 4.2 من كريتا. كيفية عمله يمكنك رسم شكل واحد أو عدة أشكال على عجلة الألوان، بحيث تقتصر اختياراتك للألوان على الألوان الموجودة داخل تلك الأشكال، ولكنك تنشئ علاقة وانسجامًا بينها. يتوفر قناع التدرج اللوني في كلٍّ من منتقي الألوان المتقدم والفني. اختيار قناع التدرج اللوني افتح لوحة أقنعة التدرج اللوني Gamut Masks Docker لاختيار وإدارة هذه الأقنعة من قائمة إعدادات Settings ثم لوحات (أرصفة) Dockers ثم أقنعة التدرج اللوني Gamut Masks. يمكنك في هذه اللوحة الاختيار من بين العديد من أقنعة التدرج اللوني الكلاسيكية مثل "Atmospheric Triad" أو "Complementary" أو "Dominant Hue With Accent". كما يمكنك تكرار هذه الأقنعة وإجراء تعديلات عليها (3 و 4)، أو إنشاء أقنعة جديدة من البداية (2). يؤدي النقر على أيقونة القناع المصغرة (1) إلى تطبيقه على منتقي الألوان. منتقي الألوان يمكنك تدوير قناع موجود مباشرة في منتقي الألوان عن طريق سحب شريط التمرير أعلى المنتقي (2). كما يمكن إيقاف تشغيل القناع وتشغيله مرة أخرى بواسطة زر تبديل القناع في الزاوية اليسرى العلوية (1). منتقي الألوان المتقدم والفني مع قناع التدرج اللوني تحرير أو إنشاء قناع تدرج لوني مخصص إذا اخترت إنشاء قناع جديد أو تحرير أو تكرار قناع محدَّد، فإن مستندات قالب القناع تفتح كعرض جديد (1)، حيث يمكنك إنشاء أشكال جديدة وتعديل القناع باستخدام أدوات متجهة معيارية (رسوميات متجهة Vector Graphics)، فالقناع مُصمَّم ليكون مكونًا من أشكال متجهة أساسية. يمكن ظهور نتائج جذابة من استخدام تقنيات الرسوميات المتجهة المتقدمة، إلا أنه لا يمكن ضمان عمل جميع الميزات بصورة صحيحة (مثل التجميع والنص المتجهي وغير ذلك). يمكنك معاينة Preview القناع في منتقي الألوان (4)، فإذا كنت راضيًا عن التغييرات التي أجريتها، فاحفظ Save القناع (5)، بينما يغلق زر الإلغاء Cancel (3) عرض التحرير دون حفظ التغييرات. تحرير قناع التدرج اللوني الاستيراد والتصدير يمكن استيراد وتصدير أقنعة التدرج اللوني في حزم في مدير الموارد Resource Manager. ترجمة -وبتصرّف- للمقالين Soft Proofing و Gamut Masks من موقع Krita. اقرأ أيضًا خطوات العمل المعتادة في كريتا تحبير مسودة الرسم في كريتا تلميحات مختلفة حول استخدام الفرش في كريتا تلميحات مختلفة حول استخدام الفرش في كريتا رسم أزهار الأزاليا باستخدام أقنعة التحول في برنامج كريتا أفضل مؤشر في برنامج كريتا Krita لإنشاء عملك الفني النسخة الكاملة من كتاب أساسيات تصميم الرسوميات
-
يوفّر ليبرأوفيس LibreOffice طريقة لكتابة الماكرو Macro الذي تحتاجه لأتمتة المهام المتكررة في تطبيقك المكتبي، إذ يمكنك استخدام لغتي بايثون Python أو بيسك Basic لتطوير هذا الماكرو. سنتعلّم في هذا المقال كيفية كتابة ماكرو في ليبرأوفيس باستخدام ماكرو "Hello World" بلغة بيسك، حيث سننشئ ماكرو يضع السلسلة النصية "Hello World" في الخلية الأولى من برنامج ليبرأوفيس كالك Calc، أي خلية الصف 1 والعمود A وأيضًا سنتطرق إلى موضوع تنظيم الماكرو وكيفية تصديره واستيراده كمكتبة مستقلة. هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبرأوفيس كالك، فهرس السلسلة: مدخل إلى كتابة ماكرو Macro في ليبرأوفيس كالك LibreOffice Calc معالجة محتويات خلايا ليبرأوفيس كالك باستخدام الماكرو معالجة مجال من الخلايا باستخدام الماكرو في ليبرأوفيس كالك استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبرأوفيس التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبرأوفيس كالك أتمتة حفظ أوراق ليبرأوفيس كالك بتنسيق PDF باستعمال الماكرو إنشاء الماكرو افتح برنامج ليبرأوفيس كالك من قائمة ابدأ ثم كافة البرامج ثم اختر ليبرأوفيس LibreOffice ثم ليبرأوفيس كالك LibreOffice Calc في نظام ويندوز أو من تطبيقات Applications ثم اختر Office ثم ليبرأوفيس كالك LibreOffice Calc في نظام لينكس. انتقل إلى قائمة أدوات Tools ثم ماكرو Macros ثم نظّم وحدات الماكرو Organize Macros ثم LibreOffice Basic، حيث ستفتح نافذة "ماكروهات أساسية LibreOffice basic macros". أدخِل الاسم الذي تريده في خانة اسم الماكرو وانقر على جديد. استخدمنا الاسم hello_world، ولكن يمكنك استخدام الاسم الذي تريده. سيفتح محرر الماكرو macro editor بعد النقر على زر "جديد"، وهذا المحرّر هو المكان الذي يجب أن تكتب فيه شيفرتك وتنقّح الأخطاء debugging الموجودة فيها وغير ذلك الكثير، حيث يمكنك أن ترى أن اسم الماكرو أصبح اسمًا لدالة الماكرو المكتوبة بلغة بيسك. لنكتب الآن شيفرة الماكرو الأول من خلال التصريح عن متغيرين من النوع كائن object كما يلي: dim document as object dim dispatcher as object ثم نسند قيمتين للمتغيرين السابقين كما يلي: document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") يشير ThisComponent إلى المستند الحالي. يكون كل شيء في ليبرأوفيس -مثل الكتابة والتلوين والإدراج- مراقبًا باستخدام متحكم controller، حيث يرسل هذا المتحكم التغييرات إلى إطار المستند، أي منطقة نافذة كالك الرئيسية. لذلك يشير المتغير document إلى منطقة كالك الرئيسية. يُنشِئ التابع createUnoService نسخةً من خدمة DispatchHelper التي تساعد في إرسال المهام من الماكرو إلى الإطار، حيث يمكن تنفيذ جميع مهام ماكرو في ليبرأوفيس تقريبًا باستخدام المرسل dispatcher. سنصرّح الآن عن مجموعة من الخاصيات التي تتكوّن من الزوج اسم/قيمة name/value، وبالتالي يحتوي الاسم name على اسم الخاصية وتحتوي القيمة value على قيمة تلك الخاصية. dim args1(0) as new com.sun.star.beans.PropertyValue dim args2(0) as new com.sun.star.beans.PropertyValue هدفنا هو وضع النص "Hello World" في الخلية الأولى، حيث يمكن الإشارة إلى الخلية الأولى A1 ثم وضع نص فيها من خلال استخدام الخاصيتين ToPoint و StringName. args1(0).Name = "ToPoint" args1(0).Value = "$A$1" args2(0).Name = "StringName" args2(0).Value = "Hello World!" يجب بعد ضبط الخاصيات استدعاء المرسل لإرسالها إلى المستند، لذلك استدعِ الحدث executeDispatch الخاص بالمرسل باستخدام أمرين هما: .uno:GoToCell و .uno:EnterString، حيث يخبر هذان الأمران الإطارَ بما يجب تنفيذه، ويمرّران مصفوفة الخاصيات بأكملها مع القيم. ضع الآن مربع رسالة message box لإعلامك باكتمال التنفيذ كما يلي: تشغيل الماكرو يمكن تشغيل الماكرو بالضغط على مفتاح F5 أو بالنقر على زر تشغيل الماكرو Run Macro من شريط الأدوات، ثم يظهر مربع الرسالة بعد التنفيذ. إذا تحققت من جدول بيانات كالك، فيجب أن ترى النص "Hello World!" مكتوبًا في الخلية الأولى. إليك الشيفرة الكاملة: REM ***** BASIC ***** sub hello_world dim document as object dim dispatcher as object document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") dim args1(0) as new com.sun.star.beans.PropertyValue dim args2(0) as new com.sun.star.beans.PropertyValue args1(0).Name = "ToPoint" args1(0).Value = "$A$1" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1()) args2(0).Name = "StringName" args2(0).Value = "Hello World!" dispatcher.executeDispatch(document, ".uno:EnterString", "", 0, args2()) msgbox "Completed!" end sub تنقيح أخطاء الماكرو باستخدام نقطة التوقف والمراقبة سنتعلّم الآن تقنية تنقيح أخطاء debugging ماكرو بيسك في ليبرأوفيس باستخدام نقطة التوقف breakpoint والمراقبة watch، حيث بُنيَت هذه التقنية على نظام أبونتو Ubuntu 14.04LTS وبرنامج ليبرأوفيس الذي يستخدم لغة بيسك، وتُطبَّق على جميع لغات البرمجة تقريبًا مع ليبرأوفيس. تعريف المتغيرات لنعرّف 3 متغيرات سنستخدمها في مثالنا كما يلي: dim i, j, cnt عرّف حلقة for التي ستنفّذ من القيمة 1 إلى 10، ثم زِد متغيرين داخل هذه الحلقة على النحو التالي: for cnt = 1 to 10 i = i + 1 j = i + 1 next cnt إضافة نقطة توقف Breakpoint نريد وضع نقطتي توقف للعبارتين for cnt = 1 to 10 و j = i + 1، حيث تُشغَّل نقطة التوقف عند وضعها ضمن برنامجك في وضع تنقيح الأخطاء ويتوقف التنفيذ عند هذه النقطة. يمكنك وضع نقطة توقف من خلال وضع المؤشر عند العبارة، ثم الضغط على مفتاح F9 أو الضغط على الزر التالي من شريط الأدوات: سترى بعد ذلك دائرة حمراء بجانب العبارة مما يعني إضافة نقطة توقف كما يلي: إذا أردت إزالة نقطة توقف من عبارة، فاضغط على مفتاح F9 مرةً أخرى عند هذه العبارة أو يمكنك النقر نقرًا مزدوجًا على الدائرة الحمراء. إضافة مراقبة Watch سنضيف الآن مراقبة watch إلى المتغير cnt. تساعد هذه المراقبة عندما ينفّذ البرنامج في وضع تنقيح الأخطاء في مراقبة قيمة المتغير خلال خطوات البرنامج، حيث يمكنك إضافة مراقبة إلى المتغير cnt من خلال تحديد المتغير والضغط على مفتاح F7 أو النقر على أيقونة النظارات في شريط الأدوات. ستلاحظ بعد ذلك إضافة المتغير إلى قائمة المراقبة أسفل المحرر. تنفيذ خطوة تلو الأخرى شغّل البرنامج بالضغط على مفتاح F5، وبما أننا أضفنا نقطة توقف سابقًا، فسترى توقف التنفيذ عند نقطة التوقف الأولى حيث يظهر سهم برتقالي صغير. لديك الآن خياران هما: اضغط على مفتاح F5 مرة أخرى لمتابعة تنفيذ البرنامج، ولكنه سيتوقف مرةً أخرى في نقطة التوقف التالية. اضغط على مفتاح F8 (تنفيذ خطوة) والذي سينفذ خطوةً تلو الخطوة، ويمكنك أن ترى تغيُّر قيمة المتغير cnt المُراقَبة. لنضغط على مفتاح F8، حيث يمكنك أن ترى السهم البرتقالي ينتقل إلى العبارة التالية وينتظر. إذا ألقيت نظرة على نافذة المراقبة، فيمكنك رؤية قيمة المتغير cnt هي 1. ويمكنك بهذه الطريقة تنقيح الأخطاء وإضافة نقطة توقف وإضافة مراقبة لأيّ ماكرو في ليبرأوفيس أو أوبن أوفيس OpenOffice باستخدام محرّره الخاص. تنظيم الماكرو في ليبرأوفيس إذا كنت معتادًا على استخدام البرمجة بلغة فيجوال بيسك Visual Basic for Applications -اختصارًا VBA- في مايكروسوفت إكسل Excel، فلا بدّ أنك تعرف أن شيفرات فيجوال بيسك VB الخاصة بالماكرو موجودة في مشروع VB، وإذا أردت تضمين الماكرو ضمن ملف إكسل Excel مثلًا، فيجب أن تحفظه بالتنسيق .xlsm الذي يوضّح احتواء الملف على ماكرو. البنى الافتراضية لملف الماكرو في ليبرأوفيس ينشئ ليبرأوفيس افتراضيًا الماكرو ضمن المسار ماكروهاتي My Macros ثم Standard ثم Module1 عند إنشائه لأول مرة، إذ توجد جميع دوال الماكرو الخاصة بك ضمن الوحدة Module1، حيث أنشأنا في مثالنا الدالة my_macro ضمن الوحدة Module1. يحتفظ ليبرأوفيس بجميع شيفرات الماكرو التي أُنشئت ضمن الوحدة Module1 الافتراضية في المسار الآتي: /home/[user name]/.config/libreoffice/4/user/basic/Standard يجب أن يوجد ضمن المسار ملف يسمى Module1.xba يحتوي على دوال الماكرو الافتراضية، حيث يجب أن تكون دالة الاختبار my_macro ومحتوياتها داخل هذا الملف. كيفية إنشاء الماكرو بوصفه جزءا من ملف مكتبي إذا كتبت سابقًا كثيرًا من وحدات الماكرو والدوال باستخدام بنية الملفات الافتراضية السابقة وحفظت الملف، فلن تُحفَظ وحدات الماكرو مع الملف. إذا وزّعتَ هذا الملف أو أرسلته إلى شخص آخر، فلن يتمكن من رؤية وحدات الماكرو عند فتح الملف، لأن محتويات الماكرو تبقى في القرص الصلب حيث كُتِبت أو طُوِّرت شيفرتها. إذا أردت توزيع أو إرسال ملف ليبرأوفيس مثل كالك Calc أو إمبرس Impress أو غيرها مع دوال الماكرو، فيجب عليك إنشاء وحدات الماكرو بطريقة مختلفة، إذ يجب إنشاء الماكرو داخل الملف أثناء إنشاء وحدات الماكرو ومربع الحوار الذي تريد توزيعه بوصفه جزءًا من ملف ليبرأوفيس. افتح مربع الحوار من قائمة أدوات Tools ثم ماكرو Macros ثم تنظيم الماكرو Organize Macros ثم بيسك LibreOffice Basic. حدّد اسم الملف من قائمة "الماكرو من Macro From" داخل مربع الحوار، ثم اضغط "جديد New"، حيث سيطلب ليبرأوفيس كتابة اسم الوحدة Module. يستخدم ليبرأوفيس الوحدة "Module1" افتراضيًا، لذلك اكتب أي اسم تريده واضغط على "موافق" (استخدمنا اسم الوحدةdebugpoint_demo_module). سيفتح بعد ذلك محرّر الماكرو الذي يحتوي الوحدة الجديدة والماكرو ضمن ملف عملك. يمكنك الآن كتابة العديد من وحدات الماكرو التي تريدها ضمن الوحدة الحالية وحفظ ملف ليبرأوفيس الحالي، ثم ستُحفَظ جميع وحدات الماكرو ومحتوياتها مع الملف ويمكنك بسهولة مشاركة الملف أو توزيعه على المستخدمين. تُخزَّن وحدات الماكرو Macros ضمن الوحدات Modules في ليبرأوفيس، والوحدات هي جزء من المكتبات Libraries والمكتبات هي جزء من الحاويات Containers كما هو موضح أدناه: تحميل الوحدة التي يعرفها المستخدم يفترض ليبرأوفيس أن جميع مربعات الحوار والمتغيرات موجودة في الوحدة "Module1" وفقًا للتنظيم الافتراضي، لكننا أنشأنا وحدة جديدة بالاسم "debugpointdemomodule" التي تبقى مع الملف، حيث يجب تحميل الوحدة قبل البدء في كتابة شيفرات الماكرو. يمكنك تحميل الوحدات التي يعرّفها المستخدم باستخدام التابع التالي: ThisComponent.BasicLibraries.LoadLibrary("debugpoint_demo_module") إذا أنشأتَ مربع حوار -"my_dialog" مثلًا- أسفل ملف العمل نفسه، فيمكنك إنشاء كائن الحوار Dialog باستخدام ما يلي: Dim oDialog1 As Object oDialog1 = CreateUnoDialog(DialogLibraries.Standard.my_dialog) تفعيل الماكرو في ملفات ليبرأوفيس قد يواجه المستخدم الخطأ الموضح أدناه عند فتح الملف على نظام آخر بعد توزيع ملف ليبرأوفيس أو مشاركته مع الماكرو الموجود فيه، حيث يُعطَّل تنفيذ الماكرو افتراضيًا في ليبرأوفيس لأسباب أمنية. انتقل إلى قائمة أدوات Tools ثم خيارات Options ثم ليبرأوفيس LibreOffice ثم الأمن Security ثم أمان الماكرو Macro Security، حيث يُضبَط أمان الماكرو على الخيار "عالٍ high"، ولكن يمكنك تغييره إلى الخيار "منخفض low" إذا كنت واثقًا من مصدر الماكرو، ثم يمكنك إعادة محاولة تنفيذ الماكرو. ترجمة -وبتصرُّف- للمقالات Writing a Macro in LibreOffice Calc – Getting Started و Debugging LibreOffice Macro Basic using Breakpoint and Watch و LibreOffice Macro Organization لصاحبهما Arindam. اقرأ أيضًا تعلّم أساسيات التعامل مع جداول بيانات LibreOffice Calc كيفية تحرير البيانات في LibreOffice Calc كيفية التحكّم في طرق عرض جداول بيانات LibreOffice Calc
-
يُعَد برنامج كريتا Krita أداة لتحرير الرسومات النقطية Raster Graphics، مما يعني أن معظم عمليات التحرير التي تغير قيم البكسلات تُطبَّق على البيانات النقطية التي تشكل الصورة. تستخدم الرسومات المتجهة Vector Graphics الحسابات الرياضية لوصف الشكل، إذ يمكن تغيير حجم الرسومات المتجهة إلى أيّ حجم نظرًا لأنها تستخدم صيغة معينة، مما يجعل الرسومات المتجهة مناسبة للشعارات واللافتات. بينما يُعَد تحرير الرسومات النقطية أسهل بكثير، لذلك تميل الرسومات المتجهة إلى أن تكون مجال التصميم المدروس مع كثير من الدقة. سنتحدّث في هذا المقال عن إمكانات كريتا في العمل على الرسوم المتجهة وأدواتها وأشكالها إضافة إلى استخدام مزايا اﻹنجذاب لمطابقة نقاط إرتكاز وحواف الرسومات المتجهة وغيرها مع شرح عن كيفية إدارة الوسوم في كريتا. أدوات إنشاء الأشكال يمكنك إنشاء رسومات متجهة عن طريق إنشاء طبقة متجهة Vector Layer أولًا من خلال الضغط على زر السهم بجوار إشارة + في لوحة الطبقات للحصول على أنواع طبقات إضافية، ثم يمكنك استخدام جميع أدوات الرسم المعتادة مثل أداة الرسم بيد حرة Freehand وأداة الفرشاة الديناميكية Dynamic والأداة ذات الفُرش المتعددة Multibrush لرسم الأشكال. أداة المسار Path والأداة متعددة الخطوط Polyline هي الأدوات التي تستخدمها على طبقة متجهة في أغلب الأحيان، لأنها تتيح لك جعل الأشكال أكثر ديناميكية. بينما تسمح أدوات الدائرة Ellipse والمستطيل Rectangle برسم أشكال خاصة يمكن تعديلها لاحقًا لإنشاء أشكال دائرية خاصة أو لإنشاء مستطيلات ذات زوايا مستديرة بسهولة. كما تنشئ أداة الخط Calligraphy والنص Text أشكالًا متجهةً خاصة، حيث تُستخدَم أداة الخط لإنتاج أثر يشبه أثر الفرشاة، بينما تنشئ أداة النص كائن نص يمكن تحريره لاحقًا. تستخدم جميع هذه الأدوات حجم الفرشاة الحالي لتحديد ثُخن الحدّ Stroke، ويُستخدَم لونا المقدمة والخلفية الحاليين. كما توجد طريقة أخرى لإنشاء الرسوم المتجهة هي أداة الصورة المتجهة Vector Image التي تسمح بإضافة الأشكال المُحدَّدة في ملف SVG كرموز، ويكون لهذه الأداة تعبئة وحدّ خاصين بها على عكس الأدوات الأخرى. ترتيب الأشكال تحتوي الطبقة المتجهة على تسلسل هرمي من الأشكال يشبه إلى حد كبير كيفية احتواء الصورة بأكملها على تسلسل طبقات هرمي، لذلك يمكن أن تكون هذه الأشكال أمام بعضها البعض، ولكن يمكن تعديل ذلك باستخدام لوحة الترتيب Arrange أو باستخدام أداة تحديد الأشكال Select Shapes. كما تسمح لوحة الترتيب بتجميع الأشكال وفك تجميعها، وبمحاذاة الأشكال بدقة مثل محاذاتها مع المركز أو أن تكون الأشكال على بعدٍ متساوٍ من بعضها البعض. تحرير الأشكال يمكن تحرير الأشكال المتجهة باستخدام أداة تحديد الأشكال Select Shapes وأداة تحرير الأشكال Edit Shapes. كما يمكن استخدام أداة تحديد الأشكال Select Shapes لتحديد الأشكال المتجهة أو تجميعها (باستخدام زر الفأرة الأيمن)، أو فك تجميعها، أو استخدام القيم المنطقية لدمج الأشكال أو طرحها من بعضها البعض (باستخدام زر الفأرة الأيمن)، أو تحريكها للأعلى وللأسفل، أو تطبيق تحويلات سريعة. يمكنك تغيير لون تعبئة Fill الشكل من خلال تحديده ثم تغيير لون المقدمة النشط. كما يمكنك تغييره بالانتقال إلى خيارات أداة تحديد الأشكال Select Shapes والانتقال إلى تبويب تعبئة Fill، حيث يمكن تعبئة الأشكال المتجهة بلون واحد أو بتدرج لوني أو بنمط Pattern. يمكن تعبئة الحدود Strokes بالأمور نفسها المُستخدَمة مع لون التعبئة، ولكن يمكن إضافة أمور إضافية مثل إضافة شرطات وعلامات إلى الخط. ويمكن تحريك الأشكال باستخدام أداة تحديد الأشكال Select Shapes، حيث يمكنك تحديد الإحداثيات Coordinates الدقيقة من خيارات هذه الأداة. تحرير العقد والمعاملات الخاصة إذا حدَّدتَ شكلًا، فيمكنك النقر عليه نقرًا مزدوجًا للوصول إلى الأداة المناسبة لتحريره، وهي أداة تحرير الشكل Edit Shape، ولكن الأداة المناسبة للنصوص هي أداة النص Text. يمكنك في أداة تحرير الشكل تحريك العقد على رقعة الرسم في المسارات العادية، بينما يمكنك تحريك العقد وتحرير المعاملات المحددة في لوحة خيارات الأداة Tool Options بالنسبة للمسارات الخاصة مثل الدائرة والمستطيل. العمل مع برامج أخرى أحد الأمور المهمة التي جلبها الإصدار 4.0 من كريتا هو الانتقال من ODG إلى SVG، أي أن كريتا يمكنه الحفظ بتنسيق SVG ضمن ملفات KRA، وبالتالي يمكن لكريتا فتح ملف SVG بطريقة صحيحة، وهذا مهم لأنه تنسيق الرسوم المتجهة الأكثر شيوعًا. يمكنك نسخ المتجهات ولصقها من كريتا إلى برنامج إنكسكيب Inkscape أو من إنكسكيب إلى كريتا. ميزات SVG 1.1 هي الميزات المدعومة فقط باستثناء الميزات الأقل مثل التدرجات اللونية الشبكية. الانجذاب Snapping احتوى الإصدار رقم 3.0 من برنامج كريتا Krita على وظائف خاصة بالشبكات Grids والأدلة Guides، ولكن هذه الوظائف ليست مفيدة دون خاصية اﻻنجذاب Snapping. اﻻنجذاب هو قدرة كريتا تلقائيًا على محاذاة التحديد أو الشكل مع الشبكات والأدلة ومركز المستند وأطراف المستند، وتتاح اﻻنجذاب في الطبقات المتجهة إلى المربعات المحيطة والتقاطعات والخطوط المتقطعة الإضافية Extrapolated Lines وغير ذلك. يمكن تبديل كل هذه العناصر باستخدام قائمة الانجذاب Snap المنبثقة التي تظهر باستخدام الاختصار Shift + S. لنستعرض ما يعنيه كل خيار فيما يلي: الشبكات Grids: يؤدي هذا الخيار إلى انجذاب المؤشر إلى الشبكة الحالية كما ضُبِط في لوحة الشبكة Grid، ولا يحتاج هذا الخيار إلى أن تكون الشبكة مرئية. تُحفَظ الشبكات في كل مستند، مما يفيد في أن يلائم عملك الفني الشبكات، كما هو الحال بالنسبة للرسوم المتحركة والتصميمات القائمة على الشبكة. البكسل Pixel: يسمح هذا الخيار بانجذاب كل بكسل تحت المؤشر، وهو مشابه لانجذاب الشبكة Grid Snapping ولكن مع تباعد مقداره 1 بكسل وإزاحة مقدارها 0 بكسل. الأدلة Guides: يتيح هذا الخيار الانجذاب إلى الأدلة التي يمكن سحبها من المسطرة Ruler. يمكن أن تكون الأدلة غير مرئية، وتُحفَظ في كل مستند. تفيد الأدلة في اللوحات الهزلية وتخطيطات الطباعة المماثلة، لكننا نوصي باستخدام سكريبوس Scribus لمزيد من التفاصيل الأخرى. المتعامد Orthogonal (في العناصر المتجهة فقط): يتيح هذا الخيار الانجذاب إلى خط أفقي أو رأسي من عُقد الكائنات المتجهة الموجودة باستثناء حالة التعامل مع تغيير حجم الارتفاع أو العرض حيث يمكنك سحب المؤشر فوق المسار. يفيد هذا الخيار في محاذاة الكائن أفقيًا أو رأسيًا، كما هو الحال مع اللوحات الهزلية. العقدة Node (للعناصر المتجهة فقط): يجذب هذا الخيار عقدة أو كائنًا متجهًا إلى عقد مسار آخر. الامتدادات Extension (للعناصر المتجهة فقط): إذا رسمنا مسارًا مفتوحًا، فيمكن تمديد العقد الأخيرة على كلا الجانبين رياضيًا، مما يسمح بالانجذاب إلى هذا الامتداد، حيث يعتمد اتجاه العقدة على مقابضها الجانبية في وضع تحرير المسار. التقاطعات Intersection (للعناصر المتجهة فقط): يتيح هذا الخيار الانجذاب إلى تقاطع متجهين. المربع المحيط Bounding box (للعناصر المتجهة فقط): يتيح هذا الخيار الانجذاب إلى المربع المحيط بشكل متجهي. حدود الصورة Image bounds: يسمح هذا الخيار بالانجذاب إلى حدود الصورة الرأسية والأفقية. مركز الصور Image center: يتيح هذا الخيار الانجذاب إلى مركز الصورة الأفقي والرأسي. يعمل الانجذاب مع الأدوات التالية: الخط المستقيم Straight Line. المستطيل Rectangle. الدائرة Ellipse. متعددة الخطوط Polyline. المسار Path. المسار بيد حرة Freehand Path. المضلع Polygon. التدرج اللوني Gradient. أداة معالجة الأشكال Shape Handling. أداة النص Text-tool. أدوات التحرير المساعدة Assistant Editing. أداة التحريك Move (لاحظ أنها تنجذب إلى موضع المؤشر وليس إلى مربع الطبقة المحيط أو التحديد أو أيّ شيء تريد تحريكه). أداة التحويل Transform. أداة التحديد المستطيلي Rectangle Select. أداة التحديد الدائري Elliptical Select. أداة التحديد المضلعي Polygonal Select. أداة تحديد المسار Path Select. يمكن أن تنجذب الأدلة Guides نفسها إلى الشبكات والأشكال المتجهة. لا يتمتع الانجذاب بالحساسية حتى الآن، ويُضبَط افتراضيًا على قيمة 10 بكسلات للشاشات. إدارة الوسوم تحدّد الوسوم Tags كيفية تنظيم أنواع الموارد المشتركة، إذ يمكن استخدامها مع الفُرش والتدرجات اللونية والأنماط ورؤوس الفرش، ويمكنك تحديدها من القائمة المنسدلة أعلى الموارد. يؤدي تحديد وسم إلى ترشيح جميع الموارد حسب ذلك الوسم، بينما يؤدي تحديد الوسم على خيار الكل All إلى إظهار جميع الموارد. يُثبَّت مع كريتا Krita بعض الوسوم الافتراضية، ولكن يمكنك إنشاء وتحرير وسومك الخاصة، وتُدار الوسوم عبر أنواع مختلفة من الموارد. كما يمكنك استخدام الوسوم مع اللوحة المنبثقة Pop-up Palette لزيادة الإنتاجية. إضافة وسم فرشاة جديد اضغط على إشارة + بجوار اختيار الوسم لتحصل على خيار لإضافة وسم، ثم اكتب الاسم الذي تريده واضغط على مفتاح Enter، ثم يجب العودة إلى وسم الكل All لبدء تخصيص الفرش. تخصيص وسم فرشاة موجودة مسبقًا انقر بزر الفأرة الأيمن على فرشاة في لوحة الفُرش مسبقة الضبط Brush Presets Docker لتحصل على خيار تخصيص وسمٍ للفرشاة assign a tag to the brush. تغيير اسم وسم حدّد الوسم الموجود مسبقًا الذي تريد تغييره من القائمة المنسدلة، ثم اضغط على أيقونة + الموجودة بجانب الوسم لتحصل على خيار إعادة تسميته Rename، ثم اضغط على مفتاح Enter للتأكيد، حيث ستبقى جميع الفُرش الموجودة مسبقًا ضمن الوسم الذي أعدنا تسميته. حذف وسم حدّد الوسم الموجود مسبقًا الذي تريد إزالته من القائمة المنسدلة، ثم اضغط على أيقونة + الموجودة بجانب الوسم لتحصل على خيار إزالته Remove. ترجمة -وبتصرّف- للمقالات Vector Graphics و Snapping و Tag Management من موقع Krita. اقرأ أيضًا استخدام الألوان في نمط التصاميم المسطحة في كريتا خطوات العمل المعتادة في كريتا تحبير مسودة الرسم في كريتا أفضل مؤشر في برنامج كريتا Krita لإنشاء عملك الفني التثبيت والبدء باستخدام كريتا
-
سنوضّح من خلال هذا المقال كيفية إنشاء دواليب هوائية ملوّنة في برنامج الإليستريتور Adobe Illustrator، حيث سنتعلم أولًا كيفية إنشاء المروحة الأولى باستخدام الأدوات الأساسية وتأثير Feather، ثم ننتقل إلى إنشاء المراوح الأخرى باستخدام تأثيرات التحويل Transform مع تقنيات بناء الأشكال المتجهة vector، وسنستخدم مجموعة ألوان جديدة لإعادة تلوين المراوح الجديدة. نكرّر بعد ذلك الخطوات نفسها لإنشاء الدولابين الإضافيين، ثم سنتعلم كيفية إنشاء خلفية مناسبة. إنشاء مستند جديد شغّل برنامج الإليستريتور Illustrator، ثم اضغط على الاختصار Ctrl + N لإنشاء مستند جديد. حدّد خيار البكسلات Pixels من قائمة الوحدات Units، وأدخِل القيمة 940 في خانة العرض width، والقيمة 700 في خانة الارتفاع height، ثم انقر على خيارات متقدمة Advanced. حدّد نمط الألوان RGB والخيار Screen (72ppi)، وتأكّد من إلغاء تحديد مربع اختيار محاذاة الكائنات الجديدة إلى شبكة البكسلات Align New Objects to Pixel Grid قبل النقر على موافق OK. إنشاء الدولاب الهوائي الأول استخدم أداة المستطيل Rectangle Tool (باستخدام الاختصار M) لإنشاء مستطيل أبعاده 233×94 بكسل، ثم استخدم أداة القلم Pen Tool (باستخدام الاختصار P) لإنشاء الكائن الأسود الموضّح في الشكل الثاني أدناه. استخدم أداة التحديد المباشر Direct Selection Tool (باستخدام الاختصار A) مع مفتاح Shift، وذلك من أجل تحديد نقاط ارتكاز الكائن الأسود الثلاث العلوية، ثم انقر على أيقونة تحويل نقطة الارتكاز المحدَّدة إلى سلِسة Convert selected anchor point to smooth من شريط خصائص Properties. اختر أداة التحديد المباشر (A) واضبط مقابض نقاط الارتكاز الثلاث العلوية كما هو موضّح أدناه. اختر أداة تحويل نقاط الارتكاز Convert Anchor Point Tool باستخدام الاختصار Shift + C، وانقر على نقطة ارتكاز الكائن الأسود السفلية اليسرى، ثم اضغط على الفأرة واسحبها للأسفل، ثم حدّد المقبض السفلي لنقطة الارتكاز السفلية اليسرى واسحبه إلى اليمين. أعِد تحديد المستطيل الذي أنشأناه في الخطوة رقم 2، وأزِله بعد الانتهاء من ضبط شكل الكائن الأسود. حدّد الكائن الأسود الذي أنشأناه في الخطوة رقم 3، وأنشئ نسخةً منه (بالضغط على الاختصار Ctrl + C ثم Ctrl + F)، ثم استبدل لون حدّ هذه النسخة الحالي باللون الأحمر. اختر الآن أداة إضافة نقطة ارتكاز Add Anchor Point (+)، وانقر على النقطة المميزة باللون الأزرق لإضافة نقطة ارتكاز جديدة، ثم استخدم أداة التحديد المباشر (A) مع مفتاح Shift لتحديد نقطتي الارتكاز المميزتين باللون الأسود وأزِلهما. حدّد الآن نقطة ارتكاز الكائن الأحمر السفلية، ثم حرّكها بمقدار 10 بكسلات للأسفل و2 بكسل إلى اليسار. اختر أداة التحديد المباشر (A)، واضبط مقابض نقطة الارتكاز السفلية كما هو موضّح أدناه، ثم اختر أداة تحويل نقاط الارتكاز Convert Anchor Point Tool باستخدام الاختصار Shift + C، وحدّد المقبض الأيمن لنقطة الارتكاز اليمنى، واسحبه إلى اليسار. حدّد الكائن الأسود وأزِل حدّه، ثم املأه بالتدرج اللوني الخطي الموضّح في الشكل الأول أدناه، ثم أنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم استبدل لون تعبئة النسخة الحالي بتدرج لوني خطي جديد. حدّد الشكل الناتج وانتقل إلى قائمة تأثير Effect، ثم Stylize، ثم Feather، وأدخِل نصف قطر Radius مقداره 4 بكسلات، ثم انقر على موافق. حدّد الكائن الأحمر وأزِل حدّه، ثم املأه بالتدرج اللوني الخطي الموضّح أدناه، ثم أنشئ نسخة منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم استبدل لون تعبئة هذه النسخة الحالي بتدرج لوني خطي جديد. حدّد الشكل الناتج، ثم طبّق عليه تأثير Feather بمقدار 8 بكسلات. حدّد ثم جمّع (Ctrl + G) جميع الكائنات التي أنشأناها من بداية الخطوة رقم 2 حتى الآن. أبقِ هذه المجموعة محدَّدة، واختر أداة التدوير Rotate Tool (باستخدام الاختصار R)، ثم استمر في الضغط على مفتاح Alt، وانقر على النقطة السفلية اليسرى من المجموعة، ثم أدخِل زاويةً مقدارها 90 درجة، وانقر على نسخ Copy، ثم اضغط على الاختصار Ctrl + D مرتين للحصول على النتائج الموضّحة أدناه. حدّد المروحة العلوية اليمنى، وحرّكها بمقدار 20 بكسلًا للأسفل و10 بكسلات إلى اليسار، ثم حدّد المروحة العلوية اليسرى وحرّكها بمقدار 10 بكسلات للأسفل و20 بكسلًا إلى اليمين. حدّد الآن المروحة السفلية اليسرى، ثم حرّكها بمقدار 20 بكسلًا للأعلى و10 بكسلات إلى اليمين، ثم حدّد المروحة السفلية اليمنى وحرّكها بمقدار 10 بكسلات للأعلى و20 بكسلًا إلى اليسار. حدّد المروحة العلوية اليمنى واجلبها إلى الأمام (Ctrl + Shift + Right Square)، ثم أعِد تحديد المراوح الأربع، واضغط على الاختصار Ctrl + Shift + G لفك تجميعها، بعد ذلك حدّد الأشكال الثمانية الكبيرة الخاصة بالمراوح، وأرسِلها للخلف (Ctrl + Shift + Left Square Bracket). ركّز الآن على المروحة العلوية اليسرى، وحدّد الشكل الأكبر الذي طبّقنا عليه تأثير Feather، ثم اضغط على الاختصار Ctrl +3 لإخفائه. بعد ذلك حدّد الشكل الأكبر الآخر الخاص بهذه المروحة واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالي، ثم استبدل لون تعبئة هذا الشكل الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. حدّد الشكل الأصغر الذي طبّقنا عليه تأثير Feather في المروحة العلوية اليسرى، ثم اضغط على الاختصار Ctrl +3 لإخفائه، بعد ذلك حدّد الشكل الأصغر المتبقي الخاص بهذه المروحة، واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية، ثم استبدل لون تعبئة هذا الشكل الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. ركّز الآن على المروحة السفلية اليسرى، وحدّد الشكل الأكبر الذي طبّقنا عليه تطبيق Feather، واضغط على الاختصار Ctrl +3 لإخفائه. بعد ذلك حدّد الشكل الأكبر المتبقي الخاص بهذه المروحة، واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية، ثم استبدل لون تعبئة هذا الشكل الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. حدّد الآن الشكل الأصغر الذي طبّقنا عليه تأثير Feather الخاص بهذه المروحة واخفيه، ثم حدّد الشكل الأصغر المتبقي، مع استبدال لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية، ثم استبدل لون تعبئة هذا الشكل الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. اتبع تسلسل الصور التالية، وكرّر الخطوات السابقة نفسها لاستبدال ألوان الأشكال الرئيسية المستخدمة في المروحة السفلية اليمنى. يجب أن يبدو الدولاب الهوائي الآن كما في الشكل التالي: حدّد جميع الكائنات التي أنشأناها من بداية الخطوة رقم 2 حتى الآن، وانقر نقرًا مزدوجًا على أيقونة أداة التدوير Rotate Tool من شريط الأدوات، ثم أدخِل زاويةً مقدارها 33 درجة، وانقر على موافق. حدّد الآن الأشكال الأربعة الأصغر التي طبّقنا عليها تأثير Feather الخاصة بالمراوح، وأنشئ نسخةً منها بالضغط على Ctrl + C ثم Ctrl + F. أبقِ هذه النسخ محدَّدةً ثم افتح لوحة مستكشف المسار Pathfinder من قائمة Window ثم Pathfinder، وانقر على زر دمج Unite. حدّد الشكل الذي أنشأناه في الخطوة رقم 15، واضغط على الاختصار Ctrl +3 لإخفائه. ركّز الآن على المروحة الزرقاء وحدّد الشكل الأصغر الذي طبّقنا عليه تأثير Feather، وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة وافتح لوحة Appearance (من قائمة Window ثم Appearance)، ثم أزِل تأثير Feather. حدّد الشكل الناتج وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه وانقر على موافق. اضغط الآن على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية، وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم اخفِ هذه النسخة. أعِد تحديد الشكل الأصلي والشكل الذي طبّقنا عليه تأثير الظل Shadow في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الشكلين الصغيرين الخاصين بالمروحة الزرقاء. ركّز الآن على المروحة الخضراء، وحدّد الشكل الأصغر الذي طبّقنا عليه تأثير Feather، وأنشئ نسخةً منه، وذلك بالضغط على Ctrl + C ثم Ctrl + F. حدّد هذه النسخة وافتح لوحة Appearance من قائمة Window ثم Appearance، ثم أزِل تأثير Feather. حدّد الشكل الناتج وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه، وانقر على موافق. اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة رقم 16، ثم أنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم اخفِ هذه النسخة. أعِد تحديد الشكل الأصلي والشكل الذي طبّقنا عليه تأثير الظل Shadow في الخطوة الحالية، ثم انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، بعد ذلك اخفِ مجموعة القطع خلف الشكلين الصغيرين الخاصين بالمروحة الخضراء. ركّز الآن على المروحة الصفراء وحدّد الشكل الأصغر الذي طبّقنا عليه تأثير Feather وأنشئ نسخةً منه (بالضغط على Ctrl + C ثم Ctrl + F)، ثم حدّد هذه النسخة وأزِل تأثير Feather. حدّد الشكل الناتج وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه وانقر على موافق. اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة رقم 17، ثم حدّد هذا الشكل، واستمر في الضغط على مفتاح Shift مع النقر على الشكل الذي طبّقنا عليه تأثير الظل Shadow في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الشكلين الصغيرين الخاصين بالمروحة الصفراء. يجب أن يبدو الدولاب الهوائي الآن مثل الشكل التالي: ركّز الآن على المروحة الزرقاء، وحدّد الشكل الأكبر الذي طبّقنا عليه تأثير Feather وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). أبقِ هذه النسخة محددةً ثم افتح لوحة Appearance (من قائمة Window ثم Appearance)، وأزِل تأثير Feather. حدّد الشكل الناتج وأزِل لون تعبئته، ثم أضِف حدًا أحمر بمقدار 2 بكسل. اختر أداة إضافة نقاط ارتكاز Add Anchor Point (+)، وانقر على النقطتين المميزتين باللون الأزرق لإضافة نقطتي ارتكاز جديدتين، ثم حدّد نقطتي الارتكاز المميزتين باللون الأسود وأزِلهما. اختر الآن أداة تحويل نقاط الارتكاز Convert Anchor Point Tool (باستخدام الاختصار Shift + C)، وحدّد المقبض الأيمن لنقطة الارتكاز العلوية اليمنى واسحبه للأسفل، ثم حدّد المقبض الأيمن لنقطة الارتكاز السفلية اليمنى واسحبه للأعلى. أعِد تحديد الكائن الأحمر الذي أنشأناه في الخطوة رقم 20، ثم أزِل حدّه واملأه باللون الأزرق (# 1a28b3). حدّد الشكل الناتج وانتقل إلى قائمة تأثير Effect، ثم Blur، ثم Gaussian Blur، وأدخِل نصف قطر مقداره 10 بكسلات، ثم انقر على موافق. حدّد الآن الشكل الأكبر الذي طبّقنا عليه تأثير Feather في المروحة الزرقاء، وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام من خلال الاختصار Ctrl + Shift + Right Square Bracket. حدّد هذه النسخة واستمر في الضغط على مفتاح Shift، ثم انقر على الشكل الذي طبّقنا عليه تأثير الضبابية Blur في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع قطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الشكلين الصغيرين في المروحة الزرقاء. كرّر الخطوات السابقة نفسها لإنشاء الكائن الأسود الموضّح أدناه. أعِد تحديد هذا الشكل بعد إنشائه، ثم أزِل حدّه واملأه باللون البرتقالي (# e6480b)، ثم طبّق عليه تأثير Gaussian Blur بمقدار 10 بكسلات. حدد الآن الشكل الأكبر الذي طبّقنا عليه تأثير Feather في المروحة البرتقالية، وأنشئ نسخةً منه بالضغط على Ctrl + C ثم Ctrl + F، ثم أحضِر هذه النسخة إلى الأمام (Ctrl + Shift + Right Square Bracket). حدّد هذه النسخة واستمر في الضغط على مفتاح Shift، ثم انقر على الشكل الذي طبّقنا عليه تأثير الضبابية Blur في الخطوة الحالية. انقر بزر الفأرة الأيمن على لوحة الرسم، ثم حدّد خيار إنشاء قناع القطع Make Clipping Mask من القائمة، ثم اخفِ مجموعة القطع خلف الشكلين الصغيرين في المروحة البرتقالية. اتبع تسلسل الصور التالية، وكرّر الخطوات السابقة نفسها لإضافة ظلال إلى المروحتين المتبقيتين: لننتقل الآن إلى المروحة الصفراء. يجب أن يبدو الدولاب الهوائي الآن كما في الشكل التالي: استخدم أداة القلم (P) لإنشاء مسارين منحنيين كما هو موضّح أدناه، وأعِد تحديد هذين المسارين بعد رسمهما، وغيّر ثُخن الحدّ إلى 3 بكسلات، مع استبدال لون الحدّ الحالي باللون البرتقالي الداكن (# a53009). حدّد المسارين الناتجين، وطبّق عليهما الخيار Width Profile 5، ثم أعِد تحديد المسار السفلي، واستبدل لون الحدّ الحالي باللون الأخضر (# 2c972a). حدّد الآن المسارين اللذين أنشأناهما في الخطوة ،وطبّق عليهما تأثير Gaussian Blur بمقدار 3 بكسلات، ثم اضبط نمط المزج Blending Mode على الخيار Multiply، وقلل التعتيم Opacity إلى 40%. أخيرًا، اخفِ هذين المسارين خلف الأشكال الصغيرة في المراوح. استخدم أداة الدائرة Ellipse Tool (باستخدام الاختصار L) لإنشاء دائرة أبعادها 22×22 بكسل، ثم ضعها في الموضع الموضّح أدناه. حدّد هذه الدائرة، ثم أزِل حدّها، واملأها بالتدرج اللوني الشعاعي radial gradient الموضّح أدناه. حدّد الدائرة الناتجة وانتقل إلى قائمة تأثير Effect ثم Stylize ثم ظل ساقط Drop Shadow، واتبع البيانات الموضّحة أدناه وانقر على موافق. يجب أن يبدو الدولاب الهوائي الآن كما يلي: إنشاء الدولاب الهوائي الثاني حدّد جميع كائنات الدولاب الهوائي السابق وانتقل إلى قائمة كائن Object، ثم Transform، ثم Transform Each، واتبع البيانات الموضّحة أدناه وانقر على نسخ Copy، ثم انقل المروحة الجديدة إلى موضعٍ آخر. حدّد الأشكال الأربعة الكبيرة التي طبّقنا عليها تأثير Feather في المراوح الأربعة، واضغط على الاختصار Ctrl +2 لقفلها، ثم حدّد الأشكال الأربعة الكبيرة المتبقية، واجلبها إلى الأمام (Ctrl + Shift + Right Square Bracket). أعِد تحديد الشكل الأزرق، واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح في الشكل الثاني أدناه، ثم غيّر ألوان التعبئة الحالية للأشكال الثلاثة المتبقية كما هو موضّح في الشكل الثالث أدناه. أخيرًا، حدّد الأشكال الأربعة التي غيّرت ألوانها وأرسلها للخلف باستخدام اختصار Ctrl + Shift + Left Square Bracket. اضغط على الاختصار Ctrl + Alt +2 لفتح الأشكال الأربعة التي قفلناها في الخطوة رقم 30، ثم بدّل ألوان تعبئة هذه الأشكال الحالية كما هو موضّح أدناه. حدّد الشكل الأزرق الذي طبّقنا عليه تأثير Feather واضغط على الاختصار Ctrl +3 لإخفائه، ثم حدّد الشكل الأزرق الآخر واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه، ثم اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية. حدّد الشكل الأخضر الصغير الذي طبّقنا عليه تأثير Feather، واضغط على الاختصار Ctrl +3 لإخفائه، ثم حدّد الشكل الأخضر الصغير الآخر واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه، ثم اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية. حدّد الشكلين البرتقالي والأصفر المُطبَّق عليهما تأثير Feather، واضغط على الاختصار Ctrl +3 لإخفائهما، ثم حدّد الأشكال البرتقالية والصفراء الأخرى، واستبدل ألوان التعبئة الحالية بتدرج لوني خطي جديد كما هو موضّح أدناه، ثم اضغط على الاختصار Ctrl + Alt +3 لإظهار الأشكال التي أخفيناها في الخطوة الحالية. حدّد الأشكال الأربعة الصغيرة المُطبَّق عليها تأثير Feather، ثم استبدل ألوان التعبئة الحالية بتدرج لوني خطي جديد كما هو موضّح أدناه. اختر أداة التحديد المباشر (A)، وانقر على النقطة المميزة باللون الأحمر، مما سيؤدي إلى تحديد الشكل المُطبَّق عليه تأثير الظل Shadow في المروحة العلوية، ثم استبدل لون تعبئة الشكل المُحدَّد الحالي باللون الأخضر الداكن (# 194f00). ركّز على الشكل الثاني أدناه، وكرّر الخطوات نفسها على المراوح الثلاثة المتبقية. أخيرًا، حدّد الدائرة ذات اللون البرتقالي الداكن، واستبدل لون التعبئة الحالي بتدرج لوني شعاعي جديد كما هو موضّح أدناه. يجب أن يبدو الدولاب الهوائي الثاني مثل الشكل التالي: إنشاء الدولاب الهوائي الثالث حدّد جميع كائنات الدولاب الهوائي السابق وانتقل إلى قائمة كائن Object ثم Transform ثم Transform Each، واتبع البيانات الموضّحة أدناه وانقر على نسخ Copy، ثم انقل الدولاب الهوائي الجديد إلى موضعٍ آخر. حدّد الأشكال الأربعة الخضراء الكبيرة المُطبَّق عليها تأثير Feather الخاصة بالمراوح، واضغط على الاختصار Ctrl +2 لقفلها، ثم حدّد الأشكال الأربعة الخضراء الكبيرة المتبقية، واجلبها إلى الأمام باستخدام الاختصار Ctrl + Shift + Right Square Bracket. حدّد هذه الأشكال الأربعة واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه، ثم أعِد تحديد الأشكال الأربعة التي بدّلت ألوانها وأرسلها للخلف (Ctrl + Shift + Left Square Bracket)، ثم اضغط على الاختصار Ctrl + Alt +2 لفك قفل الأشكال الخضراء الأربعة التي قفلناها في الخطوة الحالية، ثم استبدل لون التعبئة الحالي لهذه الأشكال الخضراء الأربعة بتدرج لوني خطي جديد كما هو موضّح أدناه. حدّد الشكل الأصفر المُطبَّق عليه تأثير Feather في المروحة العلوية، واضغط على الاختصار Ctrl +3 لإخفائه، ثم حدّد الشكل الأصفر الآخر في المروحة العلوية واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه، ثم اضغط على الاختصار Ctrl + Alt +3 لإظهار الشكل الذي أخفيناه في الخطوة الحالية. حدّد الأشكال الثلاثة الصفراء المُطبَّق عليها تأثير Feather الخاصة بالمراوح الثلاثة المتبقية، واضغط على الاختصار Ctrl +3 لإخفائها، ثم استبدل ألوان تعبئة الأشكال الصفراء السفلية الثلاثة المتبقية الحالية بتدرج لوني خطي جديد. بعد ذلك اضغط على الاختصار Ctrl + Alt +3 لإظهار الأشكال التي أخفيناها في الخطوة الحالية. حدّد الشكل الأصفر العلوي، واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه، ثم حدّد الأشكال الثلاثة الصفراء المتبقية، واستبدل لون التعبئة الحالي بتدرج لوني خطي جديد كما هو موضّح أدناه. اختر أداة التحديد المباشر (A)، وانقر على النقطة المميزة باللون الأخضر، مما سيؤدي إلى تحديد الشكل المطبّق عليه تأثير الظل Shadow الخاص بالمروحة العلوية، ثم استبدل لون تعبئة الشكل المحدَّد الحالي باللون الأحمر الداكن (# 5d1020). ركّز الآن على الشكل الثاني أدناه، وكرّر الخطوات نفسها على المراوح الثلاثة المتبقية، ثم حدّد الدائرة ذات اللون الأخضر الداكن، واستبدل لون التعبئة الحالي بتدرج لوني شعاعي جديد كما هو موضّح أدناه. يجب أن يبدو الدولاب الهوائي الثالث الآن كما في الشكل الآتي. انتهينا بذلك من الدواليب الهوائية جميعها، حيث يمكنك رؤيتها جميعًا في الشكل الثاني أدناه. إنشاء عيدان الدواليب الهوائية استخدم أداة المستطيل (M) وأداة التدرج (G) لإنشاء مستطيل أبعاده 14×470 بكسل، ثم ضعه في الموضع الموضّح أدناه. حدّد هذا المستطيل وأنشئ نسخةً منه (بالضغط على الاختصار Ctrl + C ثم Ctrl + F)، ثم استبدل لون تعبئة المستطيل الحالي بالتدرج اللوني الخطي الجديد كما هو موضّح أدناه. حدّد المستطيل الناتج، ثم اضبط نمط المزج Blending Mode على الخيار Hard Light وقلّل التعتيم Opacity إلى 60%، ثم حدّد المستطيلين اللذين أنشأناهما في الخطوة الحالية، وأرسلهما للخلف باستخدام الاختصار Ctrl + Shift + Left Square Bracket. أخيرًا، حدّد وجمّع (Ctrl + G) جميع كائنات الدولاب الهوائي الأول. كرّر الخطوات السابقة نفسها لإنشاء عيدان الدواليب الهوائية المتبقية. إنشاء الخلفية استخدم أداة المستطيل (M) وأداة التدرج (G) لإنشاء مستطيل أبعاده 940×700 بكسل كما هو موضّح أدناه، ثم حدّد هذا المستطيل وانتقل إلى قائمة تأثير Effect ثم Sketch ثم Water Paper، ثم اتبع البيانات الموضّحة أدناه وانقر على موافق. حدّد المستطيل الناتج، ثم طبّق عليه تأثير Gaussian Blur بمقدار 2 بكسل. استخدم أداة الدائرة (L) لإنشاء بعض الدوائر ذات اللون الأزرق الفاتح (# b3d3f0)، ثم ضعها في المواضع الموضّحة أدناه. أعِد تحديد جميع هذه الدوائر، ثم طبّق عليها تأثير Gaussian Blur بمقدار 10 بكسلات، ثم اضبط نمط المزج Blending Mode على الخيار Hard Light وقلّل التعتيم Opacity إلى 10%. وبهذا نكون انتهينا من الخلفية، حيث يجب الآن وضع الدواليب الثلاثة في هذه الخلفية. وبذلك يكون كل شيء قد أصبح جاهزًا، وسنحصل على الشكل الآتي: ترجمة -وبتصرّف- للمقال Create the Colorful Pinwheels in Adobe Illustrator لصاحبه Bao Nguyen. اقرأ أيضًا كيفية إنشاء مصباح كهربائي في برنامج إليستريتور رسم خلفية شاطئ صيفي ببرنامج الإليستريتور كيفية رسم طائر النحام الوردي باستخدام برنامج أدوبي إليستريتور كيفية إنشاء ميزان مطبخ واقعي باستخدام إليستريتور كيفية إنشاء عربة يدوية مليئة بالرمال باستخدام إليستريتور
-
تسمح التحديدات Selections باختيار منطقة معينة من عملك الفني لتعديلها، وهذا مفيد لتحريك قسم من لوحتك أو تحويله أو الرسم فوقه دون التأثير على الأقسام الأخرى، حيث يمكنك استخدام أدوات تحديد متعددة للعمل بطرق مختلفة. تعمل معظم الأدوات ضمن تلك المنطقة بعد تحديدها، إذ يمكنك رسم أو استخدام التدرجات اللونية في هذه المنطقة للحصول بسرعة على أشكال ملونة و/أو مظلَّلة ذات حواف حادّة. لا تقتصر التحديدات في كريتا على حدود رقعة الرسم، حيث يمكنك تحديد أجزاء من لوحتك خارج حدود رقعة الرسم. إنشاء التحديدات توجد أدوات التحديد الأكثر شيوعًا في الجزء السفلي من لوحة الأدوات، حيث تحدّد كل أداة بطريقة مختلفة. table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } أداة التحديد أيقونة الأداة عملها أداة التحديد المستطيلة تحدّد شكل مربع. أداة التحديد الدائرية تحدّد شكل دائرة. أداة التحديد المضلعية انقر حيث تريد أن تكون نقاط المضلع، ثم انقر نقرًا مزدوجًا لإنهاء المضلع وإنهاء منطقة التحديد. استخدم الاختصار Shift + Z للتراجع عن النقطة السابقة. أداة التحديد بيد حرة تُستخدَم أداة التحديد بيد حرة Freehand أوأداة التحديد الحر Lasso لإجراء تحديد تقريبي عن طريق رسم مخطط التحديد يدويًا على رقعة الرسم. أداة تحديد اللون المشابه أداة تحديد اللون المشابه Similar Color Selection Tool. أداة التحديد المجاورة تحدّد أداة التحديد المجاور Contiguous أو أداة التحديد السحرية Magic Wand حقل اللون. اضبط الضبابية Fuzziness من خيارات الأداة للسماح بمزيد من التغييرات في مجال اللون، وتقتصر هذه الأداة على الطبقة الحالية افتراضيًا. أداة تحديد المسار أو اداة التحديد بمنحنى بيزييه يحدّد المسار منطقة بناءً على مسار متجه. انقر للحصول على زوايا حادّة أو اسحب للحصول على خطوط انسيابية وأغلق المسار باستخدام مفتاح Enter من لوحة المفاتيح أو من خلال الرجوع مرة أخرى إلى النقطة الأولى. أداة التحديد المغناطيسي تنشئ أداة التحديد المغناطيسي Magnetic selection تحديدًا بيد حرة حيث ينجذب التحديد إلى التباينات الحادة في الصورة. تعديل التحديدات تمنحك خيارات الأداة لكل أداة تحديد القدرة على تعديل هذا التحديد. الإجراء مفتاح التبديل الاختصار الوصف الاستبدال Replace مفتاح Ctrl مفتاح R استبدال التحديد الحالي. التقاطع Intersect الاختصار Shift + Alt - الحصول على القسم المتداخل بين تحديدين. الإضافة Add مفتاح Shift مفتاح A إضافة التحديد الجديد إلى التحديد الحالي. الطرح Subtract مفتاح Alt مفتاح S طرح التحديد من التحديد الحالي. الفرق المتماثل Symmetric Difference - - يعطي التحديد التي يمثل مكان عدم تداخل التحديد الجديد مع التحديد الحالي. ويمكنك تغييرها من إعدادات الأدوات Tools Settings. إذا مرّرت الفأرة فوق تحديد باستخدام أداة التحديد دون تنشيطه، فيمكنك تحريك هذا التحديد. كما يمكنك الانتقال بسرعة إلى وضع التحويل من خلال النقر بزر الفأرة الأيمن ثم اختيار تعديل التحديد Edit Selection. إزالة التحديدات إذا أردت حذف التحديد بالكامل، فإن أسهل طريقة هي إلغاء تحديد كل شيء من خلال الانتقال إلى قائمة تحديد Select ثم أزِل التحديد Deselect، أو من خلال الضغط على الاختصار Ctrl + Shift + A. إذا كانت إحدى أدوات التحديد نشطة وكان وضع التحديد في حالة تقاطع أو استبدال أو فرق متماثل، فيمكنك إلغاء التحديد بمجرد النقر بزر الفأرة الأيسر في أي مكان على رقعة الرسم. أوضاع عرض التحديد يوجد زر في الزاوية اليسرى السفلية من شريط الحالة وظيفته تبديل كيفية عرض التحديد، التي لها وضعان هما: (مسير Marching) النمل Ants والقناع Mask. يمكن تغيير اللون الأحمر مع القناع من التفضيلات Preferences، إذ يمكنك تعديل اللون من قائمة إعدادات Settings ثم ضبط كريتا Configure Krita ثم العرض Display ثم Selection Overlay، وإن لم يكن هناك تحديد، فلن يفعل هذا الزر أي شيء. يُعَد وضع عرض النمل (الوضع الافتراضي كما في الشكل السابق) الأفضل، إذا أردت رؤية المناطق غير المُحدَّدة. يُعَد وضع عرض القناع الموضَّح في الشكل السابق مناسبًا لرؤية مستويات شفافية التحديد المختلفة مثل التحديد الذي لديه حواف ناعمة جدًا بسبب استخدام ميزة تنعيم الحواف Feathering. لكن يمكن تنشيط وضع القناع في إصدار كريتا 4.2 عندما يكون قناع التحديد هو الطبقة النشطة لتتمكّن من رؤية مستويات التحديد المختلفة. قناع التحديد العام Global Selection Mask (طلاء تحديد) قناع التحديد العام Global Selection Mask هو التحديد الذي يظهر على لوحة الطبقات Layers. يكون قناع التحديد العام مخفيًا افتراضيًا، لذلك ستحتاج إلى جعله مرئيًا من قائمة تحديد Select ثم إظهار قناع التحديد العام Show Global Selection Mask. يجب إنشاء تحديد بعد إظهار قناع التحديد العام، وفائدة استخدام ذلك هو أنه يمكنك الرسم على التحديد باستخدام أيِّ من أدوات الرسم العادية، بما في ذلك التحويل والتحريك، وتُحفَظ المعلومات كتدرج رمادي Grayscale. يمكنك الانتقال إلى وضع قناع التحديد العام بسرعة من أدوات التحديد عن طريق النقر بزر الفأرة الأيمن وتحديد خيار تعديل التحديد Edit Selection. التحديد من طبقة شفافية يمكنك إنشاء تحديد بناءً على شفافية الطبقة عن طريق النقر بزر الفأرة الأيمن على الطبقة في لوحة طبقات ثم تحديد الخيار تحديد المنطقة العاتمة Select Opaque من قائمة السياق. كما يمكنك في إصدار كريتا 4.2 تطبيق ذلك مع خيارات الإضافة والطرح والتقاطع بالانتقال إلى قائمة تحديد Select ثم Select Opaque، حيث يمكنك العثور على إجراءات محددة لكل منها. إذا أردت تحديد أجزاء من الطبقات بسرعة، فيمكنك الاستمرار في الضغط على مفتاح Ctrl مع النقر بزر الفأرة الأيسر على صورة الطبقة المصغَّرة Layer thumbnail. كما يمكنك إضافة تحديد من خلال الضغط على الاختصار Ctrl + Shift مع النقر على زر الفأرة الأيسر، واستخدم الاختصار Ctrl + Alt مع النقر على زر الفأرة الأيسر لإزالة تحديد، واستخدم الاختصار Ctrl + Shift + Alt مع زر الفأرة الأيسر لتطبيق التقاطع. تعمل جميع هذه الاختصارات مع أيّ قناع يحتوي على بيانات مؤلفة من بكسلات أو متجهات باستثناء أقنعة التحويل. أنواع تحديد البكسلات والمتجهات تسمح التحديدات المتجهة بتعديل تحديدك من خلال أدوات الارتكاز المتجهة Vector anchor tools، بينما تسمح تحديدات البكسلات بتعديل التحديدات باستخدام معلومات البكسلات. لكل نوع من هذين التحديدين فوائده وعيوبه، ويمكنك تحويل أحد هذين النوعين إلى النوع الآخر. يمكنك تحديد نوع التحديد الذي أنشأته من خيار الوضع Mode في خيارات أداة التحديد، حيث يمكنك إما اختيار نوع البكسلات Pixel أو النوع المتجهي Vector، ولكن يكون الخيار الافتراضي هو Vector. يمكن تعديل التحديدات المتجهة -مثل أيّ شكل متجه آخر- باستخدام أداة تحديد الشكل Shape Selection Tool. إن حاولت الرسم على قناع تحديد متجهي، فسيتحوّل إلى تحديد بكسلات. كما يمكنك تحويل الأشكال المتجهة إلى تحديد، ولكن يمكن إنشاء تحديدات متجهة من الأشكال المتجهة، ويمكن تحويل الأشكال المتجهة إلى تحديدات متجهة باستخدام الخيارات الموجودة في قائمة تحديد Selection، حيث سيضيف كريتا طبقةً متجهةً جديدةً لهذا الشكل. أحد الأسباب الأكثر شيوعًا لاستخدام التحديدات المتجهة هو أنها تمنحك القدرة على تحريك وتحويل تحديد دون الحاجة إلى أدوات تغيير الحجم التي تحصل عليها من خلال استخدام تحديد البكسلات. كما يمكنك استخدام أداة تعديل الشكل Shape Edit Tool لتغيير نقاط الارتكاز في التحديد، مما يتيح ضبط منحنيات بيزييه بدقة أو إضافة زوايا إلى التحديدات المستطيلة. إذا بدأت باستخدام تحديد بكسلات، فلا يزال بإمكانك تحويله إلى تحديد متجهي للحصول على هذه الفوائد من خلال الانتقال إلى قائمة تحديد Select ثم تحويل إلى تحديد متجهي Convert to Vector Selection. الاختصارات الشائعة أثناء استخدام التحديدات إليك الاختصارات الشائعة التي تسهل عليك عملية التحديد: نسخ: Ctrl + C أو Ctrl + Ins. لصق: Ctrl + V أو Shift + Ins. قص: Ctrl + X أو Shift + Del. نسخ من جميع الطبقات: Ctrl + Shift + C. نسخ التحديد إلى طبقة جديدة: Ctrl + Alt + J. قص التحديد إلى طبقة جديدة: Ctrl + Shift + J. عرض أو إخفاء تحديد: Ctrl + H. تحديد المنطقة العاتمة: Ctrl مع النقر بزر الفأرة الأيسر على صورة الطبقة المُصغَّرة. تحديد المنطقة العاتمة Select Opaque (إضافة): Ctrl + Shift مع النقر بزر الفأرة الأيسر على صورة الطبقة المُصغَّرة. تحديد المنطقة العاتمة (طرح): Ctrl + Alt مع النقر بزر الفأرة الأيسر على صورة الطبقة المُصغَّرة. تحديد المنطقة العاتمة (تقاطع): Ctrl + Shift + Alt مع النقر بزر الفأرة الأيسر على صورة الطبقة المُصغَّرة. ترجمة -وبتصرّف- للمقال Selections من موقع Krita. اقرأ أيضًا المقال السابق: دليل الطبقات والأقنعة في كريتا المفاهيم الأساسية لكريتا النسخة الكاملة من كتاب: أساسيات تصميم الرسوميات
-
يدعم كريتا الطبقات التي تساعد على التحكم في أجزاء وعناصر رسوماتك بطريقة أفضل، إذ تشبه الطبقات Layers إلى حدٍ ما الأوراق المكدَّسة فوق بعضها البعض بحيث تظهِر بعض الأوراق ما تحتها بينما يخفي البعض الآخر ما تحته. إذا أردت استبدال عنصر في عملك الفني، فيمكنك استبدال تلك الورقة بدلًا من رسم كل شيء مرة أخرى، حيث تعمل الطبقات بالآلية نفسها. تُعَد الطبقات جزءًا من المستند، وقد تكون شفافة أو غير شفافة، وتكون أصغر أو أكبر من المستند نفسه، ويمكنها ترتيبها فوق بعضها البعض وتسميتها وتجميعها. تمنحك الطبقات تحكمًا أفضل في عملك الفني، حيث يمكنك إعادة تلوينه من خلال العمل على طبقة ألوان منفصلة فقط على سبيل المثال، وبالتالي عدم إتلاف الرسوم الخطية التي توجد فوق طبقة الألوان هذه. يمكنك تعديل طبقات مفردة وإضافة تأثيرات خاصة إليها مثل أنماط الطبقة Layer styles وأوضاع المزج Blending modes والشفافية Transparency والمرشّحات Filters والتحويلات Transforms. يضع كريتا كل هذه الطبقات مع التأثيرات الخاصة المطبَّقة عليها في مكدس طبقاته، ثم يجمعها معًا لتشكيل الصورة النهائية، وهذه مجرد طريقة من بين طرق معالجة الصور الرقمية المتعددة التي يمتلكها كريتا. إذا وضعتَ طبقة طلاء Paint layer فوق طبقة أخرى، فستكون طبقة الطلاء العلوية مرئية بالكامل، بينما تكون الطبقة التي تحتها إما محجوبة أو مغلقة أو مرئية جزئيًا. إدارة الطبقات يفضل بعض الرسامين الرسم على عدد محدود من الطبقات، بينما يفضّل البعض الآخر أن يضع عناصر عمله الفني المختلفة على طبقات منفصلة. يمتلك كريتا بعض الميزات التي تسهّل مهمة إدارة الطبقات، إذ يمكنك تجميع الطبقات وتنظيم عناصر عملك الفني. كما يمكن تغيير ترتيب الطبقات أو نقلها داخل وخارج مجموعةٍ في مكدس الطبقات عن طريق الضغط عليها ثم سحبها وإفلاتها، ويمكن نسخ الطبقات بين المستندات في وضع النافذة الفرعية Subwindow mode عن طريق سحب هذه الطبقة وإفلاتها من مستند إلى آخر. توفّر هذه الميزات الوقت وتساعد الرسامين على تسهيل فهم مكدّس طبقات الملف للأشخاص الآخرين الذين يعملون على الملف نفسه. كما يمكن تمييز هذه الطبقات والمجموعات وتصنيفها حسب الألوان، مما يساعد الرسامين على التمييز بينها بالنظر فقط. يمكنك تخصيص لصاقة لونية لطبقة أو لمجموعة طبقات من خلال الضغط بزر الفأرة الأيمن على الطبقة واختيار أحد الألوان المحدَّدة من قائمة السياق، ويمكنك إزالتها من خلال النقر على المربع "x" المحدَّد في قائمة السياق. ويمكنك تصنيف الطبقات التي لها لصاقة لونية متشابهة من خلال النقر على لون واحد أو أكثر في القائمة الموجودة في الزاوية العلوية اليمنى من لوحة الطبقات. جديد في الإصدار رقم 5.0: يمكنك استخدام هذه القائمة لتصنيف الطبقات حسب اسمها أنواع الطبقات يوضّح الشكل السابق أنواع الطبقات المختلفة، فلكل نوع طبقة غرضٌ مختلف، حيث يمكن على سبيل المثال وضع جميع العناصر المتجهية على طبقة متجهية Vector elements، كما تكون العناصر النقطية Raster العادية على طبقة الطلاء Paint layer. كيفية تراكب الطبقات في كريتا تشكّل الطبقات المرئية في كريتا صورة مركبة تظهر على رقعة الرسم، حيث تُرتَّب هذه الطبقات من الأسفل إلى الأعلى مثل كومة من الأوراق، فإن أضفتَ مزيدًا من الطبقات، فستتغير الصورة التي نراها وفقًا لخصائص الطبقات المضافَة في الأعلى. تتراكب طبقات المجموعة بطريقة منفصلة عن الطبقات الأخرى في المكدّس، إلّا عند تنشيط وضع التمرير. تشكّل الطبقات الموجودة ضمن المجموعة أحد مركبات الصورة أولًا، ثم يُستخدَم هذا المركب أثناء تركيب مكدّس الطبقات لتشكيل صورة كاملة. إذا فعّلتَ وضع التمرير عن طريق الضغط على أيقونة مشابهة للجدار المكسور، فستُعَدّ طبقات المجموعة كما لو أنها خارج تلك المجموعة في مكدس الطبقات، ولكن يعتمد ظهور الطبقات في مجموعة على ظهور هذه المجموعة. للمجموعات الموجودة في ملف PSD المحفوظ في برنامج الفوتوشوب وضع تمرير افتراضي إن لم تُضبَط على أوضاع مزج أخرى. طبقات توريث ألفا Inherit Alpha أو طبقات القطع Clipping توجد ميزة قطع في كريتا تسمى توريث ألفا Inherit Alpha، ويُشار إليها برمز ألفا في مكدس الطبقات. تقتصر بكسلات الطبقة التي ترسم عليها على منطقة البكسلات المشتركة لجميع الطبقات الموجودة أسفلها بعد النقر على رمز توريث ألفا في مكدّس الطبقات، فإذا كانت الطبقة الأولى لديك هي طبقة الخلفية البيضاء الافتراضية، فسيبدو أن النقر على رمز توريث ألفا والرسم على أيّ طبقة فوقها دون أيّ تأثير، حيث ستمتلئ رقعة الرسم بأكملها باللون الأبيض، لذلك يُنصَح بوضع الطبقة الأساسية التي تريد أن تقطع البكسلات فيها ضمن طبقة مجموعة. تتراكب طبقات المجموعة بطريقة منفصلة كما ذكرنا سابقًا، وبالتالي تكون الطبقة الدنيا في المجموعة الطبقةَ المحيطة، ويُقطَع محتوى الطبقات الموجودة أعلى هذه الطبقة إذا جرى تفعيل خيار توريث ألفا. كما يمكنك تفعيل توريث ألفا لطبقة مجموعة. الأقنعة Masks والمرشحات Filters يدعم كريتا التعديل غير المدمّر Non-destructive editing لمحتوى الطبقة، فالتعديل غير المدمّر هو تعديل أو تغيير طبقة أو صورة دون تغيير صورة المصدر الأصلية تغييرًا دائمًا، حيث تُضاف التغييرات فقط بوصفها مرشّحات Filters أو أقنعة Masks على الصورة الأصلية مع الحفاظ على هذه الصورة سليمة دون تغيير، وهذا يساعد كثيرًا عندما يتطلب سير العمل ذهابًا وإيابًا متواصلًا، إذ يمكنك العودة إلى الصورة الأصلية بنقرة واحدة، فما عليك سوى إخفاء المرشّح أو القناع المطبَّق على صورتك الأولية. يمكنك إضافة مرشّحات متعددة إلى طبقة باستخدام قناع مرشّح Filter mask، أو إضافة طبقة مرشّح تؤثر على الصورة بأكملها. كما يمكن تحويل الطبقات تحويلًا غير مدمر باستخدام أقنعة التحويل Transformation masks، بل ويمكن إخفاء أجزاء منها مؤقتًا باستخدام قناع شفاف Transparent Mask. تُعَد هذه التأثيرات غير المدمرة مفيدة للغاية إذا غيّرت رأيك لاحقًا، أو إذا احتجت إنشاء مجموعة من نسخٍ مختلفة لصورة معينة. يمكن الوصول إلى هذه المرشّحات والأقنعة من خلال النقر بزر الفأرة الأيمن كما هو موضّح في الشكل الآتي، أو من خلال النقر على إشارة زائد في لوحة الطبقات. كما يمكنك إضافة مرشّح بوصفه قناعًا من نافذة المرشح نفسه من خلال النقر على زر أنشئ قناع ترشيح Create Filter Mask. يمكن تطبيق جميع المرشّحات والأقنعة على مجموعة أيضًا، مما يسهّل تعديل طبقات متعددة تعديلًا غير مدمر دفعةً واحدة. ترجمة -وبتصرّف- للمقال Introduction to Layers and Masks من موقع Krita. اقرأ أيضًا المقال السابق: حفظ الملفات والحفظ التلقائي والنسخ الاحتياطي في كريتا المفاهيم الأساسية لكريتا النسخة الكاملة من كتاب: أساسيات تصميم الرسوميات
-
تُستخدَم لغة معالجة البيانات Data Manipulation Language -أو DML اختصارًا- الخاصة بلغة SQL للاستعلام عن البيانات في قاعدة البيانات وتعديلها، وسنشرح في هذا المقال كيفية استخدام تعليمات أوامر لغة SQL DML والتي هي SELECT وINSERT وUPDATE، وDELETE المُعرَّفة كما يلي: SELECT: للاستعلام عن بيانات في قاعدة البيانات. INSERT: لإدخال بيانات في جدول. UPDATE: لتحديث بيانات في جدول. DELETE: لحذف بيانات من جدول. في تعليمة SQL DML: يجب بدأ كل شرط في عبارة بسطر جديد. يجب انتظام بداية كل شرط مع بداية الشروط الأخرى. إذا تألّف شرط من عدة أجزاء، فيجب توضُّع هذه الأجزاء على سطور منفصلة، كما يجب إضافة مسافة بادئة لها تحت بداية الشرط لإظهار العلاقة. تُستخدَم الأحرف الكبيرة لتمثيل الكلمات المحجوزة. تُستخدَم الحروف الصغيرة لتمثيل الكلمات التي يُعرِّفها المستخدِم. تعليمة SELECT تسمح التعليمة أو الأمر SELECT للمستخدِم باستخراج البيانات من الجداول، بناءً على معايير محدَّدة، حيث تُعالَج وفقًا للتسلسل التالي: SELECT DISTINCT اختيار عنصر أو مجموعة عناصر. FROM من جدول أو مجموعة جداول. WHERE يليها تعبير شرطي. GROUP BY يليها حقل أو مجموعة حقول. ORDER BY يليها مجموعة حقول. يمكننا استخدام تعليمة SELECT لإنشاء قائمة بهواتف الموظفين من جدول الموظفين Employees كما يلي: SELECT FirstName, LastName, phone FROM Employees ORDER BY LastName سيعرض هذا الإجراء اسم عائلة last name الموظف، واسمه الأول first name، ورقم هاتفه phone number من جدول الموظفين Employees كما في الجدول التالي: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } Last Name First Name Phone Number Hagans Jim 604-232-3232 Wong Bruce 604-244-2322 سنستخدم في المثال التالي جدول الناشرين Publishers table الذي يمثِّله الجدول الآتي، حيث ستلاحظ أنّ كندا Canada مكتوبة بطريقة خاطئة في حقل بلد الناشر Publisher Country المقابل لحقل اسم الناشر Example Publishing، ومدينة الناشر ABC Publishing. استخدم تعليمة UPDATE لتصحيح الأخطاء وتوحيد حقل البلد ليصبح Canada، -كما سنتكلم لاحقًا عن تعليمة UPDATE في هذا المقال. Publisher Name Publisher City Publisher Province Publisher Country Acme Publishing Vancouver BC Canada Example Publishing Edmonton AB Cnada ABC Publishing Toronto ON Canda إذا أضفتَ اسم الناشر Publisher Name، ومدينة الناشر Publisher City، فستستخدِم تعليمة SELECT، ويتبعها اسم الحقول التي يُفصَل بينها بفاصلة أجنبية comma، أي كما يلي: SELECT PubName, city FROM Publishers سيؤدي هذا الإجراء إلى عرض اسم الناشر ومدينته من جدول الناشرين. إذا أردت عرض حقل اسم الناشر باسم حقل المدينة -أي تبديل اسم الحقل PubName ليصبح city-، فاستخدِم تعليمة SELECT مع عدم وضع فاصلة أجنبية بين Pub_Name وcity، أي كما يلي: SELECT PubName city FROM Publishers سيعرض تنفيذ هذا الإجراء فقط الحقل PUB_NAME من جدول الناشرين، بحيث يكون له العنوان city. يفترض SQL Server أنك تريد وضع اسم عمود جديد للحقل PUB_NAME إذا لم تضمّن الفاصلة الأجنبية. تعليمة SELECT مع معيار WHERE قد ترغب أحيانًا في التركيز على جزء من جدول الناشرين، مثل الناشرين الموجودين في مدينة فانكوفر Vancouver فقط، إذ ستستخدم في هذه الحالة عبارة SELECT مع معيار WHERE، أي كما يلي: 'WHERE city = 'Vancouver. يوضِّح المثالان الأوليّان التاليان كيفية تحديد اختيار سجل مع المعيار WHERE باستخدام BETWEEN، إذ يعطي كل من هذين المثالَين نتائج تخزين العناصر نفسها التي عددها بين 20 و50 عنصر في المخزن. يستخدم المثال رقم 1 الكمية التي قيمتها بين 20 و50 عنصر مع تضمين العنصرين 20 و50 بالصورة التالية: qty BETWEEN 20 and 50. SELECT StorID, qty, TitleID FROM Sales WHERE qty BETWEEN 20 and 50 يستخدِم المثال رقم 2 الشرط qty >=20 and qty <=50. SELECT StorID, qty, TitleID FROM Sales WHERE qty >= 20 and qty <= 50 يوضِّح المثال رقم 3 كيفية تحديد اختيار سجل مع المعيار WHERE باستخدام NOT BETWEEN. SELECT StorID, qty, TitleID FROM Sales WHERE qty NOT BETWEEN 20 and 50 يظهر المثالان التاليان طريقتَين مختلفتَين لتحديد اختيار سجل مع المعيار WHERE باستخدام IN مع النتائج نفسها. يوضح المثال رقم 4 كيفية اختيار السجلات باستخدام حقل المقاطعة province من جدول Publishers -أي =province- على أساس جزء من تعليمة WHERE. SELECT * FROM Publishers WHERE province = 'BC' OR province = 'AB' OR province = 'ON' يوضِّح المثال رقم 5 كيفية اختيار السجلات باستخدام المقاطعة province مع IN على أساس جزء من تعليمة WHERE: SELECT * FROM Publishers WHERE province IN (‘BC’, ‘AB’, ‘ON’) يوضِّح المثالان الأخيران كيف يمكن استخدام NULL وNOT NULL لتحديد السجلات، ولكن سنستخدم في هذين المثالين جدول الكتب Books table الغير موضَّح هنا، والذي يحتوي على حقول، وهي: العنوان Title، والكمية Quantity، وسعر الكتاب Price، وكل ناشر لديه جدول كتب يعطي قائمةً بجميع كتب الناشر. يستخدِم المثال رقم 6 القيمة NULL: SELECT price, title FROM Books WHERE price IS NULL يستخدِم المثال رقم 7 القيمة NOT NULL: SELECT price, title FROM Books WHERE price IS NOT NULL استخدام محارف البدل wildcards في شرط LIKE يحدِّد الشرط LIKE الصفوف التي تحتوي على الحقول التي تطابق أجزاءً محددة من سلاسل محرفية، كما يُستخدَم LIKE مع البيانات التي من النوع char وvarchar وtext وdatetime وsmalldatetime. يسمح محرف البدل wildcard للمستخدِم بمطابقة الحقول التي تحتوي على محارف معينة، حيث سيعطي محرف البدل '%province = 'N جميع المقاطعات التي تبدأ بالمحرف N. يوضِّح الجدول التالي أربعة طرق لتحديد محارف البدل في تعليمة SELECT في صيغة التعبير المنتظم: محرف البدل wildcard نتيجة استخدامه % يمثل أيّ سلسلة تتألف من صفر أو أكثر من المحارف _ يمثل أيّ محرف واحد [ ] يمثل أيّ محرف واحد ضمن مجال محدد مثل المجال [a-f]، أو مجموعة محدَّدة مثل المجموعة [abcdef] [^] يمثل أي محرف واحد ليس ضمن مجال محدد مثل المجال [a - f^]، أو مجموعة محدَّدة مثل المجموعة [abcdef^] تبحث التعليمة '%LIKE 'Mc في المثال رقم 1 عن جميع أسماء العائلة last names التي تبدأ بالمحرفين Mc مثل McBadden: SELECT LastName FROM Employees WHERE LastName LIKE 'Mc%' تبحث التعليمة 'LIKE '%inger في المثال رقم 2 عن جميع أسماء العائلة التي تنتهي بالمحارف inger، مثل Ringer وStringer: SELECT LastName FROM Employees WHERE LastName LIKE '%inger' تبحث التعليمة '%LIKE '%en عن جميع أسماء العائلة التي تحتوي على المحرفين en، مثل Bennett وGreen وMcBadden: SELECT LastName FROM Employees WHERE LastName LIKE '%en%' تعليمة SELECT مع الشرط ORDER BY يُستخدَم الشرط ORDER BY لترتيب السجلات في القائمة الناتجة، ويمكنك استخدام ASC لترتيب النتائج تصاعديًا، وDESC لترتيب النتائج تنازليًا. يستخدِم المثال التالي ASC: SELECT * FROM Employees ORDER BY HireDate ASC يستخدم المثال التالي DESC: SELECT * FROM Books ORDER BY type, price DESC تعليمة SELECT مع الشرط GROUP BY يُستخدَم الشرط GROUP BY لإنشاء خرج هو عبارة عن صف واحد لكل مجموعة، وينتج قيمًا موجِزةً للأعمدة المحدَّدة، كما هو موضَّح أدناه: SELECT type FROM Books GROUP BY type يستخدم المثال التالي التعليمة السابقة: SELECT type AS 'Type', MIN(price) AS 'Minimum Price' FROM Books WHERE royalty > 10 GROUP BY type إذا تضمنت تعليمة SELECT معيار WHERE ليكون السعر price قيمةً غير فارغة not null كما يلي: SELECT type, price FROM Books WHERE price is not null فستكون التعليمة التي تحتوي على شرط GROUP BY كما يلي: SELECT type AS 'Type', MIN(price) AS 'Minimum Price' FROM Books WHERE price is not null GROUP BY type استخدام COUNT مع GROUP BY يمكننا استخدام COUNT لإحصاء عدد العناصر الموجودة في حاوية container، ولكن إذا أردت حساب عدد عناصر مختلفة في مجموعات منفصلة مثل رخام ذي ألوان مختلفة، فسنستخدِم دالة COUNT مع الأمر GROUP BY. توضح تعليمة SELECT أدناه كيفية حساب عدد مجموعات من البيانات باستخدام دالة COUNT مع الشرط أو الأمر GROUP BY: SELECT COUNT(*) FROM Books GROUP BY type استخدام AVG وSUM مع GROUP BY يمكننا استخدام دالة AVG لتعطينا متوسط أي مجموعة، وتُستخدَم الدالة SUM لإعطاء المجموع. يستخدِم المثال رقم 1 التالي دالة AVG مع الشرط GROUP BY type: SELECT AVG(qty) FROM Books GROUP BY type يستخدِم المثال رقم 2 التالي دالة SUM مع الشرط GROUP BY type: SELECT SUM(qty) FROM Books GROUP BY type يستخدِم المثال رقم 3 كلًا من الدالتين AVG، وSUM مع الشرط GROUP BY type في تعليمة SELECT: SELECT 'Total Sales' = SUM(qty), 'Average Sales' = AVG(qty), stor_id FROM Sales GROUP BY StorID ORDER BY 'Total Sales' تقييد الصفوف مع HAVING يمكن استخدام الشرط HAVING لتقييد الصفوف، فهو يشبه شرط WHERE باستثناء أنه يتضمّن دالة تجميع aggregate function؛ إذ لا يستطيع الشرط WHERE فعل ذلك، أي يتصرّف الشرط HAVING مثل الشرط WHERE، ولكنه قابل للتطبيق على المجموعات. نستخدم في هذا المثال الشرط HAVING لاستبعاد المجموعات التي مقاطعتها 'BC'. SELECT au_fname AS 'Author"s First Name', province as 'Province' FROM Authors GROUP BY au_fname, province HAVING province <> 'BC' تعليمة INSERT تضيف تعليمة INSERT صفوفًا إلى جدول، وأيضًا ما يلي: تحدِّد تعليمة INSERT الجدول أو العرض view التي ستُدخَل البيانات فيه. تعرض Column List قائمةً بالأعمدة التي ستتأثر بتعليمة INSERT. يجب توفير كل قيمة إذا حُذِف عمود. يمكن وضع الأعمدة في قائمة ضمن أي ترتيب إذا ضمّنتها. تحدِّد الكلمة VALUES البيانات التي تريد إدخالها في الجدول، وتكون VALUES إلزامية). يجب عدم إدراج الأعمدة ذات الخاصية IDENTITY بصورة صريحة في column_list أو value_sclause. صيغة تعليمة INSERT هي: INSERT [INTO] Table_name | view name [column_list] DEFAULT VALUES | values_list | select statement تُطبَّق القواعد التالية عند إدخال صفوف باستخدام تعليمة INSERT: يؤدي إدخال سلسلة فارغة (' ') في عمود من النوع varchar، أو text إلى إدخال مسافة واحدة. تُحشَى جميع الأعمدة ذات النوع char على اليمين right-padded حتى تصل إلى الطول المحدد. تُزال جميع المسافات الزائدة من البيانات المدرجة في أعمدة من النوع varchar، باستثناء السلاسل التي تحتوي على مسافات فقط، إذ تُختصَر هذه السلاسل إلى مسافة واحدة فقط. إذا أخلَّت تعليمة INSERT بالقيد، أو الافتراض، أو القاعدة، أو إذا كان نوع البيانات خاطئًا، فستفشل هذه التعليمة، وسيعرض خادم SQL Server رسالة خطأ. يمكن حدوث أحد الأشياء الثلاثة التالية للأعمدة التي لا تحتوي على قيم عند تحديد قيم بعض الأعمدة في column_list فقط: تُدخَل قيمة افتراضية إذا كان للعمود قيد DEFAULT، أو إذا كان الافتراض مرتبط بالعمود، أو إذا كان الافتراض مرتبط بنوع البيانات التي يعرِّفها المستخدم. تُدخَل القيمة الفارغة NULL إذا سمح العمود بالقيم الفارغة، ولا توجد قيمة افتراضية موجودة للعمود. تُعرَض رسالة خطأ ويُرفَض الصف إذا عُرَِف العمود بأنه غير فارغ NOT NULL، ولا توجد قيمة افتراضية. يستخدِم المثال التالي تعليمة INSERT لإضافة سجل إلى جدول الكتّاب Authors: INSERT INTO Authors VALUES('555-093-467', 'Martin', 'April', '281 555-5673', '816 Market St.,' , 'Vancouver', 'BC', 'V7G3P4', 0) يوضِّح المثال التالي كيفية إدخال صف جزئي partial row في جدول الناشرِين Publishers مع قائمة أعمدة. يملك عمود الدولة country قيمة افتراضية هي Canada، لذلك لا يلزمك تضمينه في قيمك. INSERT INTO Publishers (PubID, PubName, city, province) VALUES ('9900', 'Acme Publishing', 'Vancouver', 'BC') اتبع المثال التالي لإدخال صفوف في جدول مع عمود IDENTITY، ولا تعطي قيمةً للعمود IDENTITY، ولا قيمةً لاسم العمود ضمن قائمة الأعمدة. INSERT INTO jobs VALUES ('DBA', 100, 175) إدخال قيم محددة ضمن عمود IDENTITY لا يمكن إدخال البيانات مباشرة في عمود IDENTITY افتراضيًا، ولكن إذا حُذِف صف خطأً، أو إذا كانت هناك ثغرات في قيم عمود IDENTITY، فيمكنك إدخال صف وتحديد قيمة العمود IDENTITY. IDENTITY_INSERT option يمكن استخدام خيار IDENTITY_INSERT على النحو التالي للسماح بإدخال قيمة هوية identity محدَّدة: SET IDENTITY_INSERT jobs ON INSERT INTO jobs (job_id, job_desc, min_lvl, max_lvl) VALUES (19, 'DBA2', 100, 175) SET IDENTITY_INSERT jobs OFF إدخال صفوف باستخدام عبارة SELECT يمكننا أحيانًا إنشاء جدول مؤقت صغير من جدول كبير، لذلك يمكننا إدخال صفوف مع تعليمة SELECT. لا يوجد تحقق لصحة التفرد uniqueness عند استخدام هذا الأمر، وبالتالي، قد يكون هناك العديد من الصفوف بالمعرّف pub_id نفسه في المثال التالي. ينشِئ هذا المثال جدول ناشرِين Publishers مؤقت هو tmpPublishers أصغر باستخدام تعليمة إنشاء جدول CREATE TABLE، ثم تُستخدَم تعليمة INSERT مع تعليمة SELECT لإضافة سجلات إلى جدول الناشرِين المؤقت من جدول الناشرين Publishers. CREATE TABLE dbo.tmpPublishers ( PubID char (4) NOT NULL , PubName varchar (40) NULL , city varchar (20) NULL , province char (2) NULL , country varchar (30) NULL DEFAULT ('Canada') ) INSERT tmpPublishers SELECT * FROM Publishers ننسخ في هذا المثال مجموعةً فرعيةً من البيانات: INSERT tmpPublishers (pub_id, pub_name) SELECT PubID, PubName FROM Publishers تُنسَخ بيانات الناشرين في هذا المثال إلى جدول tmpPublishers ويُضبَط عمود الدولة country إلى القيمة Canada: INSERT tmpPublishers (PubID, PubName, city, province, country) SELECT PubID, PubName, city, province, ‘Canada’ FROM Publishers تعليمة UPDATE تغيّر تعليمة UPDATE البيانات في الصفوف الموجودة إما بإضافة بيانات جديدة أو بتعديل البيانات الموجودة. يستخدِم المثال التالي تعليمة UPDATE لتوحيد حقل الدولة country ليكون Canada لجميع السجلات في جدول Publishers: UPDATE Publishers SET country = 'Canada' يزيد المثال التالي مبالغ حقوق المؤلف royalty التي قيمتها بين 10 و20 بنسبة 10%: UPDATE roysched SET royalty = royalty + (royalty * .10) WHERE royalty BETWEEN 10 and 20 تضمين استعلامات فرعية subqueries ضمن عبارة UPDATE يُمنَح الموظفون في جدول الموظفين Employees الذين وظّفهم الناشر في عام 2010 ترقيةً إلى أعلى مستوى وظيفي حسب نوع عملهم كما يلي: UPDATE Employees SET job_lvl = (SELECT max_lvl FROM jobs WHERE employee.job_id = jobs.job_id) WHERE DATEPART(year, employee.hire_date) = 2010 تعليمة DELETE تزيل تعليمة DELETE صفوفًا من مجموعة سجلات، كما تحدِّد عبارة DELETE الجدول أو العرض view الذي يحوي الصفوف التي ستُحذَف، ويمكن إدراج جدول أو صف واحد فقط في الوقت نفسه. يُعَدّ الشرط WHERE المعيار الذي يحدِّد السجلات المراد حذفها، وتكون صيغة تعليمة DELETE كما يلي: DELETE [FROM] {table_name | view_name } [WHERE clause] قواعد تعليمة DELETE هي: إذا حُذِف شرط WHERE فستُزال جميع الصفوف الموجودة في الجدول باستثناء الفهارس indexes، والجدول، والقيود. لا يمكن استخدام عبارة DELETE بعرض view يحتوي على شرط FROM يسمّي أكثر من جدول واحد، فتعليمة DELETE يمكن أن تؤثر على جدول أساسي فقط في الوقت نفسه. فيما يلي ثلاث تعليمات DELETE مختلفة يمكن استخدامها: حذف جميع الصفوف من جدول: DELETE FROM Discounts حذف صفوف محدَّدة: DELETE FROM Sales WHERE stor_id = '6380' حذف صفوف بناءً على قيمة ضمن استعلام فرعي: DELETE FROM Sales WHERE title_id IN (SELECT title_id FROM Books WHERE type = 'mod_cook') الدوال المبنية مسبقا Built-in Functions يوجد العديد من الدوال المبنية مسبقًا في SQL Server، مثل: دوال التجميع Aggregate: ترجع قيمًا موجِزة summary values. دوال التحويل Conversion: تحوِّل نوع بيانات معين إلى نوع آخر. دوال التاريخ Date: تعرض معلومات عن التواريخ والأوقات. الدوال الرياضية Mathematical: تجري عمليات على البيانات العددية. الدوال المتعلِّقة بالسلاسل String: تجري عمليات على سلاسل المحارف، أو البيانات الثنائية، أو التعابير. الدوال المتعلِّقة بالنظام System: ترجع معلومات من قاعدة البيانات. الدوال المتعلِّقة بالنصوص Text، والصور image: تجري عمليات على بيانات نصية، أو على بيانات الصور. سنشرح أدناه الدوال الأربع الأولى شرحًا مفصَّلًا مع أمثلة عنها. دوال التجميع Aggregate functions تجري دوال التجميع حسابات على مجموعة من القيم، وترجع قيمةً واحدةً أو قيمةً موجِزةً. يعرض الجدول التالي هذه الدوال: الدالة FUNCTION وصفها AVG ترجع متوسط average جميع القيم، أو القيم المميزة DISTINCT فقط، ضمن التعبير COUNT ترجع عدد القيم غير الفارغة في التعبير، وإذا استخدِم التمايز DISTINCT فستجد الدالة COUNT عدد القيم غير الفارغة الفريدة (*)COUNT ترجع عدد الصفوف، ولا تأخذ الدالة (*)COUNT معاملات، كما لا يمكن استخدام التمايز DISTINCT معها MAX ترجع القيمة العليا في التعبير، ويمكن استخدام الدالة Max مع الأعمدة ذات النوع العددي، والمحرفي، والأعمدة ذات النوع datetime، ولكنها لا تُستخدَم مع الأعمدة ذات النوع bit، كما تعطي الدالة MAX مع الأعمدة المحرفية أعلى قيمة في تسلسل مرتَّب، وتتجاهل هذه الدالة القيم الفارغة MIN ترجع القيمة الدنيا في التعبير. يمكن استخدام الدالة MIN مع أعمدة عددية، ومحرفية، وذات النوع datetime، ولكنها لا تُستخدَم مع أعمدة لها النوع bit، كما تعطي الدالة MIN مع الأعمدة المحرفية أعلى قيمة في تسلسل مرتَّب، وتتجاهل هذه الدالة القيم الفارغة SUM ترجع مجموع كل القيم، أو فقط القيم المميزة DISTINCT في التعبير، ويمكن استخدام الدالة SUM مع الأعمدة العددية فقط سنعرض فيما يلي أمثلةً عن كل من دوال التجميع الموجودة في الجدول السابق. المثال الأول: الدالة AVG SELECT AVG (price) AS 'Average Title Price' FROM Books المثال الثاني: الدالة COUNT SELECT COUNT(PubID) AS 'Number of Publishers' FROM Publishers المثال الثالث: الدالة COUNT SELECT COUNT(province) AS 'Number of Publishers' FROM Publishers المثال الرابع: الدالة (*) COUNT SELECT COUNT(*) FROM Employees WHERE job_lvl = 35 المثال الخامس: الدالة MAX SELECT MAX (HireDate) FROM Employees المثال السادس: الدالة MIN SELECT MIN (price) FROM Books المثال السابع: الدالة SUM SELECT SUM(discount) AS 'Total Discounts' FROM Discounts دالة التحويل Conversion function تحوّل دالة التحويل نوع بيانات معين إلى نوع بيانات آخر. يُحوَّل السعر price الذي يحتوي ضمنه على تسعتين 99 إلى خمسة محارف في المثال الآتي، حيث تكون صيغة التعليمة بالصورة التالية: SELECT 'The date is ' + CONVERT(varchar(12), getdate()) إليك مثال: SELECT CONVERT(int, 10.6496) SELECT title_id, price FROM Books WHERE CONVERT(char(5), price) LIKE '%99%' مثال آخر عن تغيِّر دالة التحويل في المثال التالي البيانات إلى نوع بيانات بحجم مختلف: SELECT title_id, CONVERT(char(4), ytd_sales) as 'Sales' FROM Books WHERE type LIKE '%cook' دالة التاريخ Date function تُنتج دالة التاريخ تاريخًا عن طريق إضافة فاصل زمني إلى تاريخ محدَّد، والنتيجة هي قيمة لها نوع datetime، وتساوي التاريخ مضافًا إليه عدد أجزاء التاريخ date parts. إذا كان معامل دالة التاريخ قيمةً من النوع smalldatetime، فستكون النتيجة قيمةً من النوع smalldatetime أيضًا. تُستخدَم الدالة DATEADD لإضافة وزيادة قيم التاريخ، وصيغة هذه الدالة هي: (DATEADD(datepart, number, date. SELECT DATEADD(day, 3, hire_date) FROM Employees يستخدِم المثال الآتي الدالة (DATEDIFF(datepart, date1, date2، ويعيد هذا الأمر عدد أجزاء التاريخ أو الحدود boundaries المتقاطعة بين تاريخَين محددين. تجعل طريقة حساب الحدود المتقاطعة النتيجة التي أعطتها الدالة DATEDIFF متوافقة مع جميع أنواع البيانات، مثل الدقائق، والثواني، والميلي ثانية. SELECT DATEDIFF(day, HireDate, 'Nov 30 1995') FROM Employees يمكننا فحص أي جزء من تاريخ معيَّن من السنة إلى الميلي ثانية. يعرض الجدول التالي أجزاء التاريخ DATEPART، واختصاراتها، وقيمها المقبولة التي يعترف بها خادم SQL Server. جزء التاريخ DATE PART اختصاره ABBREVIATION قيمه VALUES Year yy 1753-9999 Quarter qq 1-4 Month mm 1-12 Day of year dy 1-366 Day dd 1-31 Week wk 1-53 Weekday dw 1-7 (Sun.-Sat.) Hour hh 0-23 Minute mi 0-59 Second ss 0-59 Millisecond ms 0-999 الدوال الرياضية Mathematical functions تجري الدوال الرياضية عمليات على البيانات العددية، ويعرض المثال التالي السعر الحالي لكل كتاب يبيعه الناشر، كما يعرض ما سيكون عليه الأمر إذا ارتفعت جميع الأسعار بنسبة 10%: SELECT Price, (price * 1.1) AS 'New Price', title FROM Books SELECT 'Square Root' = SQRT(81) SELECT 'Rounded' = ROUND(4567.9876,2) SELECT FLOOR (123.45) ربط الجداول Joining Tables يُعَدّ ربط جدولين أو أكثر مثل عملية موازنة بيانات ضمن أعمدة محدَّدة، واستخدام نتائج الموازنة لتشكيل جدول جديد من الصفوف المؤهلة لذلك. تقوم عبارة الربط join بما يلي: تحدِّد عمودًا من كل جدول. توازن القيم الموجودة في تلك الأعمدة صفًا صفًا. تدمج الصفوف ذات القيم المؤهلة ضمن صف جديد. تكون الموازنة عادةً مساواةً -أي القيم التي تتطابق مع بعضها البعض تمامًا-، ولكن يمكن تحديد أنواع ربط أخرى أيضًا. سنشرح جميع أنواع الربط المختلفة أدناه، مثل: الربط الداخلي inner، واليساري (الخارجي)، واليميني (الخارجي)، والربط المتقاطع cross join (التام). الربط الداخلي Inner join يربط جدولين في عمود له نفس نوع البيانات، وينتج الصفوف التي تتطابق فيها قيم العمود فقط، حيث يجري تجاهل الصفوف التي لا مثيل لها. المثال الأول: SELECT jobs.job_id, job_desc FROM jobs INNER JOIN Employees ON emp loyee.job_id = jobs.job_id WHERE jobs.job_id < 7 المثال الثاني: SELECT authors.au_fname, authors.au_lname, books.royalty, title FROM authorsINNER JOIN titleauthor ON authors.au_id=titleauthor.au_id INNER JOIN books ON titleauthor.title_id=books.title_id GROUP BY authors.au_lname, authors.au_fname, title, title.royalty ORDER BY authors.au_lname الربط اليساري الخارجي Left outer join ينتج عن الربط الخارجي اليساري كل الصفوف الخارجية اليسرى، إذ تُضمَّن جميع الصفوف من الجدول الأيسر التي لا تحقّق الشرط المحدّد في مجموعة النتائج، وتُضبَط أعمدة الخرج من الجدول الآخر على القيمة الفارغة NULL. يستخدِم المثال التالي الصيغة الجديدة للربط اليساري الخارجي: SELECT publishers.pub_name, books.title FROM Publishers LEFT OUTER JOIN Books On publishers.pub_id = books.pub_id بينما يستخدِم المثال التالي الصيغة القديمة للربط الخارجي اليساري: SELECT publishers.pub_name, books.title FROM Publishers, Books WHERE publishers.pub_id *= books.pub_id الربط الخارجي الأيمن Right outer join يتضّمن الربط الخارجي الأيمن في مجموعة النتائج الخاصة به كافة الصفوف من الجدول الأيمن التي لا تحقّق الشرط المحدّد، وتُضبَط أعمدة الخرج المقابلة من الجدول الآخر على القيمة الفارغة NULL. يستخدِم المثال التالي الصيغة الجديدة للربط الخارجي الأيمن: SELECT titleauthor.title_id, authors.au_lname, authors.au_fname FROM titleauthor RIGHT OUTER JOIN authors ON titleauthor.au_id = authors.au_id ORDERY BY au_lname بينما يوضِّح المثال التالي الصيغة القديمة المستخدَمة للربط الخارجي الأيمن: SELECT titleauthor.title_id, authors.au_lname, authors.au_fname FROM titleauthor, authors WHERE titleauthor.au_id =* authors.au_id ORDERY BY au_lname الربط الخارجي الكامل Full outer join يحدِّد الربط الخارجي الكامل أنه في حالة عدم تطابق صف من أي من الجدولين مع معايير التحديد، فسيُضمَّن الصف في مجموعة النتائج، وتُضبَط أعمدة الخرج الخاصة به التي تتوافق مع الجدول الآخر إلى القيمة الفارغة NULL. فيما يلي مثال عن ربط خارجي كامل: SELECT books.title, publishers.pub_name, publishers.province FROM Publishers FULL OUTER JOIN Books ON books.pub_id = publishers.pub_id WHERE (publishers.province <> "BC" and publishers.province <> "ON") ORDER BY books.title_id الربط المتقاطع Cross join الربط المتقاطع هو ناتج دمج جدولين، وينتج عن هذا الربط صفوف حالة عدم استخدام الشرط WHERE نفسها، أي كما يلي: SELECT au_lname, pub_name, FROM Authors CROSS JOIN Publishers للمزيد من المعلومات، انظر توثيق SQL في موسوعة حسوب. ترجمة -وبتصرّف- للمقال SQL Data Manipulation Language لصاحبَيه Adrienne Watt و Nelson Eng. اقرأ أيضًا المقال التالي: أمثلة عملية عن كيفية تصميم قواعد البيانات المقال السابق: نظرة سريعة على لغة الاستعلامات الهيكلية SQL الاعتماديات الوظيفية المستخدمة في تصميم قواعد البيانات قواعد السلامة وقيودها لضمان سلامة البيانات في قواعد البيانات الاستعلامات الفرعية والإجراءات في SQL البحث والتنقيب والترشيح في SQL معالجة الأخطاء والتعديل على قواعد البيانات في SQL النسخة العربية الكاملة لكتاب تصميم قواعد البيانات
-
لقد اعتُمدت الإنترنت منذ نشأتها على أساس نموذج نظيف، تكون فيه الموجّهات routers داخل الشبكة مسؤولةً عن تمرير الرزم من المصدر إلى الوجهة، وتُشغَّل البرامج التطبيقية على الأجهزة المضيفة المتصلة بأطراف الشبكة. يلتزم نموذج العميل / الخادم الموضح في التطبيقات التي ناقشناها سابقًا على هذا النموذج، لكن أصبح التمييز بين تمرير الرزم ومعالجة التطبيقات أقل وضوحًا في السنوات القليلة الماضية، حيث توزَّع التطبيقات الجديدة عبر الإنترنت، وفي كثيرٍ من الحالات تتخذ هذه التطبيقات قرارات التمرير الخاصة بها. يمكن أحيانًا تنفيذ هذه التطبيقات الهجينة الجديدة من خلال توسيع الموجّهات والمبدّلات التقليدية لدعم قدرٍ صغيرٍ من المعالجة الخاصة بالتطبيقات، حيث يتواجد مثلًا ما يسمى بمبدّلات المستوى 7 أمام عناقيد الخادم server clusters، وتمرر طلبات HTTP إلى خادمٍ معين بناءً على عنوان URL المطلوب، وتظهر شبكات التراكب overlay networks بسرعةٍ مثل آليةٍ مختارةٍ لإدخال وظائف جديدةٍ إلى الإنترنت. يمكنك التفكير في التراكب على أنه شبكةٌ منطقيةٌ مُطبَّقةٌ فوق بعض الشبكات الأساسية، فقد بدأت الإنترنت من خلال هذا التعريف مثل شبكة تراكبٍ على الروابط التي توفرها شبكة الهاتف القديمة. يوضح الشكل السابق تراكبًا مطبَّقًا على شبكةٍ أساسية، وكل عقدة في شبكة التراكب موجودةٌ أيضًا في الشبكة الأساسية؛ أي أن هذا التراكب يعالج ويمرر الرزم بطريقةٍ خاصةٍ بالتطبيق. تُنفَّذ الروابط التي تربط عقد التراكب مثل أنفاق tunnels عبر الشبكة الأساسية، ويمكن أن توجد شبكات تراكبٍ متعددةٍ على نفس الشبكة الأساسية، فتطبّق كل منها سلوكها الخاص بالتطبيق، ويمكن أن تتداخل التراكبات، أي تراكبٌ فوق الآخر، وتُعامِل جميعُ أمثلة شبكات التراكب التي نُوقشت في هذا القسم الإنترنت اليوم على أنه الشبكة الأساسية. رأينا بالفعل أمثلةً عن إنشاء أنفاقٍ لتنفيذ الشبكات الوهمية الخاصة VPN، حيث تعامِل العقدُ الموجودة على طرفي النفق المسارَ متعدد القفزات بينها مثل رابطٍ منطقي واحد، ولا تدركُ العقد الممرَّرة عبر نفقٍ باستخدام رزم التمرير المستندة على الترويسة الخارجية أن العقد النهائية قد أرفَقت ترويسةً داخليةً. يوضح الشكل السابق ثلاث عقد تراكب (A وB وC) متصلةً بواسطة زوجٍ من الأنفاق. قد تتخذ عقدة التراكب B في هذا المثال قرارًا بتمرير الرزم من العقدة A إلى العقدة C استنادًا إلى الترويسة الداخلية IHdr، ثم ترفِق ترويسةً خارجية OHdr تحدّد العقدة C على أنها وِجهةٌ في الشبكة الأساسية. يمكن للعقد A وB وC تفسير كلٍّ من الترويسة الداخلية والخارجية، بينما لا تفهم الموجّهات الوسيطة سوى الترويسة الخارجية، وتكون للعقد A وB وC عناوينٌ في كلٍ من شبكة التراكب والشبكة الأساسية، ولكنها ليست عناوينًا متطابقةً بالضرورة؛ فقد يكون العنوان الأساسي هو عنوان IP مؤلَّفٌ من 32 بتًا، بينما قد يكون عنوان التراكب عنوانًا تجريبيًا مؤلفًّا من 128 بتًا. لا تحتاج شبكة التراكب إلى استخدام عناوينٍ تقليديةٍ على الإطلاق، ولكنها قد توجِّه بناءً على عناوين URL، أو أسماء النطاق أو استعلامات XML، أو حتى محتوى الرزمة. توجيه شبكة التراكب أبسط نوعٍ من التراكب هو الذي يوجد فقط لدعم استراتيجية توجيهٍ بديلة؛ حيث تُجرَى معالجةٌ إضافيةٌ على مستوى التطبيق في عُقد التراكب، حيث يمكنك استخدام شبكةٍ وهميةٍ خاصة VPN بمثابة مثالٍ عن توجيه شبكات التراكب، ولكن لا يحدد هذا المثال الكثير لاستراتيجيةٍ أو خوارزميةٍ بديلة، لأنه يدخل مدخلات جدول توجيهٍ بديلة لتُعالَج بواسطة خوارزمية تمرير IP القياسية، حيث يُقال في هذه الحالة بالذات أن التراكب يستخدم أنفاق IP، وتُدعمَ القدرة على استخدام شبكات VPN هذه في العديد من الموجّهات التجارية. لنفترض أنك أردت استخدام خوارزمية توجيه لم يرغب مصنّعو الموجّهات التجارية في تضمينها في منتجاتهم. إذًا ماذا ستفعل؟ يمكنك ببساطةٍ تشغيل الخوارزمية الخاصة بك على مجموعةٍ من المضيفين النهائيين، وتشغيل النفق عبر موجّهات الإنترنت، حيث سيتصرّف هؤلاء المضيفون مثل موجهاتٍ في شبكة التراكب، أي مثل مضيفين متصلين بالإنترنت، من خلال رابطٍ فيزيائيٍ واحدٍ فقط، ويتصرفون مثل عقدةٍ في التراكب، ويُوصلون بالعديد من الجيران عبر الأنفاق. تُعَد التراكبات وسيلةٌ لإدخال تقنياتٍ جديدةٍ مستقلةٍ عن المعايير الأساسية، فلا توجد تراكباتٌ معياريةٌ يمكننا الإشارة إليها على أنها أمثلة، لذلك سنوضح الفكرة العامة لتوجيه التراكبات من خلال وصف العديد من الأنظمة التجريبية التي أنشأها باحثو الشبكات. إصدارات تجريبية من بروتوكول IP تُعَد التراكبات مثاليةً لنشر إصدارات تجريبية من بروتوكول IP التي تأمل أن تسيطر على العالم في النهاية، حيث بدأ بث IP المتعدد على سبيل المثال مثل إضافةٍ لبروتوكول IP، ولكن لم يُفعَّل في العديد من موجهات الإنترنت حتى اليوم، كما كانت شبكة MBone شبكة العمود الفقري متعدد البث multicast backbone عبارةً عن شبكة تراكب طبّقت بروتوكول IP متعدد البث على التوجيه أحادي البث الذي يوفره الإنترنت. وقد طُوِّرت أدوات المؤتمرات متعددة الوسائط ونُشِرت على شبكة Mbone، حيث بُثَّت اجتماعات منظمة IETF التي تستغرق أسبوعًا وتجذب الآلاف من المشاركين لسنواتٍ عديدة عبر شبكة MBone على سبيل المثال، ولكن حلّ التوافر الواسع لأدوات المؤتمرات التجارية محل النهج القائم على شبكة MBone. استخدمت شبكة MBone مثل شبكات VPN كلًا من أنفاق وعناوين IP، ولكنها طبّقت خوارزمية تمريرٍ مختلفةٍ عن تلك المستخدمة في شبكات VPN، حيث استخدمت تمرير الرزم إلى جميع الأجهزة الموجودة تحتها في المسار الأقصر لشجرة البث المتعدد. تمر الموجهات ذات البث المتعدد عبر نفقٍ من الموجهات القديمة مثل تراكب overlay، على أمل ألا تكون هناك يومًا ما موجهاتٌ قديمة. كانت شبكة 6-BONE شبكة تراكبٍ مشابهة، واُستخدِمت لنشر الإصدار IPv6 تدريجيًا، حيث استخدمت شبكةُ 6-BONE، مثل شبكة MBone، الأنفاقَ لتمرير الرزم عبر موجّهات IPv4، لكن لم تقدّم عقد شبكة 6-BONE تفسيرًا جديدًا لعناوين IPv4 المؤلفة من 32 بتًا على عكس شبكة MBone، حيث مررت العقد الرزم بناءً على حيز عناوين IPv6 ذات 128 بتًا، ودعمت شبكة 6-BONE أيضًا بث IPv6 المتعدد. بث النظام النهائي المتعدد End System Multicast بث بروتوكول IP المتعدد شائعٌ بين الباحثين وقطاعات معينة من مجتمع الشبكات، إلا أن نشره في الإنترنت العالمي كان محدودًا. لذلك تحوّلت التطبيقات القائمة على البث المتعدد مثل مؤتمرات الفيديو مؤخرًا إلى استراتيجيةٍ بديلةٍ، هي بث النظام النهائي المتعدد، حيث تتمثل فكرة هذه الاستراتيجية في قبول أن البث المتعدد لبروتوكول IP لن يصبح موجودًا في كل مكانٍ مطلقًا، ولذلك يُسمَح للمضيفين النهائيين المشاركين في تطبيقٍ معينٍ قائمٍ على البث المتعدد بتطبيق أشجار البث المتعدد الخاصة بهم. يجب أن نفهم أولًا أن بث النظام النهائي المتعدد، على عكس شبكات VPN وMBone، يفترض مشاركة مضيفي الإنترنت فقط دون موجهات الإنترنت في التراكب، ويتبادل هؤلاء المضيفون الرسائل مع بعضهم بعضًا من خلال أنفاق UDP، بدلًا من أنفاق IP، مما يسهّل تنفيذها مثل برامج تطبيقاتٍ عادية، ويؤدي إلى إمكانية عرض الشبكة الأساسية مثل رسمٍ بيانيٍ متصلٍ بالكامل، حيث أن كل مضيف في الإنترنت قادرٌ على إرسال رسالةٍ إلى كل مضيفٍ آخر. إذًا، يحل بث النظام النهائي المتعدد مشكلة العثور على شجرة البث المتعدد المضمَّنة التي تمتد عبر جميع أعضاء المجموعة، بدءًا من رسمٍ بيانيٍ متصلٍ بالكامل يمثّل الإنترنت. لاحظ أن هناك نسخةً أبسط من هذه المشكلة من خلال التوافر الجاهز للآلات الافتراضية VM المستضافة على السحابة حول العالم، حيث يمكن أن تعمل الأنظمة النهائية ذات البث المتعدد آلاتٍ افتراضيةٍ في مواقعٍ متعددة؛ هذه المواقع معروفةٌ جيدًا وثابتةٌ نسبيًا، لذلك يمكن إنشاء شجرةٍ ثابتةٍ متعددة البث في السحابة، ويمكن جعل المضيفين النهائيين الفعليين يتصلون ببساطةٍ بأقرب موقعٍ سحابي. بما أننا نفترض أن شبكة الإنترنت الأساسية متصلةٌ بصورةٍ كاملة، فإن الحل البسيط هو أن يكون كل مصدر متصلًا مباشرةً بكل عضوٍ في المجموعة، أي يمكن تطبيق بث النظام النهائي المتعدد من خلال إرسال كل عقدةٍ رسائل أحادية البث إلى كل عضوٍ في المجموعة. ضع في حساباتك مثال مخطط الشبكة الموضح في الشكل السابق لفهم المشكلة، حيث أن الموجهَين R1 وR2 متصلان باستخدام رابط عابرٍ للقارات بحيز نطاقٍ تراسلي منخفض، والمضيفات A وB وC وD هي مضيفاتٌ نهائية وتأخيرات الروابط مُعطاةٌ مثل أوزانٍ للأضلاع. بافتراض أن المضيف A أراد إرسال رسالةٍ متعددة البث إلى المضيفين الثلاثة الآخرين مثلما يوضح الشكل السابق كيف سيعمل البث الأحادي البسيط، لكنه غير مرغوبٍ لأن نفس الرسالة يجب أن تعبر الرابط بين المضيف A والموجّه R1 ثلاث مرات، وتعبر نسختان من الرسالة الرابط بين الموجه R1 والموجه R2. يوضح الشكل السابق أيضًا شجرة بث IP المتعدد التي أنشأها بروتوكول التوجيه متعدد البث لمُتجّه المسافات Distance Vector Multicast Routing Protocol -أو اختصارًا DVMRP. يلغي هذا الأسلوب الرسائل الزائدة، لكن بدون دعمٍ من الموجهات، فإن أفضل ما يمكن تتمناه من بث النظام النهائي المتعدد هو شجرةٌ مشابهةٌ لتلك الموضحة في الشكل السابق، حيث يحدد بث النظام النهائي المتعدد معماريةً لإنشاء هذه الشجرة. يتمثل النهج العام في دعم مستوياتٍ متعددةٍ من شبكات التراكب، حيث يَستخرج كلٌ منها رسمًا بيانيًا فرعيًا من التراكب الموجود أسفله، حتى نختار الرسم البياني الفرعي الذي يتوقعه التطبيق. يحدث هذا على مرحلتين بالنسبة إلى بث النظام النهائي المتعدد، هما: إنشاء تراكبٍ شبكيٍ بسيط على شبكة الإنترنت المتصلة بالكامل. اختيار شجرةٍ متعددة البث داخل هذه الشبكة. يوضح الشكل السابق هذه الفكرة، بافتراض وجود المضيفين النهائيين الأربعة A وB وC وD. بمجرد اختيار شبكة تراكب شبكة مناسبة، نشغّل خوارزميةَ توجيه البث المتعدد القياسية مثل بروتوكول DVMRP فوقها لبناء شجرة البث المتعدد. يمكننا أيضًا تجاهل مشكلة قابلية التوسع التي يواجهها البث المتعدد على مستوى الإنترنت، حيث يمكن تحديد الشبكة الوسيطة لتضمين فقط العقد التي ترغب في المشاركة في مجموعة بثٍ متعدد معينة. إن مفتاح إنشاء شبكة تراكبٍ وسيطة هو تحديد مخطط شبكةٍ متوافق تقريبًا مع مخطط شبكة الإنترنت الأساسي، ولكن يجب علينا فعل ذلك دون أن نعلم بما يبدو عليه الإنترنت الأساسي في الواقع، نظرًا لأننا نعمل فقط على المضيفين النهائيين وليس على الموجّهات. تتمثل الإستراتيجية العامة للمضيفين النهائيين في قياس زمن الانتقال ذهابًا وإيابًا إلى العقد الأخرى واتخاذ قرار إضافة روابطٍ إلى الشبكة فقط عندما تكون الأمور جيدةً، حيث يحصل ذلك على النحو التالي: أولًا، افترض وجود شبكةٍ بالفعل، حيث تتبادل كل عقدةٍ قائمةً list بجميع العقد الأخرى التي تعتقد أنها جزءٌ من الشبكة مع جيرانها المتصلين مباشرةً. إذا تلقّت العقدة قائمةَ العضوية من أحد الجيران، فإنها تدمج تلك المعلومات في قائمة العضوية الخاصة بها وتمرر القائمة الناتجة إلى جيرانها. تنتشر هذه المعلومات في النهاية عبر الشبكة، كما هو الحال في بروتوكول توجيه متجه المسافات. إذا أراد مضيفٌ الانضمام إلى شبكة تراكب البث المتعدد، فيجب أن يعرف عنوان IP لعقدةٍ أخرى على الأقل موجودةٍ بالفعل في شبكة التراكب، ثم يرسل رسالة الانضمام إلى الشبكة join mesh إلى هذه العقدة، وهذا يربط العقدة الجديدة بالشبكة عن طريق ضلعٍ إلى العقدة المعروفة. قد ترسل العقدة الجديدة رسالة انضمامٍ إلى عقدٍ حالية متعددة، وبالتالي تنضم إلى الشبكة عن طريق روابطٍ متعددة، وترسل العقدة الجديدة دوريًا رسائل أنها لا زالت نشطة keepalive إلى جيرانها بمجرد توصيلها بالشبكة من خلال مجموعةٍ من الروابط، لإعلام جيرانها بأنها لا تزال تريد أن تكون جزءًا من المجموعة. ترسل العقدة التي تغادر المجموعة رسالة ترك الشبكة leave mesh إلى جيرانها المتصلين مباشرةً، وتُنشَر هذه المعلومات إلى العقد الأخرى في الشبكة عبر قائمة العضوية الموضحة أعلاه. يمكن أن تفشل العقدة أو تقرر ترك المجموعة بصمت، وفي هذه الحالة يكتشف جيرانها أنها لم تَعُد ترسل رسائل keepalive. بعض حالات مغادرة العقدة لها تأثيرٌ ضئيلٌ على الشبكة، ولكن إذا اكتشفت العقدة أن الشبكة أصبحت مقسَّمةً بسبب مغادرة عقدةٍ ما، فإنها تنشئ ضلعًا جديدًا إلى عقدةٍ في القسم الآخر بإرسال رسالة انضمام إلى الشبكة. لاحظ أنه يمكن للجيران المتعددين أن يقرروا في نفس الوقت حدوث تقسيمٍ في الشبكة، مما يؤدي إلى إضافة أضلاعٍ متعددة إلى الأقسام المتقاطعة من الشبكة. ستتشكّل في النهاية شبكةٌ تمثل رسمًا فرعيًا من شبكة الإنترنت الأصلية المتصلة بالكامل، ولكن قد يكون لها أداءٌ دون المستوى الأمثل للأسباب الأربعة التالية: اختيار الجار الأولي يضيف روابطًا عشوائيةً إلى مخطط الشبكة. قد يضيف إصلاح التقسيم أضلاعًا أساسيةً في الوقت الحالي، ولكنها ليست مفيدةً على المدى الطويل. قد تتغير عضوية المجموعة بسبب عمليات الانضمام والمغادرة الديناميكية. قد تتغير ظروف الشبكة الأساسية. ما يجب أن يحدث هو أن يقيّم النظام قيمة كل ضلع، مما يؤدي إلى إضافة أضلاعٍ جديدة إلى الشبكة وإزالة الأضلاع الموجودة بمرور الوقت. لإضافة أضلاعٍ جديدة، تتحقق كل عقدةٍ i دوريًا من بعض الأعضاء العشوائية j التي لا تتصل بها حاليًا في الشبكة، وتقيس زمن انتقال الأضلاع ذهابًا وإيابًا (i,j)، ثم تقيّم فائدة إضافة هذا الضلع، حيث يُضاف الرابط (i,j) إلى الشبكة إذا كانت الفائدة أعلى من حدٍ معين. يكون تقييم فائدة إضافة الضلع (i,j) على النحو التالي: EvaluateUtility(j) utility = 0 for each member m not equal to i CL = current latency to node m along route through mesh NL = new latency to node m along mesh if edge (i,j) is added} if (NL < CL) then utility += (CL - NL)/CL return utility قرار إزالة ضلعٍ مماثلٌ لإضافة ضلع باستثناء أن كل عقدة i تحسب تكلفة كل رابطٍ إلى الجار الحالي j على النحو التالي: EvaluateCost(j) Cost[i,j] = number of members for which i uses j as next hop Cost[j,i] = number of members for which j uses i as next hop return max(Cost[i,j], Cost[j,i]) ثم تختار العقدة الجار ذا التكلفة الأقل، وتلغيه إذا انخفضت التكلفة إلى ما دون حدٍ معين. أخيرًا، بما أن الحفاظ على الشبكة يحدث باستخدام بروتوكول متجه مسافة، فلا يُعَد تشغيل بروتوكول DVMRP للعثور على شجرة البث المتعدد المناسبة في الشبكة أمرًا مفيدًا. لاحظ أنه ليس من الممكن إثبات أن البروتوكول الموصوف للتو ينتج عن شبكةٍ مثلى، مما يسمح لبروتوكول DVMRP بتحديد أفضل شجرةٍ متعددة البث ممكنة، لكن تشير كلٌ من المحاكاة والخبرة العملية الواسعة إلى أنها تعمل جيدًا. شبكات التراكب المرنة Resilient Overlay Networks يمكن أن يؤدي التراكب وظيفةً أخرى وهي إيجاد طرقٍ بديلة لتطبيقات البث الأحادي التقليدية، حيث تستغل هذه التراكباتُ الملاحَظةَ التي تفيد بأن عدم المساواة في المثلث لا ينطبق على شبكة الإنترنت. يوضح الشكل الآتي ما نعنيه بذلك، فليس غريبًا العثور على ثلاثة مواقعٍ على الإنترنت A وB وC، بحيث يكون زمن الانتقال بين الموقعين A وB أكبرُ من مجموع فترات الانتقال من الموقع A إلى الموقع C، ومن الموقع C إلى الموقع B؛ أي يُفضَّل في بعض الأحيان إرسال الرزم الخاصة بك بصورةٍ غير مباشرة عبر عقدةٍ وسيطةٍ بدلًا من إرسالها مباشرةً إلى الوِجهة. لكن كيف يمكن أن يحدث هذا؟ لم يَعِد بروتوكول البوابة الحدودية Border Gateway Protocol -أو اختصارًا BGP- أبدًا بأنه سيجد أقصر مسارٍ بين أي موقعين، فهو يحاول فقط إيجاد مسارٍ ما. تتأثر مسارات بروتوكول BGP بشدة بأمور السياسات policy، مثل سياسة من يدفع لمن ينقل حركة المرور. يحدث هذا غالبًا عند نقاط التناظر بين مزودي خدمة الإنترنت الأساسيين، فلا ينبغي أن يكون عدم وجود مساواة بمثلثٍ في شبكة الإنترنت أمرًا مفاجئًا. كيف نستغل هذه الملاحظة؟ تتمثل الخطوة الأولى في إدراك أن هناك مقايضةً أساسيةً بين قابلية التوسع والأمثلية لخوارزمية التوجيه. ويتوسّع نطاق بروتوكول BGP لشبكات كبيرة جدًا، ولكنه غالبًا لا يختار أفضل مسارٍ ممكن ويكون بطيئًا في التكيف مع انقطاعات الشبكة؛ فإذا كنت قلقًا فقط بشأن العثور على أفضل مسارٍ بين عددٍ قليلٍ من المواقع، فيمكنك التوجّه إلى عملٍ أفضل بكثير من مراقبة جودة كل مسار قد تستخدمه، مما يتيح لك تحديد أفضل مسارٍ ممكنٍ في أي لحظة. أدّى تراكبٌ تجريبي يُسمى شبكة التراكب المرنة Resilient Overlay Network -أو اختصارًا RON- ذلك بالضبط، حيث توسّعت شبكة RON إلى بضع عشراتٍ فقط من العقد، وذلك لأنها استخدمت استراتيجية N × N لمراقبة ثلاثة جوانبٍ لجودة المسار عن كثب عبر بحثٍ نشطٍ بين كل زوجٍ من المواقع، وهذه الجوانب الثلاثة هي: زمن الانتقال latency، وحيز النطاق التراسلي bandwidth المتاح، واحتمالية الخسارة loss probability. أصبحت شبكة RON بعد ذلك قادرةً على تحديد المسار الأمثل بين أي زوجٍ من العقد، وتغيير المسارات بسرعةٍ في حالة تغير ظروف الشبكة، فقد أظهرت التجربة أن شبكة RON كانت قادرةً على تقديم تحسيناتٍ متواضعة في الأداء للتطبيقات، ولكن الأهم من ذلك أنها تعافت من أعطال الشبكة بسرعةٍ أكبر. اكتشَف مثيلٌ لشبكة RON يعمل على 12 عقدةً 32 انقطاعًا استمر لأكثر من 30 دقيقةً خلال فترةٍ واحدةٍ مدتها 64 ساعةً في عام 2001 على سبيل المثال، وتمكَّن من التعافي منها جميعًا في أقل من 20 ثانيةً وسطيًا. اقترحت هذه التجربة أيضًا أن تمرير البيانات من خلال عقدةٍ وسيطةٍ واحدةٍ فقط يكون كافيًا عادةً للتعافي من حالات فشل الإنترنت. بما أن شبكة RON غير مصمَّمةٍ لتكون نهجًا قابلًا للتوسّع، فلا يمكن استخدامها لمساعدة المضيف العشوائي A على التواصل مع المضيف العشوائي B؛ أي يجب أن يعرف المضيفان A وB مسبقًا أنه من المُحتمَل أن يتواصلا، ثم ينضما إلى نفس شبكة RON. تُعَد شبكة RON فكرةً جيدةً في إعداداتٍ معينة، مثل توصيل بضع عشراتٍ من مواقع الشركات المنتشرة عبر الإنترنت أو السماح لك أنت و50 صديقٍ من أصدقائك بإنشاء شبكة تراكبٍ خاصة بك من أجل تشغيل بعض التطبيقات، حيث تطبَّق هذه الفكرة اليوم مع الاسم التسويقي Software-Defined WAN -أو اختصارًا SD-WAN-، لكن السؤال الحقيقي هو ماذا يحدث عندما يبدأ الجميع في تشغيل شبكة RON الخاصة بهم؟ وهل يؤدي حمل الملايين من شبكات RON التي تستكشف المسارات بقوة إلى إغراق الشبكة؟ وهل يرى أي شخصٍ تحسّن السلوك عندما تتنافس عدة شبكات RON على نفس المسارات؟ لا تزال هذه الأسئلة دون إجابة. توضِّح كل هذه التراكبات مفهومًا أساسيًا لشبكات الحاسوب هو الافتراضية virtualization، أي يمكن بناء شبكةٍ افتراضية من موارد مجردة أو منطقية على شبكةٍ فيزيائيةٍ مبنيةٍ من موارد فيزيائية أيضًا. يمكن تكديس هذه الشبكات الافتراضية فوق بعضها بعضًا، كما ويمكن أن تتعايش شبكاتٌ افتراضيةٌ متعددةٌ على نفس المستوى، حيث توفر كل شبكةٍ افتراضيةٍ بدورها إمكاناتٍ جديدة ذات قيمة لمجموعةٍ معينةٍ من المستخدمين، أو التطبيقات، أو الشبكات ذات المستوى الأعلى. ترجمة -وبتصرّف- للقسم Overlay Networks من فصل Applications من كتاب Computer Networks: A Systems Approach. اقرأ أيضًا المقال السابق: تطبيقات البنية التحتية في الشبكات الحاسوبية تطبيقات الشبكات الحاسوبية: خدمات الويب تطبيق مبدلات وموجهات الشبكات الحاسوبية برمجيا وعتاديا
-
يبذل كريتا Krita قصارى جهده للحفاظ على عملك آمنًا. ولكن إذا أردت التأكّد من أنك لن تفقد عملك، فستحتاج إلى فهم كيفية الحفظ والحفظ التلقائي ونسخ الملفات الاحتياطي في كريتا. الحفظ لا يخزّن كريتا صورك في مكانٍ ما دون تدخلك، لذلك يجب أن تحفظ عملك بنفسك، وإلّا فسيضيع دون رجعة. يحفظ كريتا صورك بتنسيقات عديدة، لكن يجب عليك دائمًا حفظ عملك بتنسيق كريتا الأصلي .kra لأنه يدعم جميع ميزات كريتا. كما يمكنك تصدير عملك إلى تنسيقات أخرى للتوافق مع التطبيقات الأخرى أو النشر على الويب أو على الورق. سيعطيك كريتا تحذيرًا يوضّح فيه أيَّ جانب من جوانب عملك سيُفقَد عندما تحفظه بتنسيق آخر غير تنسيق .kra ويعرض عليك إنشاء ملف .kra. إذا حفظت عملك، فسيسألك كريتا عن المكان الذي يجب حفظ عملك فيه على حاسوبك، وهذا المكان هو مجلد الصور Pictures ضمن مجلد المستخدم User افتراضيًا في جميع أنظمة التشغيل. إذا استخدمت خيار حفظ كـ Save As، فستُحفَظ صورتك باسم جديد دون حذف الملف الأصلي الذي يحمل اسم القديم، بحيث يُحفَظ ملفك بالاسم الجديد من الآن فصاعدًا. إذا استخدمتَ خيار تصدير Export باسم ملف جديد، فسينشأ ملف جديد باسم جديد، لكن سيحتفظ الملف الذي فتحته بالاسم القديم، حيث سيُحفَظ بالاسم القديم في المرة التالية التي تحفظه فيها. يمكنك في كريتا استخدام خيار الحفظ Save والحفظ كـ Save As، والتصدير Export إلى أيّ تنسيق ملف تريده. حفظ وتصدير وفتح الملفات توجد نسخة يمكن تعديلها من الملف الذي ينشئه أو يفتحه كريتا في الذاكرة، فهذا جزء من طريقة عمل الحواسيب التي تنشئ نسخةً من ملفها في ذاكرة RAM، وبالتالي يأخذ كريتا عند الحفظ نسخته وينسخها فوق الملف الحالي. حفظ Save: يحفظ كريتا الصورة الحالية في ذاكرته في مكان محدَّد على القرص الصلب. إن لم تُحفَظ الصورة من قبل، فسيسألك كريتا عن مكان حفظها. حفظ كـ Save As: ينشئ هذا الخيار نسخة من ملفك الحالي عن طريق حفظه باسم مختلف، وسيتحول كريتا إلى الملف المُنشَأ حديثًا بوصفه المستند النشط حاليًا. فتح Open: يفتح هذا الخيار ملفًا محفوظًا. تصدير Export: يحفظ هذا الخيار ملفًا في موقع جديد دون فتحه ليكون نشطًا، وهو مفيد عندما تعمل على ملف ذي طبقات متعددة، لكنك ستحتاج إلى حفظ نسخة مسطحة flattened منه في مكان معين. فتح مستند موجود مسبقًا كمستند غير معنون Open Existing Document as Untitled Document: يفتح هذا الخيار ملفًا وينسى المكان الذي حفظته فيه، لذلك إذا ضغطتَ على "حفظ save" فسيسألك عن مكان حفظه. يسمى هذا الخيار "استيراد import" في برامج أخرى. إنشاء نسخة من الصورة الحالية Create Copy from Current Image: ينشئ نسخة جديدة من الصورة الحالية، حيث يشبه الخيار فتح مستند موجود مسبقًا كمستند غير معنون Open Existing Document as Untitled Document، ولكنه يتعامل مع الملفات المفتوحة حاليًا. حفظ نسخة تزايدية Save Incremental Version: يحفظ الصورة الحالية باسم filename_XXX.kra ويحوّل المستند الحالي إليها. حفظ نسخة احتياطية تزايدية Save Incremental Backup: ينسخ ويعيد تسمية آخر نسخة محفوظة من ملفك إلى ملف نسخة احتياطية ويحفظ المستند بالاسم الأصلي. الحفظ التلقائي الحفظ التلقائي AutoSave هو ما يحدث عندما تعمل قليلًا ولا تحفظ عملك بنفسك، فيحفظ كريتا عملك، حيث تُخفَى ملفات الحفظ التلقائي افتراضيًا ضمن مدير ملفاتك، لكن يمكنك ضبط الإصدار 4.2 والإصدارات الأحدث من كريتا لإنشاء ملفات الحفظ التلقائي المرئية في مدير الملفات. يحفظ كريتا ملفك تلقائيًا كل خمس عشرة دقيقة افتراضيًا، لكن يمكنك ضبط هذه العملية من تبويب ملف File في صفحة الإعدادات العامة General Settings من نافذة ضبط كريتا Configure Krita التي يمكنك الوصول إليها في قائمة إعدادات Settings في نظامي تشغيل ويندوز ولينكس أو من قائمة تطبيق Application في نظام ماك. إن أغلقت برنامج كريتا دون حفظ، فستفقد عملك غير المحفوظ ولا يمكن استرجاعه، كما أن إغلاق كريتا يعني إزالة ملفات الحفظ التلقائي. هناك احتمالان للحفظ التلقائي هما: لم تحفظ عملك على الإطلاق. حفظت عملك فعليًا. الحفظ التلقائي للملفات غير المحفوظة إن لم تحفظ عملك بعد، فسينشئ كريتا ملف حفظ تلقائي بدون اسم. إن استخدمت نظام لينكس أو ماك، فسيكون ملف الحفظ التلقائي ملفًا مخفيًا في شجرة الملفات الرئيسية. بينما إن استخدمت نظام ويندوز، فسيكون ملف الحفظ التلقائي ملفًا في مجلد %TEMP% الخاص بمستخدمك. يمكنك ضبط كريتا في الإصدار 4.2 والإصدارات الأحدث من كريتا لجعل ملفات الحفظ التلقائي مرئية افتراضيًا. يُسمَّى ملف الحفظ التلقائي المخفي مثل الاسم .krita-12549-document_1-autosave.kra إذا تعطّل كريتا قبل حفظ ملفك، فسترى هذا الملف في نافذة تظهر عند بدء كريتا في المرة التالية التي تشغّله بها، حيث يمكنك اختيار استعادة الملفات أو حذفها. إذا تعطّل كريتا عند استخدام نظام ويندوز ومُسِح مجلد %TEMP%، فستفقد عملك. لا يمسح ويندوز المجلد %TEMP% افتراضيًا، ولكن يمكن تفعيل هذه الميزة في الإعدادات، كما توجد بعض التطبيقات مثل Disk Cleanup أو CCleaner التي تمسح المجلد %TEMP%. تذكّر أنه إن تعطّل كريتا ولم تحفظ عملك، وجرى تفعيل شيءٍ ما يمسح مجلد %TEMP%، فستفقد عملك. إن لم يتعطل كريتا وأغلقته دون حفظ عملك، فسيزيل كريتا ملف الحفظ التلقائي، وبالتالي سيختفي عملك ولا يمكنك استعادته، وإذا حفظت عملك وتابعت العمل أو أغلقت كريتا وحفظت عملك، فسيُزال ملف الحفظ التلقائي أيضًا. الحفظ التلقائي للملفات المحفوظة إذا حفظت عملك، فسينشئ كريتا ملف حفظ تلقائي باسم، وسيكون هذا الملف المخفي بالشكل: .myimage.kra-autosave.kra. تُخفَى ملفات الحفظ التلقائي المسمَّاة افتراضيًا، وتوضَع في المجلد نفسه الموجود فيه الملف الذي تعمل عليه. إذا شغّلت كريتا مرة أخرى بعد تعطّله وحاولت فتح ملفك الأصلي، فسيظهِر كريتا الرسالة التالية التي تسألك عن فتح ملف الحفظ التلقائي بدلًا من فتح الملف الأصلي: إذا اخترت "لا"، فسيُزال ملف الحفظ التلقائي، وستفقد العمل الذي أجريته منذ آخر مرة حفظتَ فيها الملف بنفسك ولا يمكن استرجاعه. بينما إذا اخترت "نعم"، فسيفتح كريتا ملف الحفظ التلقائي ثم يزيله، حيث سيكون للملف الذي فتحته اسم ملفك الأصلي. سيُعَد الملف مُعدَّلًا، لذا سيسألك كريتا عن حفظ الملف في المرة القادمة التي تحاول فيها إغلاق كريتا، فإن لم ترِد حفظه، فسيذهب عملك بلا رجعة ولا يمكنك استعادته. إذا استخدمتَ خيار حفظ كـ Save As، فستُحفَظ صورتك باسم جديد دون حذف الملف الأصلي الذي يحمل الاسم الأصلي وملف الحفظ التلقائي الخاص به. يُحفَظ ملفك بالاسم الجديد من الآن فصاعدًا، حيث إذا حفظته مرة أخرى، فسيُنشَأ ملف حفظ تلقائي باسم الملف الجديد. إذا استخدمت خيار تصدير Export باسم ملف جديد، فسيُنشَأ ملف جديد باسم جديد، وسيحتفظ الملف الذي فتحته بالاسم الجديد، وسيُنشَأ ملف الحفظ التلقائي من آخر ملف محفوظ بالاسم الحالي في المرة التالية التي تحفظه فيها، وهو ليس الاسم الذي تختاره عند استخدام خيار تصدير Export. ملفات النسخ الاحتياطي هناك ثلاثة أنواع من ملفات النسخ الاحتياطي هي: ملفات النسخ الاحتياطي العادية Ordinary Backup التي تنشأ عند حفظ ملف مفتوح من القرص الصلب. ملفات النسخ الاحتياطي التزايدية Incremental Backup التي هي نسخ من الملف بحيث تكون هذه النسخ الاحتياطية المرقمة للملف كما هو موجود على القرص الصلب وأثناء حفظ الملف بالاسم الحالي. ملفات الإصدارات التزايدية Incremental Version التي تحفظ الملف الذي تعمل عليه برقم جديد دون المساس بالملفات الموجودة على القرص الصلب. ملفات النسخ الاحتياطي العادية يحفظ كريتا نسخة احتياطية من ملفك، إذا فتحت ملفًا وأجريت تعديلات عليه ثم حفظته أو إذا حفظت ملفًا جديدًا بعد المرة الأولى التي تحفظه فيها. يمكنك تعطيل هذه الآلية من تبويب ملف File في صفحة الإعدادات العامة General Settings من نافذة ضبط كريتا Configure Krita التي يمكنك الوصول إليها من قائمة إعدادات Settings في نظامي ويندوز ولينكس أو من قائمة تطبيق Application في نظام ماك، إذ تكون ملفات النسخ الاحتياطي مفعَّلة افتراضيًا. يكون ملف النسخ الاحتياطي في مجلد الملف الأصلي افتراضيًا، ويمكنك اختيار حفظ ملفات النسخ الاحتياطي في مجلد المستخدم User أو مجلد %TEMP%، حيث لا يُعَد ذلك آمنًا لأنك إذا عدّلتَ ملفين بالاسم نفسه في مجلدين مختلفين، فستحل النسخ الاحتياطية الخاصة بهما محل بعضهما البعض. يكون لملف النسخ الاحتياطي اللاحقة ~ افتراضيًا، لتمييزه عن الملف العادي. يجب تفعيل خيار إظهار امتدادات الملفات show file extensions في مستكشف ويندوز عند استخدام نظام ويندوز لرؤية الامتداد. إذا أردت فتح ملف النسخ الاحتياطي، فيجب عليك إعادة تسميته في مدير الملفات والتأكّد من أن الامتداد ينتهي بـ .kra. تُنسَخ آخر نسخة من ملفك بدون اللاحقة ~ في كل مرة تحفظه فيها إلى النسخة التي تحمل اللاحقة ~، وستختفي محتويات الملف الأصلي، حيث لا يمكنك استعادة هذه النسخة. ملفات النسخ الاحتياطي التزايدية تشبه ملفاتُ النسخ الاحتياطي التزايدية ملفاتَ النسخ الاحتياطي العادية، إذ تُنسَخ الحالة المحفوظة الأخيرة إلى ملف آخر قبل الحفظ مباشرة، ولكن تُرقَّم ملفات النسخ الاحتياطي بدلًا من استبدال ملف النسخ الاحتياطي. يمكنك استخدام ملفات النسخ الاحتياطي التزايدية عندما تريد الاحتفاظ بمجموعة من حالات صورتك الجيدة خلال عملية الرسم، ولكن سيستهلك ذلك مساحة أكبر على القرص الصلب بالطبع. لا يحفظ كريتا حالة عملك الحالية في أحدث ملف تزايدي، ولكنه ينسخ آخر ملف محفوظ إلى ملف نسخ احتياطي ثم يحفظ صورتك باسم الملف الأصلي. ملفات الإصدارات التزايدية يشبه الإصدار التزايدي النسخَ الاحتياطي التزايدي بعض الشيء ولكن دون المساس بالملفات الأصلية، إذ يحفظ ملفًا جديدًا برقم ملف. ترجمة -وبتصرّف- للمقال Saving, AutoSave and Backup Files من موقع Krita. اقرأ أيضًا المقال السابق: دليل الصور والقوالب في كريتا المفاهيم الأساسية لكريتا النسخة الكاملة من كتاب: أساسيات تصميم الرسوميات
-
لغة الاستعلامات الهيكلية Structured Query Language -أو SQL اختصارًا- هي لغة قاعدة بيانات مصمَّمة لإدارة البيانات الموجودة في نظام إدارة قواعد البيانات العلائقية. طوّرت شركة IBM لغة SQL في أوائل السبعينات -عُرِفت بالإصدار 1986-، حيث صُمِّم الإصدار الأولي المسمَّى بلغة الاستعلامات الهيكلية الإنجليزية SEQUEL -اختصارًا للعبارة Structured English Query Language- لمعالجة واسترداد البيانات المخزَّنة في نظام خاص بشركة IBM وشبه علائقي لإدارة قواعد البيانات، ويُسمَّى نظام R. قدّمت بعد ذلك شركة Relational Software Inc -والتي أصبحت الآن شركة Oracle Corporation- أول تطبيق متاح تجاريًا للغة SQL والمسمَّى بـ Oracle V2 لحواسيب VAX في أواخر السبعينات. تُستخدَم العديد من أنظمة DBMS العلائقية المتاحة حاليًا، مثل: Oracle Database، وMicrosoft SQL Server -الموضَّح في الشكل التالي-، وMySQL، وIBM DB2، وIBM Informix، وMicrosoft Access، لغة SQL. تُستخدَم لغة قاعدة بيانات SQL في نظام DBMS من أجل: إنشاء بنى قواعد البيانات والجداول. إجراء الأعمال الأساسية لإدارة البيانات، مثل الإضافة والحذف والتعديل. إجراء استعلامات معقَّدة لتحويل البيانات الأولية إلى معلومات مفيدة. سوف نركز في هذا المقال على استخدام لغة SQL لإنشاء بنى قواعد البيانات والجداول، باستخدام لغة SQL على أساس لغة تعريف بيانات data definition language -أو DDL اختصارًا- بصورة أساسية. سنستخدم لغة SQL في مقال لاحق على أساس لغة معالجة بيانات data manipulation language -أو DML اختصارًا- لإدخال البيانات، وحذفها، واختيارها، وتحديثها في جداول قاعدة البيانات. إنشاء قاعدة بيانات Create Database تتكوّن عبارات لغة SQL DDL الرئيسية من: CREATE DATABASE وCREATE/DROP/ALTER TABLE، إذ تُستخدَم عبارة CREATE في لغة SQL لإنشاء بنى قواعد البيانات والجداول. إنشاء قاعدة بيانات تُنشَأ قاعدة بيانات جديدة تسمَّى SW باستخدام العبارة CREATE DATABASE SW بلغة SQL. الخطوة التالية بعد إنشاء قاعدة البيانات هي إنشاء جداول قاعدة البيانات. التنسيق العام للأمر CREATE TABLE هو: CREATE TABLE <tablename> ( ColumnName, Datatype, Optional Column Constraint, ColumnName, Datatype, Optional Column Constraint, Optional table Constraints ); يكون Tablename اسم جدول قاعدة البيانات مثل جدول الموظف Employee، كما يتكون كل حقل من الأمر CREATE TABLE من ثلاثة أجزا، هي: اسم العمود ColumnName. نوع البيانات Data type. قيد عمود اختياري Optional Column Constraint. يجب أن يكون اسم العمود ColumnName فريدًا في الجدول، وبعض الأمثلة على أسماء الأعمدة هي FirstName وLastName. أما نوع البيانات Data Type، فيجب أن يكون نوع بيانات نظام أو نوع بيانات يعرِّفه المستخدِم، كما تملك العديد من أنواع البيانات حجمًا، مثل (CHAR(35 أو (Numeric(8,2 وإليك قائمة بأشهر أنواع البيانات: النوع Bit: بيانات أعداد صحيحة Integer لها قيمة 1 أو 0. النوع Int: بيانات أعداد صحيحة Integer لها القيم من -2^31 أي (-2,147,483,648) حتى 2^31 – 1، أي (2,147,483,647). النوع Smallint: بيانات أعداد صحيحة Integer لها القيم من (-32,768) 2^15 أي حتى 2^15 – 1أي 32,767. النوع Tinyint: بيانات أعداد صحيحة Integer لها القيم من 0 حتى 255. النوع Decimal: بيانات ذات دقة ثابتة وقياس رقمي لها القيم من -10^38 -1 إلى 10^38. النوع Numeric: مرادف للنوع decimal. النوع Timestamp: رقم فريد على مستوى قاعدة البيانات. النوع Uniqueidentifier: معرَّف فريد عالميًا globally unique identifier -أو GUID اختصارًا-. النوع Money: تتراوح قيم البيانات النقدية من -2^63 أي -922,337,203,685,477.5808 حتى 2^63 – 1 أي 922,337,203,685,477.5807 بدقة تصل إلى واحد من عشرة آلاف من الوحدة النقدية. النوع Smallmoney: تتراوح قيم البيانات النقدية من -214,748.3648إلى +214,748.3647 بدقة تصل إلى واحد من عشرة آلاف من الوحدة النقدية. النوع Float: بيانات أرقام ذات دقة عشرية تتراوح قيمها بين -1.79E + 308و 1.79E + 308. النوع Real: بيانات أرقام ذات دقة عشرية قيمها تتراوح من -3.40E + 38 حتى 3.40E + 38. النوع Datetime: بيانات التاريخ والوقت تتراوح قيمها من January 1, 1753 إلى December 31, 9999 بدقة تبلغ واحد إلى ثلاثة أجزاء من مئة من الثانية، أو 3.33 ميلي ثانية. النوع Smalldatetime: بيانات التاريخ والوقت تتراوح قيمها من January 1, 1900 حتى June 6, 2079 بدقة تبلغ دقيقة واحدة. النوع Char: بيانات محارف ثابتة الطول وليست يونيكود بطول أقصى 8000 محرف. النوع Varchar: بيانات متغيرة الطول وليست يونيكود بحد أقصى 8000 محرف. النوع Text: بيانات متغيرة الطول وليست يونيكود بطول أقصى يبلغ 2^31 – 1 أي 2,147,483,647 محرفًا. النوع Binary: بيانات ثنائية ذات طول ثابت بطول أقصى 8000 بايت. النوع Varbinary: بيانات ثنائية متغيرة الطول بطول أقصى يبلغ 8000 بايت. النوع Image: بيانات ثنائية متغيرة الطول بطول أقصى 2^31 – 1 أي 2,147,483,647بايت. أخيرًا في ما يتعلق بقيود العمود الاختيارية Optional Column Constraints، فهي الآتي: NULL. NOT NULL. UNIQUE. PRIMARY KEY. DEFAULT. وتُستخدَم لتهيئة قيمة لسجل جديد. يشير قيد العمود NULL إلى أن القيمة الفارغة null مسموح بها، مما يعني أنه يمكن إنشاء صف بدون قيمة لهذا العمود؛ كما يشير قيد العمود NOT NULL إلى وجوب توفير قيمة عند إنشاء صف جديد. سنستخدم تعليمة لغة SQL للتوضيح والتي هي CREATE TABLE EMPLOYEES لإنشاء جدول موظفين يحتوي على 16 سمة attributes أو حقل fields. USE SW CREATE TABLE EMPLOYEES ( EmployeeNo CHAR(10) NOT NULL UNIQUE, DepartmentName CHAR(30) NOT NULL DEFAULT "Human Resources", FirstName CHAR(25) NOT NULL, LastName CHAR(25) NOT NULL, Category CHAR(20) NOT NULL, HourlyRate CURRENCY NOT NULL, TimeCard LOGICAL NOT NULL, HourlySalaried CHAR(1) NOT NULL, EmpType CHAR(1) NOT NULL, Terminated LOGICAL NOT NULL, ExemptCode CHAR(2) NOT NULL, Supervisor LOGICAL NOT NULL, SupervisorName CHAR(50) NOT NULL, BirthDate DATE NOT NULL, CollegeDegree CHAR(5) NOT NULL, CONSTRAINT Employee_PK PRIMARY KEY(EmployeeNo) ); الحقل الأول هو EmployeeNo من النوع CHAR، ويبلغ طول هذا الحقل 10 محارف، ولا يمكن للمستخدِم ترك هذا الحقل فارغًا NOT NULL، والحقل الثاني هو DepartmentName من النوع CHAR بطول 30. يُستخدَم قيد الجدول المعرَّف بواسطة الكلمة CONSTRAINT لإنشاء المفتاح الأساسي primary key، وذلك بعد تعريف جميع أعمدة الجدول، أي كما يلي: CONSTRAINT EmployeePK PRIMARY KEY(EmployeeNo) يمكننا إنشاء جدول أقسام Department، وجدول مشاريع Project، وجدول مهام Assignment باستخدام الأمر CREATE TABLE بلغة SQL DDL، كما هو موضَّح في المثال التالي: USE SW CREATE TABLE DEPARTMENT ( DepartmentName Char(35) NOT NULL, BudgetCode Char(30) NOT NULL, OfficeNumber Char(15) NOT NULL, Phone Char(15) NOT NULL, CONSTRAINT DEPARTMENT_PK PRIMARY KEY(DepartmentName) ); أُنشِئ جدول المشاريع project التالي بسبعة حقول هي: معرِّف المشروع ProjectID، واسم المشروع ProjectName، والقسم Department، والحد الأقصى للساعات MaxHours، وتاريخ البدء StartDate، وتاريخ الانتهاء EndDate. USE SW CREATE TABLE PROJECT ( ProjectID Int NOT NULL IDENTITY (1000,100), ProjectName Char(50) NOT NULL, Department Char(35) NOT NULL, MaxHours Numeric(8,2) NOT NULL DEFAULT 100, StartDate DateTime NULL, EndDate DateTime NULL, CONSTRAINT ASSIGNMENT_PK PRIMARY KEY(ProjectID) ); بينما أُنشِئ جدول المهام assignment بثلاثة حقول، هي: معرِّف المشروع ProjectID، ورقم الموظف EmployeeNumber، وساعات العمل HoursWorked. يُستخدَم جدول المهام لتسجيل الموظف باستخدام الحقل EmployeeNumber، ومقدار الوقت باستخدام الحقل HoursWorked الذي عمل فيه الموظف في مشروع معين باستخدام الحقل ProjectID، أي كما يلي: USE SW CREATE TABLE ASSIGNMENT ( ProjectID Int NOT NULL, EmployeeNumber Int NOT NULL, HoursWorked Numeric(6,2) NULL, ); قيود الجدول Table Constraints تُعرَّف قيود الجدول بواسطة الكلمة المفتاحية CONSTRAINT ويمكن استخدامها لتطبيق العديد من القيود الموضَّحة أدناه. القيد IDENTITY يمكننا استخدام قيد العمود الاختياري IDENTITY لتوفير قيمة فريدة تزايدية لهذا العمود، إذ تُستخدَم أعمدة الهوية Identity مع قيود المفتاح الرئيسي PRIMARY KEY لتكون بمثابة معرِّف صف فريد للجدول، كما يمكن إسناد الخاصية IDENTITY إلى عمود له نوع بيانات tinyint، أو smallint، أو int، أو decimal، أو numeric، وهذا القيد: يولِّد أرقامًا متسلسلةً. لا يفرض سلامة الكيان entity integrity. يمكن أن يحتوي عمود واحد فقط على الخاصية IDENTITY. يجب تعريفه على أساس نوع بيانات integer أو numeric أو decimal. لا يمكن تحديث عمود له الخاصية IDENTITY. لا يمكن أن يحتوي على قيم فارغة NULL. لا يمكنه ربط الافتراضات والقيود الافتراضية بالعمود. بالنسبة للقيد [(IDENTITY[(seed, increment: Seed: هي القيمة الأولية لعمود الهوية identity. Increment: هي القيمة المطلوب إضافتها إلى عمود الزيادة increment الأخير. سنستخدم مثال قاعدة بيانات آخر لتوضيح عبارات لغة SQL DDL بصورة أكبر من خلال إنشاء الجدول tblHotel في قاعدة بيانات الفندق HOTEL كما يلي: CREATE TABLE tblHotel ( HotelNo Int IDENTITY (1,1), Name Char(50) NOT NULL, Address Char(50) NULL, City Char(25) NULL, ) القيد UNIQUE يمنع القيد UNIQUE من إدخال قيم مكررة في عمود، حيث: يُستخدَم القيدان PK، و UNIQUE لفرض سلامة الكيان. يمكن تعريف قيود UNIQUE متعددة للجدول. يجري دائمًا التحقق من صحة البيانات الموجودة عند إضافة قيد UNIQUE إلى جدول موجود. يمكن وضع القيد UNIQUE على الأعمدة التي تقبل القيم الفارغة، حيث يمكن أن يكون صفٌ واحد فقط NULL. ينشِئ القيد UNIQUE دليلًا فريدًا للعمود المُختار تلقائيًا. الصيغة التالية هي الصيغة العامة للقيد UNIQUE: [CONSTRAINT constraint_name] UNIQUE [CLUSTERED | NONCLUSTERED] (col_name [, col_name2 […, col_name16]]) [ON segment_name] يستخدم المثال التالي القيد UNIQUE كما يلي: CREATE TABLE EMPLOYEES ( EmployeeNo CHAR(10) NOT NULL UNIQUE, ) القيد FOREIGN KEY المفتاح الخارجي يعرِّف القيد FOREIGN KEY -أو FK اختصارًا- عمودًا، أو مجموعة من الأعمدة التي تتطابق قيمها مع المفتاح الرئيسي PRIMARY KEY -أو PK اختصارًا- لجدول آخر، بحيث: تُحدَّث القيم في المفتاح الخارجي FK تلقائيًا عند تحديث أو تغيير قيم المفتاح الرئيسي PK في الجدول المرتبط. يجب أن تشير قيود المفتاح الخارجي FK إلى القيد المفتاح الرئيسي PK، أو القيد UNIQUE لجدول آخر. يجب أن يكون عدد أعمدة المفتاح الخارجي FK هو نفسه قيد المفتاح الرئيسي PK، أو قيد UNIQUE. إذا اُستخدِم الخيار WITH NOCHECK، فلن يتحقق قيد المفتاح الخارجي FK من صحة البيانات الموجودة في الجدول. لا يوجد دليل index للأعمدة التي تشارك في قيد المفتاح الخارجي FK. الصيغة التالية هي الصيغة العامة لقيد المفتاح الخارجي FOREIGN KEY: [CONSTRAINT constraint_name] [FOREIGN KEY (col_name [, col_name2 […, col_name16]])] REFERENCES [owner.]ref_table [(ref_col [, ref_col2 […, ref_col16]])] يكون الحقل HotelNo في المثال التالي في الجدول tblRoom مفتاحًا خارجيًا FK للحقل HotelNo في الجدول tblHotel الموضَّح سابقًا: USE HOTEL GO CREATE TABLE tblRoom ( HotelNo Int NOT NULL , RoomNo Int NOT NULL, Type Char(50) NULL, Price Money NULL, PRIMARY KEY (HotelNo, RoomNo), FOREIGN KEY (HotelNo) REFERENCES tblHotel ) القيد CHECK يقيِّد القيد CHECK القيم التي يمكن إدخالها في جدول، بحيث: يمكن أن يحتوي على شروط بحث مشابهة لعبارة WHERE. يمكنه الربط بين الأعمدة في نفس الجدول. يجب تقييم قاعدة التحقق من صحة البيانات للقيد CHECK من خلال تعبير بولياني boolean expression. يمكن تعريفه لعمود له قاعدة مرتبطة به. الصيغة التالية هي الصيغة العامة للقيد CHECK: [CONSTRAINT constraint_name] CHECK [NOT FOR REPLICATION] (expression) يقتصر حقل النوع Type في المثال التالي على الأنواع "Single"، أو "Double"، أو "Suite"، أو "Executive". USE HOTEL GO CREATE TABLE tblRoom ( HotelNo Int NOT NULL, RoomNo Int NOT NULL, Type Char(50) NULL, Price Money NULL, PRIMARY KEY (HotelNo, RoomNo), FOREIGN KEY (HotelNo) REFERENCES tblHotel CONSTRAINT Valid_Type CHECK (Type IN ('Single', 'Double', 'Suite', 'Executive')) ) يجب في المثال التالي أن يكون تاريخ تعيين الموظف قبل January 1, 2004، أو يجب أن يكون الحد الأقصى للراتب 300 ألف دولار: GO CREATE TABLE SALESREPS ( Empl_num Int Not Null CHECK (Empl_num BETWEEN 101 and 199), Name Char (15), Age Int CHECK (Age >= 21), Quota Money CHECK (Quota >= 0.0), HireDate DateTime, CONSTRAINT QuotaCap CHECK ((HireDate < "01-01-2004") OR (Quota <=300000)) ) القيد DEFAULT يُستخدَم القيد DEFAULT لتوفير قيمة تُضاف تلقائيًا لعمود ما إذا لم يوفّرها المستخدم، بحيث: يمكن احتواء العمود على قيد DEFAULT واحد فقط. لا يمكن استخدام القيد DEFAULT في الأعمدة التي لها نوع البيانات timestamp، أو الخاصية identity. ترتبط القيود DEFAULT تلقائيًا بعمود عند إنشائها. الصيغة العامة للقيد DEFAULT هي: [CONSTRAINT constraint_name] DEFAULT {constant_expression | niladic-function | NULL} [FOR col_name] يضبط المثال التالي القيمة الافتراضية default لحقل المدينة city field على القيمة "Vancouver": USE HOTEL ALTER TABLE tblHotel Add CONSTRAINT df_city DEFAULT ‘Vancouver’ FOR City الأنواع التي يعرفها المستخدم User Defined Types تعتمد الأنواع التي يعرِّفها المستخدِم دائمًا على نوع البيانات التي يوفرها النظام، فيمكن لهذه الأنواع فرض سلامة البيانات والسماح بالقيم الفارغة nulls. اختر الأنواع التي تكون تحت الكلمة "Programmability" في قاعدة البيانات الخاصة بك، لإنشاء نوع بيانات يعرِّفه المستخدِم في خادم SQL Server، ثم انقر بزر الماوس الأيمن واختر المسار New’ –>‘User-defined data type’، أو نفّذ إجراء النظام sp_addtype المخزّن system stored procedure، ثم اكتب ما يلي: sp_addtype ssn, 'varchar(11)', 'NOT NULL' سيؤدي هذا إلى إضافة نوع بيانات جديد عرّفه المستخدم يسمى SIN بتسعة محارف. يستخدم الحقل EmployeeSIN نوع البيانات SIN الذي عرّفه المستخدم في المثال التالي: CREATE TABLE SINTable ( EmployeeID INT Primary Key, EmployeeSIN SIN, CONSTRAINT CheckSIN CHECK (EmployeeSIN LIKE ' [0-9][0-9][0-9] – [0-9][0-9] [0-9] – [0-9][0-9][0-9] ') ) التعليمة ALTER TABLE يمكن استخدام تعليمات ALTER TABLE لإضافة وحذف القيود، بحيث: تسمح تعليمة ALTER TABLE بإزالة الأعمدة. يُتحقق من جميع البيانات الموجودة عند إضافة قيد للتأكد من عدم وجود انتهاكات. نستخدم في المثال التالي تعليمة ALTER TABLE للخاصية IDENTITY في الحقل ColumnName: USE HOTEL GO ALTER TABLE tblHotel ADD CONSTRAINT unqName UNIQUE (Name) استخدم تعليمة ALTER TABLE لإضافة عمود مع الخاصية IDENTITY مثل التعليمة ALTER TABLE TableName. ADD ColumnName int IDENTITY(seed, increment) التعليمة DROP TABLE تزيل التعليمة DROP TABLE جدولًا من قاعدة البيانات، لذلك تأكد من تحديد قاعدة البيانات الصحيحة. DROP TABLE tblHotel سيؤدي تنفيذ عبارة DROP TABLE السابقة بلغة SQL إلى إزالة الجدول tblHotel من قاعدة البيانات. تمارين باستخدام المعلومات الخاصة بالتمرين الموجود في المقال قواعد السلامة والقيود المُطبَّقة عند تصميم قواعد البيانات، طبّق التخطيط باستخدام لغة Transact SQL -أي اعرض تعليمات SQL لكل جدول-، وطبّق القيود أيضًا. أنشئ الجدول الموضَّح أدناه في خاوم SQL Server، واعرض التعليمات التي استخدمتها. الجدول: Employee table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } ATTRIBUTE (FIELD) NAME DATA DECLARATION EMP_NUM CHAR(3) EMP_LNAME VARCHAR(15) EMP_FNAME VARCHAR(15) EMP_INITIAL CHAR(1) EMP_HIREDATE DATE JOB_CODE CHAR(3) اكتب شيفرة لغة SQL لإدخال صفوف الجدول السابق، بعد إنشاء بنيته. استخدم الشكل السابق للإجابة على الأسئلة من 4 إلى 10. اكتب شيفرة لغة SQL لتغيير رمز الوظيفة job code إلى 501 للموظف الذي رقمه 107، وافحص النتائج بعد الانتهاء من المهمة، ثم أعد ضبط رمز الوظيفة إلى قيمته الأصلية. اكتب شيفرة لغة SQL لإعطاء قائمة بجميع السمات الخاصة برمز الوظيفة 502، بافتراض إدخال البيانات الموضَّحة في جدول الموظف Employee. اكتب شيفرة لغة SQL لحذف الصف الخاص بالشخص الذي اسمه "William Smithfield"، والذي وُظِّف في June 22, 2004، والذي تصنيف رمز وظيفته هو 500. أضف السمتين EMP_PCT، وPROJ_NUM إلى جدول الموظف، بحيث تكون السمة EMP_PCT هي نسبة المكافأة المدفوعة لكل موظف. اكتب شيفرة لغة SQL باستخدام أمر واحد لإدخال رقم المشروع PROJ_NUM = 18 لجميع الموظفين الذين تصنيف الوظيفة JOB_CODE الخاص بهم هو 500. اكتب شيفرة لغة SQL باستخدام أمر واحد لإدخال رقم المشروع PROJ_NUM = 25 لجميع الموظفين الذين تصنيف الوظيفة JOB_CODE الخاص بهم يساوي 502 أو أعلى. اكتب شيفرة لغة SQL لتغيير رقم المشروع PROJ_NUM إلى 14 للموظفين الذين تعيّنوا قبل January 1, 1994، ورمز الوظيفة الخاصة بهم يساوي 501 على الأقل. (قد تفترض أن الجدول سيعاد إلى حالته الأصلية التي سبقت هذا السؤال). ترجمة -وبتصرّف- للمقال SQL Structured Query Language لصاحبَيه Adrienne Watt وNelson Eng. اقرأ أيضًا المقال التالي: لغة معالجة البيانات DML الخاصة بلغة SQL المقال السابق: عملية تطوير قواعد البيانات Database Development النسحة الكاملة من كتاب ملاحظات للعاملين بلغة SQL الاستعلامات الفرعية والإجراءات في SQL قواعد السلامة وقيودها لضمان سلامة البيانات في قواعد البيانات الاعتماديات الوظيفية المستخدمة في تصميم قواعد البيانات