/** * Generate space-exploration-4.template.html — 9-page worksheet with * addition and subtraction crossing 10 and 20. * * Usage: node tasks/space-exploration/scripts/generate-crossing.mjs * Output: tasks/space-exploration/docs/space-exploration-4.template.html */ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, '../../..'); const pack1Icons = fs.readdirSync(path.join(ROOT, 'assets/themes/nms/icons/pack1')) .filter(f => f.endsWith('.png')) .map(f => `assets/themes/nms/icons/pack1/${f}`); const pack2Icons = fs.readdirSync(path.join(ROOT, 'assets/themes/nms/icons/pack2')) .filter(f => f.endsWith('.png')) .map(f => `assets/themes/nms/icons/pack2/${f}`); function shuffle(arr) { const a = [...arr]; for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } function randInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function pickAlignment() { const opts = ['justify-start', 'justify-center', 'justify-end']; return opts[Math.floor(Math.random() * opts.length)]; } // Generate 20 unique crossing problems (A ± B crosses 10 or 20) function genCrossingProblems() { const problems = []; const seen = new Set(); while (problems.length < 20) { const isAdd = Math.random() < 0.5; const crossAt = Math.random() < 0.5 ? 10 : 20; let a, b; if (isAdd) { if (crossAt === 10) { // A ∈ [1,9], A+B ∈ [11,min(29,A+10)] a = randInt(1, 9); const minB = 11 - a; const maxB = Math.min(10, 29 - a); if (minB > maxB) continue; b = randInt(minB, maxB); } else { // A ∈ [11,19], A+B ∈ [21,min(29,A+10)] a = randInt(11, 19); const minB = 21 - a; const maxB = Math.min(10, 29 - a); if (minB > maxB) continue; b = randInt(minB, maxB); } const result = a + b; if (result < 1 || result > 29) continue; const expr = `${a} + ${b}`; if (!seen.has(expr)) { seen.add(expr); problems.push(expr); } } else { if (crossAt === 10) { // A ∈ [11,19], A−B ∈ [1,9] a = randInt(11, 19); const minB = a - 9; const maxB = Math.min(10, a - 1); if (minB > maxB || minB < 1) continue; b = randInt(Math.max(1, minB), maxB); } else { // A ∈ [21,29], A−B ∈ [11,19] a = randInt(21, 29); const minB = a - 19; const maxB = Math.min(10, a - 11); if (minB > maxB || minB < 1) continue; b = randInt(Math.max(1, minB), maxB); } const result = a - b; if (result < 1 || result > 29) continue; const expr = `${a} − ${b}`; if (!seen.has(expr)) { seen.add(expr); problems.push(expr); } } } return problems; } const pages = [ { hero: 'assets/themes/nms/hero-images/spaceship1.jpeg', footer: 'assets/themes/nms/footers/planet1.jpeg', dir: 'flex-row-reverse', pack: 'pack1' }, { hero: 'assets/themes/nms/hero-images/spaceship2.jpeg', footer: 'assets/themes/nms/footers/planet2.jpeg', dir: '', pack: 'pack1' }, { hero: 'assets/themes/nms/hero-images/spaceship3.png', footer: 'assets/themes/nms/footers/planet3.jpeg', dir: 'flex-row-reverse', pack: 'pack1' }, { hero: 'assets/themes/nms/hero-images/spaceship4.jpeg', footer: 'assets/themes/nms/footers/planet4.jpeg', dir: '', pack: 'pack1' }, { hero: 'assets/themes/nms/hero-images/spaceship5.jpeg', footer: 'assets/themes/nms/footers/planet5.jpeg', dir: 'flex-row-reverse', pack: 'pack1' }, { hero: 'assets/themes/nms/hero-images/spaceship6.jpeg', footer: 'assets/themes/nms/footers/planet6.jpeg', dir: '', pack: 'pack1' }, { hero: 'assets/themes/nms/hero-images/spaceship7.jpeg', footer: 'assets/themes/nms/footers/planet7.jpeg', dir: 'flex-row-reverse', pack: 'pack2' }, { hero: 'assets/themes/nms/hero-images/spaceship8.jpeg', footer: 'assets/themes/nms/footers/planet8.jpeg', dir: '', pack: 'pack2' }, { hero: 'assets/themes/nms/hero-images/spaceship9.jpeg', footer: 'assets/themes/nms/footers/planet9.jpeg', dir: 'flex-row-reverse', pack: 'pack2' }, ]; // Icons: pages 0-5 → pack1 (shuffled twice across 3-page sections), pages 6-8 → pack2 const iconSections = [ shuffle(pack1Icons), // pages 0-2 shuffle(pack1Icons), // pages 3-5 shuffle(pack2Icons), // pages 6-8 ]; function buildProblemCard(icon, expression, alignment) { return `
Собери ресурсы, решая примеры!