aboutsummaryrefslogtreecommitdiff
path: root/modules/ext/calc.js
blob: 9b602f6c00ed718c3b253b43e43a99d62bbf1d1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class CalcModule {
    constructor() {
        this.commands = {};
        this.terminal = null;
        this.units = {
            'km': { to: { 'miles': 0.621371, 'meters': 1000, 'feet': 3280.84 } },
            'miles': { to: { 'km': 1.60934, 'meters': 1609.34, 'feet': 5280 } },
            'meters': { to: { 'km': 0.001, 'miles': 0.000621371, 'feet': 3.28084 } },
            'feet': { to: { 'km': 0.0003048, 'miles': 0.000189394, 'meters': 0.3048 } },
            'kg': { to: { 'pounds': 2.20462, 'grams': 1000, 'ounces': 35.274 } },
            'pounds': { to: { 'kg': 0.453592, 'grams': 453.592, 'ounces': 16 } },
            'grams': { to: { 'kg': 0.001, 'pounds': 0.00220462, 'ounces': 0.035274 } },
            'ounces': { to: { 'kg': 0.0283495, 'pounds': 0.0625, 'grams': 28.3495 } },
            'celsius': { to: { 'fahrenheit': 'c2f', 'kelvin': 'c2k' } },
            'fahrenheit': { to: { 'celsius': 'f2c', 'kelvin': 'f2k' } },
            'kelvin': { to: { 'celsius': 'k2c', 'fahrenheit': 'k2f' } },
            'inch': { to: { 'cm': 2.54, 'mm': 25.4, 'feet': 0.0833333 } },
            'cm': { to: { 'inch': 0.393701, 'mm': 10, 'm': 0.01 } },
            'mm': { to: { 'cm': 0.1, 'inch': 0.0393701, 'm': 0.001 } },
            'liters': { to: { 'gallons': 0.264172, 'ml': 1000, 'cups': 4.22675 } },
            'gallons': { to: { 'liters': 3.78541, 'ml': 3785.41, 'cups': 16 } }
        };
    }
    getHelpInfo() {
        return { 'calc': 'calc <expression> or calc <value> <from-unit> to <to-unit> — Evaluate expressions or convert between units' };
    }
    registerCommands() {
        this.commands['calc'] = (args) => this.calc(args);
    }
    calc(args) {
        if (!args[0]) return this.terminal.print('Usage: calc <expression> or calc <value> <from-unit> to <to-unit>', 'warning');
        const input = args.join(' ');
        const convertMatch = input.match(/^([+-]?\d*\.?\d+)\s*(\w+)\s+(?:to|in|->)\s+(\w+)$/i);
        if (convertMatch) {
            return this.convert(parseFloat(convertMatch[1]), convertMatch[2].toLowerCase(), convertMatch[3].toLowerCase());
        }
        this.evaluate(input);
    }
    evaluate(expr) {
        const sanitized = expr.replace(/[^0-9+\-*/.()%eE\s]/g, '');
        if (!sanitized) return this.terminal.print('Invalid expression', 'error');
        try {
            const result = new Function('return (' + sanitized + ')')();
            if (typeof result === 'number' && !isNaN(result)) {
                this.terminal.print(`${sanitized} = ${result}`, 'success');
            } else {
                this.terminal.print('Invalid result', 'error');
            }
        } catch (e) {
            this.terminal.print(`Error: ${e.message}`, 'error');
        }
    }
    convert(value, from, to) {
        if (!this.units[from]) return this.terminal.print(`Unknown unit: ${from}`, 'error');
        if (!this.units[from].to[to]) {
            const avail = Object.keys(this.units[from].to).join(', ');
            return this.terminal.print(`Cannot convert ${from} to ${to}. Available: ${avail}`, 'warning');
        }
        const factor = this.units[from].to[to];
        if (typeof factor === 'string') {
            let result;
            if (factor === 'c2f') result = value * 9/5 + 32;
            else if (factor === 'c2k') result = value + 273.15;
            else if (factor === 'f2c') result = (value - 32) * 5/9;
            else if (factor === 'f2k') result = (value - 32) * 5/9 + 273.15;
            else if (factor === 'k2c') result = value - 273.15;
            else if (factor === 'k2f') result = (value - 273.15) * 9/5 + 32;
            else return this.terminal.print('Conversion not implemented', 'error');
            this.terminal.print(`${value} ${from} = ${result.toFixed(4)} ${to}`, 'success');
        } else {
            this.terminal.print(`${value} ${from} = ${(value * factor).toFixed(4)} ${to}`, 'success');
        }
    }
}
if (typeof window.webx11 !== 'undefined' && window.webx11) {
    webx11.moduleManager.registerModule(new CalcModule(), 'https://webx11.duckdns.org/spaces/newos4/modules/ext/calc.js');
}