scientificcalculator / index.html
kokofixcomputers's picture
undefined - Follow Up Deployment
79cf6bd verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modern Scientific Calculator</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.sidebar {
transform: translateX(-100%);
transition: transform 0.3s ease;
}
.sidebar.open {
transform: translateX(0);
}
.calculator-btn {
transition: all 0.2s ease;
transform: scale(1);
}
.calculator-btn:active {
transform: scale(0.95);
}
.history-item:hover {
background-color: rgba(255, 255, 255, 0.1);
cursor: pointer;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3e%3cpath d='M7 10l5 5 5-5z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.5rem center;
background-size: 1.5em;
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-md">
<div class="bg-gray-800 rounded-2xl shadow-xl overflow-hidden">
<!-- Display Area -->
<div class="p-4">
<div class="flex justify-between items-center mb-2">
<h1 class="text-xl font-bold text-blue-400">Scientific Calculator</h1>
<div class="flex space-x-2">
<button id="sidebar-toggle" class="text-gray-300 hover:text-white">
<i class="fas fa-sliders-h"></i>
</button>
<button id="theme-toggle" class="text-gray-300 hover:text-white">
<i class="fas fa-moon"></i>
</button>
</div>
</div>
<div class="bg-gray-700 rounded-lg p-3 mb-2">
<div id="history-display" class="text-gray-400 text-sm h-6 overflow-x-auto whitespace-nowrap scrollbar-hide"></div>
<div id="display" class="text-right text-3xl font-semibold break-all">0</div>
</div>
<div class="flex space-x-2 mb-2">
<button id="clear" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg flex-1 calculator-btn">AC</button>
<button id="backspace" class="bg-gray-600 hover:bg-gray-500 text-white px-4 py-2 rounded-lg calculator-btn">
<i class="fas fa-backspace"></i>
</button>
<button id="percentage" class="bg-gray-600 hover:bg-gray-500 text-white px-4 py-2 rounded-lg calculator-btn">%</button>
<button id="divide" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg calculator-btn">÷</button>
</div>
</div>
<!-- Main Calculator -->
<div class="grid grid-cols-4 gap-2 p-4">
<!-- Row 1 -->
<button data-value="7" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">7</button>
<button data-value="8" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">8</button>
<button data-value="9" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">9</button>
<button id="multiply" class="bg-blue-500 hover:bg-blue-600 text-white text-xl p-3 rounded-lg calculator-btn">×</button>
<!-- Row 2 -->
<button data-value="4" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">4</button>
<button data-value="5" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">5</button>
<button data-value="6" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">6</button>
<button id="subtract" class="bg-blue-500 hover:bg-blue-600 text-white text-xl p-3 rounded-lg calculator-btn">-</button>
<!-- Row 3 -->
<button data-value="1" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">1</button>
<button data-value="2" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">2</button>
<button data-value="3" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">3</button>
<button id="add" class="bg-blue-500 hover:bg-blue-600 text-white text-xl p-3 rounded-lg calculator-btn">+</button>
<!-- Row 4 -->
<button id="negative" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">+/-</button>
<button id="decimal" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">.</button>
<button data-value="0" class="bg-gray-700 hover:bg-gray-600 text-white text-xl p-3 rounded-lg calculator-btn">0</button>
<button id="equals" class="bg-green-500 hover:bg-green-600 text-white text-xl p-3 rounded-lg calculator-btn">=</button>
<button id="sqrt" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn"></button>
<!-- Scientific Functions Row -->
<button id="power" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">x^y</button>
<button id="sin" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">sin</button>
<button id="cos" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">cos</button>
<button id="tan" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">tan</button>
<!-- More Functions Row -->
<button id="log" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">log</button>
<button id="ln" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">ln</button>
<button id="pi" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">π</button>
<button id="factorial" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">n!</button>
<button id="gcd" class="bg-purple-500 hover:bg-purple-600 text-white text-xl p-3 rounded-lg calculator-btn">GCD</button>
<!-- Conversion Mode -->
<button id="convert-mode" class="bg-indigo-500 hover:bg-indigo-600 text-white text-xl p-3 rounded-lg calculator-btn col-span-4">Convert</button>
<div id="conversion-ui" class="hidden col-span-4 space-y-2">
<div class="flex space-x-2">
<input type="number" id="convert-input" class="bg-gray-700 text-white p-2 rounded-lg flex-1" placeholder="Value">
<select id="convert-from" class="bg-gray-700 text-white p-2 rounded-lg">
<optgroup label="Length">
<option value="mm">Millimeters (mm)</option>
<option value="cm">Centimeters (cm)</option>
<option value="m">Meters (m)</option>
<option value="hm">Hectometers (hm)</option>
<option value="km">Kilometers (km)</option>
<option value="in">Inches (in)</option>
<option value="ft">Feet (ft)</option>
<option value="yd">Yards (yd)</option>
<option value="mi">Miles (mi)</option>
</optgroup>
<optgroup label="Mass">
<option value="mg">Milligrams (mg)</option>
<option value="g">Grams (g)</option>
<option value="kg">Kilograms (kg)</option>
<option value="oz">Ounces (oz)</option>
<option value="lb">Pounds (lb)</option>
</optgroup>
<optgroup label="Volume">
<option value="ml">Milliliters (ml)</option>
<option value="l">Liters (l)</option>
<option value="tsp">Teaspoons (tsp)</option>
<option value="tbsp">Tablespoons (tbsp)</option>
<option value="cup">Cups (cup)</option>
<option value="pt">Pints (pt)</option>
<option value="qt">Quarts (qt)</option>
<option value="gal">Gallons (gal)</option>
</optgroup>
</select>
</div>
<div class="flex space-x-2">
<input type="number" id="convert-result" class="bg-gray-700 text-white p-2 rounded-lg flex-1" placeholder="Result" readonly>
<select id="convert-to" class="bg-gray-700 text-white p-2 rounded-lg">
<optgroup label="Length">
<option value="mm">Millimeters (mm)</option>
<option value="cm">Centimeters (cm)</option>
<option value="m">Meters (m)</option>
<option value="hm">Hectometers (hm)</option>
<option value="km">Kilometers (km)</option>
<option value="in">Inches (in)</option>
<option value="ft">Feet (ft)</option>
<option value="yd">Yards (yd)</option>
<option value="mi">Miles (mi)</option>
</optgroup>
<optgroup label="Mass">
<option value="mg">Milligrams (mg)</option>
<option value="g">Grams (g)</option>
<option value="kg">Kilograms (kg)</option>
<option value="oz">Ounces (oz)</option>
<option value="lb">Pounds (lb)</option>
</optgroup>
<optgroup label="Volume">
<option value="ml">Milliliters (ml)</option>
<option value="l">Liters (l)</option>
<option value="tsp">Teaspoons (tsp)</option>
<option value="tbsp">Tablespoons (tbsp)</option>
<option value="cup">Cups (cup)</option>
<option value="pt">Pints (pt)</option>
<option value="qt">Quarts (qt)</option>
<option value="gal">Gallons (gal)</option>
</optgroup>
</select>
</div>
</div>
</div>
<!-- Scientific Sidebar -->
<div id="sidebar" class="sidebar absolute top-0 left-0 w-64 h-full bg-gray-800 z-10 p-4 overflow-y-auto">
<div class="flex justify-between items-center mb-4">
<h2 class="text-lg font-semibold text-blue-400">Scientific Functions</h2>
<button id="close-sidebar" class="text-gray-300 hover:text-white">
<i class="fas fa-times"></i>
</button>
</div>
<div class="grid grid-cols-2 gap-2 mb-4">
<button id="cube-root" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn"></button>
<button id="nth-root" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">ⁿ√</button>
<button id="gcd" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">GCD</button>
<button id="lcm" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">LCM</button>
<button id="abs" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">|x|</button>
<button id="exp" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">e^x</button>
<button id="mod" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">mod</button>
<button id="rand" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">Rand</button>
</div>
<div class="mb-4">
<h3 class="text-md font-semibold text-blue-400 mb-2">Parentheses</h3>
<div class="grid grid-cols-2 gap-2">
<button id="open-paren" class="bg-blue-500 hover:bg-blue-600 text-white p-2 rounded calculator-btn">(</button>
<button id="close-paren" class="bg-blue-500 hover:bg-blue-600 text-white p-2 rounded calculator-btn">)</button>
</div>
</div>
<div class="mb-4">
<h3 class="text-md font-semibold text-blue-400 mb-2">Constants</h3>
<div class="grid grid-cols-2 gap-2">
<button id="e" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">e</button>
<button id="phi" class="bg-purple-500 hover:bg-purple-600 text-white p-2 rounded calculator-btn">φ</button>
</div>
</div>
</div>
<!-- History Panel -->
<div class="bg-gray-700 p-4 border-t border-gray-600">
<div class="flex justify-between items-center mb-2">
<h2 class="text-lg font-semibold text-blue-400">History</h2>
<button id="clear-history" class="text-gray-300 hover:text-white text-sm">Clear</button>
</div>
<div id="history-list" class="max-h-40 overflow-y-auto scrollbar-hide space-y-1"></div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Calculator state
let currentInput = '0';
let previousInput = '';
let operation = null;
let resetInput = false;
let calculationHistory = [];
// DOM elements
const display = document.getElementById('display');
const historyDisplay = document.getElementById('history-display');
const historyList = document.getElementById('history-list');
const themeToggle = document.getElementById('theme-toggle');
const clearHistoryBtn = document.getElementById('clear-history');
// Number buttons
const numberButtons = document.querySelectorAll('[data-value]');
// Operation buttons
const addButton = document.getElementById('add');
const subtractButton = document.getElementById('subtract');
const multiplyButton = document.getElementById('multiply');
const divideButton = document.getElementById('divide');
const equalsButton = document.getElementById('equals');
const clearButton = document.getElementById('clear');
const backspaceButton = document.getElementById('backspace');
const decimalButton = document.getElementById('decimal');
const percentageButton = document.getElementById('percentage');
// Scientific functions
const sqrtButton = document.getElementById('sqrt');
const powerButton = document.getElementById('power');
const sinButton = document.getElementById('sin');
const cosButton = document.getElementById('cos');
const tanButton = document.getElementById('tan');
const logButton = document.getElementById('log');
const lnButton = document.getElementById('ln');
const piButton = document.getElementById('pi');
const factorialButton = document.getElementById('factorial');
const gcdButton = document.getElementById('gcd');
// Initialize
updateDisplay();
// Theme toggle
themeToggle.addEventListener('click', toggleTheme);
// Clear history
clearHistoryBtn.addEventListener('click', clearHistory);
// Number buttons
numberButtons.forEach(button => {
button.addEventListener('click', () => {
appendNumber(button.getAttribute('data-value'));
});
});
// Operation buttons
addButton.addEventListener('click', () => setOperation('+'));
document.getElementById('negative').addEventListener('click', appendNegative);
subtractButton.addEventListener('click', () => setOperation('-'));
multiplyButton.addEventListener('click', () => setOperation('×'));
divideButton.addEventListener('click', () => setOperation('÷'));
equalsButton.addEventListener('click', compute);
clearButton.addEventListener('click', clear);
backspaceButton.addEventListener('click', backspace);
decimalButton.addEventListener('click', appendDecimal);
percentageButton.addEventListener('click', percentage);
// Sidebar toggle
const sidebarToggle = document.getElementById('sidebar-toggle');
const closeSidebar = document.getElementById('close-sidebar');
const sidebar = document.getElementById('sidebar');
sidebarToggle.addEventListener('click', () => {
sidebar.classList.add('open');
});
closeSidebar.addEventListener('click', () => {
sidebar.classList.remove('open');
});
// Scientific functions
sqrtButton.addEventListener('click', () => appendFunction('√('));
powerButton.addEventListener('click', () => setOperation('^'));
sinButton.addEventListener('click', () => applyFunction('sin'));
cosButton.addEventListener('click', () => applyFunction('cos'));
tanButton.addEventListener('click', () => applyFunction('tan'));
logButton.addEventListener('click', () => applyFunction('log'));
lnButton.addEventListener('click', () => applyFunction('ln'));
piButton.addEventListener('click', appendPi);
factorialButton.addEventListener('click', factorial);
gcdButton.addEventListener('click', () => appendFunction('gcd('));
// Keyboard support
document.addEventListener('keydown', handleKeyboardInput);
// Functions
function toggleTheme() {
document.body.classList.toggle('bg-gray-100');
document.body.classList.toggle('text-gray-900');
document.body.classList.toggle('bg-gray-900');
document.body.classList.toggle('text-white');
const calculator = document.querySelector('.bg-gray-800');
calculator.classList.toggle('bg-gray-800');
calculator.classList.toggle('bg-white');
const displayBg = document.querySelector('.bg-gray-700');
displayBg.classList.toggle('bg-gray-700');
displayBg.classList.toggle('bg-gray-100');
const buttons = document.querySelectorAll('.bg-gray-600, .bg-gray-700');
buttons.forEach(btn => {
btn.classList.toggle('bg-gray-600');
btn.classList.toggle('bg-gray-700');
btn.classList.toggle('bg-gray-200');
btn.classList.toggle('bg-gray-300');
btn.classList.toggle('text-white');
btn.classList.toggle('text-gray-900');
});
const icon = themeToggle.querySelector('i');
if (icon.classList.contains('fa-moon')) {
icon.classList.remove('fa-moon');
icon.classList.add('fa-sun');
} else {
icon.classList.remove('fa-sun');
icon.classList.add('fa-moon');
}
}
function clearHistory() {
calculationHistory = [];
updateHistoryList();
}
function appendNumber(number) {
if (resetInput) {
currentInput = number;
resetInput = false;
} else if (currentInput === '0') {
currentInput = number;
} else {
currentInput += number;
}
updateDisplay();
}
function appendNegative() {
if (resetInput) {
currentInput = '-';
resetInput = false;
} else if (currentInput === '0') {
currentInput = '-';
} else if (currentInput.endsWith('(')) {
currentInput += '-';
} else if (currentInput.endsWith('^') || currentInput.endsWith('mod') ||
currentInput.endsWith('+') || currentInput.endsWith('-') ||
currentInput.endsWith('×') || currentInput.endsWith('÷')) {
currentInput += '(-';
} else {
currentInput += '-';
}
updateDisplay();
}
function appendDecimal() {
if (resetInput) {
currentInput = '0.';
resetInput = false;
return;
}
if (currentInput.indexOf('.') === -1) {
currentInput += '.';
}
updateDisplay();
}
function appendPi() {
if (currentInput !== '0' && !resetInput) {
currentInput += Math.PI.toString();
} else {
currentInput = Math.PI.toString();
resetInput = false;
}
updateDisplay();
}
function setOperation(op) {
if (currentInput === '0' && previousInput && !resetInput) {
operation = op;
updateDisplay();
return;
}
if (operation && !resetInput) {
compute();
}
previousInput = currentInput;
operation = op;
resetInput = true;
updateDisplay();
}
function compute() {
try {
// Replace display symbols with JS-compatible ones
let expression = currentInput
.replace(/×/g, '*')
.replace(/÷/g, '/')
.replace(/√\(/g, 'Math.sqrt(')
.replace(/∛\(/g, 'Math.cbrt(')
.replace(/\^/g, '**')
.replace(/mod/g, '%')
.replace(/abs\(/g, 'Math.abs(')
.replace(/exp\(/g, 'Math.exp(')
.replace(/log\(/g, 'Math.log10(')
.replace(/ln\(/g, 'Math.log(')
.replace(/sin\(/g, 'Math.sin(')
.replace(/cos\(/g, 'Math.cos(')
.replace(/tan\(/g, 'Math.tan(')
.replace(/π/g, 'Math.PI')
.replace(/φ/g, '((1 + Math.sqrt(5)) / 2)')
.replace(/e/g, 'Math.E');
// Handle factorial (must be done after other replacements)
expression = expression.replace(/(-?\d+)!/g, function(match, num) {
let n = parseInt(num);
if (n < 0) return 'NaN';
let result = 1;
for (let i = 2; i <= n; i++) result *= i;
return result;
});
// Handle negative numbers in parentheses and functions
expression = expression.replace(/([√∛]|sin|cos|tan|log|ln|abs|exp|gcd|lcm)\(-(\d+)/g, '$1(-$2');
// Handle gcd and lcm (simple implementations)
expression = expression.replace(/gcd\(([^,]+),([^)]+)\)/g, function(match, a, b) {
a = parseFloat(a);
b = parseFloat(b);
while (b) [a, b] = [b, a % b];
return a;
});
expression = expression.replace(/lcm\(([^,]+),([^)]+)\)/g, function(match, a, b) {
a = parseFloat(a);
b = parseFloat(b);
return (a * b) / gcd(a, b);
});
// Evaluate the expression
let computation;
try {
computation = eval(expression);
if (operation) {
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
switch (operation) {
case '+':
computation = prev + current;
break;
case '-':
computation = prev - current;
break;
case '×':
computation = prev * current;
break;
case '÷':
computation = prev / current;
break;
case '^':
computation = Math.pow(prev, current);
break;
default:
return;
}
}
} catch (error) {
currentInput = 'Error';
operation = null;
resetInput = true;
updateDisplay();
return;
}
// Add to history
const historyEntry = {
expression: operation ? `${previousInput} ${operation} ${currentInput}` : expression,
result: computation.toString()
};
calculationHistory.unshift(historyEntry);
if (calculationHistory.length > 10) {
calculationHistory.pop();
}
currentInput = computation.toString();
operation = null;
resetInput = true;
updateDisplay();
updateHistoryList();
} catch (error) {
currentInput = 'Error';
operation = null;
resetInput = true;
updateDisplay();
return;
}
}
function clear() {
currentInput = '0';
previousInput = '';
operation = null;
updateDisplay();
}
function backspace() {
if (currentInput.length === 1) {
currentInput = '0';
} else {
currentInput = currentInput.slice(0, -1);
}
updateDisplay();
}
function percentage() {
currentInput = (parseFloat(currentInput) / 100).toString();
updateDisplay();
}
function squareRoot() {
currentInput = Math.sqrt(parseFloat(currentInput)).toString();
updateDisplay();
// Add to history
const historyEntry = {
expression: `√(${currentInput})`,
result: currentInput
};
calculationHistory.unshift(historyEntry);
if (calculationHistory.length > 10) {
calculationHistory.pop();
}
updateHistoryList();
}
function applyFunction(func) {
const value = parseFloat(currentInput);
let result;
switch (func) {
case 'sin':
result = Math.sin(value);
break;
case 'cos':
result = Math.cos(value);
break;
case 'tan':
result = Math.tan(value);
break;
case 'log':
result = Math.log10(value);
break;
case 'ln':
result = Math.log(value);
break;
}
currentInput = result.toString();
// Add to history
const historyEntry = {
expression: `${func}(${value})`,
result: currentInput
};
calculationHistory.unshift(historyEntry);
if (calculationHistory.length > 10) {
calculationHistory.pop();
}
updateDisplay();
updateHistoryList();
}
// Sidebar buttons
document.getElementById('cube-root').addEventListener('click', () => appendFunction('∛('));
document.getElementById('nth-root').addEventListener('click', () => appendFunction('^(1/'));
document.getElementById('gcd').addEventListener('click', () => appendFunction('gcd('));
document.getElementById('lcm').addEventListener('click', () => appendFunction('lcm('));
document.getElementById('abs').addEventListener('click', () => appendFunction('abs('));
document.getElementById('exp').addEventListener('click', () => appendFunction('exp('));
document.getElementById('mod').addEventListener('click', () => appendFunction(' mod '));
document.getElementById('rand').addEventListener('click', randomNumber);
document.getElementById('open-paren').addEventListener('click', () => appendValue('('));
document.getElementById('close-paren').addEventListener('click', () => appendValue(')'));
document.getElementById('e').addEventListener('click', appendE);
document.getElementById('phi').addEventListener('click', appendPhi);
// New functions
function appendFunction(func) {
if (resetInput) {
currentInput = func;
resetInput = false;
} else if (currentInput === '0') {
currentInput = func;
} else {
currentInput += func;
}
updateDisplay();
}
function appendValue(value) {
if (currentInput === '0' || resetInput) {
currentInput = value;
resetInput = false;
} else {
currentInput += value;
}
updateDisplay();
}
function appendE() {
if (currentInput !== '0' && !resetInput) {
currentInput += Math.E.toString();
} else {
currentInput = Math.E.toString();
resetInput = false;
}
updateDisplay();
}
function appendPhi() {
const phi = (1 + Math.sqrt(5)) / 2;
if (currentInput !== '0' && !resetInput) {
currentInput += phi.toString();
} else {
currentInput = phi.toString();
resetInput = false;
}
updateDisplay();
}
function randomNumber() {
const random = Math.random();
if (currentInput !== '0' && !resetInput) {
currentInput += random.toString();
} else {
currentInput = random.toString();
resetInput = false;
}
updateDisplay();
}
function factorial() {
let num = parseInt(currentInput);
if (num < 0) {
currentInput = 'Error';
updateDisplay();
return;
}
let result = 1;
for (let i = 2; i <= num; i++) {
result *= i;
}
currentInput = result.toString();
// Add to history
const historyEntry = {
expression: `${num}!`,
result: currentInput
};
calculationHistory.unshift(historyEntry);
if (calculationHistory.length > 10) {
calculationHistory.pop();
}
updateDisplay();
updateHistoryList();
}
function updateDisplay() {
display.textContent = currentInput;
if (operation !== null) {
historyDisplay.textContent = `${previousInput} ${operation}`;
} else {
historyDisplay.textContent = '';
}
}
// Helper functions
function gcd(a, b) {
a = Math.abs(a);
b = Math.abs(b);
while (b) [a, b] = [b, a % b];
return a;
}
function lcm(a, b) {
return (a * b) / gcd(a, b);
}
function updateHistoryList() {
historyList.innerHTML = '';
calculationHistory.forEach((entry, index) => {
const historyItem = document.createElement('div');
historyItem.className = 'history-item bg-gray-600 rounded p-2 text-sm';
historyItem.innerHTML = `
<div class="text-gray-300">${entry.expression} =</div>
<div class="text-right font-semibold">${entry.result}</div>
`;
historyItem.addEventListener('click', () => {
currentInput = entry.result;
resetInput = true;
updateDisplay();
});
historyList.appendChild(historyItem);
});
}
// Conversion mode elements
const convertModeBtn = document.getElementById('convert-mode');
const conversionUI = document.getElementById('conversion-ui');
const convertInput = document.getElementById('convert-input');
const convertResult = document.getElementById('convert-result');
const convertFrom = document.getElementById('convert-from');
const convertTo = document.getElementById('convert-to');
// Conversion groups
const conversionGroups = {
length: {
mm: 0.001,
cm: 0.01,
m: 1,
hm: 100,
km: 1000,
in: 0.0254,
ft: 0.3048,
yd: 0.9144,
mi: 1609.34
},
mass: {
mg: 0.001, // base: grams
g: 1,
kg: 1000,
lb: 453.59237, // pounds
oz: 28.3495 // ounces
},
volume: {
ml: 1, // base: milliliters
l: 1000,
tsp: 4.92892,
tbsp: 14.7868,
cup: 240,
pt: 473.176, // pint (US)
qt: 946.353, // quart (US)
gal: 3785.41 // gallon (US)
}
};
// Find which group (dimension) a unit belongs to
function getGroup(unit) {
for (const [group, units] of Object.entries(conversionGroups)) {
if (unit in units) return group;
}
return null;
}
// Toggle conversion panel
convertModeBtn.addEventListener('click', () => {
conversionUI.classList.toggle('hidden');
if (!conversionUI.classList.contains('hidden')) {
convertInput.focus();
}
});
// Perform conversion
function performConversion() {
const value = parseFloat(convertInput.value);
if (isNaN(value)) {
convertResult.value = "";
return;
}
const fromUnit = convertFrom.value;
const toUnit = convertTo.value;
const fromGroup = getGroup(fromUnit);
const toGroup = getGroup(toUnit);
// Incompatible units
if (!fromGroup || !toGroup || fromGroup !== toGroup) {
convertResult.value = "Error";
return;
}
const factors = conversionGroups[fromGroup];
// Convert to base → then to target
const baseValue = value * factors[fromUnit];
const result = baseValue / factors[toUnit];
convertResult.value = result.toFixed(6);
}
// Event listeners
convertInput.addEventListener('input', performConversion);
convertFrom.addEventListener('change', performConversion);
convertTo.addEventListener('change', performConversion);
function handleKeyboardInput(e) {
if (e.key >= '0' && e.key <= '9') {
appendNumber(e.key);
} else if (e.key === '.') {
appendDecimal();
} else if (e.key === '+' || e.key === '-' || e.key === '*' || e.key === '/') {
// Check if we're inside parentheses
const openParens = (currentInput.match(/\(/g) || []).length;
const closeParens = (currentInput.match(/\)/g) || []).length;
if (openParens > closeParens) {
// Inside parentheses - just append the operator
appendValue(e.key === '*' ? '×' : e.key === '/' ? '÷' : e.key);
} else {
// Not inside parentheses - treat as operation
setOperation(e.key === '*' ? '×' : e.key === '/' ? '÷' : e.key);
}
} else if (e.key === '^') {
setOperation('^');
} else if (e.key === '(') {
appendValue('(');
} else if (e.key === ')') {
appendValue(')');
} else if (e.key === 'Enter' || e.key === '=') {
compute();
} else if (e.key === 'Escape') {
clear();
} else if (e.key === 'Backspace') {
backspace();
} else if (e.key === '%') {
percentage();
} else if (e.key === '_' || e.key === 'n') {
appendNegative();
}
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=kokofixcomputers/scientificcalculator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>