smoothretro82

Power Calculator HUD v.1.3

Dec 18th, 2025 (edited)
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.38 KB | None | 0 0
  1. (function() {
  2. if (document.getElementById('win95Hud')) return;
  3.  
  4. function loadDecimal(callback) {
  5. if (window.Decimal) return callback(true);
  6. const script = document.createElement('script');
  7. script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/decimal.min.js';
  8. script.onload = () => callback(true);
  9. script.onerror = () => { alert('Failed to load Decimal.js'); callback(false); };
  10. document.head.appendChild(script);
  11. }
  12.  
  13. loadDecimal(() => {
  14. const hud = document.createElement('div');
  15. hud.id = 'win95Hud';
  16. Object.assign(hud.style, {
  17. position: 'fixed',
  18. top: '50px',
  19. left: '50px',
  20. width: '480px',
  21. background: '#C0C0C0',
  22. border: '2px solid #808080',
  23. zIndex: '99999',
  24. fontFamily: 'Tahoma, Geneva, sans-serif',
  25. userSelect: 'none',
  26. boxShadow: '4px 4px 0 #000',
  27. display: 'flex',
  28. flexDirection: 'column',
  29. resize: 'both',
  30. overflow: 'hidden'
  31. });
  32.  
  33. // Title bar
  34. const titleBar = document.createElement('div');
  35. Object.assign(titleBar.style, {
  36. background: '#000080',
  37. color: '#fff',
  38. padding: '2px',
  39. display: 'flex',
  40. alignItems: 'center',
  41. cursor: 'move',
  42. justifyContent: 'space-between'
  43. });
  44.  
  45. const titleText = document.createElement('span');
  46. titleText.innerText = 'Power Calc';
  47. const icon = document.createElement('span');
  48. Object.assign(icon.style, {
  49. width: '12px',
  50. height: '12px',
  51. marginRight: '4px',
  52. background: '#fff',
  53. border: '1px solid #000',
  54. display: 'inline-block'
  55. });
  56. titleText.prepend(icon);
  57. titleBar.appendChild(titleText);
  58.  
  59. const btnContainer = document.createElement('div');
  60. btnContainer.style.display = 'flex';
  61. btnContainer.style.alignItems = 'center';
  62. btnContainer.style.justifyContent = 'flex-end';
  63. btnContainer.style.gap = '0px';
  64. btnContainer.style.marginRight = '2px';
  65.  
  66. const minimizeBtn = document.createElement('button');
  67. const closeBtn = document.createElement('button');
  68. minimizeBtn.innerText = '_';
  69. closeBtn.innerText = 'X';
  70.  
  71. [minimizeBtn, closeBtn].forEach(btn => {
  72. Object.assign(btn.style, {
  73. width: '20px',
  74. height: '18px',
  75. padding: '0',
  76. margin: '0',
  77. fontWeight: 'bold',
  78. fontSize: '12px',
  79. textAlign: 'center',
  80. cursor: 'pointer',
  81. background: '#C0C0C0',
  82. border: '2px outset #fff',
  83. lineHeight: '14px',
  84. display: 'flex',
  85. alignItems: 'center',
  86. justifyContent: 'center',
  87. userSelect: 'none'
  88. });
  89. btn.onmousedown = () => btn.style.border = '2px inset #fff';
  90. btn.onmouseup = btn.onmouseleave = () => btn.style.border = '2px outset #fff';
  91. });
  92.  
  93. btnContainer.appendChild(minimizeBtn);
  94. btnContainer.appendChild(closeBtn);
  95. titleBar.appendChild(btnContainer);
  96. hud.appendChild(titleBar);
  97.  
  98. // Content
  99. const content = document.createElement('div');
  100. Object.assign(content.style, {
  101. padding: '8px',
  102. display: 'flex',
  103. flexDirection: 'column',
  104. gap: '6px'
  105. });
  106.  
  107. function createNumberInput(labelText, id, def = '0') {
  108. const c = document.createElement('div');
  109. c.style.display = 'flex';
  110. c.style.alignItems = 'center';
  111. c.style.gap = '4px';
  112. const l = document.createElement('label');
  113. l.innerText = labelText;
  114. const i = document.createElement('input');
  115. i.type = 'text';
  116. i.id = id;
  117. i.value = def;
  118. Object.assign(i.style, {
  119. width: '100px',
  120. border: '2px inset #fff'
  121. });
  122. c.append(l, i);
  123. return c;
  124. }
  125.  
  126. content.appendChild(createNumberInput('Base (a):', 'win95Base', '2'));
  127. content.appendChild(createNumberInput('Start (b):', 'win95Exp', '1'));
  128. content.appendChild(createNumberInput('Iterations (n):', 'win95Iter', '1'));
  129.  
  130. // Notation selector
  131. const notationWrap = document.createElement('div');
  132. notationWrap.style.display = 'flex';
  133. notationWrap.style.alignItems = 'center';
  134. notationWrap.style.gap = '4px';
  135.  
  136. const notationLabel = document.createElement('label');
  137. notationLabel.innerText = 'Notation:';
  138.  
  139. const notationSelect = document.createElement('select');
  140. notationSelect.id = 'win95Notation';
  141. [
  142. 'Scientific',
  143. 'Scientific (comma)',
  144. 'Engineering',
  145. 'Power Tower',
  146. 'Knuth ↑',
  147. 'Knuth ↑↑↑',
  148. 'Knuth ↑↑↑↑',
  149. 'Knuth ↑^k',
  150. 'Log Height',
  151. 'Conway →',
  152. 'Exp Tower',
  153. 'Super-log10',
  154. 'Tetrational Height',
  155. 'Arrow Chain Extended',
  156. 'Graham ↑^k',
  157. 'Reciprocal Log',
  158. 'Illions',
  159. 'Metric Prefix',
  160. 'Binary',
  161. 'Hexadecimal',
  162. 'Factorial !',
  163. 'Double Factorial !!',
  164. 'Triple Factorial !!!',
  165. 'Superfactorial sf(n)',
  166. 'Ackermann A(m,n)',
  167. 'Nested Exp Exp_n'
  168. ].forEach(n => {
  169. const o = document.createElement('option');
  170. o.value = n;
  171. o.innerText = n;
  172. notationSelect.appendChild(o);
  173. });
  174.  
  175. notationWrap.append(notationLabel, notationSelect);
  176. content.appendChild(notationWrap);
  177.  
  178. const calcBtn = document.createElement('button');
  179. calcBtn.innerText = 'Calculate';
  180. calcBtn.style.border = '2px outset #fff';
  181. content.appendChild(calcBtn);
  182.  
  183. const resultBox = document.createElement('div');
  184. Object.assign(resultBox.style, {
  185. minHeight: '20px',
  186. background: '#fff',
  187. border: '2px inset #fff',
  188. padding: '2px',
  189. fontFamily: 'monospace'
  190. });
  191. content.appendChild(resultBox);
  192.  
  193. const historyContainer = document.createElement('div');
  194. Object.assign(historyContainer.style, {
  195. maxHeight: '100px',
  196. overflowY: 'auto',
  197. background: '#e0e0e0',
  198. border: '2px inset #fff',
  199. padding: '2px',
  200. fontFamily: 'monospace'
  201. });
  202. content.appendChild(historyContainer);
  203.  
  204. hud.appendChild(content);
  205. document.body.appendChild(hud);
  206.  
  207. // Drag
  208. let ox, oy, drag = false;
  209. titleBar.onmousedown = e => {
  210. drag = true;
  211. ox = hud.offsetLeft - e.clientX;
  212. oy = hud.offsetTop - e.clientY;
  213. };
  214. document.onmouseup = () => drag = false;
  215. document.onmousemove = e => {
  216. if (!drag) return;
  217. hud.style.left = e.clientX + ox + 'px';
  218. hud.style.top = e.clientY + oy + 'px';
  219. };
  220.  
  221. closeBtn.onclick = () => hud.remove();
  222. minimizeBtn.onclick = () => { content.style.display = content.style.display==='none'?'flex':'none'; };
  223.  
  224. const history = [];
  225. let memory = null;
  226.  
  227. // Formatting helpers (Illions, Metric, Binary, Hex, Factorials)
  228. function formatIllions(dec) {
  229. if (!dec.isFinite()) return 'Infinity';
  230. const illions = ['', 'million','billion','trillion','quadrillion','quintillion','sextillion','septillion','octillion','nonillion','decillion','undecillion','duodecillion','tredecillion','quattuordecillion','quindecillion','sexdecillion','septendecillion','octodecillion','novemdecillion','vigintillion','centillion'];
  231. const log10 = dec.log(10);
  232. if (log10.lt(6)) return dec.toFixed();
  233. const idx = Math.min(illions.length-1, log10.div(3).floor().sub(1).toNumber());
  234. const scale = Decimal.pow(10,(idx+1)*3);
  235. const mantissa = dec.div(scale);
  236. return `${mantissa.toFixed(3)} ${illions[idx]}`;
  237. }
  238.  
  239. function formatMetricPrefix(dec) {
  240. if (!dec.isFinite()) return 'Infinity';
  241. const prefixes = ['', 'kilo','mega','giga','tera','peta','exa','zetta','yotta','ronna','quetta'];
  242. const log10 = dec.log(10);
  243. if (log10.lt(3)) return dec.toFixed();
  244. const idx = Math.min(prefixes.length-1, Math.floor(log10.div(3).toNumber()));
  245. const scale = Decimal.pow(10, idx*3);
  246. const mantissa = dec.div(scale);
  247. return `${mantissa.toFixed(3)} ${prefixes[idx]}`;
  248. }
  249.  
  250. function factorialSymbolic(n) { return n<21?new Decimal(n).factorial().toString():`${n}!`; }
  251. function doubleFactorialSymbolic(n){ return n<21?`${n}!!`: `${n}!!`; }
  252. function tripleFactorialSymbolic(n){ return n<21?`${n}!!!`: `${n}!!!`; }
  253. function superfactorialSymbolic(n){ return n<21?Array.from({length:n},(_,i)=>new Decimal(i+1).pow(i+1)).reduce((a,b)=>a.mul(b),new Decimal(1)).toString():`sf(${n})`; }
  254. function ackermannSymbolic(m,n){ return `A(${m},${n})`; }
  255.  
  256. function formatNotation(result,a,b,n,notation,infinite=false){
  257. if(infinite) return `${notation} overflow`;
  258. switch(notation){
  259. case 'Scientific': return result.toExponential(10);
  260. case 'Scientific (comma)': return result.toExponential(0).replace(/\B(?=(\d{3})+(?!\d))/g,',');
  261. case 'Engineering': { const exp = Decimal.floor(result.log(10).div(3)).mul(3); return result.div(Decimal.pow(10,exp)).toFixed(3)+'E'+exp.toString();}
  262. case 'Power Tower': return `${a} ↑↑ ${n} (start=${b})\n≈ ${result.toExponential(6)}`;
  263. case 'Knuth ↑': return `${a} ↑↑ ${n}\n≈ ${result.toExponential(6)}`;
  264. case 'Knuth ↑↑↑': return `${a} ↑↑↑ ${n} (symbolic)`;
  265. case 'Knuth ↑↑↑↑': return `${a} ↑↑↑↑ ${n} (symbolic)`;
  266. case 'Knuth ↑^k': return `${a} ↑^k ${n} (symbolic)`;
  267. case 'Log Height': return `log10(result) ≈ ${result.log(10).toFixed(6)}`;
  268. case 'Conway →': return `${a} → ${n} → ${b}`;
  269. case 'Exp Tower': return `${a}^( ${a}^( ... ^${b}) ) with ${n} layers`;
  270. case 'Super-log10': return `slog10 ≈ ${Math.log10(result.log(10).toNumber()).toFixed(6)}`;
  271. case 'Tetrational Height': return `${a} ↑↑ ${n} → height ${result.log(10).toFixed(6)}`;
  272. case 'Arrow Chain Extended': return `${a} → ${n} → ${b} → extended`;
  273. case 'Graham ↑^k': return `${a} ↑^k ${n}`;
  274. case 'Reciprocal Log': return `1 / 10^(${result.log(10).toFixed(6)})`;
  275. case 'Illions': return formatIllions(result);
  276. case 'Metric Prefix': return formatMetricPrefix(result);
  277. case 'Binary': return !result.isFinite()?'2^∞':'2^'+(result.log(2).gt('1e15')?result.log(2).toExponential(3):result.log(2).toFixed(3));
  278. case 'Hexadecimal': return !result.isFinite()?'16^∞':(result.log(16).gt('1e15')?'16^'+result.log(16).toExponential(3):result.toNumber().toString(16));
  279. case 'Factorial !': return factorialSymbolic(b);
  280. case 'Double Factorial !!': return doubleFactorialSymbolic(b);
  281. case 'Triple Factorial !!!': return tripleFactorialSymbolic(b);
  282. case 'Superfactorial sf(n)': return superfactorialSymbolic(n);
  283. case 'Ackermann A(m,n)': return ackermannSymbolic(a,b);
  284. case 'Nested Exp Exp_n': return `Exp_${n}(${a},${b})`;
  285. }
  286. return result.toExponential(6);
  287. }
  288.  
  289. function calculate(){
  290. let a,b,n;
  291. try{ a=new Decimal(win95Base.value); b=new Decimal(win95Exp.value); n=parseInt(win95Iter.value,10);}catch{return alert('Invalid input');}
  292. if(!Number.isInteger(n)||n<1) return alert('Iterations must be positive integer');
  293. if(n>1000) return alert('Iteration cap: 1000');
  294.  
  295. const notation = win95Notation.value;
  296. let result = b;
  297. let i=1;
  298. let infinite=false;
  299. const chunkSize = 5;
  300. resultBox.innerText='Calculating...';
  301.  
  302. function nextChunk(){
  303. for(let j=0;j<chunkSize && i<=n;j++,i++){
  304. try{ result=a.pow(result); if(!result.isFinite()){infinite=true; finish(result); return;} }
  305. catch{infinite=true; finish(result); return;}
  306. }
  307. if(i<=n){
  308. resultBox.innerText=`Iteration ${i-1}/${n} complete...`;
  309. requestAnimationFrame(nextChunk);
  310. }else finish(result);
  311. }
  312.  
  313. function finish(finalResult){
  314. const display=formatNotation(finalResult,a,b,n,notation,infinite);
  315. resultBox.innerText=display;
  316. history.unshift(display.replace(/\n/g,' '));
  317. if(history.length>10) history.pop();
  318. historyContainer.innerHTML=history.join('<br>');
  319. }
  320.  
  321. nextChunk();
  322. }
  323.  
  324. // Memory buttons
  325. const memoryContainer = document.createElement('div');
  326. memoryContainer.style.display='flex';
  327. memoryContainer.style.gap='4px';
  328. const memoryStore=document.createElement('button'); memoryStore.innerText='MS';
  329. const memoryRecall=document.createElement('button'); memoryRecall.innerText='MR';
  330. const memoryClear=document.createElement('button'); memoryClear.innerText='MC';
  331. [memoryStore,memoryRecall,memoryClear].forEach(btn=>{
  332. Object.assign(btn.style,{border:'2px outset #fff',padding:'2px',cursor:'pointer',background:'#C0C0C0',fontWeight:'bold'});
  333. btn.onmousedown=()=>btn.style.border='2px inset #fff';
  334. btn.onmouseup=btn.onmouseleave=()=>btn.style.border='2px outset #fff';
  335. memoryContainer.appendChild(btn);
  336. });
  337. content.appendChild(memoryContainer);
  338. memoryStore.onclick=()=>{memory=resultBox.innerText.split('\n')[1]||resultBox.innerText;};
  339. memoryRecall.onclick=()=>{if(memory) win95Base.value=memory;};
  340. memoryClear.onclick=()=>{memory=null;};
  341.  
  342. // Keyboard shortcuts
  343. ['win95Base','win95Exp','win95Iter'].forEach(id=>{
  344. const input=document.getElementById(id);
  345. input.addEventListener('keydown',e=>{
  346. if(e.key==='Enter') calculate();
  347. if(e.key==='ArrowUp'){try{input.value=new Decimal(input.value).add(1).toString();}catch{} e.preventDefault();}
  348. if(e.key==='ArrowDown'){try{input.value=new Decimal(input.value).sub(1).toString();}catch{} e.preventDefault();}
  349. if(e.key==='Escape') hud.remove();
  350. });
  351. });
  352.  
  353. calcBtn.onclick=calculate;
  354. });
  355. })();
  356.  
Advertisement
Add Comment
Please, Sign In to add comment