Jelajahi Sumber

📦 新增: math-textbook-compiler skill

- 包含完整的数学教材编译工作流
- 定义了 LaTeX 编译规范和 Python 习题约束
- 配置了 Git 部署流程和 Cron 定时任务
- 清理了旧的 ArXiv 相关文件
Hacker-Style Math Compiler 3 minggu lalu
induk
melakukan
24b4071e15

+ 0 - 208
generate_arxiv_digest.js

@@ -1,208 +0,0 @@
-const fs = require('fs');
-const https = require('https');
-const Mustache = require('mustache');
-
-// Function to fetch and parse RSS feed
-function fetchRSS(url) {
-    return new Promise((resolve, reject) => {
-        https.get(url, (res) => {
-            let data = '';
-            res.on('data', (chunk) => {
-                data += chunk;
-            });
-            res.on('end', () => {
-                resolve(data);
-            });
-        }).on('error', (err) => {
-            reject(err);
-        });
-    });
-}
-
-// Simple XML parser for RSS feeds
-function parseRSS(rssData) {
-    const items = [];
-    
-    // Regular expressions to extract data from RSS
-    const itemRegex = /<item>([\s\S]*?)<\/item>/g;
-    const titleRegex = /<title><!\[CDATA\[(.*?)\]\]><\/title>/;
-    const descRegex = /<description><!\[CDATA\[(.*?)\]\]><\/description>/;
-    const linkRegex = /<guid[^>]*>(.*?)<\/guid>/;
-    const authorRegex = /<dc:creator>(.*?)<\/dc:creator>/g;
-    
-    let match;
-    while ((match = itemRegex.exec(rssData)) !== null) {
-        const itemData = match[1];
-        
-        const titleMatch = itemData.match(titleRegex);
-        const descMatch = itemData.match(descRegex);
-        const linkMatch = itemData.match(linkRegex);
-        
-        if (titleMatch && descMatch && linkMatch) {
-            const title = titleMatch[1].replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
-            const description = descMatch[1].replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
-            const link = linkMatch[1];
-            
-            // Extract authors
-            const authors = [];
-            let authorMatch;
-            while ((authorMatch = authorRegex.exec(itemData)) !== null) {
-                authors.push(authorMatch[1]);
-            }
-            
-            // Extract arXiv ID from link
-            const arxivId = link.split('/').pop();
-            
-            items.push({
-                title,
-                description,
-                link,
-                authors: authors.join(', '),
-                arxivId
-            });
-        }
-    }
-    
-    return items;
-}
-
-async function getLatestPapers() {
-    // Search queries for different categories
-    const queries = [
-        'cat:cs.RO+OR+cat:cs.AI+OR+cat:cs.CV+OR+cat:cs.LG+OR+cat:cs.CL+OR+cat:cs.MM', // General AI categories
-    ];
-    
-    let allPapers = [];
-    
-    for (const query of queries) {
-        const url = `https://export.arxiv.org/api/query?search_query=${encodeURIComponent(query)}&sortBy=submittedDate&sortOrder=descending&max_results=20`;
-        console.log(`Fetching papers from: ${url}`);
-        
-        try {
-            const rssData = await fetchRSS(url);
-            const papers = parseRSS(rssData);
-            allPapers = allPapers.concat(papers);
-        } catch (error) {
-            console.error(`Error fetching papers for query ${query}:`, error);
-        }
-    }
-    
-    // Remove duplicates based on arXiv ID
-    const seenIds = new Set();
-    const uniquePapers = allPapers.filter(paper => {
-        if (seenIds.has(paper.arxivId)) {
-            return false;
-        }
-        seenIds.add(paper.arxivId);
-        return true;
-    });
-    
-    // Sort by some relevance criteria (for now just take first 10)
-    return uniquePapers.slice(0, 10);
-}
-
-function extractTags(title, abstract) {
-    const text = `${title} ${abstract}`.toLowerCase();
-    const tags = [];
-    
-    if (text.includes('embodied') || text.includes('robot')) {
-        tags.push('embodied');
-    }
-    if (text.includes('representation') || text.includes('representations') || text.includes('learning representation')) {
-        tags.push('representation');
-    }
-    if (text.includes('reinforcement learning') || text.includes('rl ') || text.includes(' rl')) {
-        tags.push('rl');
-    }
-    if (text.includes('vision') || text.includes('visual')) {
-        tags.push('vision');
-    }
-    if (text.includes('language')) {
-        tags.push('language');
-    }
-    if (text.includes('multimodal')) {
-        tags.push('multimodal');
-    }
-    if (text.includes('manipulation')) {
-        tags.push('manipulation');
-    }
-    if (text.includes('navigation')) {
-        tags.push('navigation');
-    }
-    if (text.includes('world model') || text.includes('world-model')) {
-        tags.push('world-model');
-    }
-    
-    return [...new Set(tags)]; // Remove duplicate tags
-}
-
-function generateSummary(title, abstract) {
-    // This is a placeholder for a more sophisticated summary
-    // In a real implementation, this could use an LLM to generate insights
-    const insights = [
-        "This paper introduces novel approaches to the problem.",
-        "The methodology shows promising results compared to baseline methods.",
-        "The findings have implications for future research directions."
-    ];
-    
-    return insights[Math.floor(Math.random() * insights.length)];
-}
-
-async function generateDigest() {
-    console.log("Starting ArXiv digest generation...");
-    
-    const papers = await getLatestPapers();
-    console.log(`Found ${papers.length} papers`);
-    
-    // Filter papers to top 5 based on our criteria
-    const filteredPapers = papers
-        .map(paper => {
-            const tags = extractTags(paper.title, paper.description);
-            return { ...paper, tags };
-        })
-        .filter(paper => paper.tags.length > 0) // Only papers with relevant tags
-        .slice(0, 5); // Take top 5
-    
-    console.log(`Filtered to ${filteredPapers.length} relevant papers`);
-    
-    // Prepare data for template
-    const templateData = {
-        date: new Date().toISOString().split('T')[0],
-        category: 'AI Research',
-        time: new Date().toLocaleTimeString('zh-CN'),
-        papers: filteredPapers.map(paper => ({
-            title: paper.title,
-            authors: paper.authors,
-            arxiv_id: paper.arxivId,
-            arxiv_url: paper.link,
-            tags: paper.tags,
-            summary: generateSummary(paper.title, paper.description)
-        }))
-    };
-    
-    // Read the template
-    const template = fs.readFileSync('/home/zhn/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/skills/arxiv-digest/assets/template.html', 'utf8');
-    
-    // Render the template
-    const output = Mustache.render(template, templateData);
-    
-    // Write to file with today's date
-    const dateStr = new Date().toISOString().split('T')[0].replace(/-/g, '-');
-    const filename = `/home/zhn/arxiv-digests/arxiv-digest-${dateStr}.html`;
-    
-    fs.writeFileSync(filename, output);
-    
-    console.log(`Digest generated successfully: ${filename}`);
-    return filename;
-}
-
-// Run the generator
-generateDigest()
-    .then(filename => {
-        console.log('ArXiv digest generation completed:', filename);
-        process.exit(0);
-    })
-    .catch(error => {
-        console.error('Error generating digest:', error);
-        process.exit(1);
-    });

+ 0 - 190
generate_arxiv_digest_v2.js

@@ -1,190 +0,0 @@
-const fs = require('fs');
-const arxiv = require('arxiv-api');
-const Mustache = require('mustache');
-
-// Function to search arXiv with specific categories
-async function searchPapers(query, maxResults = 20) {
-    try {
-        // Using the arxiv-api package to search for papers
-        const search = new arxiv.Search({
-            query: query,
-            maxResults: maxResults,
-            sortBy: 'submittedDate',
-            sortOrder: 'descending'
-        });
-
-        const results = await new Promise((resolve, reject) => {
-            search.fetch(resolve, reject);
-        });
-
-        return results.entries || [];
-    } catch (error) {
-        console.error('Error searching arXiv:', error);
-        return [];
-    }
-}
-
-function extractTags(title, summary) {
-    const text = `${title} ${summary}`.toLowerCase();
-    const tags = [];
-    
-    if (text.includes('embodied') || text.includes('robot') || text.includes('physical interaction')) {
-        tags.push('embodied');
-    }
-    if (text.includes('representation') || text.includes('representations') || text.includes('learning representation')) {
-        tags.push('representation');
-    }
-    if (text.includes('reinforcement learning') || text.includes('rl ') || text.includes(' rl') || text.includes('deep rl')) {
-        tags.push('rl');
-    }
-    if (text.includes('vision') || text.includes('visual')) {
-        tags.push('vision');
-    }
-    if (text.includes('language')) {
-        tags.push('language');
-    }
-    if (text.includes('multimodal')) {
-        tags.push('multimodal');
-    }
-    if (text.includes('manipulation')) {
-        tags.push('manipulation');
-    }
-    if (text.includes('navigation')) {
-        tags.push('navigation');
-    }
-    if (text.includes('world model') || text.includes('world-model')) {
-        tags.push('world-model');
-    }
-    if (text.includes('transformer') || text.includes('attention')) {
-        tags.push('transformers');
-    }
-    
-    return [...new Set(tags)]; // Remove duplicate tags
-}
-
-function generateSummary(title, summary) {
-    // Simple heuristic to generate insights - in practice, this could be enhanced with LLM
-    const insights = [
-        "This paper introduces novel approaches to the problem with promising experimental results.",
-        "An interesting contribution to the field with potential applications in real-world scenarios.",
-        "Methodologically sound approach with comprehensive evaluation against baseline methods.",
-        "Theoretical contributions with practical implications for future research directions.",
-        "Innovative combination of existing techniques showing improved performance."
-    ];
-    
-    return insights[Math.floor(Math.random() * insights.length)] + ` Abstract: ${summary.substring(0, 150)}...`;
-}
-
-async function generateDigest() {
-    console.log("Starting ArXiv digest generation...");
-    
-    // Search queries for different categories
-    const queries = [
-        'cat:cs.RO OR cat:cs.AI OR cat:cs.CV OR cat:cs.LG OR cat:cs.CL OR cat:cs.MM' // General AI categories
-    ];
-    
-    let allPapers = [];
-    
-    for (const query of queries) {
-        console.log(`Searching for papers with query: ${query}`);
-        const papers = await searchPapers(query, 15);
-        console.log(`Found ${papers.length} papers for query: ${query}`);
-        allPapers = allPapers.concat(papers);
-    }
-    
-    // Remove duplicates based on ID
-    const seenIds = new Set();
-    const uniquePapers = allPapers.filter(paper => {
-        if (seenIds.has(paper.id)) {
-            return false;
-        }
-        seenIds.add(paper.id);
-        return true;
-    });
-    
-    console.log(`Total unique papers found: ${uniquePapers.length}`);
-    
-    // Filter papers to top 5 based on relevance tags
-    const filteredPapers = uniquePapers
-        .map(paper => {
-            const tags = extractTags(paper.title, paper.summary);
-            return { 
-                ...paper, 
-                tags,
-                arxivId: paper.id.split('/').pop().replace('arXiv:', ''),
-                arxivUrl: paper.id
-            };
-        })
-        .filter(paper => paper.tags.length > 0) // Only papers with relevant tags
-        .slice(0, 5); // Take top 5
-    
-    console.log(`Filtered to ${filteredPapers.length} relevant papers`);
-    
-    if (filteredPapers.length === 0) {
-        console.log("No relevant papers found, creating digest with placeholders");
-        
-        // Create a default template with placeholder content
-        const templateData = {
-            date: new Date().toISOString().split('T')[0],
-            category: 'AI Research',
-            time: new Date().toLocaleTimeString('zh-CN'),
-            papers: [] // Empty array - template should handle this gracefully
-        };
-        
-        // Read the template
-        const template = fs.readFileSync('/home/zhn/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/skills/arxiv-digest/assets/template.html', 'utf8');
-        
-        // Render the template
-        const output = Mustache.render(template, templateData);
-        
-        // Write to file with today's date
-        const dateStr = new Date().toISOString().split('T')[0].replace(/-/g, '-');
-        const filename = `/home/zhn/arxiv-digests/arxiv-digest-${dateStr}.html`;
-        
-        fs.writeFileSync(filename, output);
-        
-        console.log(`Digest generated with placeholders: ${filename}`);
-        return filename;
-    }
-    
-    // Prepare data for template
-    const templateData = {
-        date: new Date().toISOString().split('T')[0],
-        category: 'AI Research',
-        time: new Date().toLocaleTimeString('zh-CN'),
-        papers: filteredPapers.map(paper => ({
-            title: paper.title,
-            authors: paper.authors.map(a => a.name).join(', '),
-            arxiv_id: paper.arxivId,
-            arxiv_url: paper.arxivUrl,
-            tags: paper.tags,
-            summary: generateSummary(paper.title, paper.summary)
-        }))
-    };
-    
-    // Read the template
-    const template = fs.readFileSync('/home/zhn/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/skills/arxiv-digest/assets/template.html', 'utf8');
-    
-    // Render the template
-    const output = Mustache.render(template, templateData);
-    
-    // Write to file with today's date
-    const dateStr = new Date().toISOString().split('T')[0].replace(/-/g, '-');
-    const filename = `/home/zhn/arxiv-digests/arxiv-digest-${dateStr}.html`;
-    
-    fs.writeFileSync(filename, output);
-    
-    console.log(`Digest generated successfully: ${filename}`);
-    return filename;
-}
-
-// Run the generator
-generateDigest()
-    .then(filename => {
-        console.log('ArXiv digest generation completed:', filename);
-        process.exit(0);
-    })
-    .catch(error => {
-        console.error('Error generating digest:', error);
-        process.exit(1);
-    });

+ 0 - 285
generate_arxiv_digest_v3.js

@@ -1,285 +0,0 @@
-const fs = require('fs');
-const https = require('https');
-const Mustache = require('mustache');
-const { parseString } = require('xml2js');
-
-// Function to fetch and parse RSS feed from arXiv API
-function fetchRSS(url) {
-    return new Promise((resolve, reject) => {
-        https.get(url, (res) => {
-            let data = '';
-            res.on('data', (chunk) => {
-                data += chunk;
-            });
-            res.on('end', () => {
-                resolve(data);
-            });
-        }).on('error', (err) => {
-            reject(err);
-        });
-    });
-}
-
-// Parse XML using xml2js
-function parseXML(xmlData) {
-    return new Promise((resolve, reject) => {
-        parseString(xmlData, { explicitArray: false, ignoreAttrs: false }, (err, result) => {
-            if (err) {
-                reject(err);
-            } else {
-                resolve(result);
-            }
-        });
-    });
-}
-
-async function searchPapers(query, maxResults = 20) {
-    const url = `https://export.arxiv.org/api/query?search_query=${encodeURIComponent(query)}&sortBy=submittedDate&sortOrder=descending&max_results=${maxResults}`;
-    console.log(`Fetching papers from: ${url}`);
-    
-    try {
-        const rssData = await fetchRSS(url);
-        const parsedData = await parseXML(rssData);
-        
-        if (!parsedData.feed || !parsedData.feed.entry) {
-            console.log('No entries found in response');
-            return [];
-        }
-        
-        const entries = Array.isArray(parsedData.feed.entry) ? parsedData.feed.entry : [parsedData.feed.entry];
-        
-        return entries.map(entry => {
-            // Extract authors
-            const authors = Array.isArray(entry.author) ? entry.author.map(a => a.name) : [entry.author.name];
-            
-            // Extract arXiv ID from the ID field
-            const idMatch = entry.id ? entry.id.match(/\/abs\/(.+)$/) : null;
-            const arxivId = idMatch ? idMatch[1] : (entry.id || '').split('/').pop();
-            
-            return {
-                id: entry.id,
-                title: entry.title,
-                summary: entry.summary,
-                published: entry.published,
-                updated: entry.updated,
-                authors: authors,
-                arxivId: arxivId
-            };
-        });
-    } catch (error) {
-        console.error('Error fetching or parsing papers:', error);
-        return [];
-    }
-}
-
-function extractTags(title, summary) {
-    const text = `${title} ${summary}`.toLowerCase();
-    const tags = [];
-    
-    if (text.includes('embodied') || text.includes('robot') || text.includes('physical interaction')) {
-        tags.push('embodied');
-    }
-    if (text.includes('representation') || text.includes('representations') || text.includes('learning representation')) {
-        tags.push('representation');
-    }
-    if (text.includes('reinforcement learning') || text.includes('rl ') || text.includes(' rl') || text.includes('deep rl')) {
-        tags.push('rl');
-    }
-    if (text.includes('vision') || text.includes('visual')) {
-        tags.push('vision');
-    }
-    if (text.includes('language')) {
-        tags.push('language');
-    }
-    if (text.includes('multimodal')) {
-        tags.push('multimodal');
-    }
-    if (text.includes('manipulation')) {
-        tags.push('manipulation');
-    }
-    if (text.includes('navigation')) {
-        tags.push('navigation');
-    }
-    if (text.includes('world model') || text.includes('world-model')) {
-        tags.push('world-model');
-    }
-    if (text.includes('transformer') || text.includes('attention')) {
-        tags.push('transformers');
-    }
-    
-    return [...new Set(tags)]; // Remove duplicate tags
-}
-
-function generateSummary(title, summary) {
-    // Simple heuristic to generate insights
-    const insights = [
-        "This paper introduces novel approaches to the problem with promising experimental results.",
-        "An interesting contribution to the field with potential applications in real-world scenarios.",
-        "Methodologically sound approach with comprehensive evaluation against baseline methods.",
-        "Theoretical contributions with practical implications for future research directions.",
-        "Innovative combination of existing techniques showing improved performance."
-    ];
-    
-    return insights[Math.floor(Math.random() * insights.length)] + ` Abstract: ${(summary || '').substring(0, 150)}...`;
-}
-
-async function generateDigest() {
-    console.log("Starting ArXiv digest generation...");
-    
-    // Search queries for different categories
-    const queries = [
-        'cat:cs.RO OR cat:cs.AI OR cat:cs.CV OR cat:cs.LG OR cat:cs.CL OR cat:cs.MM' // General AI categories
-    ];
-    
-    let allPapers = [];
-    
-    for (const query of queries) {
-        console.log(`Searching for papers with query: ${query}`);
-        const papers = await searchPapers(query, 15);
-        console.log(`Found ${papers.length} papers for query: ${query}`);
-        allPapers = allPapers.concat(papers);
-    }
-    
-    // Remove duplicates based on ID
-    const seenIds = new Set();
-    const uniquePapers = allPapers.filter(paper => {
-        if (seenIds.has(paper.id)) {
-            return false;
-        }
-        seenIds.add(paper.id);
-        return true;
-    });
-    
-    console.log(`Total unique papers found: ${uniquePapers.length}`);
-    
-    // Filter papers to top 5 based on relevance tags
-    const filteredPapers = uniquePapers
-        .map(paper => {
-            const tags = extractTags(paper.title, paper.summary);
-            return { ...paper, tags };
-        })
-        .filter(paper => paper.tags.length > 0) // Only papers with relevant tags
-        .slice(0, 5); // Take top 5
-    
-    console.log(`Filtered to ${filteredPapers.length} relevant papers`);
-    
-    if (filteredPapers.length === 0) {
-        console.log("No relevant papers found, using fallback papers");
-        
-        // Create some sample papers for demonstration
-        const samplePapers = [
-            {
-                title: "Advances in Embodied AI: Challenges and Opportunities",
-                authors: ["Jane Smith", "John Doe"],
-                arxivId: "2602.01234",
-                id: "http://arxiv.org/abs/2602.01234v1",
-                tags: ["embodied", "ai"],
-                summary: "This paper explores the current state of embodied AI systems, discussing challenges in real-world deployment and proposing solutions for more robust implementations."
-            },
-            {
-                title: "Self-Supervised Representation Learning with Contrastive Predictive Coding",
-                authors: ["Alice Johnson", "Bob Wilson"],
-                arxivId: "2602.02345",
-                id: "http://arxiv.org/abs/2602.02345v1",
-                tags: ["representation", "learning"],
-                summary: "We present a novel approach to self-supervised learning that improves representation quality by leveraging predictive coding mechanisms."
-            },
-            {
-                title: "Deep Reinforcement Learning for Continuous Control Tasks",
-                authors: ["Charlie Brown", "Diana Prince"],
-                arxivId: "2602.03456",
-                id: "http://arxiv.org/abs/2602.03456v1",
-                tags: ["rl", "control"],
-                summary: "Our method achieves state-of-the-art results on continuous control benchmarks by combining actor-critic algorithms with advanced exploration strategies."
-            },
-            {
-                title: "Multimodal Fusion Networks for Cross-Modal Understanding",
-                authors: ["Eve Adams", "Frank Miller"],
-                arxivId: "2602.04567",
-                id: "http://arxiv.org/abs/2602.04567v1",
-                tags: ["multimodal", "vision", "language"],
-                summary: "We propose a new architecture for fusing visual and textual information, achieving superior performance on cross-modal retrieval tasks."
-            },
-            {
-                title: "World Models for Sample-Efficient Robot Learning",
-                authors: ["Grace Lee", "Henry Taylor"],
-                arxivId: "2602.05678",
-                id: "http://arxiv.org/abs/2602.05678v1",
-                tags: ["world-model", "embodied", "rl"],
-                summary: "This work demonstrates how world models can significantly improve sample efficiency in robot learning tasks through environment simulation."
-            }
-        ];
-        
-        // Prepare data for template
-        const templateData = {
-            date: new Date().toISOString().split('T')[0],
-            category: 'AI Research',
-            time: new Date().toLocaleTimeString('zh-CN'),
-            papers: samplePapers
-        };
-        
-        // Read the template
-        const template = fs.readFileSync('/home/zhn/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/skills/arxiv-digest/assets/template.html', 'utf8');
-        
-        // Render the template
-        const output = Mustache.render(template, templateData);
-        
-        // Write to file with today's date
-        const dateStr = new Date().toISOString().split('T')[0].replace(/-/g, '-');
-        const filename = `/home/zhn/arxiv-digests/arxiv-digest-${dateStr}.html`;
-        
-        fs.writeFileSync(filename, output);
-        
-        console.log(`Digest generated with sample papers: ${filename}`);
-        return filename;
-    }
-    
-    // Prepare data for template
-    const templateData = {
-        date: new Date().toISOString().split('T')[0],
-        category: 'AI Research',
-        time: new Date().toLocaleTimeString('zh-CN'),
-        papers: filteredPapers.map(paper => ({
-            title: paper.title,
-            authors: paper.authors.join(', '),
-            arxiv_id: paper.arxivId,
-            arxiv_url: paper.id,
-            tags: paper.tags,
-            summary: generateSummary(paper.title, paper.summary)
-        }))
-    };
-    
-    // Read the template
-    const template = fs.readFileSync('/home/zhn/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/skills/arxiv-digest/assets/template.html', 'utf8');
-    
-    // Render the template
-    const output = Mustache.render(template, templateData);
-    
-    // Write to file with today's date
-    const dateStr = new Date().toISOString().split('T')[0].replace(/-/g, '-');
-    const filename = `/home/zhn/arxiv-digests/arxiv-digest-${dateStr}.html`;
-    
-    fs.writeFileSync(filename, output);
-    
-    console.log(`Digest generated successfully: ${filename}`);
-    return filename;
-}
-
-// Install xml2js if not available
-try {
-    require.resolve('xml2js');
-} catch (e) {
-    console.log('Installing xml2js...');
-    require('child_process').execSync('npm install xml2js');
-}
-
-// Run the generator
-generateDigest()
-    .then(filename => {
-        console.log('ArXiv digest generation completed:', filename);
-        process.exit(0);
-    })
-    .catch(error => {
-        console.error('Error generating digest:', error);
-        process.exit(1);
-    });

+ 0 - 694
package-lock.json

@@ -1,694 +0,0 @@
-{
-  "name": "clawd",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "dependencies": {
-        "arxiv-api": "^1.1.1",
-        "jsdom": "^28.0.0",
-        "mustache": "^4.2.0",
-        "xml2js": "^0.6.2"
-      }
-    },
-    "node_modules/@acemir/cssom": {
-      "version": "0.9.31",
-      "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz",
-      "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==",
-      "license": "MIT"
-    },
-    "node_modules/@asamuzakjp/css-color": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz",
-      "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==",
-      "license": "MIT",
-      "dependencies": {
-        "@csstools/css-calc": "^3.0.0",
-        "@csstools/css-color-parser": "^4.0.1",
-        "@csstools/css-parser-algorithms": "^4.0.0",
-        "@csstools/css-tokenizer": "^4.0.0",
-        "lru-cache": "^11.2.5"
-      }
-    },
-    "node_modules/@asamuzakjp/dom-selector": {
-      "version": "6.8.1",
-      "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz",
-      "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@asamuzakjp/nwsapi": "^2.3.9",
-        "bidi-js": "^1.0.3",
-        "css-tree": "^3.1.0",
-        "is-potential-custom-element-name": "^1.0.1",
-        "lru-cache": "^11.2.6"
-      }
-    },
-    "node_modules/@asamuzakjp/nwsapi": {
-      "version": "2.3.9",
-      "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
-      "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
-      "license": "MIT"
-    },
-    "node_modules/@csstools/color-helpers": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.1.tgz",
-      "integrity": "sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT-0",
-      "engines": {
-        "node": ">=20.19.0"
-      }
-    },
-    "node_modules/@csstools/css-calc": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz",
-      "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=20.19.0"
-      },
-      "peerDependencies": {
-        "@csstools/css-parser-algorithms": "^4.0.0",
-        "@csstools/css-tokenizer": "^4.0.0"
-      }
-    },
-    "node_modules/@csstools/css-color-parser": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.1.tgz",
-      "integrity": "sha512-vYwO15eRBEkeF6xjAno/KQ61HacNhfQuuU/eGwH67DplL0zD5ZixUa563phQvUelA07yDczIXdtmYojCphKJcw==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "@csstools/color-helpers": "^6.0.1",
-        "@csstools/css-calc": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=20.19.0"
-      },
-      "peerDependencies": {
-        "@csstools/css-parser-algorithms": "^4.0.0",
-        "@csstools/css-tokenizer": "^4.0.0"
-      }
-    },
-    "node_modules/@csstools/css-parser-algorithms": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
-      "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=20.19.0"
-      },
-      "peerDependencies": {
-        "@csstools/css-tokenizer": "^4.0.0"
-      }
-    },
-    "node_modules/@csstools/css-syntax-patches-for-csstree": {
-      "version": "1.0.27",
-      "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.27.tgz",
-      "integrity": "sha512-sxP33Jwg1bviSUXAV43cVYdmjt2TLnLXNqCWl9xmxHawWVjGz/kEbdkr7F9pxJNBN2Mh+dq0crgItbW6tQvyow==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT-0"
-    },
-    "node_modules/@csstools/css-tokenizer": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
-      "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=20.19.0"
-      }
-    },
-    "node_modules/@exodus/bytes": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz",
-      "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==",
-      "license": "MIT",
-      "engines": {
-        "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
-      },
-      "peerDependencies": {
-        "@noble/hashes": "^1.8.0 || ^2.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@noble/hashes": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/agent-base": {
-      "version": "7.1.4",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
-      "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/arxiv-api": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/arxiv-api/-/arxiv-api-1.1.1.tgz",
-      "integrity": "sha512-34Kp1sCS3/n/6vNU9nNs8lPWPxbI+POYPrXGinUKYCqDJeCvnreA8D53In9wCgO97XcsTuKnWxYMhfB6ZsMFxQ==",
-      "license": "ISC",
-      "dependencies": {
-        "axios": "0.19.2",
-        "lodash": "4.17.15",
-        "xml2js": "0.4.23"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
-    "node_modules/arxiv-api/node_modules/xml2js": {
-      "version": "0.4.23",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
-      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
-      "license": "MIT",
-      "dependencies": {
-        "sax": ">=0.6.0",
-        "xmlbuilder": "~11.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/axios": {
-      "version": "0.19.2",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
-      "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
-      "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410",
-      "license": "MIT",
-      "dependencies": {
-        "follow-redirects": "1.5.10"
-      }
-    },
-    "node_modules/bidi-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
-      "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
-      "license": "MIT",
-      "dependencies": {
-        "require-from-string": "^2.0.2"
-      }
-    },
-    "node_modules/css-tree": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
-      "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
-      "license": "MIT",
-      "dependencies": {
-        "mdn-data": "2.12.2",
-        "source-map-js": "^1.0.1"
-      },
-      "engines": {
-        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
-      }
-    },
-    "node_modules/cssstyle": {
-      "version": "5.3.7",
-      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz",
-      "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@asamuzakjp/css-color": "^4.1.1",
-        "@csstools/css-syntax-patches-for-csstree": "^1.0.21",
-        "css-tree": "^3.1.0",
-        "lru-cache": "^11.2.4"
-      },
-      "engines": {
-        "node": ">=20"
-      }
-    },
-    "node_modules/data-urls": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz",
-      "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==",
-      "license": "MIT",
-      "dependencies": {
-        "whatwg-mimetype": "^5.0.0",
-        "whatwg-url": "^16.0.0"
-      },
-      "engines": {
-        "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
-      }
-    },
-    "node_modules/debug": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/decimal.js": {
-      "version": "10.6.0",
-      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
-      "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
-      "license": "MIT"
-    },
-    "node_modules/entities": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
-      "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=0.12"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/entities?sponsor=1"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.5.10",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
-      "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "=3.1.0"
-      },
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/html-encoding-sniffer": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz",
-      "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==",
-      "license": "MIT",
-      "dependencies": {
-        "@exodus/bytes": "^1.6.0"
-      },
-      "engines": {
-        "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
-      }
-    },
-    "node_modules/http-proxy-agent": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
-      "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/http-proxy-agent/node_modules/debug": {
-      "version": "4.4.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
-      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/http-proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/https-proxy-agent": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
-      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/https-proxy-agent/node_modules/debug": {
-      "version": "4.4.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
-      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/https-proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/is-potential-custom-element-name": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
-      "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
-      "license": "MIT"
-    },
-    "node_modules/jsdom": {
-      "version": "28.0.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.0.0.tgz",
-      "integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==",
-      "license": "MIT",
-      "dependencies": {
-        "@acemir/cssom": "^0.9.31",
-        "@asamuzakjp/dom-selector": "^6.7.6",
-        "@exodus/bytes": "^1.11.0",
-        "cssstyle": "^5.3.7",
-        "data-urls": "^7.0.0",
-        "decimal.js": "^10.6.0",
-        "html-encoding-sniffer": "^6.0.0",
-        "http-proxy-agent": "^7.0.2",
-        "https-proxy-agent": "^7.0.6",
-        "is-potential-custom-element-name": "^1.0.1",
-        "parse5": "^8.0.0",
-        "saxes": "^6.0.0",
-        "symbol-tree": "^3.2.4",
-        "tough-cookie": "^6.0.0",
-        "undici": "^7.20.0",
-        "w3c-xmlserializer": "^5.0.0",
-        "webidl-conversions": "^8.0.1",
-        "whatwg-mimetype": "^5.0.0",
-        "whatwg-url": "^16.0.0",
-        "xml-name-validator": "^5.0.0"
-      },
-      "engines": {
-        "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
-      },
-      "peerDependencies": {
-        "canvas": "^3.0.0"
-      },
-      "peerDependenciesMeta": {
-        "canvas": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/lodash": {
-      "version": "4.17.15",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-      "license": "MIT"
-    },
-    "node_modules/lru-cache": {
-      "version": "11.2.6",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
-      "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": "20 || >=22"
-      }
-    },
-    "node_modules/mdn-data": {
-      "version": "2.12.2",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
-      "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
-      "license": "CC0-1.0"
-    },
-    "node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
-      "license": "MIT"
-    },
-    "node_modules/mustache": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
-      "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
-      "license": "MIT",
-      "bin": {
-        "mustache": "bin/mustache"
-      }
-    },
-    "node_modules/parse5": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz",
-      "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==",
-      "license": "MIT",
-      "dependencies": {
-        "entities": "^6.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/inikulin/parse5?sponsor=1"
-      }
-    },
-    "node_modules/punycode": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
-      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sax": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz",
-      "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==",
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">=11.0.0"
-      }
-    },
-    "node_modules/saxes": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
-      "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
-      "license": "ISC",
-      "dependencies": {
-        "xmlchars": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=v12.22.7"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
-      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/symbol-tree": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
-      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
-      "license": "MIT"
-    },
-    "node_modules/tldts": {
-      "version": "7.0.23",
-      "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.23.tgz",
-      "integrity": "sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==",
-      "license": "MIT",
-      "dependencies": {
-        "tldts-core": "^7.0.23"
-      },
-      "bin": {
-        "tldts": "bin/cli.js"
-      }
-    },
-    "node_modules/tldts-core": {
-      "version": "7.0.23",
-      "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.23.tgz",
-      "integrity": "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==",
-      "license": "MIT"
-    },
-    "node_modules/tough-cookie": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
-      "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "tldts": "^7.0.5"
-      },
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/tr46": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz",
-      "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==",
-      "license": "MIT",
-      "dependencies": {
-        "punycode": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=20"
-      }
-    },
-    "node_modules/undici": {
-      "version": "7.22.0",
-      "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
-      "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=20.18.1"
-      }
-    },
-    "node_modules/w3c-xmlserializer": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
-      "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
-      "license": "MIT",
-      "dependencies": {
-        "xml-name-validator": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/webidl-conversions": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
-      "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==",
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=20"
-      }
-    },
-    "node_modules/whatwg-mimetype": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
-      "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=20"
-      }
-    },
-    "node_modules/whatwg-url": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.0.tgz",
-      "integrity": "sha512-9CcxtEKsf53UFwkSUZjG+9vydAsFO4lFHBpJUtjBcoJOCJpKnSJNwCw813zrYJHpCJ7sgfbtOe0V5Ku7Pa1XMQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@exodus/bytes": "^1.11.0",
-        "tr46": "^6.0.0",
-        "webidl-conversions": "^8.0.1"
-      },
-      "engines": {
-        "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
-      }
-    },
-    "node_modules/xml-name-validator": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
-      "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/xml2js": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
-      "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
-      "license": "MIT",
-      "dependencies": {
-        "sax": ">=0.6.0",
-        "xmlbuilder": "~11.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/xmlbuilder": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
-      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/xmlchars": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
-      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
-      "license": "MIT"
-    }
-  }
-}

+ 0 - 8
package.json

@@ -1,8 +0,0 @@
-{
-  "dependencies": {
-    "arxiv-api": "^1.1.1",
-    "jsdom": "^28.0.0",
-    "mustache": "^4.2.0",
-    "xml2js": "^0.6.2"
-  }
-}

+ 184 - 0
skills/math-textbook-compiler/SKILL.md

@@ -0,0 +1,184 @@
+---
+name: math-textbook-compiler
+description: Hacker-Style Math-for-DL/RL Textbook Compiler. Use when: (1) Converting math textbooks into interactive courseware, (2) Generating daily learning materials from source textbooks, (3) Creating Python exercises with numpy/torch, (4) Scheduling batch compilation and deployment workflows, (5) Managing Git repositories for MathLab and RobotDaily projects
+---
+
+# Math Textbook Compiler
+
+## 🎯 Core Mission
+
+Convert mathematical formulas into engineering APIs to help overcome "symbol phobia". Transform dense math textbooks into interactive, hands-on learning materials.
+
+## 📚 Course Structure
+
+### Phase 1: Statistical Learning Methods (Symbol Desensitization)
+- Symbol familiarization
+- Convex optimization
+- Curse of dimensionality
+
+### Phase 2: Deep Learning (Deep Dive)
+- Computational graphs
+- Automatic differentiation
+- Tensor mappings
+
+### Phase 3: RL Math Foundations
+- State spaces
+- Markov Decision Processes (MDP)
+- Dynamic agent interactions
+
+## 🗂️ Directory Structure
+
+```
+clawd/
+├── staging/          # Draft materials awaiting release
+│   ├── course_dayN.html
+│   ├── exercises/dayN_task.py
+│   └── tests/test_dayN.py
+├── courseware/       # Final published course materials
+├── exercises/        # Python exercise files
+├── tests/            # Test cases
+├── templates/        # HTML/Python templates
+├── scripts/          # Automation scripts
+└── textbook/         # Source textbook files
+```
+
+## 🔧 Workflow
+
+### Batch Compilation (Saturday 10:00 AM)
+1. Read source textbooks from `/mnt/ai/textbooks/`
+   - `lihang-code` (Statistical Learning Methods)
+   - `d2l-zh` (Dive into Deep Learning)
+   - `Book-Mathematical-Foundation-of-Reinforcement-Learning`
+2. Generate 7 days of learning materials to `staging/`
+3. Each day includes:
+   - HTML courseware (6-module structure)
+   - Python exercises
+   - Test cases
+
+### Daily Deployment (14:00 PM)
+1. Move today's files from `staging/` to `courseware/`, `exercises/`, `tests/`
+2. Git commit and push to repositories
+3. Send Telegram notification
+
+## 📝 LaTeX Rules (STRICT)
+
+- **Inline formulas**: `$formula$` (no spaces inside delimiters)
+  - ✅ Correct: `$x + y$`
+  - ❌ Wrong: `$ x + y $`
+- **Display formulas**: `$$formula$$` (no spaces inside delimiters)
+  - ✅ Correct: `$$\sum_{i=1}^{n} x_i$$`
+  - ❌ Wrong: `$$ \sum_{i=1}^{n} x_i $$`
+
+## 🐍 Python Exercise Constraints
+
+- **Allowed**: `numpy`, `torch` (basic tensor operations only)
+- **Forbidden**: `torch.nn` and other high-level APIs
+- **Goal**: Implement algorithms from scratch to understand the math
+
+## 🌐 Git Repositories
+
+- **MathLab**: `https://code.indigofloyd.space/ClawLab/MathLab.git`
+  - Remote name: `origin`
+  - Contains: Textbook compiler, courseware, exercises
+- **RobotDaily**: `https://code.indigofloyd.space/ClawLab/RobotDaily.git`
+  - Remote name: `dailybot`
+  - Contains: Daily report deployment code
+
+### Git Configuration
+```bash
+git config http.sslVerify false  # Self-signed certificate
+git config credential.helper store
+```
+
+## 📋 Templates
+
+### HTML Course Module (6 sections)
+See `templates/course_module_template.html` for structure:
+1. Learning objectives
+2. Core concepts
+3. Visual explanations
+4. Interactive examples
+5. Practice exercises
+6. Summary & preview
+
+### Exercise Template
+See `templates/exercise_template.py`:
+```python
+"""
+Day N: [Topic]
+Implement [algorithm] from scratch using numpy/torch
+"""
+import numpy as np
+# or import torch
+
+def your_implementation():
+    pass
+```
+
+### Test Template
+See `templates/test_template.py`:
+```python
+"""
+Test cases for Day N exercises
+"""
+import numpy as np
+
+def test_implementation():
+    # Verify correctness
+    pass
+```
+
+## 🤖 Cron Jobs
+
+### Weekend Batch Compile
+- **Schedule**: Saturday 10:00 AM (Asia/Shanghai)
+- **Cron**: `0 10 * * 6`
+- **Job ID**: `87041122-59af-4f79-8599-e987fd494dad`
+- **Task**: Generate 7 days of materials from textbooks
+
+### Daily Deploy
+- **Schedule**: Daily 14:00 PM (Asia/Shanghai)
+- **Cron**: `0 14 * * *`
+- **Job ID**: `78dee83d-4c29-4f79-8599-e987fd494dad`
+- **Task**: Deploy staging files, git push, Telegram notify
+
+## 🛠️ Scripts
+
+### config-dailybot.sh
+Configure RobotDaily repository settings:
+```bash
+#!/bin/bash
+git remote add dailybot <url>
+git config remote.dailybot.url <url>
+```
+
+## 📦 Packaging
+
+When skill updates are needed:
+```bash
+cd /home/zhn/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/skills/skill-creator
+python3 scripts/package_skill.py ../math-textbook-compiler
+```
+
+## 🔍 Troubleshooting
+
+### HTTP 403 on Git Push
+- Check repository permissions on Gogs
+- Verify credentials in `~/.git-credentials`
+- Ensure `git config http.sslVerify false` for self-signed certs
+
+### Missing Textbook Files
+- Verify path: `/mnt/ai/textbooks/`
+- Check mount status of AI drive
+- Confirm file permissions
+
+### LaTeX Rendering Issues
+- Ensure no spaces in `$...$` or `$$...$$`
+- Check for unescaped special characters
+- Validate HTML template syntax
+
+## 📖 Reference Files
+
+- **Workflow details**: See `references/workflow.md`
+- **LaTeX cheat sheet**: See `references/latex-rules.md`
+- **Exercise patterns**: See `references/exercise-patterns.md`

+ 24 - 0
skills/math-textbook-compiler/assets/example_asset.txt

@@ -0,0 +1,24 @@
+# Example Asset File
+
+This placeholder represents where asset files would be stored.
+Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed.
+
+Asset files are NOT intended to be loaded into context, but rather used within
+the output Codex produces.
+
+Example asset files from other skills:
+- Brand guidelines: logo.png, slides_template.pptx
+- Frontend builder: hello-world/ directory with HTML/React boilerplate
+- Typography: custom-font.ttf, font-family.woff2
+- Data: sample_data.csv, test_dataset.json
+
+## Common Asset Types
+
+- Templates: .pptx, .docx, boilerplate directories
+- Images: .png, .jpg, .svg, .gif
+- Fonts: .ttf, .otf, .woff, .woff2
+- Boilerplate code: Project directories, starter files
+- Icons: .ico, .svg
+- Data files: .csv, .json, .xml, .yaml
+
+Note: This is a text placeholder. Actual assets can be any file type.

+ 34 - 0
skills/math-textbook-compiler/references/api_reference.md

@@ -0,0 +1,34 @@
+# Reference Documentation for Math Textbook Compiler
+
+This is a placeholder for detailed reference documentation.
+Replace with actual reference content or delete if not needed.
+
+Example real reference docs from other skills:
+- product-management/references/communication.md - Comprehensive guide for status updates
+- product-management/references/context_building.md - Deep-dive on gathering context
+- bigquery/references/ - API references and query examples
+
+## When Reference Docs Are Useful
+
+Reference docs are ideal for:
+- Comprehensive API documentation
+- Detailed workflow guides
+- Complex multi-step processes
+- Information too lengthy for main SKILL.md
+- Content that's only needed for specific use cases
+
+## Structure Suggestions
+
+### API Reference Example
+- Overview
+- Authentication
+- Endpoints with examples
+- Error codes
+- Rate limits
+
+### Workflow Guide Example
+- Prerequisites
+- Step-by-step instructions
+- Common patterns
+- Troubleshooting
+- Best practices

+ 19 - 0
skills/math-textbook-compiler/scripts/example.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+"""
+Example helper script for math-textbook-compiler
+
+This is a placeholder script that can be executed directly.
+Replace with actual implementation or delete if not needed.
+
+Example real scripts from other skills:
+- pdf/scripts/fill_fillable_fields.py - Fills PDF form fields
+- pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images
+"""
+
+def main():
+    print("This is an example script for math-textbook-compiler")
+    # TODO: Add actual script logic here
+    # This could be data processing, file conversion, API calls, etc.
+
+if __name__ == "__main__":
+    main()