feat: add Calculator & Grapher tool
Adds a full-featured mathematical calculator and interactive function grapher at /calculate. Powered by Math.js v15 with a HiDPI Canvas renderer for the graph. - Evaluates arbitrary math expressions (trig, log, complex, matrices, factorials, combinatorics, and more) with named variable scope - Persists history (50 entries) and variables via localStorage - 32 quick-insert buttons for constants and functions - Interactive graph: pan (drag), zoom (scroll), crosshair tooltip showing cursor coords and f₁(x)…f₈(x) values simultaneously - Up to 8 color-coded functions with inline color pickers and visibility toggles - Discontinuity detection for functions like tan(x) - Adaptive grid labels that rescale with zoom - Responsive layout: 2/5–3/5 split on desktop, tabbed on mobile Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
67
pnpm-lock.yaml
generated
67
pnpm-lock.yaml
generated
@@ -56,6 +56,9 @@ importers:
|
||||
lucide-react:
|
||||
specifier: ^0.575.0
|
||||
version: 0.575.0(react@19.2.4)
|
||||
mathjs:
|
||||
specifier: ^15.1.1
|
||||
version: 15.1.1
|
||||
next:
|
||||
specifier: ^16.1.6
|
||||
version: 16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -257,6 +260,10 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/runtime@7.28.6':
|
||||
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/template@7.28.6':
|
||||
resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -1938,6 +1945,9 @@ packages:
|
||||
resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
complex.js@2.4.3:
|
||||
resolution: {integrity: sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
@@ -2035,6 +2045,9 @@ packages:
|
||||
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
decimal.js@10.6.0:
|
||||
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
|
||||
|
||||
dedent@1.7.1:
|
||||
resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==}
|
||||
peerDependencies:
|
||||
@@ -2173,6 +2186,9 @@ packages:
|
||||
escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
|
||||
escape-latex@1.2.0:
|
||||
resolution: {integrity: sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2416,6 +2432,9 @@ packages:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
fraction.js@5.3.4:
|
||||
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
|
||||
|
||||
framer-motion@12.34.3:
|
||||
resolution: {integrity: sha512-v81ecyZKYO/DfpTwHivqkxSUBzvceOpoI+wLfgCgoUIKxlFKEXdg0oR9imxwXumT4SFy8vRk9xzJ5l3/Du/55Q==}
|
||||
peerDependencies:
|
||||
@@ -2806,6 +2825,9 @@ packages:
|
||||
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
javascript-natural-sort@0.7.1:
|
||||
resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==}
|
||||
|
||||
jiti@2.6.1:
|
||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||
hasBin: true
|
||||
@@ -3051,6 +3073,11 @@ packages:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
mathjs@15.1.1:
|
||||
resolution: {integrity: sha512-rM668DTtpSzMVoh/cKAllyQVEbBApM5g//IMGD8vD7YlrIz9ITRr3SrdhjaDxcBNTdyETWwPebj2unZyHD7ZdA==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
|
||||
media-typer@1.1.0:
|
||||
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -3558,6 +3585,9 @@ packages:
|
||||
scheduler@0.27.0:
|
||||
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
|
||||
|
||||
seedrandom@3.0.5:
|
||||
resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==}
|
||||
|
||||
semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
@@ -3773,6 +3803,9 @@ packages:
|
||||
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tiny-emitter@2.1.0:
|
||||
resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
|
||||
|
||||
tiny-invariant@1.3.3:
|
||||
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
||||
|
||||
@@ -3853,6 +3886,10 @@ packages:
|
||||
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typed-function@4.2.2:
|
||||
resolution: {integrity: sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
@@ -4218,6 +4255,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/runtime@7.28.6': {}
|
||||
|
||||
'@babel/template@7.28.6':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.29.0
|
||||
@@ -5911,6 +5950,8 @@ snapshots:
|
||||
|
||||
commander@14.0.3: {}
|
||||
|
||||
complex.js@2.4.3: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
content-disposition@1.0.1: {}
|
||||
@@ -5988,6 +6029,8 @@ snapshots:
|
||||
|
||||
decamelize@1.2.0: {}
|
||||
|
||||
decimal.js@10.6.0: {}
|
||||
|
||||
dedent@1.7.1: {}
|
||||
|
||||
deep-is@0.1.4: {}
|
||||
@@ -6172,6 +6215,8 @@ snapshots:
|
||||
|
||||
escape-html@1.0.3: {}
|
||||
|
||||
escape-latex@1.2.0: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-config-next@15.1.7(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3):
|
||||
@@ -6538,6 +6583,8 @@ snapshots:
|
||||
|
||||
forwarded@0.2.0: {}
|
||||
|
||||
fraction.js@5.3.4: {}
|
||||
|
||||
framer-motion@12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
motion-dom: 12.34.3
|
||||
@@ -6883,6 +6930,8 @@ snapshots:
|
||||
has-symbols: 1.1.0
|
||||
set-function-name: 2.0.2
|
||||
|
||||
javascript-natural-sort@0.7.1: {}
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
jose@6.1.3: {}
|
||||
@@ -7124,6 +7173,18 @@ snapshots:
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
mathjs@15.1.1:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.6
|
||||
complex.js: 2.4.3
|
||||
decimal.js: 10.6.0
|
||||
escape-latex: 1.2.0
|
||||
fraction.js: 5.3.4
|
||||
javascript-natural-sort: 0.7.1
|
||||
seedrandom: 3.0.5
|
||||
tiny-emitter: 2.1.0
|
||||
typed-function: 4.2.2
|
||||
|
||||
media-typer@1.1.0: {}
|
||||
|
||||
merge-descriptors@2.0.0: {}
|
||||
@@ -7704,6 +7765,8 @@ snapshots:
|
||||
|
||||
scheduler@0.27.0: {}
|
||||
|
||||
seedrandom@3.0.5: {}
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
@@ -8015,6 +8078,8 @@ snapshots:
|
||||
|
||||
tapable@2.3.0: {}
|
||||
|
||||
tiny-emitter@2.1.0: {}
|
||||
|
||||
tiny-invariant@1.3.3: {}
|
||||
|
||||
tinyexec@1.0.2: {}
|
||||
@@ -8113,6 +8178,8 @@ snapshots:
|
||||
possible-typed-array-names: 1.1.0
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typed-function@4.2.2: {}
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
|
||||
Reference in New Issue
Block a user