diff --git a/app/apps/common/templatetags/formats.py b/app/apps/common/templatetags/formats.py new file mode 100644 index 0000000..9a3492c --- /dev/null +++ b/app/apps/common/templatetags/formats.py @@ -0,0 +1,17 @@ +from django import template +from django.utils.formats import get_format + + +register = template.Library() + + +@register.simple_tag +def get_thousand_separator(): + print(get_format("THOUSAND_SEPARATOR")) + return get_format("THOUSAND_SEPARATOR") + + +@register.simple_tag +def get_decimal_separator(): + print(get_format("DECIMAL_SEPARATOR")) + return get_format("DECIMAL_SEPARATOR") diff --git a/app/templates/includes/navbar.html b/app/templates/includes/navbar.html index c03b369..79620d8 100644 --- a/app/templates/includes/navbar.html +++ b/app/templates/includes/navbar.html @@ -126,7 +126,15 @@ diff --git a/app/templates/layouts/base.html b/app/templates/layouts/base.html index c2538da..63d3395 100644 --- a/app/templates/layouts/base.html +++ b/app/templates/layouts/base.html @@ -1,3 +1,4 @@ +{% load formats %} {% load i18n %} {% load title %} {% load webpack_loader %} @@ -19,6 +20,8 @@ {% block extra_styles %}{% endblock %} {% include 'includes/scripts.html' %} + + {% block extra_js_head %}{% endblock %} @@ -34,7 +37,93 @@ {% include 'includes/offcanvas.html' %} {% include 'includes/toasts.html' %} - + +
+ +
+ +
+ + +
+
+
=
+
+
+
+
+ +
+
{% block extra_js_body %}{% endblock %} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cba75b0..ea8bf2c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -34,6 +34,7 @@ "htmx.org": "^2.0.1", "hyperscript.org": "^0.9.12", "jquery": "^3.7.1", + "mathjs": "^14.0.1", "mini-css-extract-plugin": "^2.5.1", "postcss-loader": "^6.2.1", "postcss-preset-env": "^7.2.3", @@ -1615,9 +1616,10 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -3342,6 +3344,19 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, + "node_modules/complex.js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz", + "integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -3792,6 +3807,12 @@ "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "license": "MIT" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4050,6 +4071,12 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -5561,6 +5588,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "license": "MIT" + }, "node_modules/jest-worker": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", @@ -5837,6 +5870,42 @@ "resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz", "integrity": "sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg==" }, + "node_modules/mathjs": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-14.0.1.tgz", + "integrity": "sha512-yyJgLwC6UXuve724np8tHRMYaTtb5UqiOGQkjwbSXgH8y1C/LcJ0pvdNDZLI2LT7r+iExh2Y5HwfAY+oZFtGIQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.25.7", + "complex.js": "^2.2.5", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "^5.2.1", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.2.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mathjs/node_modules/fraction.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.2.1.tgz", + "integrity": "sha512-Ah6t/7YCYjrPUFUFsOsRLMXAdnYM+aQwmojD2Ayb/Ezr82SwES0vuyQ8qZ3QO8n9j7W14VJuVZZet8U3bhSdQQ==", + "license": "MIT", + "engines": { + "node": ">= 12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -7951,6 +8020,12 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "license": "MIT" + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -9091,6 +9166,12 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "license": "MIT" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -9181,6 +9262,15 @@ "node": ">= 0.6" } }, + "node_modules/typed-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, "node_modules/typer-dot-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/typer-dot-js/-/typer-dot-js-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7b681a3..0fb153b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -47,6 +47,7 @@ "htmx.org": "^2.0.1", "hyperscript.org": "^0.9.12", "jquery": "^3.7.1", + "mathjs": "^14.0.1", "mini-css-extract-plugin": "^2.5.1", "postcss-loader": "^6.2.1", "postcss-preset-env": "^7.2.3", diff --git a/frontend/src/application/htmx.js b/frontend/src/application/htmx.js index f85fbfd..c3f3fd6 100644 --- a/frontend/src/application/htmx.js +++ b/frontend/src/application/htmx.js @@ -2,14 +2,18 @@ import _hyperscript from 'hyperscript.org/dist/_hyperscript.min'; import './_htmx.js'; import Alpine from "alpinejs"; import mask from '@alpinejs/mask'; +import { create, all } from 'mathjs'; window.Alpine = Alpine; window._hyperscript = _hyperscript; +window.math = create(all, { }); Alpine.plugin(mask); Alpine.start(); _hyperscript.browserInit(); + + const successAudio = new Audio("/static/sounds/success.mp3"); const popAudio = new Audio("/static/sounds/pop.mp3"); window.paidSound = successAudio; diff --git a/frontend/src/styles/_animations.scss b/frontend/src/styles/_animations.scss index 5fa1a42..44787e0 100644 --- a/frontend/src/styles/_animations.scss +++ b/frontend/src/styles/_animations.scss @@ -101,3 +101,32 @@ z-index: 101; } } + +.swing-out-top-bck { + animation: swing-out-top-bck 0.45s cubic-bezier(0.600, -0.280, 0.735, 0.045) both; +} + +/* ---------------------------------------------- + * Generated by Animista on 2024-12-14 15:59:19 + * Licensed under FreeBSD License. + * See http://animista.net/license for more info. + * w: http://animista.net, t: @cssanimista + * ---------------------------------------------- */ + +/** + * ---------------------------------------- + * animation swing-out-top-bck + * ---------------------------------------- + */ +@keyframes swing-out-top-bck { + 0% { + transform: rotateX(0deg); + transform-origin: top; + opacity: 1; + } + 100% { + transform: rotateX(-100deg); + transform-origin: top; + opacity: 0; + } +}