Files
ESPDocs/lib/data/zh-CN/topicos.js
T
Lucas RayanandClaude Sonnet 5.5 5a9fe676fc
CI / Lint e auditorias (push) Successful in 1m10s
CI / Trivy (dependências e segredos) (push) Successful in 12s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m39s
Release / Plano (reaproveitar a imagem?) (push) Successful in 6s
Release / ci (push) Skipped
Release / Publica a imagem (linux/arm64) (push) Successful in 18s
Release / Cria a release no Gitea (push) Successful in 5s
feat(i18n): Simplified Chinese (zh-CN), search answers per locale, fr/de/es data fixes
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 23:28:39 -03:00

185 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Conhecimento de domínio da busca inteligente (zh-CN).
*
* Sem dependências nem alias de import: roda no servidor (montando o índice),
* no navegador (interpretando a consulta) e em scripts de teste no Node.
*
* Todos os textos de `termos` já estão normalizados (minúsculos, sem acento).
*/
export const normalizar = (s = "") =>
String(s)
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "");
/**
* Reconhece pinos ocupados por flash/PSRAM com base no que o diagrama diz.
* "forte": o pino é consumido pela memória (ou é a alimentação dela).
* "fraco": só é afetado em certos modos (ex.: SPI de 8 linhas/octal).
* Avisos genéricos de tensão mínima ("para chips com flash integrada...") não contam.
*/
const nivelMemoria = (palavra) => (p) => {
const citam = p._avs.filter((a) => a.includes(palavra) && !/^对于集成/.test(a));
if (citam.some((a) => /(存储使用|专用于|连接到|用于存储)/.test(a) && !/除非/.test(a))) return "forte";
if (p._fn.some((f) => /(供电|alimentacao|vdd)/.test(f) && f.includes(palavra))) return "forte";
if (citam.length) return "fraco";
return null;
};
/**
* Assuntos que o usuário pode citar. Cada um sabe:
* - termos: como as pessoas escrevem (sinônimos, siglas, plurais comuns);
* - pinoCats / pinoRe: como reconhecer os pinos relacionados no diagrama;
* - pinoRotulo: frase usada no título do resultado de pinos.
* Os dados de especificação ligam-se aos assuntos por SPEC_CAMPOS.
*/
export const TOPICOS = [
{ id: "flash", nome: "闪存", termos: ["flash", "memoria flash", "spi flash", "armazenamento", "firmware", "rom externa", "闪存", "外部闪存", "程序存储", "固件存储"], pinoNivel: nivelMemoria("flash"), pinoRotulo: "连接到闪存" },
{ id: "psram", nome: "PSRAM", termos: ["psram", "ram externa", "spiram", "外部内存", "伪静态"], pinoNivel: nivelMemoria("psram"), pinoRotulo: "连接到 PSRAM" },
{ id: "memoria", nome: "内存", termos: ["memoria", "sram", "heap", "rtc ram", "kb de ram", "memoria interna", "ram", "memory", "内存", "内部内存", "堆", "存储器", "容量"], pinoRotulo: "" },
{ id: "wifi", nome: "Wi-Fi", termos: ["wifi", "wi-fi", "wireless", "sem fio", "802.11", "wifi6", "wifi 6", "wi-fi 6", "无线网", "无线", "无线网络"], pinoCats: ["Antena"], pinoRotulo: "天线与射频" },
{ id: "bluetooth", nome: "蓝牙", termos: ["bluetooth", "ble", "bt", "bluetooth le", "mesh", "蓝牙", "低功耗蓝牙", "经典蓝牙"], pinoCats: ["Antena"], pinoRotulo: "天线与射频" },
{ id: "zigbee", nome: "Zigbee/Thread", termos: ["zigbee", "thread", "802.15.4", "ieee 802.15.4", "组网"], pinoRotulo: "" },
{ id: "matter", nome: "Matter", termos: ["matter", "casa inteligente", "smart home", "智能家居", "家居"], pinoRotulo: "" },
{ id: "ethernet", nome: "以太网", termos: ["ethernet", "rmii", "cabo de rede", "lan", "以太网", "网口", "有线网络", "网线"], pinoCats: ["Ethernet"], pinoRotulo: "以太网" },
{ id: "can", nome: "CAN / TWAI", termos: ["can", "twai", "can bus", "canbus", "can fd", "总线", "车载总线"], pinoRe: /twai|\bcan\b/, pinoRotulo: "CAN/TWAI" },
{ id: "usb", nome: "USB", termos: ["usb", "otg", "usb serial", "usb otg", "hid", "cdc", "原生usb"], pinoCats: ["USB"], pinoRotulo: "USB" },
{ id: "jtag", nome: "JTAG / 调试", termos: ["jtag", "debug", "depuracao", "depurar", "openocd", "gdb", "调试", "调试器", "断点"], pinoCats: ["JTAG"], pinoRotulo: "JTAG" },
{ id: "adc", nome: "ADC", termos: ["adc", "analogico", "entrada analogica", "conversor analogico", "analogread", "saradc", "analog", "模数转换", "模拟输入", "模拟量", "模拟"], pinoCats: ["ADC"], pinoRotulo: "带 ADC 功能" },
{ id: "dac", nome: "DAC", termos: ["dac", "saida analogica", "conversor digital", "数模转换", "模拟输出"], pinoCats: ["DAC"], pinoRotulo: "带 DAC 功能" },
{ id: "touch", nome: "电容触摸", termos: ["touch", "capacitivo", "toque", "touchpad", "sensor de toque", "触摸", "触控", "电容"], pinoCats: ["Touch"], pinoRotulo: "电容触摸" },
{ id: "uart", nome: "UART", termos: ["uart", "serial", "tx", "rx", "txd", "rxd", "porta serial", "串口", "串行", "串行通信"], pinoCats: ["UART"], pinoRotulo: "UART" },
{ id: "spi", nome: "SPI", termos: ["spi", "mosi", "miso", "sclk", "barramento spi", "spi总线"], pinoCats: ["SPI"], pinoRotulo: "SPI" },
{ id: "i2c", nome: "I2C", termos: ["i2c", "sda", "scl", "twi", "iic", "i2c总线"], pinoCats: ["I2C"], pinoRotulo: "I2C" },
{ id: "i2s", nome: "I2S", termos: ["i2s", "audio", "som", "microfone", "pdm", "codec", "音频", "声音", "麦克风", "编解码"], pinoRe: /i2s|\bpdm\b/, pinoRotulo: "I2S / 音频" },
{ id: "pwm", nome: "PWM", termos: ["pwm", "ledc", "mcpwm", "servo", "dimmer", "脉宽", "舵机", "调光", "电机"], pinoRe: /ledc|pwm/, pinoRotulo: "PWM" },
{ id: "sd", nome: "SD 卡 / SDIO", termos: ["sd", "sdio", "sd card", "sdcard", "cartao sd", "microsd", "sdmmc", "mmc", "sd卡", "存储卡", "内存卡"], pinoCats: ["SD"], pinoRe: /sdio|sdmmc|\bsd\b/, pinoRotulo: "SD 卡 / SDIO" },
{ id: "camera", nome: "摄像头", termos: ["camera", "cam", "dvp", "csi", "mipi csi", "ov2640", "video", "摄像头", "相机", "视频", "拍照"], pinoCats: ["CSI"], pinoRe: /\bcam\b|dvp|cam_/, pinoRotulo: "摄像头" },
{ id: "lcd", nome: "显示屏 / LCD", termos: ["lcd", "display", "tela", "dsi", "mipi dsi", "oled", "tft", "lvgl", "rgb", "显示屏", "屏幕", "液晶", "显示"], pinoCats: ["DSI"], pinoRe: /lcd/, pinoRotulo: "显示屏/LCD" },
{ id: "strapping", nome: "启动配置", termos: ["strapping", "boot", "bootstrap", "modo de boot", "download mode", "modo de gravacao", "inicializacao", "启动配置", "启动模式", "下载模式", "烧录模式"], pinoCats: ["Strapping"], pinoRotulo: "启动配置" },
{ id: "energia_pinos", nome: "电源", termos: ["alimentacao", "vdd", "3v3", "3.3v", "tensao", "regulador", "ldo", "fonte", "power", "电源", "供电", "电压", "稳压", "稳压器"], pinoCats: ["Power"], pinoRotulo: "电源" },
{ id: "clock", nome: "时钟 / 晶振", termos: ["clock", "xtal", "cristal", "oscilador", "32khz", "40mhz", "crystal", "时钟", "晶振", "晶体", "振荡器"], pinoCats: ["Clock"], pinoRotulo: "时钟/晶振" },
{ id: "gpio", nome: "GPIO", termos: ["gpio", "entradas e saidas", "通用io", "输入输出"], pinoCats: ["GPIO"], pinoRotulo: "GPIO" },
{ id: "baixo_consumo", nome: "低功耗 / ULP", termos: ["ulp", "lp core", "lp cpu", "coprocessador", "lp gpio", "low power", "rtc gpio", "协处理器", "超低功耗"], pinoCats: ["Low Power"], pinoRotulo: "低功耗(LP/RTC)" },
{ id: "antena", nome: "天线 / 射频", termos: ["antena", "rf", "radiofrequencia", "ipex", "antenna", "天线", "射频"], pinoCats: ["Antena"], pinoRotulo: "天线/射频" },
{ id: "seguranca", nome: "安全", termos: ["seguranca", "secure boot", "criptografia", "encriptacao", "aes", "sha", "rsa", "hmac", "ecdsa", "efuse", "tee", "trng", "rng", "hsm", "protecao", "security", "安全", "加密", "安全启动", "密钥", "熔丝", "可信"], pinoRotulo: "" },
{ id: "consumo", nome: "功耗", termos: ["consumo", "bateria", "deep sleep", "light sleep", "sleep", "modem sleep", "corrente", "miliamperes", "autonomia", "economia de energia", "low power mode", "power consumption", "功耗", "电池", "深度睡眠", "浅睡眠", "电流", "待机", "续航", "省电", "耗电"], pinoRotulo: "" },
{ id: "temperatura", nome: "温度", termos: ["temperatura", "calor", "graus", "faixa de temperatura", "industrial", "temperature", "温度", "工作温度", "高温", "低温"], pinoRotulo: "" },
{ id: "ia", nome: "AI / 加速", termos: ["ia", "ai", "machine learning", "ml", "tinyml", "vetorial", "inteligencia artificial", "rede neural", "esp-nn", "esp-dl", "人工智能", "机器学习", "神经网络", "边缘ai", "向量"], pinoRotulo: "" },
{ id: "processador", nome: "处理器", termos: ["processador", "cpu", "nucleo", "nucleos", "core", "dual core", "single core", "arquitetura", "xtensa", "risc-v", "riscv", "processor", "处理器", "内核", "核心", "双核", "单核", "架构", "主频"], pinoRotulo: "" },
{ id: "frequencia", nome: "频率", termos: ["frequencia", "mhz", "velocidade", "desempenho", "performance", "frequency", "频率", "主频", "速度", "性能"], pinoRotulo: "" },
{ id: "ferramentas", nome: "工具 / SDK", termos: ["esp-idf", "idf", "arduino", "sdk", "toolchain", "versao do idf", "tools", "开发环境", "工具链", "开发框架"], pinoRotulo: "" },
{ id: "encapsulamento", nome: "模组与封装", termos: ["modulo", "modulos", "encapsulamento", "package", "qfn", "wroom", "wrover", "mini-1", "modules", "模组", "封装", "型号"], pinoRotulo: "" },
];
/**
* Campos de public/series.json que respondem a cada assunto.
* `campo` aceita caminho com ponto (seguranca.aes). `secao` é o id da âncora
* na página /series/[key].
*/
export const SPEC_CAMPOS = [
{ campo: "arquitetura", label: "架构", secao: "processador", topicos: ["processador"] },
{ campo: "nucleos", label: "内核", secao: "processador", topicos: ["processador"] },
{ campo: "frequencia", label: "频率", secao: "processador", topicos: ["frequencia", "processador"] },
{ campo: "coprocessador_ulp", label: "ULP 协处理器", secao: "processador", topicos: ["baixo_consumo"] },
{ campo: "aceleradores_ia", label: "AI 加速器", secao: "processador", topicos: ["ia"] },
{ campo: "wifi", label: "Wi-Fi", secao: "conectividade", topicos: ["wifi"] },
{ campo: "bluetooth", label: "蓝牙", secao: "conectividade", topicos: ["bluetooth"] },
{ campo: "zigbee_thread", label: "Zigbee/Thread", secao: "conectividade", topicos: ["zigbee"] },
{ campo: "matter", label: "Matter", secao: "conectividade", topicos: ["matter"] },
{ campo: "ethernet", label: "以太网", secao: "conectividade", topicos: ["ethernet"] },
{ campo: "ethernet_mac", label: "以太网 MAC", secao: "conectividade", topicos: ["ethernet"] },
{ campo: "can", label: "CAN", secao: "conectividade", topicos: ["can"] },
{ campo: "memoria_sram", label: "SRAM", secao: "memoria", topicos: ["memoria"] },
{ campo: "memoria_sram_rtc", label: "RTC SRAM", secao: "memoria", topicos: ["memoria", "baixo_consumo"] },
{ campo: "memoria_rom", label: "ROM", secao: "memoria", topicos: ["memoria"] },
{ campo: "flash_externa", label: "外部闪存", secao: "memoria", topicos: ["flash", "memoria"] },
{ campo: "psram_externa", label: "外部 PSRAM", secao: "memoria", topicos: ["psram", "memoria"] },
{ campo: "gpio", label: "GPIO", secao: "perifericos", topicos: ["gpio"] },
{ campo: "adc", label: "ADC", secao: "perifericos", topicos: ["adc"] },
{ campo: "dac", label: "DAC", secao: "perifericos", topicos: ["dac"] },
{ campo: "touch", label: "触摸", secao: "perifericos", topicos: ["touch"] },
{ campo: "uart", label: "UART", secao: "perifericos", topicos: ["uart"] },
{ campo: "spi", label: "SPI", secao: "perifericos", topicos: ["spi", "flash"] },
{ campo: "i2c", label: "I2C", secao: "perifericos", topicos: ["i2c"] },
{ campo: "i2s", label: "I2S", secao: "perifericos", topicos: ["i2s"] },
{ campo: "pwm", label: "PWM", secao: "perifericos", topicos: ["pwm"] },
{ campo: "usb", label: "USB", secao: "perifericos", topicos: ["usb"] },
{ campo: "lcd", label: "LCD", secao: "interfaces", topicos: ["lcd"] },
{ campo: "camera", label: "摄像头", secao: "interfaces", topicos: ["camera"] },
{ campo: "mipi_csi", label: "MIPI CSI", secao: "interfaces", topicos: ["camera"] },
{ campo: "mipi_dsi", label: "MIPI DSI", secao: "interfaces", topicos: ["lcd"] },
{ campo: "sdio", label: "SDIO", secao: "interfaces", topicos: ["sd"] },
{ campo: "sensor_temperatura", label: "温度传感器", secao: "interfaces", topicos: ["temperatura"] },
{ campo: "seguranca.aes", label: "AES", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.sha", label: "SHA", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.rsa", label: "RSA", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.ecc", label: "ECC", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.ecdsa", label: "ECDSA", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.hmac", label: "HMAC", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.assinatura_digital", label: "数字签名", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.rng", label: "随机数发生器", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.criptografia_flash", label: "闪存加密", secao: "seguranca", topicos: ["seguranca", "flash"] },
{ campo: "seguranca.secure_boot", label: "安全启动", secao: "seguranca", topicos: ["seguranca", "strapping"] },
{ campo: "temperatura_operacao", label: "工作温度", secao: "temperatura", topicos: ["temperatura"] },
{ campo: "temperatura_armazenamento", label: "存储温度", secao: "temperatura", topicos: ["temperatura"] },
{ campo: "esp_idf_minimo", label: "最低 ESP-IDF 版本", secao: "ferramentas", topicos: ["ferramentas"] },
{ campo: "arduino_core", label: "Arduino 核心", secao: "ferramentas", topicos: ["ferramentas"] },
{ campo: "depuracao", label: "调试", secao: "ferramentas", topicos: ["jtag", "ferramentas"] },
{ campo: "encapsulamento", label: "封装", secao: "ferramentas", topicos: ["encapsulamento"] },
{ campo: "modulos", label: "模组", secao: "ferramentas", topicos: ["encapsulamento"] },
];
const ROTULOS_ENERGIA = {
active: "工作",
modem_sleep: "Modem Sleep",
light_sleep: "Light Sleep",
deep_sleep: "Deep Sleep",
hibernation: "Hibernation",
};
const pegar = (obj, caminho) => caminho.split(".").reduce((o, k) => (o == null ? o : o[k]), obj);
/**
* Monta, para cada série, a lista plana de especificações (com os assuntos a
* que respondem) e os pinos do diagrama. É o que o navegador baixa.
*
* @param {Record<string, object>} series conteúdo de public/series.json
* @param {Record<string, object[]>} conexoes pinos por série (public/conexoes)
*/
export function montarConhecimento(series, conexoes) {
const saida = {};
for (const [chave, s] of Object.entries(series)) {
const specs = [];
for (const c of SPEC_CAMPOS) {
const valor = pegar(s, c.campo);
if (valor == null || valor === "") continue;
specs.push({ label: c.label, valor: String(valor), secao: c.secao, topicos: c.topicos });
}
for (const [modo, valor] of Object.entries(s.consumo_energia ?? {})) {
const base = modo.replace(/_cpu.*|_wifi.*/, "");
const label = ROTULOS_ENERGIA[modo] ?? ROTULOS_ENERGIA[base] ?? modo.replace(/_/g, " ");
specs.push({ label: `功耗:${label}`, valor: String(valor), secao: "energia", topicos: ["consumo"] });
}
saida[chave] = {
nome: s.nome_completo ?? chave,
specs,
pinos: (conexoes[chave] ?? []).map((p) => ({
n: String(p.numero),
nome: p.nome,
f: p.funcoes ?? [],
c: p.categorias ?? [],
a: p.avisos ?? [],
})),
};
}
return saida;
}