409 lines
16 KiB
TypeScript
409 lines
16 KiB
TypeScript
/**
|
||
* ESP32 Web Components
|
||
*
|
||
* Uses the official wokwi-boards SVG assets for realistic board rendering.
|
||
* Pin positions are derived from board.json definitions (mm × 5 px/mm).
|
||
*
|
||
* Supports three variants via the `board-kind` attribute:
|
||
* - esp32 → ESP32 DevKit V1 (141 × 265 px)
|
||
* - esp32-s3 → ESP32-S3 DevKitC-1 (128 × 350 px)
|
||
* - esp32-c3 → ESP32-C3 DevKitM-1 (127 × 215 px)
|
||
*/
|
||
|
||
import esp32SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/esp32-devkit-v1/board.svg?url';
|
||
import esp32S3SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/esp32-s3-devkitc-1/board.svg?url';
|
||
import esp32C3SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/esp32-c3-devkitm-1/board.svg?url';
|
||
import esp32DevkitCV4SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/esp32-devkit-c-v4/board.svg?url';
|
||
import esp32CamSvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/esp32-cam/board.svg?url';
|
||
import wemosLolin32SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/wemos-lolin32-lite/board.svg?url';
|
||
import xiaoEsp32S3SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/xiao-esp32-s3/board.svg?url';
|
||
import arduinoNanoEsp32SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/arduino-nano-esp32/board.svg?url';
|
||
import xiaoEsp32C3SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/xiao-esp32-c3/board.svg?url';
|
||
import aitewinC3SvgUrl from '../../../../wokwi-libs/wokwi-boards/boards/aitewinrobot-esp32c3-supermini/board.svg?url';
|
||
|
||
// ─── Pin positions (mm × 5 px/mm, from board.json) ───────────────────────────
|
||
|
||
// ESP32 DevKit V1: 28.2 mm × 53 mm → 141 × 265 px
|
||
// Left col: x = 1.27 mm → 6 px | Right col: x = 26.8 mm → 134 px
|
||
const PINS_ESP32 = [
|
||
{ name: 'EN', x: 6, y: 29 },
|
||
{ name: 'VN', x: 6, y: 42 },
|
||
{ name: 'VP', x: 6, y: 54 },
|
||
{ name: '34', x: 6, y: 67 },
|
||
{ name: '35', x: 6, y: 80 },
|
||
{ name: '32', x: 6, y: 93 },
|
||
{ name: '33', x: 6, y: 105 },
|
||
{ name: '25', x: 6, y: 118 },
|
||
{ name: '26', x: 6, y: 131 },
|
||
{ name: '27', x: 6, y: 143 },
|
||
{ name: '14', x: 6, y: 156 },
|
||
{ name: '12', x: 6, y: 169 },
|
||
{ name: '13', x: 6, y: 181 },
|
||
{ name: 'GND', x: 6, y: 194 },
|
||
{ name: 'VIN', x: 6, y: 207 },
|
||
{ name: '3V3', x: 134, y: 207 },
|
||
{ name: 'GND2', x: 134, y: 194 },
|
||
{ name: '15', x: 134, y: 181 },
|
||
{ name: '2', x: 134, y: 169 },
|
||
{ name: '4', x: 134, y: 156 },
|
||
{ name: 'RX2', x: 134, y: 143 },
|
||
{ name: 'TX2', x: 134, y: 131 },
|
||
{ name: '5', x: 134, y: 118 },
|
||
{ name: '18', x: 134, y: 105 },
|
||
{ name: '19', x: 134, y: 93 },
|
||
{ name: '21', x: 134, y: 80 },
|
||
{ name: 'RX0', x: 134, y: 67 },
|
||
{ name: 'TX0', x: 134, y: 54 },
|
||
{ name: '22', x: 134, y: 42 },
|
||
{ name: '23', x: 134, y: 29 },
|
||
];
|
||
|
||
// ESP32-S3 DevKitC-1: 25.527 mm × 70.057 mm → 128 × 350 px
|
||
// Left col: x = 1.343 mm → 7 px | Right col: x = 24.19 mm → 121 px
|
||
const PINS_ESP32_S3 = [
|
||
{ name: '3V3.1', x: 7, y: 38 },
|
||
{ name: '3V3.2', x: 7, y: 51 },
|
||
{ name: 'RST', x: 7, y: 64 },
|
||
{ name: '4', x: 7, y: 76 },
|
||
{ name: '5', x: 7, y: 89 },
|
||
{ name: '6', x: 7, y: 102 },
|
||
{ name: '7', x: 7, y: 115 },
|
||
{ name: '15', x: 7, y: 127 },
|
||
{ name: '16', x: 7, y: 140 },
|
||
{ name: '17', x: 7, y: 153 },
|
||
{ name: '18', x: 7, y: 166 },
|
||
{ name: '8', x: 7, y: 178 },
|
||
{ name: '3', x: 7, y: 191 },
|
||
{ name: '46', x: 7, y: 203 },
|
||
{ name: '9', x: 7, y: 216 },
|
||
{ name: '10', x: 7, y: 229 },
|
||
{ name: '11', x: 7, y: 242 },
|
||
{ name: '12', x: 7, y: 254 },
|
||
{ name: '13', x: 7, y: 267 },
|
||
{ name: '14', x: 7, y: 280 },
|
||
{ name: '5V', x: 7, y: 292 },
|
||
{ name: 'GND.1', x: 7, y: 305 },
|
||
{ name: 'GND.2', x: 121, y: 38 },
|
||
{ name: 'TX', x: 121, y: 51 },
|
||
{ name: 'RX', x: 121, y: 64 },
|
||
{ name: '1', x: 121, y: 76 },
|
||
{ name: '2', x: 121, y: 89 },
|
||
{ name: '42', x: 121, y: 102 },
|
||
{ name: '41', x: 121, y: 115 },
|
||
{ name: '40', x: 121, y: 127 },
|
||
{ name: '39', x: 121, y: 140 },
|
||
{ name: '38', x: 121, y: 153 },
|
||
{ name: '37', x: 121, y: 166 },
|
||
{ name: '36', x: 121, y: 178 },
|
||
{ name: '35', x: 121, y: 191 },
|
||
{ name: '0', x: 121, y: 203 },
|
||
{ name: '45', x: 121, y: 216 },
|
||
{ name: '48', x: 121, y: 229 },
|
||
{ name: '47', x: 121, y: 242 },
|
||
{ name: '21', x: 121, y: 254 },
|
||
{ name: '20', x: 121, y: 267 },
|
||
{ name: '19', x: 121, y: 280 },
|
||
{ name: 'GND.3', x: 121, y: 292 },
|
||
{ name: 'GND.4', x: 121, y: 305 },
|
||
];
|
||
|
||
// ESP32-C3 DevKitM-1: 25.4 mm × 42.91 mm → 127 × 215 px
|
||
// Left col: x = 1 mm → 5 px | Right col: x = 24.2 mm → 121 px
|
||
const PINS_ESP32_C3 = [
|
||
{ name: 'GND.1', x: 5, y: 26 },
|
||
{ name: '3V3.1', x: 5, y: 39 },
|
||
{ name: '3V3.2', x: 5, y: 51 },
|
||
{ name: '2', x: 5, y: 64 },
|
||
{ name: '3', x: 5, y: 77 },
|
||
{ name: 'GND.2', x: 5, y: 89 },
|
||
{ name: 'RST', x: 5, y: 102 },
|
||
{ name: 'GND.3', x: 5, y: 115 },
|
||
{ name: '0', x: 5, y: 127 },
|
||
{ name: '1', x: 5, y: 140 },
|
||
{ name: '10', x: 5, y: 153 },
|
||
{ name: 'GND.4', x: 5, y: 166 },
|
||
{ name: '5V.1', x: 5, y: 178 },
|
||
{ name: '5V.2', x: 5, y: 191 },
|
||
{ name: 'GND.5', x: 5, y: 204 },
|
||
{ name: 'GND.6', x: 121, y: 204 },
|
||
{ name: '19', x: 121, y: 191 },
|
||
{ name: '18', x: 121, y: 178 },
|
||
{ name: 'GND.7', x: 121, y: 166 },
|
||
{ name: '4', x: 121, y: 153 },
|
||
{ name: '5', x: 121, y: 140 },
|
||
{ name: '6', x: 121, y: 127 },
|
||
{ name: '7', x: 121, y: 115 },
|
||
{ name: 'GND.8', x: 121, y: 102 },
|
||
{ name: '8', x: 121, y: 89 },
|
||
{ name: '9', x: 121, y: 77 },
|
||
{ name: 'GND.9', x: 121, y: 64 },
|
||
{ name: 'RX', x: 121, y: 51 },
|
||
{ name: 'TX', x: 121, y: 39 },
|
||
{ name: 'GND.10', x: 121, y: 26 },
|
||
];
|
||
|
||
// ESP32 DevKit C V4: 27.9 mm × 56.628 mm → 140 × 283 px
|
||
// Left col: x = 1.22 mm → 6 px | Right col: x = 26.66 mm → 133 px
|
||
const PINS_ESP32_DEVKIT_C_V4 = [
|
||
{ name: '3V3', x: 6, y: 38 },
|
||
{ name: 'EN', x: 6, y: 51 },
|
||
{ name: 'VP', x: 6, y: 64 },
|
||
{ name: 'VN', x: 6, y: 76 },
|
||
{ name: '34', x: 6, y: 89 },
|
||
{ name: '35', x: 6, y: 102 },
|
||
{ name: '32', x: 6, y: 114 },
|
||
{ name: '33', x: 6, y: 127 },
|
||
{ name: '25', x: 6, y: 140 },
|
||
{ name: '26', x: 6, y: 152 },
|
||
{ name: '27', x: 6, y: 165 },
|
||
{ name: '14', x: 6, y: 178 },
|
||
{ name: '12', x: 6, y: 191 },
|
||
{ name: 'GND.1', x: 6, y: 203 },
|
||
{ name: '13', x: 6, y: 216 },
|
||
{ name: 'D2', x: 6, y: 229 },
|
||
{ name: 'D3', x: 6, y: 241 },
|
||
{ name: 'CMD', x: 6, y: 254 },
|
||
{ name: '5V', x: 6, y: 267 },
|
||
{ name: 'GND.2', x: 133, y: 38 },
|
||
{ name: '23', x: 133, y: 51 },
|
||
{ name: '22', x: 133, y: 64 },
|
||
{ name: 'TX', x: 133, y: 76 },
|
||
{ name: 'RX', x: 133, y: 89 },
|
||
{ name: '21', x: 133, y: 102 },
|
||
{ name: 'GND.3', x: 133, y: 114 },
|
||
{ name: '19', x: 133, y: 127 },
|
||
{ name: '18', x: 133, y: 140 },
|
||
{ name: '5', x: 133, y: 152 },
|
||
{ name: '17', x: 133, y: 165 },
|
||
{ name: '16', x: 133, y: 178 },
|
||
{ name: '4', x: 133, y: 191 },
|
||
{ name: '0', x: 133, y: 203 },
|
||
{ name: '2', x: 133, y: 216 },
|
||
{ name: '15', x: 133, y: 229 },
|
||
{ name: 'D1', x: 133, y: 241 },
|
||
{ name: 'D0', x: 133, y: 254 },
|
||
{ name: 'CLK', x: 133, y: 267 },
|
||
];
|
||
|
||
// ESP32-CAM: 27.2 mm × 40.42 mm → 136 × 202 px
|
||
// Left col: x = 1.9 mm → 10 px | Right col: x = 24.76 mm → 124 px
|
||
const PINS_ESP32_CAM = [
|
||
{ name: '5V.1', x: 10, y: 25 },
|
||
{ name: 'GND.1', x: 10, y: 37 },
|
||
{ name: '12', x: 10, y: 50 },
|
||
{ name: '13', x: 10, y: 63 },
|
||
{ name: '15', x: 10, y: 76 },
|
||
{ name: '14', x: 10, y: 88 },
|
||
{ name: '2', x: 10, y: 101 },
|
||
{ name: '4', x: 10, y: 114 },
|
||
{ name: '3V3', x: 124, y: 25 },
|
||
{ name: '16', x: 124, y: 37 },
|
||
{ name: '0', x: 124, y: 50 },
|
||
{ name: 'GND.2', x: 124, y: 63 },
|
||
{ name: 'VCC', x: 124, y: 76 },
|
||
{ name: 'RX', x: 124, y: 88 },
|
||
{ name: 'TX', x: 124, y: 101 },
|
||
{ name: 'GND.3', x: 124, y: 114 },
|
||
];
|
||
|
||
// Wemos Lolin32 Lite: 25.6 mm × 50 mm → 128 × 250 px
|
||
// Left col: x = 1.4 mm → 7 px | Right col: x = 24.26 mm → 121 px
|
||
const PINS_WEMOS_LOLIN32 = [
|
||
{ name: 'VP', x: 7, y: 37 },
|
||
{ name: 'VN', x: 7, y: 50 },
|
||
{ name: 'EN', x: 7, y: 62 },
|
||
{ name: 'GPIO34', x: 7, y: 75 },
|
||
{ name: 'GPIO35', x: 7, y: 88 },
|
||
{ name: 'GPIO32', x: 7, y: 100 },
|
||
{ name: 'GPIO33', x: 7, y: 113 },
|
||
{ name: 'GPIO25', x: 7, y: 126 },
|
||
{ name: 'GPIO26', x: 7, y: 139 },
|
||
{ name: 'GPIO27', x: 7, y: 151 },
|
||
{ name: 'GPIO14', x: 7, y: 164 },
|
||
{ name: 'GPIO12', x: 7, y: 177 },
|
||
{ name: 'GND', x: 7, y: 189 },
|
||
{ name: 'GPIO13', x: 121, y: 189 },
|
||
{ name: 'GPIO15', x: 121, y: 177 },
|
||
{ name: 'GPIO2', x: 121, y: 164 },
|
||
{ name: 'GPIO0', x: 121, y: 151 },
|
||
{ name: 'GPIO4', x: 121, y: 139 },
|
||
{ name: 'GPIO16', x: 121, y: 126 },
|
||
{ name: 'GPIO17', x: 121, y: 113 },
|
||
{ name: 'GPIO5', x: 121, y: 100 },
|
||
{ name: 'GPIO18', x: 121, y: 88 },
|
||
{ name: 'GPIO23', x: 121, y: 75 },
|
||
{ name: 'GPIO19', x: 121, y: 62 },
|
||
{ name: 'GPIO22', x: 121, y: 50 },
|
||
{ name: '3V', x: 121, y: 37 },
|
||
];
|
||
|
||
// Seeed XIAO ESP32-S3: 18.1 mm × 23.4 mm → 91 × 117 px
|
||
// Left col: x = 1.43 mm → 7 px | Right col: x = 16.51 mm → 83 px
|
||
const PINS_XIAO_ESP32_S3 = [
|
||
{ name: 'D0', x: 7, y: 25 },
|
||
{ name: 'D1', x: 7, y: 37 },
|
||
{ name: 'D2', x: 7, y: 50 },
|
||
{ name: 'D3', x: 7, y: 63 },
|
||
{ name: 'D4', x: 7, y: 75 },
|
||
{ name: 'D5', x: 7, y: 88 },
|
||
{ name: 'D6', x: 7, y: 101 },
|
||
{ name: 'D7', x: 83, y: 101 },
|
||
{ name: 'D8', x: 83, y: 88 },
|
||
{ name: 'D9', x: 83, y: 75 },
|
||
{ name: 'D10', x: 83, y: 63 },
|
||
{ name: '3V3', x: 83, y: 50 },
|
||
{ name: 'GND', x: 83, y: 37 },
|
||
{ name: '5V', x: 83, y: 25 },
|
||
];
|
||
|
||
// Arduino Nano ESP32: 43.3 mm × 18.05 mm → 217 × 90 px (horizontal layout)
|
||
// Top row: y = 1.5 mm → 8 px | Bottom row: y = 16.74 mm → 84 px
|
||
const PINS_ARDUINO_NANO_ESP32 = [
|
||
{ name: 'D12', x: 24, y: 8 },
|
||
{ name: 'D11', x: 37, y: 8 },
|
||
{ name: 'D10', x: 49, y: 8 },
|
||
{ name: 'D9', x: 62, y: 8 },
|
||
{ name: 'D8', x: 75, y: 8 },
|
||
{ name: 'D7', x: 88, y: 8 },
|
||
{ name: 'D6', x: 100, y: 8 },
|
||
{ name: 'D5', x: 113, y: 8 },
|
||
{ name: 'D4', x: 126, y: 8 },
|
||
{ name: 'D3', x: 138, y: 8 },
|
||
{ name: 'D2', x: 151, y: 8 },
|
||
{ name: 'GND.1',x: 164, y: 8 },
|
||
{ name: 'RST', x: 176, y: 8 },
|
||
{ name: 'RX0', x: 189, y: 8 },
|
||
{ name: 'TX1', x: 202, y: 8 },
|
||
{ name: 'D13', x: 24, y: 84 },
|
||
{ name: '3V3', x: 37, y: 84 },
|
||
{ name: 'B0', x: 49, y: 84 },
|
||
{ name: 'A0', x: 62, y: 84 },
|
||
{ name: 'A1', x: 75, y: 84 },
|
||
{ name: 'A2', x: 88, y: 84 },
|
||
{ name: 'A3', x: 100, y: 84 },
|
||
{ name: 'A4', x: 113, y: 84 },
|
||
{ name: 'A5', x: 126, y: 84 },
|
||
{ name: 'A6', x: 138, y: 84 },
|
||
{ name: 'A7', x: 151, y: 84 },
|
||
{ name: 'VBUS', x: 164, y: 84 },
|
||
{ name: 'B1', x: 176, y: 84 },
|
||
{ name: 'GND.2',x: 189, y: 84 },
|
||
{ name: 'VIN', x: 202, y: 84 },
|
||
];
|
||
|
||
// Seeed XIAO ESP32-C3: 18.1 mm × 23.4 mm → 91 × 117 px (same form as XIAO ESP32-S3)
|
||
const PINS_XIAO_ESP32_C3 = PINS_XIAO_ESP32_S3;
|
||
|
||
// Aitewinrobot ESP32-C3 SuperMini: 18.0 mm × 24.576 mm → 90 × 123 px
|
||
// Left col: x = 1.46 mm → 7 px | Right col: x = 16.70 mm → 84 px
|
||
const PINS_AITEWIN_C3 = [
|
||
{ name: '5', x: 7, y: 16 },
|
||
{ name: '6', x: 7, y: 29 },
|
||
{ name: '7', x: 7, y: 42 },
|
||
{ name: '8', x: 7, y: 54 },
|
||
{ name: '9', x: 7, y: 67 },
|
||
{ name: '10', x: 7, y: 80 },
|
||
{ name: 'RX', x: 7, y: 92 },
|
||
{ name: 'TX', x: 7, y: 105 },
|
||
{ name: '5V', x: 84, y: 16 },
|
||
{ name: 'GND', x: 84, y: 29 },
|
||
{ name: '3V3', x: 84, y: 42 },
|
||
{ name: '4', x: 84, y: 54 },
|
||
{ name: '3', x: 84, y: 67 },
|
||
{ name: '2', x: 84, y: 80 },
|
||
{ name: '1', x: 84, y: 92 },
|
||
{ name: '0', x: 84, y: 105 },
|
||
];
|
||
|
||
// ─── ADC pin map: GPIO → { adc bank, channel within bank, qemu chn index } ──────
|
||
// chn is the index passed to qemu_picsimlab_set_apin():
|
||
// 0-7 → ADC1 channels 0-7 (GPIO 36,37,38,39,32,33,34,35)
|
||
// 8-17 → ADC2 channels 0-9 (GPIO 4,0,2,15,13,12,14,27,25,26)
|
||
export const ESP32_ADC_PIN_MAP: Record<number, { adc: 1 | 2; ch: number; chn: number }> = {
|
||
36: { adc: 1, ch: 0, chn: 0 },
|
||
37: { adc: 1, ch: 1, chn: 1 },
|
||
38: { adc: 1, ch: 2, chn: 2 },
|
||
39: { adc: 1, ch: 3, chn: 3 },
|
||
32: { adc: 1, ch: 4, chn: 4 },
|
||
33: { adc: 1, ch: 5, chn: 5 },
|
||
34: { adc: 1, ch: 6, chn: 6 },
|
||
35: { adc: 1, ch: 7, chn: 7 },
|
||
4: { adc: 2, ch: 0, chn: 8 },
|
||
0: { adc: 2, ch: 1, chn: 9 },
|
||
2: { adc: 2, ch: 2, chn: 10 },
|
||
15: { adc: 2, ch: 3, chn: 11 },
|
||
13: { adc: 2, ch: 4, chn: 12 },
|
||
12: { adc: 2, ch: 5, chn: 13 },
|
||
14: { adc: 2, ch: 6, chn: 14 },
|
||
27: { adc: 2, ch: 7, chn: 15 },
|
||
25: { adc: 2, ch: 8, chn: 16 },
|
||
26: { adc: 2, ch: 9, chn: 17 },
|
||
};
|
||
|
||
// ─── Board config by variant ──────────────────────────────────────────────────
|
||
|
||
interface BoardConfig {
|
||
svgUrl: string;
|
||
w: number;
|
||
h: number;
|
||
pins: { name: string; x: number; y: number }[];
|
||
}
|
||
|
||
const BOARD_CONFIGS: Record<string, BoardConfig> = {
|
||
'esp32': { svgUrl: esp32SvgUrl, w: 141, h: 265, pins: PINS_ESP32 },
|
||
'esp32-s3': { svgUrl: esp32S3SvgUrl, w: 128, h: 350, pins: PINS_ESP32_S3 },
|
||
'esp32-c3': { svgUrl: esp32C3SvgUrl, w: 127, h: 215, pins: PINS_ESP32_C3 },
|
||
'esp32-devkit-c-v4': { svgUrl: esp32DevkitCV4SvgUrl, w: 140, h: 283, pins: PINS_ESP32_DEVKIT_C_V4 },
|
||
'esp32-cam': { svgUrl: esp32CamSvgUrl, w: 136, h: 202, pins: PINS_ESP32_CAM },
|
||
'wemos-lolin32-lite': { svgUrl: wemosLolin32SvgUrl, w: 128, h: 250, pins: PINS_WEMOS_LOLIN32 },
|
||
'xiao-esp32-s3': { svgUrl: xiaoEsp32S3SvgUrl, w: 91, h: 117, pins: PINS_XIAO_ESP32_S3 },
|
||
'arduino-nano-esp32': { svgUrl: arduinoNanoEsp32SvgUrl,w: 217, h: 90, pins: PINS_ARDUINO_NANO_ESP32},
|
||
'xiao-esp32-c3': { svgUrl: xiaoEsp32C3SvgUrl, w: 91, h: 117, pins: PINS_XIAO_ESP32_C3 },
|
||
'aitewinrobot-esp32c3-supermini': { svgUrl: aitewinC3SvgUrl, w: 90, h: 123, pins: PINS_AITEWIN_C3 },
|
||
};
|
||
|
||
// ─── Custom element ───────────────────────────────────────────────────────────
|
||
|
||
class Esp32Element extends HTMLElement {
|
||
static get observedAttributes() { return ['board-kind']; }
|
||
|
||
constructor() {
|
||
super();
|
||
this.attachShadow({ mode: 'open' });
|
||
}
|
||
|
||
connectedCallback() { this.render(); }
|
||
attributeChangedCallback() { this.render(); }
|
||
|
||
private get config(): BoardConfig {
|
||
const kind = this.getAttribute('board-kind') ?? 'esp32';
|
||
return BOARD_CONFIGS[kind] ?? BOARD_CONFIGS['esp32'];
|
||
}
|
||
|
||
get pinInfo() {
|
||
return this.config.pins;
|
||
}
|
||
|
||
private render() {
|
||
if (!this.shadowRoot) return;
|
||
const { svgUrl, w, h } = this.config;
|
||
this.shadowRoot.innerHTML = `
|
||
<style>
|
||
:host { display: inline-block; line-height: 0; }
|
||
img { display: block; }
|
||
</style>
|
||
<img
|
||
src="${svgUrl}"
|
||
width="${w}"
|
||
height="${h}"
|
||
draggable="false"
|
||
alt="ESP32 board"
|
||
/>
|
||
`;
|
||
}
|
||
}
|
||
|
||
if (!customElements.get('wokwi-esp32')) {
|
||
customElements.define('wokwi-esp32', Esp32Element);
|
||
}
|