// Lógica da faixa de placas sugeridas (components/PlacasSugeridas.jsx): quais placas entram, // em que ordem sorteada e o texto curto de motivo. Sem React, para ficar fácil de testar. import { linkForLocale } from "@/lib/boardLinks"; // Placa de loja oficial entra no sorteio com este peso; as demais valem 1. export const PESO_OFICIAL = 3; export function boardsForChips(boards, chips, locale) { const alvo = new Set(chips); return boards.filter((board) => alvo.has(board["Série"]) && linkForLocale(board, locale)); } // Sorteio ponderado sem reposição (Efraimidis-Spirakis): quanto maior o peso, maior a chance // de ficar no começo, e todas as placas aparecem uma vez na ordem final. export function weightedOrder(boards, random = Math.random) { return boards .map((board) => { const peso = board["Loja Oficial"]?.trim() === "Sim" ? PESO_OFICIAL : 1; return { board, chave: Math.pow(random(), 1 / peso) }; }) .sort((a, b) => b.chave - a.chave) .map(({ board }) => board); } export function imageOf(board) { const src = board.Imagem?.match(/]*\ssrc="([^"]+)"/i)?.[1]; if (!src) return null; return src.startsWith("//") ? `https:${src}` : src; } // Recursos que viram o texto de motivo, do mais característico para o mais comum. const FEATURES = [ { columns: ["Display Touch"], key: "touch" }, { columns: ["Display"], key: "display" }, { columns: ["Câmera"], key: "camera" }, { columns: ["LoRa"], key: "lora" }, { columns: ["GPS"], key: "gps" }, { columns: ["GSM (3G/4G)"], key: "gsm" }, { columns: ["Conector Ethernet"], key: "ethernet" }, { columns: ["RS485"], key: "rs485" }, { columns: ["Radiofrequência"], key: "rf" }, { columns: ["Infravermelho"], key: "ir" }, { columns: ["Bateria Interna"], key: "battery" }, { columns: ["Conector p/ Bateria"], key: "batteryConnector" }, { columns: ["Conector p/ Painel Solar"], key: "solar" }, { columns: ["Wi-Fi 5GHz"], key: "wifi5" }, { columns: ["Suporte a Matter"], key: "matter" }, ]; const LABELS = { pt: { touch: "tela touch", display: "tela", camera: "câmera", lora: "LoRa", gps: "GPS", gsm: "4G/GSM", ethernet: "Ethernet", rs485: "RS485", rf: "rádio sub-GHz", ir: "infravermelho", battery: "bateria", batteryConnector: "conector de bateria", solar: "entrada solar", wifi5: "Wi-Fi 5 GHz", matter: "Matter", optional: "opcional", basic: "placa de desenvolvimento essencial" }, en: { touch: "touchscreen", display: "display", camera: "camera", lora: "LoRa", gps: "GPS", gsm: "4G/GSM", ethernet: "Ethernet", rs485: "RS485", rf: "sub-GHz radio", ir: "infrared", battery: "battery", batteryConnector: "battery connector", solar: "solar input", wifi5: "5 GHz Wi-Fi", matter: "Matter", optional: "optional", basic: "essential development board" }, es: { touch: "pantalla táctil", display: "pantalla", camera: "cámara", lora: "LoRa", gps: "GPS", gsm: "4G/GSM", ethernet: "Ethernet", rs485: "RS485", rf: "radio sub-GHz", ir: "infrarrojos", battery: "batería", batteryConnector: "conector de batería", solar: "entrada solar", wifi5: "Wi-Fi de 5 GHz", matter: "Matter", optional: "opcional", basic: "placa de desarrollo esencial" }, fr: { touch: "écran tactile", display: "écran", camera: "caméra", lora: "LoRa", gps: "GPS", gsm: "4G/GSM", ethernet: "Ethernet", rs485: "RS485", rf: "radio sub-GHz", ir: "infrarouge", battery: "batterie", batteryConnector: "connecteur de batterie", solar: "entrée solaire", wifi5: "Wi-Fi 5 GHz", matter: "Matter", optional: "optionnel", basic: "carte de développement essentielle" }, de: { touch: "Touchscreen", display: "Display", camera: "Kamera", lora: "LoRa", gps: "GPS", gsm: "4G/GSM", ethernet: "Ethernet", rs485: "RS485", rf: "Sub-GHz-Funk", ir: "Infrarot", battery: "Akku", batteryConnector: "Akkuanschluss", solar: "Solareingang", wifi5: "5-GHz-WLAN", matter: "Matter", optional: "optional", basic: "Entwicklungsboard für den Einstieg" }, "zh-CN": { touch: "触摸屏", display: "显示屏", camera: "摄像头", lora: "LoRa", gps: "GPS", gsm: "4G/GSM", ethernet: "以太网", rs485: "RS485", rf: "Sub-GHz 无线电", ir: "红外", battery: "内置电池", batteryConnector: "电池接口", solar: "太阳能输入", wifi5: "5 GHz Wi-Fi", matter: "Matter", optional: "可选", basic: "基础开发板" }, }; // "tela touch, câmera e LoRa": até três recursos, do mais característico para o mais comum. // Quando há touch, a tela comum não entra à parte (já está implícita). export function reasonFor(board, locale) { const rotulos = LABELS[locale] || LABELS.pt; const temTouch = ["Sim", "Opcional"].includes(board["Display Touch"]?.trim()); const itens = []; for (const { columns, key } of FEATURES) { if (key === "display" && temTouch) continue; const valor = board[columns[0]]?.trim(); if (valor !== "Sim" && valor !== "Opcional") continue; const texto = valor === "Opcional" ? `${rotulos[key]} (${rotulos.optional})` : rotulos[key]; itens.push(texto); if (itens.length === 3) break; } if (itens.length === 0) return rotulos.basic; if (locale === "zh-CN") return itens.join("、"); if (itens.length === 1) return itens[0]; const conector = { pt: "e", en: "and", es: "y", fr: "et", de: "und" }[locale] || "e"; return `${itens.slice(0, -1).join(", ")} ${conector} ${itens[itens.length - 1]}`; }