mani-calc 1.2.2 → 2.1.0

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/SETUP.bat ADDED
@@ -0,0 +1,126 @@
1
+ @echo off
2
+ title Mani-Calc Setup
3
+ color 0B
4
+ echo.
5
+ echo ╔═══════════════════════════════════════════════════════════╗
6
+ echo ║ ║
7
+ echo ║ 🧮 MANI-CALC SETUP WIZARD 🧮 ║
8
+ echo ║ ║
9
+ echo ║ Spotlight-style Calculator for Windows ║
10
+ echo ║ ║
11
+ echo ╚═══════════════════════════════════════════════════════════╝
12
+ echo.
13
+
14
+ :: Check if Node.js is installed
15
+ where node >nul 2>&1
16
+ if %errorlevel% neq 0 (
17
+ color 0C
18
+ echo ❌ ERROR: Node.js is not installed!
19
+ echo.
20
+ echo Please install Node.js from: https://nodejs.org/
21
+ echo Then run this setup again.
22
+ echo.
23
+ pause
24
+ exit /b 1
25
+ )
26
+
27
+ echo ✓ Node.js detected
28
+ echo.
29
+
30
+ :: Get the directory where this batch file is located
31
+ cd /d "%~dp0"
32
+
33
+ :: Check if node_modules exists
34
+ if not exist "node_modules" (
35
+ echo 📦 Installing dependencies...
36
+ echo This may take a minute...
37
+ echo.
38
+ call npm install
39
+ if %errorlevel% neq 0 (
40
+ color 0C
41
+ echo.
42
+ echo ❌ ERROR: Failed to install dependencies!
43
+ pause
44
+ exit /b 1
45
+ )
46
+ echo.
47
+ echo ✓ Dependencies installed
48
+ echo.
49
+ )
50
+
51
+ echo.
52
+ echo ═══════════════════════════════════════════════════════════
53
+ echo.
54
+ echo What would you like to do?
55
+ echo.
56
+ echo [1] Install Auto-Start (run automatically when Windows boots)
57
+ echo [2] Start Mani-Calc now
58
+ echo [3] Both (Install Auto-Start AND Start now)
59
+ echo [4] Exit
60
+ echo.
61
+ echo ═══════════════════════════════════════════════════════════
62
+ echo.
63
+
64
+ set /p choice= Enter your choice (1-4):
65
+
66
+ if "%choice%"=="1" goto install_autostart
67
+ if "%choice%"=="2" goto start_now
68
+ if "%choice%"=="3" goto both
69
+ if "%choice%"=="4" goto end
70
+
71
+ echo.
72
+ echo Invalid choice. Please try again.
73
+ pause
74
+ goto end
75
+
76
+ :install_autostart
77
+ echo.
78
+ echo 📝 Installing Auto-Start...
79
+ echo.
80
+ call npm run install-autostart
81
+ echo.
82
+ echo ═══════════════════════════════════════════════════════════
83
+ echo.
84
+ echo ✅ Setup complete!
85
+ echo.
86
+ echo Mani-Calc will now start automatically when Windows boots.
87
+ echo Press Alt+Space anytime to open the calculator!
88
+ echo.
89
+ pause
90
+ goto end
91
+
92
+ :start_now
93
+ echo.
94
+ echo 🚀 Starting Mani-Calc...
95
+ echo.
96
+ echo Press Alt+Space to open the calculator!
97
+ echo Press Ctrl+C in this window to stop.
98
+ echo.
99
+ call npm run overlay
100
+ goto end
101
+
102
+ :both
103
+ echo.
104
+ echo 📝 Installing Auto-Start...
105
+ echo.
106
+ call npm run install-autostart
107
+ echo.
108
+ echo 🚀 Starting Mani-Calc...
109
+ echo.
110
+ echo Press Alt+Space to open the calculator!
111
+ echo You can close this window - Mani-Calc runs in the background!
112
+ echo.
113
+ start "" npm run overlay
114
+ echo.
115
+ echo ═══════════════════════════════════════════════════════════
116
+ echo.
117
+ echo ✅ Setup complete!
118
+ echo.
119
+ echo • Mani-Calc is now running!
120
+ echo • It will start automatically when Windows boots.
121
+ echo • Press Alt+Space anytime to open the calculator!
122
+ echo.
123
+ pause
124
+ goto end
125
+
126
+ :end
package/bin/overlay.js CHANGED
@@ -1,27 +1,95 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { spawn } = require('child_process');
4
3
  const path = require('path');
5
- const electron = require('electron');
6
4
 
7
- const mainScript = path.join(__dirname, '../src/ui/main-electron.js');
5
+ // Check if running directly via electron (electron bin/overlay.js)
6
+ // or via node (node bin/overlay.js)
7
+ if (process.versions.electron) {
8
+ // Running in Electron directly - load main-electron.js
9
+ require('../src/ui/main-electron.js');
10
+ } else {
11
+ // Running from Node - spawn electron
12
+ const { spawn, execSync } = require('child_process');
8
13
 
9
- const child = spawn(electron, [mainScript], {
10
- stdio: 'inherit',
11
- windowsHide: false
12
- });
14
+ // Get electron path (handles both string and object export)
15
+ let electronPath;
16
+ try {
17
+ const electron = require('electron');
18
+ electronPath = typeof electron === 'string' ? electron : electron.toString();
13
19
 
14
- child.on('close', (code) => {
15
- process.exit(code);
16
- });
20
+ // If still not a valid path, try finding electron
21
+ if (!electronPath || typeof electronPath !== 'string') {
22
+ electronPath = require.resolve('electron/cli.js');
23
+ }
24
+ } catch (e) {
25
+ // Fallback: use npx electron
26
+ electronPath = 'npx';
27
+ }
17
28
 
18
- // Handle termination signals
19
- process.on('SIGINT', () => {
20
- child.kill('SIGINT');
21
- process.exit(0);
22
- });
29
+ const mainScript = path.join(__dirname, '../src/ui/main-electron.js');
23
30
 
24
- process.on('SIGTERM', () => {
25
- child.kill('SIGTERM');
26
- process.exit(0);
27
- });
31
+ const args = electronPath === 'npx'
32
+ ? ['electron', mainScript]
33
+ : [mainScript];
34
+
35
+ const child = spawn(electronPath, args, {
36
+ stdio: 'inherit',
37
+ windowsHide: false,
38
+ shell: electronPath === 'npx'
39
+ });
40
+
41
+ let isExiting = false;
42
+
43
+ function gracefulShutdown(signal) {
44
+ if (isExiting) return;
45
+ isExiting = true;
46
+
47
+ console.log(`\n👋 Shutting down Mani-Calc Overlay (${signal})...`);
48
+
49
+ // Try graceful kill first
50
+ try {
51
+ child.kill('SIGTERM');
52
+ } catch (e) { }
53
+
54
+ // On Windows, also try taskkill as backup
55
+ if (process.platform === 'win32') {
56
+ setTimeout(() => {
57
+ try {
58
+ // Kill any remaining electron processes for this app
59
+ execSync('taskkill /IM electron.exe /F 2>nul', { stdio: 'ignore' });
60
+ } catch (e) {
61
+ // Ignore errors - process may already be dead
62
+ }
63
+ process.exit(0);
64
+ }, 500);
65
+ } else {
66
+ process.exit(0);
67
+ }
68
+ }
69
+
70
+ child.on('close', (code) => {
71
+ process.exit(code || 0);
72
+ });
73
+
74
+ child.on('error', (err) => {
75
+ console.error('Failed to start Mani-Calc:', err.message);
76
+ process.exit(1);
77
+ });
78
+
79
+ // Handle termination signals - Windows uses different events
80
+ process.on('SIGINT', () => gracefulShutdown('SIGINT'));
81
+ process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
82
+ process.on('SIGHUP', () => gracefulShutdown('SIGHUP'));
83
+
84
+ // Windows-specific: handle Ctrl+C and window close
85
+ if (process.platform === 'win32') {
86
+ const readline = require('readline');
87
+ const rl = readline.createInterface({
88
+ input: process.stdin,
89
+ output: process.stdout
90
+ });
91
+
92
+ rl.on('close', () => gracefulShutdown('readline-close'));
93
+ rl.on('SIGINT', () => gracefulShutdown('win-SIGINT'));
94
+ }
95
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mani-calc",
3
- "version": "1.2.2",
4
- "description": "Spotlight-style instant calculator for Windows Search | Math, natural language & unit conversions | Offline-first productivity tool",
3
+ "version": "2.1.0",
4
+ "description": "Spotlight-style instant calculator for Windows | Math, Currency, Date/Time, Programmer Mode, Password Generator, Color Converter, Text Utils, Emoji, Web Search, 8 Themes | Offline-first productivity tool",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "mani-calc": "./bin/cli.js",
@@ -10,6 +10,9 @@
10
10
  "scripts": {
11
11
  "start": "node src/index.js",
12
12
  "overlay": "electron bin/overlay.js",
13
+ "stop": "taskkill /IM electron.exe /F",
14
+ "install-autostart": "node scripts/install-autostart.js",
15
+ "uninstall-autostart": "node scripts/uninstall-autostart.js",
13
16
  "install-service": "node scripts/install-service.js",
14
17
  "uninstall-service": "node scripts/uninstall-service.js",
15
18
  "test": "node test/test.js"
@@ -22,7 +25,15 @@
22
25
  "productivity",
23
26
  "spotlight",
24
27
  "instant-calculation",
25
- "unit-conversion"
28
+ "unit-conversion",
29
+ "currency-converter",
30
+ "date-calculator",
31
+ "programmer-calculator",
32
+ "hex-converter",
33
+ "system-commands",
34
+ "themes",
35
+ "overlay",
36
+ "hotkey"
26
37
  ],
27
38
  "author": "Manideep Reddy Eevuri",
28
39
  "license": "MIT",
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Mani-Calc Auto-Start Installer
4
+ * Adds Mani-Calc to Windows Startup so it runs automatically
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { execSync } = require('child_process');
10
+
11
+ const APP_NAME = 'Mani-Calc';
12
+ const STARTUP_FOLDER = path.join(
13
+ process.env.APPDATA,
14
+ 'Microsoft\\Windows\\Start Menu\\Programs\\Startup'
15
+ );
16
+
17
+ function getProjectRoot() {
18
+ return path.resolve(__dirname, '..');
19
+ }
20
+
21
+ function createStartupShortcut() {
22
+ console.log('\n🚀 Installing Mani-Calc Auto-Start...\n');
23
+
24
+ const projectRoot = getProjectRoot();
25
+ const overlayScript = path.join(projectRoot, 'bin', 'overlay.js');
26
+ const shortcutPath = path.join(STARTUP_FOLDER, `${APP_NAME}.vbs`);
27
+
28
+ // Check if overlay.js exists
29
+ if (!fs.existsSync(overlayScript)) {
30
+ console.error('❌ Error: overlay.js not found!');
31
+ console.error(` Expected at: ${overlayScript}`);
32
+ process.exit(1);
33
+ }
34
+
35
+ // Get node path
36
+ const nodePath = process.execPath;
37
+ const npmPath = path.join(path.dirname(nodePath), 'npm.cmd');
38
+
39
+ // Create a VBS script that runs the overlay silently (no console window)
40
+ const vbsContent = `
41
+ ' Mani-Calc Auto-Start Script
42
+ ' This script launches Mani-Calc Overlay silently at Windows startup
43
+
44
+ Set WshShell = CreateObject("WScript.Shell")
45
+ WshShell.CurrentDirectory = "${projectRoot.replace(/\\/g, '\\\\')}"
46
+ WshShell.Run """${npmPath.replace(/\\/g, '\\\\')}""" & " run overlay", 0, False
47
+ Set WshShell = Nothing
48
+ `.trim();
49
+
50
+ try {
51
+ fs.writeFileSync(shortcutPath, vbsContent);
52
+ console.log('✅ Auto-start installed successfully!\n');
53
+ console.log('📁 Startup script created at:');
54
+ console.log(` ${shortcutPath}\n`);
55
+ console.log('📝 What this means:');
56
+ console.log(' • Mani-Calc will start automatically when Windows boots');
57
+ console.log(' • It runs silently in the background (no console window)');
58
+ console.log(' • Press Alt+Space anytime to use the calculator\n');
59
+ console.log('💡 To start it now, run: npm run overlay\n');
60
+ console.log('🗑️ To remove auto-start later, run: npm run uninstall-autostart\n');
61
+ } catch (error) {
62
+ console.error('❌ Failed to create startup script:', error.message);
63
+ process.exit(1);
64
+ }
65
+ }
66
+
67
+ function main() {
68
+ // Check if running on Windows
69
+ if (process.platform !== 'win32') {
70
+ console.error('❌ This script only works on Windows!');
71
+ process.exit(1);
72
+ }
73
+
74
+ // Check if Startup folder exists
75
+ if (!fs.existsSync(STARTUP_FOLDER)) {
76
+ console.error('❌ Windows Startup folder not found!');
77
+ console.error(` Expected at: ${STARTUP_FOLDER}`);
78
+ process.exit(1);
79
+ }
80
+
81
+ createStartupShortcut();
82
+ }
83
+
84
+ main();
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Mani-Calc Auto-Start Uninstaller
4
+ * Removes Mani-Calc from Windows Startup
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const APP_NAME = 'Mani-Calc';
11
+ const STARTUP_FOLDER = path.join(
12
+ process.env.APPDATA,
13
+ 'Microsoft\\Windows\\Start Menu\\Programs\\Startup'
14
+ );
15
+
16
+ function removeStartupShortcut() {
17
+ console.log('\n🗑️ Removing Mani-Calc Auto-Start...\n');
18
+
19
+ const shortcutPath = path.join(STARTUP_FOLDER, `${APP_NAME}.vbs`);
20
+
21
+ if (!fs.existsSync(shortcutPath)) {
22
+ console.log('ℹ️ Auto-start was not installed (nothing to remove).\n');
23
+ return;
24
+ }
25
+
26
+ try {
27
+ fs.unlinkSync(shortcutPath);
28
+ console.log('✅ Auto-start removed successfully!\n');
29
+ console.log('📝 What this means:');
30
+ console.log(' • Mani-Calc will NO longer start automatically');
31
+ console.log(' • You can still run it manually with: npm run overlay\n');
32
+ console.log('💡 To re-enable auto-start, run: npm run install-autostart\n');
33
+ } catch (error) {
34
+ console.error('❌ Failed to remove startup script:', error.message);
35
+ process.exit(1);
36
+ }
37
+ }
38
+
39
+ function main() {
40
+ // Check if running on Windows
41
+ if (process.platform !== 'win32') {
42
+ console.error('❌ This script only works on Windows!');
43
+ process.exit(1);
44
+ }
45
+
46
+ removeStartupShortcut();
47
+ }
48
+
49
+ main();
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Currency Converter Module
3
+ * Supports real-time and offline currency conversion
4
+ */
5
+
6
+ class CurrencyConverter {
7
+ constructor() {
8
+ // Fallback exchange rates (USD base) - Updated periodically
9
+ this.fallbackRates = {
10
+ USD: 1,
11
+ EUR: 0.92,
12
+ GBP: 0.79,
13
+ INR: 83.12,
14
+ JPY: 148.50,
15
+ CAD: 1.35,
16
+ AUD: 1.53,
17
+ CHF: 0.88,
18
+ CNY: 7.19,
19
+ HKD: 7.82,
20
+ SGD: 1.34,
21
+ KRW: 1320.50,
22
+ MXN: 17.15,
23
+ BRL: 4.97,
24
+ RUB: 89.50,
25
+ ZAR: 18.75,
26
+ AED: 3.67,
27
+ SAR: 3.75,
28
+ THB: 35.20,
29
+ MYR: 4.72,
30
+ PHP: 55.80,
31
+ IDR: 15650,
32
+ VND: 24350,
33
+ NZD: 1.62,
34
+ SEK: 10.45,
35
+ NOK: 10.65,
36
+ DKK: 6.88,
37
+ PLN: 4.02,
38
+ TRY: 30.25,
39
+ TWD: 31.50,
40
+ PKR: 278.50,
41
+ BDT: 110.25,
42
+ NGN: 890.50,
43
+ EGP: 30.90,
44
+ COP: 3950,
45
+ ARS: 815.50,
46
+ CLP: 885.50,
47
+ PEN: 3.72,
48
+ ILS: 3.65,
49
+ CZK: 22.85,
50
+ HUF: 355.50,
51
+ RON: 4.58
52
+ };
53
+
54
+ this.rates = { ...this.fallbackRates };
55
+ this.lastUpdate = null;
56
+ this.cacheTimeout = 3600000; // 1 hour cache
57
+
58
+ // Currency symbols for display
59
+ this.symbols = {
60
+ USD: '$', EUR: '€', GBP: '£', INR: '₹', JPY: '¥',
61
+ CNY: '¥', KRW: '₩', THB: '฿', RUB: '₽', TRY: '₺',
62
+ BRL: 'R$', PLN: 'zł', ILS: '₪', PHP: '₱', VND: '₫'
63
+ };
64
+
65
+ // Currency names for NLP
66
+ this.currencyNames = {
67
+ 'dollar': 'USD', 'dollars': 'USD', 'usd': 'USD',
68
+ 'euro': 'EUR', 'euros': 'EUR', 'eur': 'EUR',
69
+ 'pound': 'GBP', 'pounds': 'GBP', 'gbp': 'GBP', 'sterling': 'GBP',
70
+ 'rupee': 'INR', 'rupees': 'INR', 'inr': 'INR',
71
+ 'yen': 'JPY', 'jpy': 'JPY',
72
+ 'yuan': 'CNY', 'cny': 'CNY', 'rmb': 'CNY',
73
+ 'won': 'KRW', 'krw': 'KRW',
74
+ 'peso': 'MXN', 'pesos': 'MXN',
75
+ 'real': 'BRL', 'reais': 'BRL', 'brl': 'BRL',
76
+ 'ruble': 'RUB', 'rubles': 'RUB', 'rub': 'RUB',
77
+ 'dirham': 'AED', 'aed': 'AED',
78
+ 'riyal': 'SAR', 'sar': 'SAR',
79
+ 'baht': 'THB', 'thb': 'THB',
80
+ 'ringgit': 'MYR', 'myr': 'MYR',
81
+ 'lira': 'TRY', 'try': 'TRY',
82
+ 'franc': 'CHF', 'chf': 'CHF',
83
+ 'canadian': 'CAD', 'cad': 'CAD',
84
+ 'australian': 'AUD', 'aud': 'AUD'
85
+ };
86
+ }
87
+
88
+ /**
89
+ * Try to fetch live rates (with fallback to cached rates)
90
+ */
91
+ async fetchRates() {
92
+ // Check if cache is still valid
93
+ if (this.lastUpdate && (Date.now() - this.lastUpdate) < this.cacheTimeout) {
94
+ return this.rates;
95
+ }
96
+
97
+ try {
98
+ // Try free API (no key required)
99
+ const response = await fetch('https://api.exchangerate-api.com/v4/latest/USD', {
100
+ timeout: 5000
101
+ });
102
+
103
+ if (response.ok) {
104
+ const data = await response.json();
105
+ this.rates = data.rates;
106
+ this.lastUpdate = Date.now();
107
+ console.log('Currency rates updated from API');
108
+ }
109
+ } catch (error) {
110
+ // Use fallback rates silently
111
+ console.log('Using offline currency rates');
112
+ }
113
+
114
+ return this.rates;
115
+ }
116
+
117
+ /**
118
+ * Parse currency from text
119
+ */
120
+ parseCurrency(text) {
121
+ const upper = text.toUpperCase().trim();
122
+
123
+ // Check direct currency code
124
+ if (this.rates[upper]) {
125
+ return upper;
126
+ }
127
+
128
+ // Check currency names
129
+ const lower = text.toLowerCase().trim();
130
+ if (this.currencyNames[lower]) {
131
+ return this.currencyNames[lower];
132
+ }
133
+
134
+ return null;
135
+ }
136
+
137
+ /**
138
+ * Convert between currencies
139
+ */
140
+ async convert(amount, fromCurrency, toCurrency) {
141
+ await this.fetchRates();
142
+
143
+ const from = this.parseCurrency(fromCurrency);
144
+ const to = this.parseCurrency(toCurrency);
145
+
146
+ if (!from || !to) {
147
+ throw new Error(`Unknown currency: ${!from ? fromCurrency : toCurrency}`);
148
+ }
149
+
150
+ if (!this.rates[from] || !this.rates[to]) {
151
+ throw new Error(`Exchange rate not available for ${from} or ${to}`);
152
+ }
153
+
154
+ // Convert via USD base
155
+ const inUSD = amount / this.rates[from];
156
+ const result = inUSD * this.rates[to];
157
+
158
+ return {
159
+ amount: amount,
160
+ from: from,
161
+ to: to,
162
+ result: Math.round(result * 100) / 100,
163
+ rate: Math.round((this.rates[to] / this.rates[from]) * 10000) / 10000,
164
+ symbol: this.symbols[to] || ''
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Format currency result for display
170
+ */
171
+ formatResult(conversion) {
172
+ const fromSymbol = this.symbols[conversion.from] || '';
173
+ const toSymbol = this.symbols[conversion.to] || '';
174
+
175
+ const formattedResult = conversion.result.toLocaleString('en-US', {
176
+ minimumFractionDigits: 2,
177
+ maximumFractionDigits: 2
178
+ });
179
+
180
+ return `${fromSymbol}${conversion.amount} ${conversion.from} = ${toSymbol}${formattedResult} ${conversion.to}`;
181
+ }
182
+
183
+ /**
184
+ * Get list of supported currencies
185
+ */
186
+ getSupportedCurrencies() {
187
+ return Object.keys(this.rates);
188
+ }
189
+ }
190
+
191
+ module.exports = CurrencyConverter;