boosterarena-mcp 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nucleo.mjs +85 -3
- package/package.json +1 -1
- package/servidor.mjs +1 -0
package/dist/nucleo.mjs
CHANGED
|
@@ -1711,6 +1711,51 @@ var FORMA_DEF = {
|
|
|
1711
1711
|
blob: { anch: 26, alto: "cuadrado", color: "#c4b5fd" }
|
|
1712
1712
|
};
|
|
1713
1713
|
|
|
1714
|
+
// ../src/shared/fontsAncho.ts
|
|
1715
|
+
var ANCHO_LETRA = {
|
|
1716
|
+
"Poppins": { 100: [712, 689], 200: [724, 692], 300: [736, 696], 400: [747, 699], 500: [760, 703], 600: [770, 708], 700: [782, 715], 800: [793, 723], 900: [805, 731] },
|
|
1717
|
+
"Montserrat": { 100: [816, 695], 200: [817, 698], 300: [819, 702], 400: [821, 707], 500: [824, 713], 600: [828, 720], 700: [833, 728], 800: [838, 735], 900: [844, 744] },
|
|
1718
|
+
"Nunito": { 200: [754, 595], 300: [760, 602], 400: [766, 610], 500: [769, 614], 600: [772, 618], 700: [780, 627], 800: [789, 638], 900: [798, 649] },
|
|
1719
|
+
"Quicksand": { 300: [738, 625], 400: [736, 631], 500: [735, 638], 600: [734, 644], 700: [732, 650] },
|
|
1720
|
+
"Inter": { 100: [741, 617], 200: [748, 624], 300: [756, 630], 400: [763, 637], 500: [770, 645], 600: [777, 653], 700: [785, 661], 800: [797, 672], 900: [810, 684] },
|
|
1721
|
+
"Roboto": { 100: [696, 586], 200: [697, 588], 300: [698, 591], 400: [702, 596], 500: [703, 596], 600: [704, 596], 700: [704, 596], 800: [705, 596], 900: [706, 597] },
|
|
1722
|
+
"Open Sans": { 300: [717, 611], 400: [737, 635], 500: [744, 644], 600: [752, 654], 700: [769, 675], 800: [789, 696] },
|
|
1723
|
+
"Lato": { 100: [759, 553], 300: [761, 567], 400: [768, 585], 700: [776, 601], 900: [785, 616] },
|
|
1724
|
+
"Raleway": { 100: [756, 625], 200: [756, 629], 300: [756, 634], 400: [756, 640], 500: [756, 646], 600: [756, 652], 700: [757, 658], 800: [758, 665], 900: [761, 674] },
|
|
1725
|
+
"Work Sans": { 100: [692, 611], 200: [701, 618], 300: [716, 632], 400: [738, 651], 500: [742, 654], 600: [746, 657], 700: [751, 661], 800: [757, 666], 900: [763, 671] },
|
|
1726
|
+
"Rubik": { 300: [685, 613], 400: [699, 629], 500: [716, 647], 600: [724, 656], 700: [732, 665], 800: [747, 681], 900: [762, 698] },
|
|
1727
|
+
"Manrope": { 200: [694, 604], 300: [703, 613], 400: [713, 622], 500: [723, 632], 600: [733, 641], 700: [743, 650], 800: [753, 660] },
|
|
1728
|
+
"Archivo": { 100: [764, 570], 200: [764, 577], 300: [763, 586], 400: [763, 597], 500: [763, 607], 600: [763, 619], 700: [779, 639], 800: [804, 671], 900: [840, 714] },
|
|
1729
|
+
"Oswald": { 200: [536, 425], 300: [543, 441], 400: [556, 468], 500: [579, 498], 600: [592, 515], 700: [602, 527] },
|
|
1730
|
+
"Kanit": { 100: [664, 582], 200: [674, 593], 300: [686, 604], 400: [695, 613], 500: [704, 622], 600: [712, 632], 700: [726, 644], 800: [736, 655], 900: [750, 670] },
|
|
1731
|
+
"Fredoka": { 300: [747, 602], 400: [741, 598], 500: [735, 595], 600: [729, 593], 700: [723, 592] },
|
|
1732
|
+
"Baloo 2": { 400: [661, 576], 500: [666, 586], 600: [672, 594], 700: [679, 605], 800: [685, 615] },
|
|
1733
|
+
"Comfortaa": { 300: [817, 708], 400: [823, 707], 500: [827, 707], 600: [830, 706], 700: [834, 705] },
|
|
1734
|
+
"Bebas Neue": { 400: [429, 429] },
|
|
1735
|
+
"Anton": { 400: [524, 534] },
|
|
1736
|
+
"Oswald Title": { 200: [536, 425], 300: [543, 441], 400: [556, 468], 500: [579, 498], 600: [592, 515], 700: [602, 527] },
|
|
1737
|
+
"Righteous": { 400: [708, 614] },
|
|
1738
|
+
"Titan One": { 400: [764, 719] },
|
|
1739
|
+
"Lilita One": { 400: [695, 573] },
|
|
1740
|
+
"Luckiest Guy": { 400: [667, 670] },
|
|
1741
|
+
"Bangers": { 400: [483, 482] },
|
|
1742
|
+
"Lobster": { 400: [689, 505] },
|
|
1743
|
+
"Abril Fatface": { 400: [754, 632] },
|
|
1744
|
+
"Playfair Display": { 400: [727, 604], 500: [741, 611], 600: [755, 618], 700: [770, 625], 800: [784, 632], 900: [799, 639] },
|
|
1745
|
+
"Merriweather": { 300: [765, 652], 400: [774, 662], 500: [776, 665], 600: [779, 669], 700: [789, 678], 800: [794, 684], 900: [798, 688] },
|
|
1746
|
+
"Lora": { 400: [768, 621], 500: [773, 624], 600: [778, 628], 700: [784, 632] },
|
|
1747
|
+
"Roboto Slab": { 100: [743, 634], 200: [749, 638], 300: [754, 641], 400: [770, 650], 500: [779, 657], 600: [783, 659], 700: [787, 662], 800: [793, 665], 900: [800, 669] },
|
|
1748
|
+
"Cormorant Garamond": { 300: [738, 523], 400: [739, 524], 500: [742, 527], 600: [743, 529], 700: [746, 532] },
|
|
1749
|
+
"EB Garamond": { 400: [768, 533], 500: [776, 547], 600: [783, 561], 700: [792, 575], 800: [797, 584] },
|
|
1750
|
+
"Bitter": { 100: [776, 621], 200: [774, 623], 300: [773, 626], 400: [770, 633], 500: [769, 638], 600: [767, 642], 700: [765, 646], 800: [762, 652], 900: [760, 659] },
|
|
1751
|
+
"Caveat": { 400: [563, 420], 500: [565, 422], 600: [567, 424], 700: [569, 426] },
|
|
1752
|
+
"Pacifico": { 400: [913, 520] },
|
|
1753
|
+
"Patrick Hand": { 400: [557, 452] },
|
|
1754
|
+
"Dancing Script": { 400: [677, 462], 500: [690, 466], 600: [703, 471], 700: [717, 475] },
|
|
1755
|
+
"Permanent Marker": { 400: [755, 628] },
|
|
1756
|
+
"Shadows Into Light": { 400: [592, 479] }
|
|
1757
|
+
};
|
|
1758
|
+
|
|
1714
1759
|
// ../src/registro/esquemas.ts
|
|
1715
1760
|
var texto = (que, o = {}) => ({ tipo: "texto", que, ...o });
|
|
1716
1761
|
var html = (que) => ({ tipo: "html", que });
|
|
@@ -2693,6 +2738,19 @@ function pesoReal(family, peso) {
|
|
|
2693
2738
|
if (!w?.length) return peso;
|
|
2694
2739
|
return w.reduce((a, c) => Math.abs(c - peso) < Math.abs(a - peso) ? c : a, w[0]);
|
|
2695
2740
|
}
|
|
2741
|
+
function emsDeTexto(family, peso, texto2, caps, tracking) {
|
|
2742
|
+
const nombre = FONTS.find((f) => f.family === family)?.name;
|
|
2743
|
+
const fila = nombre ? ANCHO_LETRA[nombre] : void 0;
|
|
2744
|
+
let par = [850, 720];
|
|
2745
|
+
if (fila) {
|
|
2746
|
+
const pesos = Object.keys(fila).map(Number);
|
|
2747
|
+
par = fila[pesos.reduce((a, c) => Math.abs(c - peso) < Math.abs(a - peso) ? c : a, pesos[0])];
|
|
2748
|
+
}
|
|
2749
|
+
return Math.max(0, ...(caps ? texto2.toUpperCase() : texto2).split("\n").map((linea2) => {
|
|
2750
|
+
const letras = [...linea2];
|
|
2751
|
+
return letras.reduce((t, ch) => t + (ch !== ch.toLowerCase() ? par[0] : par[1]) / 1e3, 0) + letras.length * tracking;
|
|
2752
|
+
}));
|
|
2753
|
+
}
|
|
2696
2754
|
var esMoneda = (el) => el.kind === "widget" && el.w <= 9;
|
|
2697
2755
|
var COLOR_DE_FONDO = /^(#[0-9a-f]{3,8}|rgba?\([^)]*\)|hsla?\([^)]*\)|(linear|radial)-gradient\(.*\))$/i;
|
|
2698
2756
|
var escenaDe = (b) => b.doc[Math.min(b.escena, b.doc.length - 1)];
|
|
@@ -2713,6 +2771,12 @@ function capaPorNombre(b, ref) {
|
|
|
2713
2771
|
const id = b.aliasCapa.get(ref);
|
|
2714
2772
|
return s.layers.find((l) => l.id === id) ?? s.layers.find((l) => l.name.toLowerCase() === ref.toLowerCase()) ?? s.layers.find((l) => l.name.toLowerCase().includes(ref.toLowerCase()));
|
|
2715
2773
|
}
|
|
2774
|
+
function slideDelEl(b, el) {
|
|
2775
|
+
for (const sc of b.doc) for (const sl of sc.slides) {
|
|
2776
|
+
if (sl.base.some((e) => e.id === el.id) || sl.layers.some((l) => l.els.some((e) => e.id === el.id))) return sl;
|
|
2777
|
+
}
|
|
2778
|
+
return void 0;
|
|
2779
|
+
}
|
|
2716
2780
|
function crearCapa(b, ref) {
|
|
2717
2781
|
const s = slideDe(b);
|
|
2718
2782
|
const capa = { id: nid("capa"), name: ref || `Capa ${s.layers.length + 1}`, els: [] };
|
|
@@ -2806,6 +2870,15 @@ function armarAccion(b, a, el) {
|
|
|
2806
2870
|
return { accion: { type: "resetSequence" } };
|
|
2807
2871
|
case "abrirCapa": {
|
|
2808
2872
|
const ref = txt(a.capa).trim();
|
|
2873
|
+
if (b.estricto) {
|
|
2874
|
+
const sl = slideDelEl(b, el) ?? s;
|
|
2875
|
+
const id = b.aliasCapa.get(ref);
|
|
2876
|
+
const capa2 = sl.layers.find((l) => l.id === id) ?? sl.layers.find((l) => l.name.trim().toLowerCase() === ref.toLowerCase());
|
|
2877
|
+
if (!capa2) {
|
|
2878
|
+
return { accion: null, fallo: `${ref ? `No hay ninguna capa "${ref}"` : "Falta `capa`"} en el slide de ese objeto, y no la creo: un nombre mal escrito dejar\xEDa un bot\xF3n que abre una capa en blanco. ${sl.layers.length ? `Las que hay: ${sl.layers.map((l) => `\xAB${l.name}\xBB`).join(", ")}.` : "Ese slide no tiene capas."} Cr\xE9ala antes con \`nueva_capa\` o poniendo algo dentro con \`capa\`.` };
|
|
2879
|
+
}
|
|
2880
|
+
return { accion: { type: "showLayer", layerId: capa2.id } };
|
|
2881
|
+
}
|
|
2809
2882
|
const capa = capaPorNombre(b, ref) ?? crearCapa(b, ref);
|
|
2810
2883
|
return { accion: { type: "showLayer", layerId: capa.id } };
|
|
2811
2884
|
}
|
|
@@ -2938,6 +3011,15 @@ function ejecutar(b, nombre, args, fab) {
|
|
|
2938
3011
|
const puestos = [];
|
|
2939
3012
|
tpl.layers.forEach((l, i) => {
|
|
2940
3013
|
const dice = textos[i]?.trim() ? textos[i] : i === protagonista && unico.trim() ? unico : l.text;
|
|
3014
|
+
const f0 = (l.fontSize ?? 0) * escala;
|
|
3015
|
+
let k = 1;
|
|
3016
|
+
if (l.fontSize && dice !== l.text) {
|
|
3017
|
+
const peso = l.weight ?? 800;
|
|
3018
|
+
const nuevo = emsDeTexto(l.font, peso, dice, !!l.caps, l.tracking ?? 0);
|
|
3019
|
+
const viejo = emsDeTexto(l.font, peso, l.text, !!l.caps, l.tracking ?? 0);
|
|
3020
|
+
const anchoPx = l.w / 100 * (caja.w / 100) * 1920 * 0.97;
|
|
3021
|
+
if (nuevo * f0 > anchoPx) k = Math.min(1, Math.max(anchoPx / (nuevo * f0), nuevo > viejo ? viejo / nuevo : 1));
|
|
3022
|
+
}
|
|
2941
3023
|
const el = {
|
|
2942
3024
|
id: nid(`tt${i}`),
|
|
2943
3025
|
kind: "text",
|
|
@@ -2948,7 +3030,7 @@ function ejecutar(b, nombre, args, fab) {
|
|
|
2948
3030
|
h: +(l.h / 100 * caja.h).toFixed(2),
|
|
2949
3031
|
text: dice,
|
|
2950
3032
|
...l.font ? { font: l.font } : {},
|
|
2951
|
-
...l.fontSize ? { fontSize: Math.
|
|
3033
|
+
...l.fontSize ? { fontSize: Math.max(10, Math.floor(f0 * k)) } : {},
|
|
2952
3034
|
...l.color ? { color: l.color } : {},
|
|
2953
3035
|
...l.weight ? { weight: l.weight } : {},
|
|
2954
3036
|
...l.tracking ? { tracking: l.tracking } : {},
|
|
@@ -2967,7 +3049,7 @@ function ejecutar(b, nombre, args, fab) {
|
|
|
2967
3049
|
const r = refBase ? i === protagonista ? refBase : `${refBase}_${i + 1}` : "";
|
|
2968
3050
|
plantar(b, el, r, args.capa);
|
|
2969
3051
|
if (refBase) b.alias.set(`${refBase}_${i + 1}`, el.id);
|
|
2970
|
-
puestos.push(`${i + 1}. \xAB${dice}\xBB (id ${el.id})`);
|
|
3052
|
+
puestos.push(`${i + 1}. \xAB${dice}\xBB (id ${el.id})${k < 1 ? ` \u2014 letra ajustada de ${Math.round((l.fontSize ?? 0) * escala)} a ${el.fontSize} para que quepa en su ancho${l.curve ? "; va en ARCO y puede no caber igual, m\xEDralo" : ""}` : ""}`);
|
|
2971
3053
|
});
|
|
2972
3054
|
b.bitacora.push(`\u2712\uFE0F Plantilla \xAB${tpl.name}\xBB`);
|
|
2973
3055
|
return `Plantilla "${tpl.name}" puesta, ${tpl.layers.length} rengl\xF3n(es) agrupados:
|
|
@@ -3829,7 +3911,7 @@ var ARENAS_APP = [
|
|
|
3829
3911
|
{ type: "las-vegas", emoji: "\u{1F3B0}", label: "The Fabulous Las Vegas", blurb: "Tragamonedas para construir frases: jala la palanca, los rodillos frenan uno a uno y sale una combinaci\xF3n \u2014SHE \xB7 WRITTEN \xB7 A LETTER\u2014 que la clase dice en voz alta. De 1 a 4 rodillos, y cada casilla puede ser una palabra o un dibujo.", premium: false, ready: true },
|
|
3830
3912
|
// Sentence Line (app-native): la hermana de Word Factory — mismo motor, pero la pieza es una
|
|
3831
3913
|
// PALABRA y lo que se arma es una oración.
|
|
3832
|
-
{ type: "sentenceline", emoji: "\u{
|
|
3914
|
+
{ type: "sentenceline", emoji: "\u{1F309}", label: "Sentence Bridge", blurb: "El puente de tablones: cada palabra es un tabl\xF3n y hay que ponerlas en orden para armar el puente. El explorador salta al tabl\xF3n que acabas de poner, y si la oraci\xF3n no es, los tablones equivocados se caen al r\xEDo. Cuando la frase queda bien, cruza al otro lado. Se parte sola por los espacios, o marcas trozos con barras \u2014\xABThe black cat / is sleeping / on the sofa\xBB\u2014 para ense\xF1ar la estructura.", premium: false, ready: true },
|
|
3833
3915
|
// Word Factory (app-native): deletrear ordenando las letras que llegan por la cinta.
|
|
3834
3916
|
{ type: "wordfactory", emoji: "\u{1F3ED}", label: "Word Factory", blurb: "Una f\xE1brica de palabras: entra un dibujo y sus letras llegan revueltas por la cinta transportadora. El alumno las mete en la m\xE1quina en el orden correcto y, cuando la palabra sale bien, la m\xE1quina fabrica el objeto y lo sella. Sirve para cualquier vocabulario: sube tu dibujo y escribe su palabra.", premium: false, ready: true },
|
|
3835
3917
|
// Mazo de Cartas (app-native): reemplaza la actividad de cartas de Wordwall. El maestro
|
package/package.json
CHANGED
package/servidor.mjs
CHANGED
|
@@ -369,6 +369,7 @@ async function llamar(nombre, args = {}) {
|
|
|
369
369
|
if (p.type !== 'presentation') throw new Error(`«${p.title}» es un ${p.type}, y por aquí solo se trabajan presentaciones.`);
|
|
370
370
|
yo.proyecto = p;
|
|
371
371
|
yo.borrador = nucleo.nuevoBorrador(Array.isArray(p.document) ? p.document : [], 0, 0, '');
|
|
372
|
+
yo.borrador.estricto = true; // sin nadie delante: lo que el Robot resuelve solo, aquí se niega
|
|
372
373
|
await nucleo.cargarBiblioteca(); // `poner_dibujo` busca en caliente
|
|
373
374
|
// El id va en la PRIMERA línea y con su nombre: antes no venía y había que llamar a
|
|
374
375
|
// `listar_proyectos` y buscar por título, que con ocho pilotos de nombre parecido es jugársela.
|