অস্বাভাবিক HID ডিভাইসের সাথে সংযোগ করুন

WebHID API ওয়েবসাইটগুলিকে বিকল্প সহায়ক কীবোর্ড এবং বহিরাগত গেমপ্যাড অ্যাক্সেস করার অনুমতি দেয়।

ফ্রাঁসোয়া বিউফোর্ট
François Beaufort

প্রকাশিত: ১৫ সেপ্টেম্বর, ২০২০

Browser Support

  • ক্রোম: ৮৯।
  • প্রান্ত: ৮৯।
  • ফায়ারফক্স: সমর্থিত নয়।
  • সাফারি: সমর্থিত নয়।

Source

অনেক হিউম্যান ইন্টারফেস ডিভাইস (HIDs), যেমন বিকল্প কীবোর্ড বা বহিরাগত গেমপ্যাড, যা খুব নতুন, খুব পুরানো, অথবা সিস্টেমের ডিভাইস ড্রাইভারদের দ্বারা অ্যাক্সেসযোগ্য হওয়ার জন্য খুব অস্বাভাবিক। WebHID API জাভাস্ক্রিপ্টে ডিভাইস-নির্দিষ্ট লজিক বাস্তবায়নের একটি উপায় প্রদান করে এই সমস্যার সমাধান করে।

প্রস্তাবিত ব্যবহারের ক্ষেত্রে

একটি HID ডিভাইস মানুষের কাছ থেকে ইনপুট নেয় বা আউটপুট প্রদান করে। ডিভাইসের উদাহরণগুলির মধ্যে রয়েছে কীবোর্ড, পয়েন্টিং ডিভাইস (মাউস, টাচস্ক্রিন, ইত্যাদি) এবং গেমপ্যাড। HID প্রোটোকল অপারেটিং সিস্টেম ড্রাইভার ব্যবহার করে ডেস্কটপ কম্পিউটারে এই ডিভাইসগুলি অ্যাক্সেস করা সম্ভব করে। ওয়েব প্ল্যাটফর্ম এই ড্রাইভারগুলির উপর নির্ভর করে HID ডিভাইসগুলিকে সমর্থন করে।

বিকল্প সহায়ক কীবোর্ড (যেমন এলগাটো স্ট্রিম ডেক , জাবরা হেডসেট , এক্স-কি ) এবং বহিরাগত গেমপ্যাড সাপোর্টের ক্ষেত্রে অস্বাভাবিক HID ডিভাইসগুলিতে অ্যাক্সেস করতে না পারা বিশেষভাবে বেদনাদায়ক। ডেস্কটপের জন্য ডিজাইন করা গেমপ্যাডগুলি প্রায়শই গেমপ্যাড ইনপুট (বোতাম, জয়স্টিক, ট্রিগার) এবং আউটপুট (LED, রাম্বল) এর জন্য HID ব্যবহার করে।

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

পরিভাষা

একটি হিউম্যান ইন্টারফেস ডিভাইস (HID) মানুষকে ইনপুট নিতে বা আউটপুট দিতে পারে। একটি HID প্রোটোকল আছে, যা একটি হোস্ট এবং একটি ডিভাইসের মধ্যে দ্বি-মুখী যোগাযোগের জন্য একটি মান যা ইনস্টলেশন প্রক্রিয়া সহজ করার জন্য ডিজাইন করা হয়েছে।

HID দুটি মৌলিক ধারণা নিয়ে গঠিত: রিপোর্ট এবং রিপোর্ট বর্ণনাকারী। রিপোর্ট হল সেই ডেটা যা একটি ডিভাইস এবং একটি সফ্টওয়্যার ক্লায়েন্টের মধ্যে বিনিময় করা হয়। রিপোর্ট বর্ণনাকারী ডিভাইসটি যে ডেটা সমর্থন করে তার ফর্ম্যাট এবং অর্থ বর্ণনা করে।

অ্যাপ্লিকেশন এবং HID ডিভাইসগুলি তিনটি ধরণের রিপোর্টের মাধ্যমে বাইনারি ডেটা বিনিময় করে:

রিপোর্টের ধরণ বিবরণ
ইনপুট রিপোর্ট ডিভাইস থেকে অ্যাপ্লিকেশনে পাঠানো ডেটা (যেমন একটি বোতাম টিপলে।)
আউটপুট রিপোর্ট অ্যাপ্লিকেশন থেকে ডিভাইসে পাঠানো ডেটা (যেমন কীবোর্ড ব্যাকলাইট চালু করার অনুরোধ।)
বৈশিষ্ট্য প্রতিবেদন ডেটা যা যেকোনো দিকেই পাঠানো যেতে পারে। ফর্ম্যাটটি ডিভাইস-নির্দিষ্ট।

একটি রিপোর্ট বর্ণনাকারী ডিভাইস দ্বারা সমর্থিত রিপোর্টের বাইনারি ফর্ম্যাট বর্ণনা করে। এর গঠনটি শ্রেণিবদ্ধ এবং শীর্ষ-স্তরের সংগ্রহের মধ্যে পৃথক সংগ্রহ হিসাবে প্রতিবেদনগুলিকে একত্রিত করতে পারে। বর্ণনাকারীর ফর্ম্যাটটি HID স্পেসিফিকেশন দ্বারা সংজ্ঞায়িত করা হয়।

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

WebHID API ব্যবহার করুন

WebHID API সমর্থিত কিনা তা পরীক্ষা করতে, ব্যবহার করুন:

if ("hid" in navigator) {
  // The WebHID API is supported.
}

একটি HID সংযোগ খুলুন

WebHID API ডিজাইনের দিক থেকে অ্যাসিঙ্ক্রোনাস যাতে ইনপুটের অপেক্ষায় ওয়েবসাইট UI ব্লক না হয়। এটি গুরুত্বপূর্ণ কারণ HID ডেটা যেকোনো সময় গ্রহণ করা যেতে পারে, যার জন্য এটি শোনার একটি উপায় প্রয়োজন।

একটি HID সংযোগ খুলতে, প্রথমে একটি HIDDevice অবজেক্ট অ্যাক্সেস করুন। এর জন্য, আপনি navigator.hid.requestDevice() কল করে ব্যবহারকারীকে একটি ডিভাইস নির্বাচন করতে অনুরোধ করতে পারেন, অথবা navigator.hid.getDevices() থেকে একটি বেছে নিতে পারেন যা ওয়েবসাইটটিকে পূর্বে অ্যাক্সেস দেওয়া ডিভাইসগুলির একটি তালিকা প্রদান করে।

navigator.hid.requestDevice() ফাংশনটি একটি বাধ্যতামূলক অবজেক্ট নেয় যা ফিল্টারগুলিকে সংজ্ঞায়িত করে। এগুলি একটি USB বিক্রেতা শনাক্তকারী ( vendorId ), একটি USB পণ্য শনাক্তকারী ( productId ), একটি ব্যবহার পৃষ্ঠা মান ( usagePage ), এবং একটি ব্যবহার মান ( usage ) এর সাথে সংযুক্ত যেকোনো ডিভাইসের সাথে মেলাতে ব্যবহৃত হয়। আপনি এগুলি USB ID রিপোজিটরি এবং HID ব্যবহার টেবিল ডকুমেন্ট থেকে পেতে পারেন।

এই ফাংশন দ্বারা প্রদত্ত একাধিক HIDDevice অবজেক্ট একই ফিজিক্যাল ডিভাইসে একাধিক HID ইন্টারফেস উপস্থাপন করে।

// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2006 // Joy-Con Left
  },
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2007 // Joy-Con Right
  }
];

// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
// Get all devices the user has previously granted the website access to.
const devices = await navigator.hid.getDevices();
নিন্টেন্ডো সুইচ জয়-কন নির্বাচন করার জন্য ব্যবহারকারীর প্রম্পট।

আপনি navigator.hid.requestDevice() এ ঐচ্ছিক exclusionFilters কী ব্যবহার করে ব্রাউজার পিকার থেকে কিছু ডিভাইস বাদ দিতে পারেন যা ত্রুটিপূর্ণ বলে পরিচিত।

// Request access to a device with vendor ID 0xABCD. The device must also have
// a collection with usage page Consumer (0x000C) and usage ID Consumer
// Control (0x0001). The device with product ID 0x1234 is malfunctioning.
const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0xabcd, usagePage: 0x000c, usage: 0x0001 }],
  exclusionFilters: [{ vendorId: 0xabcd, productId: 0x1234 }],
});

একটি HIDDevice অবজেক্টে ডিভাইস সনাক্তকরণের জন্য USB বিক্রেতা এবং পণ্য সনাক্তকারী থাকে। এর collections বৈশিষ্ট্যটি ডিভাইসের রিপোর্ট ফর্ম্যাটের একটি শ্রেণিবদ্ধ বর্ণনা দিয়ে শুরু করা হয়।

for (let collection of device.collections) {
  // An HID collection includes usage, usage page, reports, and subcollections.
  console.log(`Usage: ${collection.usage}`);
  console.log(`Usage page: ${collection.usagePage}`);

  for (let inputReport of collection.inputReports) {
    console.log(`Input report: ${inputReport.reportId}`);
    // Loop through inputReport.items
  }

  for (let outputReport of collection.outputReports) {
    console.log(`Output report: ${outputReport.reportId}`);
    // Loop through outputReport.items
  }

  for (let featureReport of collection.featureReports) {
    console.log(`Feature report: ${featureReport.reportId}`);
    // Loop through featureReport.items
  }

  // Loop through subcollections with collection.children
}

HIDDevice ডিভাইসগুলি ডিফল্টরূপে "বন্ধ" অবস্থায় ফেরত পাঠানো হয় এবং ডেটা পাঠানো বা গ্রহণ করার আগে open() কল করে খুলতে হবে।

// Wait for the HID connection to open before sending/receiving data.
await device.open();

ইনপুট রিপোর্ট গ্রহণ করুন

নিন্টেন্ডো সুইচ জয়-কনস।

একবার HID সংযোগ স্থাপন হয়ে গেলে, আপনি ডিভাইস থেকে "inputreport" ইভেন্টগুলি শুনে ইনকামিং ইনপুট রিপোর্টগুলি পরিচালনা করতে পারেন। এই ইভেন্টগুলিতে HID ডেটা একটি DataView অবজেক্ট ( data ), এটি যে HID ডিভাইসের ( device ) সাথে সম্পর্কিত, এবং ইনপুট রিপোর্টের ( reportId ) সাথে যুক্ত 8-বিট রিপোর্ট আইডি থাকে।

পূর্ববর্তী উদাহরণটি অনুসরণ করে, এই কোডটি আপনাকে জয়-কন রাইট ডিভাইসে ব্যবহারকারী কোন বোতাম টিপেছেন তা সনাক্ত করতে সাহায্য করে যাতে আপনি বাড়িতে এটি চেষ্টা করতে পারেন।

device.addEventListener("inputreport", event => {
  const { data, device, reportId } = event;

  // Handle only the Joy-Con Right device and a specific report ID.
  if (device.productId !== 0x2007 && reportId !== 0x3f) return;

  const value = data.getUint8(0);
  if (value === 0) return;

  const someButtons = { 1: "A", 2: "X", 4: "B", 8: "Y" };
  console.log(`User pressed button ${someButtons[value]}.`);
});

কোডপেনের ডেমোটি দেখুন।

আউটপুট রিপোর্ট পাঠান

একটি HID ডিভাইসে আউটপুট রিপোর্ট পাঠাতে, আউটপুট রিপোর্টের সাথে যুক্ত 8-বিট রিপোর্ট আইডি ( reportId ) এবং বাইটগুলিকে BufferSource ( data ) হিসেবে device.sendReport() এ পাঠান। রিপোর্ট পাঠানোর পরে ফেরত আসা প্রতিশ্রুতি সমাধান হয়ে যায়। যদি HID ডিভাইস রিপোর্ট আইডি ব্যবহার না করে, তাহলে reportId 0 তে সেট করুন।

পরবর্তী উদাহরণটি একটি জয়-কন ডিভাইসের ক্ষেত্রে প্রযোজ্য এবং আপনাকে দেখায় কিভাবে আউটপুট রিপোর্ট দিয়ে এটিকে রাম্বল করা যায়।

// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));

// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));

কোডপেনের ডেমোটি দেখুন।

বৈশিষ্ট্য প্রতিবেদন পাঠান এবং গ্রহণ করুন

ফিচার রিপোর্ট হল একমাত্র ধরণের HID ডেটা রিপোর্ট যা উভয় দিকেই ভ্রমণ করতে পারে। এগুলি HID ডিভাইস এবং অ্যাপ্লিকেশনগুলিকে অ-মানসম্মত HID ডেটা বিনিময় করার অনুমতি দেয়। ইনপুট এবং আউটপুট রিপোর্টের বিপরীতে, অ্যাপ্লিকেশন দ্বারা নিয়মিতভাবে ফিচার রিপোর্ট গ্রহণ বা পাঠানো হয় না।

একটি HID ডিভাইসে একটি ফিচার রিপোর্ট পাঠাতে, ফিচার রিপোর্টের সাথে যুক্ত 8-বিট রিপোর্ট আইডি ( reportId ) এবং বাইটগুলিকে BufferSource ( data ) হিসেবে device.sendFeatureReport() এ পাঠান। রিপোর্ট পাঠানোর পরে ফেরত আসা প্রতিশ্রুতি সমাধান হয়ে যায়। যদি HID ডিভাইস রিপোর্ট আইডি ব্যবহার না করে, তাহলে reportId 0 তে সেট করুন।

এই উদাহরণটি আপনাকে দেখায় যে কীভাবে একটি অ্যাপল কীবোর্ড ব্যাকলাইট ডিভাইসের জন্য অনুরোধ করতে হয়, এটি খুলতে হয় এবং এটিকে ব্লিঙ্ক করতে হয়।

const waitFor = duration => new Promise(r => setTimeout(r, duration));

// Prompt user to select an Apple Keyboard Backlight device.
const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});

// Wait for the HID connection to open.
await device.open();

// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
  // Turn off
  await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
  await waitFor(100);
  // Turn on
  await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
  await waitFor(100);
}

কোডপেনের ডেমোটি দেখুন।

HID ডিভাইস থেকে ফিচার রিপোর্ট পেতে, ফিচার রিপোর্টের সাথে যুক্ত ৮-বিট রিপোর্ট আইডি ( reportId ) device.receiveFeatureReport() এ পাস করুন। ফিরে আসা প্রতিশ্রুতিটি একটি DataView অবজেক্টের সাথে সমাধান করে যাতে ফিচার রিপোর্টের বিষয়বস্তু থাকে। যদি HID ডিভাইস রিপোর্ট আইডি ব্যবহার না করে, তাহলে reportId 0 তে সেট করুন।

// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);

// Read feature report contents with dataView.getInt8(), getUint8(), etc...

সংযোগ এবং সংযোগ বিচ্ছিন্নতা শুনুন

যখন ওয়েবসাইটটিকে একটি HID ডিভাইস অ্যাক্সেস করার অনুমতি দেওয়া হয়, তখন এটি "connect" এবং "disconnect" ইভেন্টগুলি শুনে সংযোগ এবং সংযোগ বিচ্ছিন্ন ইভেন্টগুলি সক্রিয়ভাবে গ্রহণ করতে পারে।

navigator.hid.addEventListener("connect", event => {
  // Automatically open event.device or warn user a device is available.
});

navigator.hid.addEventListener("disconnect", event => {
  // Remove |event.device| from the UI.
});

একটি HID ডিভাইসে অ্যাক্সেস প্রত্যাহার করুন

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

একটি HIDDevice ইনস্ট্যান্সে forget() কল করলে একই ফিজিক্যাল ডিভাইসের সমস্ত HID ইন্টারফেসের অ্যাক্সেস বাতিল হয়ে যাবে।

// Voluntarily revoke access to this HID device.
await device.forget();

যেহেতু forget() Chrome 100 বা তার পরবর্তী সংস্করণে উপলব্ধ, তাই এই বৈশিষ্ট্যটি নিম্নলিখিতগুলির সাথে সমর্থিত কিনা তা পরীক্ষা করুন:

if ("hid" in navigator && "forget" in HIDDevice.prototype) {
  // forget() is supported.
}

ডেভেলপার টিপস

HID ডিবাগ করার জন্য অভ্যন্তরীণ পৃষ্ঠা।

Chrome-এ অভ্যন্তরীণ পৃষ্ঠা, about://device-log দিয়ে HID ডিবাগ করুন যেখানে আপনি একই জায়গায় সমস্ত HID এবং USB ডিভাইস সম্পর্কিত ইভেন্ট দেখতে পাবেন।

HID ডিভাইসের তথ্য মানুষের পঠনযোগ্য ফর্ম্যাটে ডাম্প করার জন্য HID এক্সপ্লোরারটি দেখুন। এটি প্রতিটি HID ব্যবহারের জন্য ব্যবহারের মান থেকে নাম পর্যন্ত ম্যাপ করে।

বেশিরভাগ লিনাক্স সিস্টেমে, HID ডিভাইসগুলি ডিফল্টরূপে কেবল পঠনযোগ্য অনুমতি সহ ম্যাপ করা হয়। Chrome কে একটি HID ডিভাইস খোলার অনুমতি দেওয়ার জন্য, আপনাকে একটি নতুন udev নিয়ম যুক্ত করতে হবে। নিম্নলিখিত বিষয়বস্তু সহ /etc/udev/rules.d/50-yourdevicename.rules এ একটি ফাইল তৈরি করুন:

KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

এই কোডে, [yourdevicevendor] হল 057e , উদাহরণস্বরূপ যদি আপনার ডিভাইসটি একটি Nintendo Switch Joy-Con হয়। আরও নির্দিষ্ট নিয়মের জন্য ATTRS{idProduct} যোগ করা যেতে পারে। নিশ্চিত করুন যে আপনার user plugdev গ্রুপের সদস্য । তারপর, আপনার ডিভাইসটি পুনরায় সংযোগ করুন।

ডেমো

কিছু WebHID ডেমো web.dev/hid-examples এ তালিকাভুক্ত করা হয়েছে।

নিরাপত্তা এবং গোপনীয়তা

স্পেক লেখকরা "শক্তিশালী ওয়েব প্ল্যাটফর্ম বৈশিষ্ট্যগুলিতে অ্যাক্সেস নিয়ন্ত্রণ" -এ সংজ্ঞায়িত মূল নীতিগুলি ব্যবহার করে WebHID API ডিজাইন এবং বাস্তবায়ন করেছেন, যার মধ্যে রয়েছে ব্যবহারকারীর নিয়ন্ত্রণ, স্বচ্ছতা এবং এরগনোমিক্স। এই API ব্যবহারের ক্ষমতা মূলত একটি অনুমতি মডেল দ্বারা নির্ধারিত হয় যা একবারে শুধুমাত্র একটি HID ডিভাইসে অ্যাক্সেস দেয়। ব্যবহারকারীর অনুরোধের প্রতিক্রিয়ায়, ব্যবহারকারীকে একটি নির্দিষ্ট HID ডিভাইস নির্বাচন করার জন্য সক্রিয় পদক্ষেপ নিতে হবে।

নিরাপত্তা বিনিময় বুঝতে, WebHID স্পেসিফিকেশনের নিরাপত্তা এবং গোপনীয়তা বিবেচনা বিভাগটি দেখুন।

এর উপরে, Chrome প্রতিটি শীর্ষ-স্তরের সংগ্রহের ব্যবহার পরীক্ষা করে এবং যদি একটি শীর্ষ-স্তরের সংগ্রহের একটি সুরক্ষিত ব্যবহার থাকে (যেমন জেনেরিক কীবোর্ড, মাউস), তাহলে কোনও ওয়েবসাইট সেই সংগ্রহে সংজ্ঞায়িত কোনও প্রতিবেদন পাঠাতে বা গ্রহণ করতে সক্ষম হবে না। সুরক্ষিত ব্যবহারের সম্পূর্ণ তালিকা সর্বজনীনভাবে উপলব্ধ

মনে রাখবেন যে নিরাপত্তা-সংবেদনশীল HID ডিভাইসগুলি (যেমন শক্তিশালী প্রমাণীকরণের জন্য ব্যবহৃত FIDO HID ডিভাইসগুলি) Chrome-এও ব্লক করা আছে। USB ব্লকলিস্ট এবং HID ব্লকলিস্ট ফাইলগুলি দেখুন।

প্রতিক্রিয়া

Chrome টিম WebHID API সম্পর্কে আপনার চিন্তাভাবনা এবং অভিজ্ঞতা সম্পর্কে শুনতে আগ্রহী।

API ডিজাইন সম্পর্কে আমাদের বলুন

API-তে কি এমন কিছু আছে যা প্রত্যাশা অনুযায়ী কাজ করছে না? নাকি আপনার ধারণা বাস্তবায়নের জন্য প্রয়োজনীয় কোনও পদ্ধতি বা বৈশিষ্ট্য অনুপস্থিত?

WebHID API GitHub রেপোতে একটি স্পেক সমস্যা ফাইল করুন অথবা বিদ্যমান সমস্যায় আপনার মতামত যোগ করুন।

বাস্তবায়নে কোনও সমস্যার কথা জানান

আপনি কি Chrome এর বাস্তবায়নে কোন বাগ খুঁজে পেয়েছেন? নাকি বাস্তবায়নটি স্পেসিফিকেশন থেকে আলাদা?

WebHID বাগ ফাইল করার পদ্ধতি দেখুন। যতটা সম্ভব বিস্তারিত তথ্য অন্তর্ভুক্ত করতে ভুলবেন না, বাগ পুনরুত্পাদন করার জন্য নির্দেশাবলী প্রদান করুন এবং Components কে Blink>HID এ সেট করুন।

সহায়ক লিঙ্ক

স্বীকৃতি

ম্যাট রেনল্ডস এবং জো মেডলিকে তাদের পর্যালোচনার জন্য ধন্যবাদ।