কুকুরছানা ক্লাস - কুকুরছানা টিউটোরিয়াল 7 এর একটি দুর্দান্ত শেখার গাইড

কুকুরছানা ক্লাস

ওপেন-সোর্স নোড জেএস লাইব্রেরি যা পাপ্টিয়ারটি ওয়েব স্ক্র্যাপিংয়ের সরঞ্জাম হিসাবে ব্যবহার করা যেতে পারে। কমান্ড লাইন, জাভাস্ক্রিপ্ট এবং এইচটিএমএল ডিওএম কাঠামো বোঝার জন্য এই কুকুরছানা টিউটোরিয়ালটি শুরু করা ভাল good পপিটারের টিউটোরিয়াল সিরিজটি পপিটিয়ারকে ধরে রাখতে নীচের সাব সেকশনের মধ্যে বিতরণ করা হয়েছে। 

পুতুল টিউটোরিয়াল

টসকা টিউটোরিয়াল # 1: কুকুরছানা ওভারভিউ

টসকা টিউটোরিয়াল # 2: পুতুল পরিবেশ পরিবর্তনশীল

টসকা টিউটোরিয়াল # 3: পুতুল ওয়েব স্ক্র্যাপিং এবং কুকুরছানা টেস্ট অটোমেশন ওভারভিউ

টসকা টিউটোরিয়াল # 4: পুতুল ইনস্টল করুন

টসকা টিউটোরিয়াল # 5: নমুনা পপিটার প্রকল্প

টসকা টিউটোরিয়াল # 6: পুতুল অটোমেশন টেস্টিং

টসকা টিউটোরিয়াল # 7: কুকুরছানা ক্লাস

টসকা টিউটোরিয়াল # 8: পুতুল ব্রাউজার ক্লাস

টসকা টিউটোরিয়াল # 9: কুকুরছানা পৃষ্ঠা শ্রেণি

এই "পপিটার ক্লাস" টিউটোরিয়ালে, আমরা নীচের ক্লাসগুলি ব্যাখ্যা করব যা গুরুত্বপূর্ণ নামস্পেসগুলি (যদি থাকে), ইভেন্টগুলি (যদি থাকে), এবং পপিটিয়ার ওয়েব স্ক্র্যাপিং কৌশলগুলিতে ঘন ঘন ব্যবহৃত হয় এমন পদ্ধতিগুলি অন্তর্ভুক্ত করে। 

আমরা এই নিবন্ধটি জুড়ে উদাহরণ সহ গুরুত্বপূর্ণ উপাদানগুলি ব্যাখ্যা করব।  

কুকুরছানা ক্লাস

ধারণামূলকভাবে, বর্গ হ'ল একটি বস্তুর একটি নীলনকশা যা নির্দেশাবলীর একটি সেট (পরিবর্তনশীল এবং পদ্ধতি) সংজ্ঞায়িত করে। এখানে, পাপ্পিয়ার ক্লাসটি ওয়েব স্ক্র্যাপিং করতে বিভিন্ন ক্রিয়া সম্পাদনের জন্য জাভাস্ক্রিপ্ট ব্যবহার করে সংজ্ঞায়িত করা হয়। আসুন নীচের উদাহরণটি চেক করুন, পপিটার ক্লাস মডিউলটি একটি ক্রোমিয়াম ওয়েব ইনস্ট্যান্স চালু করতে ব্যবহৃত হয়েছে।

const puppeteer = require('puppeteer');
(async () => {
  const browserChrome = await puppeteer.launch();
  const pageChrome = await browserChrome.newPage();
  await pageChrome.goto('https://www.google.com');
  // We can write steps here
  await browserChrome.close();
})();

পপিটার ক্লাস একাধিক নেমস্পেস এবং পদ্ধতি প্রদান করে যা ওয়েব স্ক্র্যাপিং প্রক্রিয়াটিকে সমর্থন করে। প্রায়শই ব্যবহৃত নেমস্পেস এবং পদ্ধতিগুলি পরবর্তী বিভাগগুলিতে ব্যাখ্যা করা হয়।

পুতুল শ্রেণীর ক্লাস - নামস্থান:

এটি এমন একটি ধারক যা জাভাস্ক্রিপ্টে একাধিক শনাক্তকারী, পদ্ধতি, ভেরিয়েবল ইত্যাদি সংজ্ঞায়িত করে। এটি একটি যৌক্তিক এবং সংগঠিত উপায়ে কোডকে গ্রুপ করার একটি উপায়। নীচের নেমস্পেসগুলি পপিটার ক্লাস দ্বারা সরবরাহ করা হয়।

পুতুল.দেবস: এটি পদ্ধতিতে ব্যবহার করা যেতে পারে এমন ডিভাইসের একটি তালিকা ফেরত দেয় পেজ.মুলেট (বিকল্পসমূহ) মোবাইল ডিভাইসে স্ক্র্যাপিং সম্পাদন করতে। 

উদাহরণ - একটি মোবাইল ডিভাইসে গুগল ওয়েব পৃষ্ঠা খুলুন এবং বন্ধ করুন -

const puppeteer = require('puppeteer');
const samsung = puppeteer.devices['Samsung J5'];
(async () => {
  const browserChrome = await puppeteer.launch();
  const pageChrome = await browserChrome.newPage();
  await pageChrome.emulate(samsung);
  await pageChrome.goto('https://www.google.com'); 
  await browserChrome.close();
})();

কুকুরছানা বিভিন্ন কুকুরছানা পদ্ধতিতে কাজ করার সময়, ব্যতিক্রম হওয়ার সম্ভাবনা রয়েছে। বেশিরভাগ ক্ষেত্রে, পদ্ধতিগুলি যদি অনুরোধগুলি পূরণ করতে অক্ষম হয় তবে এটি ত্রুটিগুলি ছুঁড়ে দেয়। 'কুকুরছানা.অরফারিজ' নেমস্পেসের মাধ্যমে ত্রুটিগুলি পরিচালনা করতে বিভিন্ন শ্রেণীর সংজ্ঞা দেওয়া আছে।

উদাহরণ - পদ্ধতির পৃষ্ঠাটির জন্য waউইটফোর্টসলেক্টর, যদি নির্দিষ্ট সময়ের মধ্যে ওয়েব উপাদান উপস্থিত না হয় তবে সময়সীমা ত্রুটি উপস্থিত হবে। দয়া করে নীচের উদাহরণটি দেখুন, যা সময়সীমা পরিচালনা করার জন্য একটি পদ্ধতির দেখায়,

try {
  await page.waitForSelector('<web-element>');
} catch (err) {
  if (err instanceof puppeteer.errors.TimeoutError) {
    // Write code to handle the timeout error.
  }
} 

কুকুরছানা। এটি নেটওয়ার্ক শর্তগুলির একটি তালিকা প্রদান করে যা পদ্ধতি পৃষ্ঠাতে ব্যবহার করা যেতে পারে emমনেট নেটকর্নিশনগুলি (নেটওয়ার্ককন্ডিশন)। নেটওয়ার্ক অবস্থার সম্পূর্ণ তালিকা সংজ্ঞায়িত করা হয় এখানে.

উদাহরণ - এই কোড নমুনার মাধ্যমে, আমরা একটি প্রাক-সংজ্ঞায়িত নেটওয়ার্ক শর্ত ব্যবহার করে গুগল ওয়েব পৃষ্ঠা খুলব।

const puppeteer = require('puppeteer');
const net = puppeteer.networkConditions['Fast 3G'];
(async () => {
  const browserChrome = await puppeteer.launch();
  const pageChrome = await browserChrome.newPage();
  await pageChrome.emulateNetworkConditions(net);
  await pageChrome.goto('https://www.google.com');
  await browserChrome.close();
})();

পুতুল। প্রোডাক্ট: এটি ব্রাউজারটির নাম দেয়, যা অটোমেশনের জন্য ব্যবহৃত হবে (ক্রোম বা ফায়ারফক্স)। ব্রাউজারের জন্য পণ্য পরিবেশ পরিবর্তনশীল PUPPETEER_PRODUCT বা পুতুল শ্রেণীর পদ্ধতিতে উপলব্ধ পণ্য বিকল্প দ্বারা সেট করা হয় puppeteer.launch ([বিকল্পসমূহ])। ডিফল্ট মান হ'ল ক্রোম।

রেফারেন্স: ক্লিক এখানে পপিটার ক্লাসের নেমস্পেসে আরও শিখতে।

পুতুল শ্রেণীর ক্লাস - পদ্ধতি:

পদ্ধতিতে নির্দিষ্ট ক্রিয়া সম্পাদনের জন্য বিবৃতি থাকে। কুকুরছানা শ্রেণীর নীচের পদ্ধতি রয়েছে,

কুকুরছানা - এটি সমস্ত নিবন্ধিত হ্যান্ডলারদের সাফ করে।

কুকুরছানা। সংযোগ (বিকল্পসমূহ) - এই পদ্ধতিটি কোনও বিদ্যমান ব্রাউজারের সাথে কুকুরছানা সংযোগ করতে ব্যবহৃত হয়। এটি টাইপ প্রতিশ্রুতির একটি অবজেক্ট প্রদান করে যা এই অ্যাসিনক্রোনাস প্রক্রিয়ার স্থিতি নির্দেশ করে। উদাহরণ - নীচের উদাহরণে, কুকুরছানা বর্তমান ব্রাউজার থেকে সংযোগ বিচ্ছিন্ন এবং পুনরায় সংযোগ,

const puppeteer = require('puppeteer');
(async () => {
  const browserChrome = await puppeteer.launch();
  // Copy the endpoint reference which will be reconnected later
  const endpoint = browserChrome.wsEndpoint();
  // Disconnect puppeteer
  browserChrome.disconnect();
  // Use the endpoint to re-connect
  const browserChrome2 = await puppeteer.connect({endpoint});
  // Close second instance of Chromium
  await browserChrome2.close();
})();

কুকুরছানা। ক্রিয়েট ব্রাউজারফ্যাচার ([বিকল্পসমূহ]) - এটি ব্রাউজারগুলির বিভিন্ন সংস্করণ (ক্রোম এবং ফায়ারফক্স) ডাউনলোড এবং পরিচালনা করতে একটি ব্রাউজার ফ্যাচার আইটেম তৈরি করে।

কনস্ট ব্রাউজারফেটার = কুকুরছানা। ক্রেটব্রাউজারফ্যাচার ();

কুকুরছানা। কাস্টমকিউরি হ্যান্ডলার নাম () - এটি সমস্ত নিবন্ধিত কাস্টম ক্যোয়ারী হ্যান্ডলারের একটি অ্যারে প্রদান করে।

puppeteer.defaultArgs ([বিকল্পসমূহ]) - এটি চালু করার সময় ক্রোম ব্রাউজারের ডিফল্ট কনফিগারেশন বিকল্পগুলিকে অ্যারে হিসাবে ফেরত দেয়। এছাড়াও, আমরা argumentচ্ছিক আর্গুমেন্ট বিকল্পটি ব্যবহার করে একটি ব্রাউজারের কনফিগারযোগ্য বিকল্পগুলি সেট করতে পারি।

কনস্ট আরগস = কুকুরছানা.ডিফল্টআর্গস ();

কুকুরছানা.এক্সকিউটেবলপথ () - এটি পাণ্ডুলিদের দ্বারা বান্ডিলযুক্ত ব্রাউজারের উদাহরণের জন্য প্রত্যাশার পথটি ফেরত দেয়। ডাউনলোডে যে পাথটি ডাউনলোডের জন্য উপলব্ধ হবে না তা পরিবেশ ভেরিয়েবল PUPPETEER_SKIP_DOWNLOAD দ্বারা এড়ানো হয়েছিল। এছাড়াও, আমরা পথ পরিবর্তন করতে পরিবেশগত ভেরিয়েবলগুলি PUPPETEER_EXECUTABLE_PATH এবং PUPPETEER_CHROMIUM_REVISION ব্যবহার করতে পারি।

কনস্ট আরগস = কুকুরছানা। এক্সকিউটেবলপ্যাথ ();

puppeteer.launch ([বিকল্পসমূহ]) - এই পুতুল শ্রেণীর পদ্ধতিটি ওয়েব ব্রাউজারটি চালু করতে ব্যবহৃত হয়। Argumentচ্ছিক যুক্তির মাধ্যমে আমরা ব্রাউজারের বিভিন্ন কনফিগারেশন যেমন পণ্য (ব্রাউজারের নাম), শিরোনামহীন, ডিভলটুল ইত্যাদি পাস করতে পারি This

কনস্ট ব্রাউজার = অপেক্ষা করুন কুকুরছানা.লাঞ্চ ();

কুকুরছানা। রেজিস্টার কাস্টম কিউইকি হ্যান্ডলার (নাম, ক্যোয়ারি হ্যান্ডলার) - এটি একটি কাস্টম ক্যোয়ারী হ্যান্ডলার নিবন্ধিত করতে ব্যবহৃত হয়। এখানে "নাম" ক্যোয়ারী হ্যান্ডলারের নাম সরবরাহ করে এবং "ক্যুয়েরি হ্যান্ডলার" প্রকৃত কাস্টম ক্যোয়ারী হ্যান্ডলারের সংজ্ঞা দেয়।

puppeteer.unregisterCustomQueryHandler (নাম) - এটি কোনও কাস্টম ক্যোয়ারী হ্যান্ডলারকে নিবন্ধন করতে ব্যবহৃত হয়।

রেফারেন্স: ক্লিক এখানে পপিটার ক্লাস পদ্ধতিতে আরও পড়তে to

টার্গেট ক্লাস

লক্ষ্য শ্রেণি লক্ষ্য সহ কাজ করার পদ্ধতি সরবরাহ করে। টার্গেট ক্লাসে সর্বাধিক ব্যবহৃত পদ্ধতিগুলি পরবর্তী বিভাগে ব্যাখ্যা করা হয়েছে।

লক্ষ্য শ্রেণি - পদ্ধতি:

টার্গেট ক্লাসে নীচের পদ্ধতিগুলি উপলভ্য -

  • টার্গেট.ব্রোজার () - এটি লক্ষ্যটির সাথে লিঙ্কযুক্ত ব্রাউজারের অবজেক্টটি প্রদান করে linked
  • টার্গেট.ব্রোজার কনটেক্সট () - এটি লক্ষ্য সংযুক্ত যা টাইপ ব্রাউজার কনটেক্সট এর একটি অবজেক্ট দেয়।
  • টার্গেট.ক্রিট সিডিপিএসসেশন () - এটি ক্রমের ডেভটোল প্রোটোকল সেশন তৈরি করে এবং প্রদান করে যা লক্ষ্যের সাথে সংযুক্ত থাকে।
  • টার্গেট.ওপেনার () - এটি লক্ষ্যটি দেয় যা এই লক্ষ্যটি খোলে op মূলত, এই পদ্ধতিটি পিতামাতার লক্ষ্য অর্জনে ব্যবহৃত হয়। এটি শীর্ষ-স্তরের টার্গেটের জন্য শূন্য ফেরায়।
  • লক্ষ্য.পৃষ্ঠা () - এটি লক্ষ্য পৃষ্ঠার অবজেক্ট প্রদান করে। যদি লক্ষ্যটির ধরণটি কোনও পৃষ্ঠা না হয় তবে এটি একটি নাল মান প্রদান করে।
  • টার্গেট.টাইপ () - এটি লক্ষ্য প্রকারটি পেতে ব্যবহৃত হয়। রিটার্ন মান হ'ল বিকল্পগুলির মধ্যে একটি হতে পারে - 'ব্যাকগ্রাউন্ড_পেজ', 'পৃষ্ঠা', 'শেয়ার্ডকর্মী', 'পরিষেবা_কর্মী', 'ব্রাউজার' বা 'অন্যান্য'।
  • Target.url () - এটি লক্ষ্যটির url প্রদান করে l
  • লক্ষ্য.কর্মী () - এটি ওয়েবকর্ম বস্তুটি ফেরত দেয়। লক্ষ্যটি যদি 'পরিষেবা_কর্মী' বা 'ভাগ করা_কর্মী' না হয় তবে প্রত্যাবর্তনের মানটি শূন্য।

রেফারেন্স: ক্লিক এখানে লক্ষ্য শ্রেণি পদ্ধতিতে আরও পড়তে।

কনসোলমেসেজ ক্লাস

কনসোলম্যাসেজ শ্রেণীর অবজেক্টগুলি পৃষ্ঠার মাধ্যমে কনসোল ইভেন্টের মাধ্যমে প্রেরণ করা হয়েছে। কনসোলমেসেজ শ্রেণীর ঘন ঘন ব্যবহৃত পদ্ধতিগুলি পরবর্তী বিভাগে ব্যাখ্যা করা হয়েছে।

কনসোলমেসেজ ক্লাস - পদ্ধতি:

কনসোলমেসেজ ক্লাসে নীচের পদ্ধতিগুলি উপলভ্য -

  • কনসোলমেসেজ.আরগস () - এটি JSHandler অবজেক্টের একটি অ্যারে প্রদান করে। জেএসহ্যান্ডলার হ্যান্ডেলটি নিষ্পত্তি না করা পর্যন্ত লিঙ্কযুক্ত জেএস বস্তুকে আবর্জনা সংগ্রহ করা থেকে বিরত রাখে। প্যারেন্ট ব্রাউজারের প্রসঙ্গটি ধ্বংস হয়ে গেলে এটি স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায়।
  • কনসোলমেসেজ.লোকেশন () - এটি সংস্থানটির একটি অবজেক্ট প্রদান করে, যা নীচের প্যারামিটারগুলি অন্তর্ভুক্ত করে।
  • url - এটি জ্ঞাত সংস্থানটির URL বোঝায়। না জানা থাকলে তা রাখবে একটি অপরিবর্তিত মান।
  • লাইন নাম্বার - এটি 0-ভিত্তিক লাইন নম্বর যা সংস্থানটিতে উপলব্ধ। যদি না পাওয়া যায় তবে তা রাখবে একটি অপরিবর্তিত মান।
  • columNumber - এটি 0-ভিত্তিক কলাম নম্বর যা সংস্থানটিতে উপলব্ধ। যদি না পাওয়া যায় তবে তা রাখবে একটি অপরিবর্তিত মান।
  • কনসোলমেসেজ.স্ট্যাকট্রেস () - এটি অবজেক্টগুলির একটি তালিকা (প্রতিটি বস্তু একটি সংস্থানকে বোঝায়) ফিরিয়ে দেয় যা নীচে প্যারামিটারগুলি অন্তর্ভুক্ত করে।
  • url - এটি জ্ঞাত সংস্থানটির URL বোঝায়। না জানা থাকলে তা রাখবে একটি অপরিবর্তিত মান।
  • লাইন নাম্বার - এটি 0-ভিত্তিক লাইন নম্বর যা সংস্থানটিতে উপলব্ধ। যদি না পাওয়া যায় তবে তা রাখবে একটি অপরিবর্তিত মান।
  • columNumber - এটি 0-ভিত্তিক কলাম নম্বর যা সংস্থানটিতে উপলব্ধ। যদি না পাওয়া যায় তবে তা রাখবে একটি অপরিবর্তিত মান।
  • কনসোলমেসেজ.টেক্সট () - এটি কনসোলটির পাঠ্য ফেরত দেয়।
  •  কনসোলমেসেজ.টাইপ () - এটি কনসোল বার্তার ধরণ হিসাবে স্ট্রিংটি প্রদান করে। প্রকারটি মানগুলির মধ্যে একটি হতে পারে - লগ, ডিবাগ, তথ্য, ত্রুটি, সতর্কতা, দির, dirxml, টেবিল, ট্রেস, পরিষ্কার, স্টার্ট গ্রুপ, স্টার্টগ্রুপ কলাপসড, এন্ডগ্রুপ, দৃsert়, প্রোফাইল, প্রোফাইল, গণনা, সময়সীমা।

রেফারেন্স: ক্লিক এখানে কনসোলমেসেজ শ্রেণি পদ্ধতিতে আরও শিখতে।

টাইমআউটআরার ক্লাস

বিভিন্ন পুতুলের সাথে কাজ করার সময়, ব্যতিক্রম হওয়ার সম্ভাবনা রয়েছে। বেশিরভাগ ক্ষেত্রে, পদ্ধতিগুলি যদি অনুরোধগুলি পূরণ করতে অক্ষম হয় তবে এটি ত্রুটিগুলি ছুঁড়ে দেয়। টাইমআউটআরার ক্লাস এই ধরণের ব্যতিক্রম পরিচালনা করতে ব্যবহৃত হয়।

টাইমআউটআরার ক্লাসের উদাহরণ - পদ্ধতির পৃষ্ঠাটির জন্য itউইটফরসলেক্টর, যদি ওয়েব উপাদান নির্দিষ্ট সময়ের মধ্যে উপস্থিত না হয় তবে সময়সীমা ত্রুটি উপস্থিত হবে। দয়া করে নীচের উদাহরণটি দেখুন, যা সময়সীমা পরিচালনা করার জন্য একটি পদ্ধতির দেখায়,

try {
  await page.waitForSelector('<element>');
} catch (e) {
  if (e instanceof puppeteer.errors.TimeoutError) {
    // Write code to handle the error.
  }
} 

ফাইলচুসার ক্লাস

ফাইল চয়নকারী শ্রেণি অবজেক্টটি পদ্ধতিটি ব্যবহার করে তৈরি করা হয়েছে পেজ.ওয়েটফরফিলচুসার। ফাইলচুজার ক্লাসটি ফাইলের সাথে ইন্টারঅ্যাক্ট করতে ব্যবহৃত হয়। ফাইলচুজার শ্রেণীর ঘন ঘন ব্যবহৃত পদ্ধতিগুলি পরবর্তী বিভাগে ব্যাখ্যা করা হয়েছে।

ফাইলচুজার ক্লাস - পদ্ধতি:

ফাইলচুসার শ্রেণীর জন্য নীচের পদ্ধতিগুলি উপলভ্য -

  • fileChooser.accept (file_with_path) - এই পদ্ধতিটি কোনও ফাইল আপলোড করতে ব্যবহৃত হয় (যার জন্য আর্গুমেন্ট হিসাবে দেওয়া হয়)।
  • fileChooser.cancel () - এই পদ্ধতিটি ফাইল আপলোড প্রক্রিয়া বাতিল করতে ব্যবহৃত হয়।
  • fileChooser.is মাল্টিপল () - এই পদ্ধতিটি ফাইলচুজার একাধিক মান নির্বাচন করতে দেয় কিনা তা পরীক্ষা করে। এটি একটি বুলিয়ান এক্সপ্রেশন (সত্য বা মিথ্যা) প্রদান করে।

ফাইলচুসার শ্রেণীর উদাহরণ -

const [fileChooser] = await Promise.all([
  page.waitForFileChooser(),
  page.click('#attach-button'), 
]);
await fileChooser.accept(['/puppeteer_proj/data/sample_file.pdf']);

উপসংহার:

এই "পপিটার ক্লাস" টিউটোরিয়ালে, আমরা পপিটার ক্লাস, টার্গেট ক্লাস, মেসেজকনসোল ক্লাস এবং টাইমআউটএরার ক্লাস ব্যাখ্যা করেছি যার মধ্যে গুরুত্বপূর্ণ নামস্থান (যদি থাকে), ইভেন্টগুলি (যদি থাকে) এবং পদ্ধতিগুলি যা প্রায়শই পপিটার ওয়েব স্ক্র্যাপিং কৌশলগুলিতে ব্যবহৃত হয় উদাহরণ সহ। পরবর্তী নিবন্ধে, আমরা ব্রাউজার কনটেক্সট, ব্রাউজার এবং ব্রাউজার কনটেক্সট ক্লাসটি ব্যাখ্যা করব।

কে মন্ডল সম্পর্কে

কুকুরছানা ক্লাস - কুকুরছানা টিউটোরিয়াল 7 এর একটি দুর্দান্ত শেখার গাইডহাই, আমি কে মন্ডল, আমি একটি শীর্ষস্থানীয় প্রতিষ্ঠানের সাথে যুক্ত। আমি ডোমেন জুড়ে 12+ বছরের কাজের অভিজ্ঞতা রাখছি যেমন, অ্যাপ্লিকেশন বিকাশ, অটোমেশন টেস্টিং, আইটি পরামর্শদাতা। আমি বিভিন্ন প্রযুক্তি শিখতে খুব আগ্রহী। আমি আমার আকাঙ্ক্ষা পূরণ করতে এবং বর্তমানে ল্যাম্বডিজিক্সে দুজনেই একজন লেখক এবং ওয়েবসাইট বিকাশকারী হিসাবে অবদান রাখছি।
লিংকডইন- https://www.linkedin.com/in/kumaresh-mondal/ এ সংযুক্ত করুন

মতামত দিন

আপনার ইমেইল প্রকাশ করা হবে না। প্রয়োজনীয় ক্ষেত্রগুলি * চিহ্নিত করা আছে।

en English
X