Compare commits

..

7 Commits

Author SHA1 Message Date
3e29592b48 Updated build packages, Updated png analyser page
Update package-lock.json and png-analyser.jinja
2025-09-08 00:38:18 +02:00
30da615199 Updated VAT calculator, fixed minor TLD issues, Added strings, Optimized assets
Update sidebar.yml, commons.yml, and 10 more files...
2025-09-08 00:15:59 +02:00
615affcc2d Added VAT calculator tool and applet, Cleaned up launch logs and DOM trash
Update .gitignore, vat-calculator.yml, and 17 more files...
2025-09-07 20:52:02 +02:00
eb2ffa296b Added uppercase option to UUID generator
Update uuid-generator.yml, uuid-generator.yml, and 2 more files...
2025-08-25 21:23:24 +02:00
41286a8253 Updated png and bmp related-libs, Updated home page and sidebar
Update sidebar.yml, home.yml, and 7 more files...
2025-08-25 00:03:01 +02:00
a20b45d86e Update IbanGenerator and UUIDGenerator styles, Updated standalone style
Update extra.css, nibblepoker.min.css, and 2 more files...
2025-08-25 00:00:15 +02:00
690b3179ed Updated and fixed IbanGenerator tool
Update purebasic-structure-on-stack.md, iban-generator.yml, and 4 more files...
2025-08-24 18:55:54 +02:00
41 changed files with 1192 additions and 151 deletions

1
.gitignore vendored
View File

@@ -14,5 +14,6 @@ node_modules/
*.ai
# Temp
static/resources/DecimalJs*
static/resources/SortableJS
static/resources/Standalone

View File

@@ -0,0 +1,7 @@
applets:
- id: "vat-calculator"
resources:
scripts:
- "applet://vat-calculator.mjs"
stylesheets:
- "applet://vat-calculator.css"

View File

@@ -48,7 +48,7 @@
abs_href: "/tools"
icon: fad fa-toolbox
active_id: tools
has_new_until_utc: 1760986472
has_new_until_utc: 1759856025
- title_key: text.downloads
raw_href: "https://files.nibblepoker.lu/"
@@ -58,11 +58,11 @@
-
- title_key: text.about
abs_href: "/about"
icon: fad fa-user
active_id: about
has_new_until_utc: 0
#- title_key: text.about
# abs_href: "/about"
# icon: fad fa-user
# active_id: about
# has_new_until_utc: 0
- title_key: text.contact
abs_href: "/contact"

View File

@@ -14,3 +14,4 @@
- "/tools/iban-generator/"
- "/tools/excel-password-remover/"
- "/tools/uuid-generator/"
- "/tools/vat-calculator/"

View File

@@ -91,3 +91,48 @@ format.json: "JSON"
format.yaml: "YAML"
action.generate: "Generate"
country.afghanistan: "Afghanistan"
country.albania: "Albania"
country.algeria: "Algeria"
country.andorra: "Andorra"
country.angola: "Angola"
country.anguilla: "Anguilla"
country.argentina: "Argentina"
country.australia: "Australia"
country.austria: "Austria"
country.azerbaijan: "Azerbaijan"
country.azores: "Azores"
country.bahamas: "Bahamas"
country.belgium: "Belgium"
country.bulgaria: "Bulgaria"
country.corsica: "Corsica"
country.croatia: "Croatia"
country.cyprus: "Cyprus"
country.czechia: "Czechia"
country.denmark: "Denmark"
country.estonia: "Estonia"
country.finland: "Finland"
country.france: "France"
country.france.corsica: "France - Corsica"
country.germany: "Germany"
country.greece: "Greece"
country.hungary: "Hungary"
country.ireland: "Ireland"
country.italy: "Italy"
country.latvia: "Latvia"
country.lithuania: "lithuania"
country.luxembourg: "Luxembourg"
country.madeira: "Madeira"
country.malta: "Malta"
country.monaco: "Monaco"
country.netherlands: "Netherlands"
country.poland: "Poland"
country.portugal: "Portugal"
country.portugal.azores: "Portugal - Azores"
country.portugal.madeira: "Portugal - Madeira"
country.romania: "Romania"
country.slovenia: "Slovenia"
country.slovakia: "Slovakia"
country.spain: "Spain"
country.sweden: "Sweden"

View File

@@ -9,12 +9,18 @@ meta.description.light: "Web application that allows you to generate IBANs in bu
country.label: "Country"
option.count: "IBAN Count"
option.human.readable: "Format for readability"
option.prefer.numbers: "Prefer numbers over letters"
option.for.each: "Generate <i>X</i> for each country"
option.sepa.enable: "Enable SEPA countries"
option.non-sepa.enable: "Enable non-SEPA countries"
option.prefer.random: "Do not prefer letters nor numbers"
option.prefer.numbers: "Prefer numbers over letters"
option.prefer.letters: "Prefer letters over numbers"
option.human.format.none: "No formatting"
option.human.format.standard: "Use recommended spacing"
option.human.format.4by4: "Use 4 character-wide spacing"
license.1: "The code for this project is released in the public domain."
license.2: "The original source code can be found on <a href=\"https://github.com/aziascreations/Web-NibblePoker\">GitHub</a>."
license.3: "Data from Swift's

View File

@@ -10,6 +10,7 @@ type.uuid4: "UUID4 / GUID4"
option.count: "UUID Count"
option.hyphen: "Add hyphens"
option.guid_brackets: "Add GUID brackets"
option.uppercase: "Generate in uppercase"
generate: "Generate"

View File

@@ -0,0 +1,52 @@
# EN - VAT Calculator
meta.title: "VAT Calculator"
meta.description: "Simple VAT calculator with a selection of common rates for 32 countries/regions."
preset.label: "Official rates"
option.detailed: "Show VAT rate types"
radio.rate: "VAT rate: "
radio.untaxed: "Excl. VAT: "
radio.taxed: "Incl. VAT: "
text.radio.explanation: "The selected radio input indicates the automatically calculated field."
rate.option.custom: "Custom rate"
rate.type.standard: "Standard"
rate.type.intermediate: "Intermediate"
rate.type.preferential: "Preferential"
rate.type.reduced: "Reduced"
rate.type.reduced.super: "Super reduced"
rate.type.special: "Special"
option.decimal-places: "Decimal places count"
option.trim-zeroes: "Trim trailing zeroes"
rounding.mode.label: "Rounding mode"
rounding.mode.group.regular: "Regular rounding"
rounding.mode.group.half: "Half rounding&emsp;(Towards nearest neighbour)"
rounding.mode.up: "Away from zero&emsp;(Up)"
rounding.mode.down: "Towards zero&emsp;(Down)"
rounding.mode.ceil: "Towards infinity&emsp;(Ceil)"
rounding.mode.floor: "Towards negative infinity&emsp;(Floor)"
rounding.mode.up.half: "Away from zero if equidistant&emsp;(Half up)"
rounding.mode.down.half: "Towards zero if equidistant&emsp;(Half down)"
rounding.mode.even.half: "Towards even neighbour if equidistant&emsp;(Half even)"
rounding.mode.ceil.half: "Towards infinity if equidistant&emsp;(Half ceil)"
rounding.mode.floor.half: "Towards negative infinity if equidistant&emsp;(Half floor)"
#rounding.mode.up.half: "Towards nearest neighbour, away from zero if equidistant&emsp;(Half up)"
#rounding.mode.down.half: "Towards nearest neighbour, towards zero if equidistant&emsp;(Half down)"
#rounding.mode.even.half: "Towards nearest neighbour, towards even neighbour if equidistant&emsp;(Half even)"
#rounding.mode.ceil.half: "Towards nearest neighbour, towards infinity if equidistant&emsp;(Half ceil)"
#rounding.mode.floor.half: "Towards nearest neighbour, towards negative infinity if equidistant&emsp;(Half floor)"
license.text.1: "This tool uses the <a href=\"https://github.com/MikeMcl/decimal.js-light\">decimal.js-light</a>
library, which is licensed under the <a href=\"https://github.com/MikeMcl/decimal.js-light/blob/master/LICENCE.md\">MIT license</a>."
license.text.2: "The rest of this tool's code is released in the <a href=\"https://github.com/aziascreations/Web-NibblePoker\">public domain</a>."

View File

@@ -91,3 +91,48 @@ format.json: "JSON"
format.yaml: "YAML"
action.generate: "Générer"
country.afghanistan: "Afghanistan"
country.albania: "Albanie"
country.algeria: "Algérie"
country.andorra: "Andorre"
country.angola: "Angola"
country.anguilla: "Anguilla"
country.argentina: "Argentine"
country.australia: "Australie"
country.austria: "Autriche"
country.azerbaijan: "Azerbaïdjan"
country.azores: "Açores"
country.bahamas: "Bahamas"
country.belgium: "Belgique"
country.bulgaria: "Bulgarie"
country.corsica: "Corse"
country.croatia: "Croatie"
country.cyprus: "Chypre"
country.czechia: "Tchéquie"
country.denmark: "Danemark"
country.estonia: "Estonie"
country.finland: "Finlande"
country.france: "France"
country.france.corsica: "France - Corse"
country.germany: "Allemagne"
country.greece: "Grèce"
country.hungary: "Hongrie"
country.ireland: "Irlande"
country.italy: "Italie"
country.latvia: "Lettonie"
country.lithuania: "Lituanie"
country.luxembourg: "Luxembourg"
country.madeira: "Madère"
country.malta: "Malte"
country.monaco: "Monaco"
country.netherlands: "Pays-Bas"
country.poland: "Pologne"
country.portugal: "Portugal"
country.portugal.azores: "Portugal - Açores"
country.portugal.madeira: "Portugal - Madère"
country.romania: "Roumanie"
country.slovenia: "Slovénie"
country.slovakia: "Slovaquie"
country.spain: "Espagne"
country.sweden: "Suède"

View File

@@ -15,7 +15,7 @@ header.title: Page d'accueil
intro.title: Bienvenue sur %0
intro.text.1: Ce site web contient une collection de mes travaux personnels tels
que des articles de blog, des logiciels utilitaires ou d'autres formes de médias.<br>Tout
est accessible gratuitement et sous des licences à l'open source.
est accessible gratuitement et sous des licences open source.
intro.text.2: Si vous souhaitez me contacter, vous pouvez le faire via la page
de contact lié dans la barre de navigation latérale.

View File

@@ -9,12 +9,18 @@ meta.description.light: "Application web qui vous permet de générer des IBANs
country.label: "Pays"
option.count: "Nombre d'IBAN"
option.human.readable: "Formatter pour lecture"
option.prefer.numbers: "Favoriser les nombres aux lettres"
option.for.each: "Générer <i>X</i> pour chaque pays"
option.sepa.enable: "Activer les pays SEPA"
option.non-sepa.enable: "Activer les pays non-SEPA"
option.prefer.random: "Pas de favorisation des lettres ou nombres"
option.prefer.numbers: "Favoriser les nombres aux lettres"
option.prefer.letters: "Favoriser les lettres aux nombres"
option.human.format.none: "Aucun formatage"
option.human.format.standard: "Utiliser le format standard des pays"
option.human.format.4by4: "Formater en segments de 4 caractères"
license.1: "Le code de ce projet est publié dans le domaine public."
license.2: "Le code source original peut être trouvé sur <a href=\"https://github.com/aziascreations/Web-NibblePoker\">GitHub</a>."
license.3: "Les données du

View File

@@ -10,6 +10,7 @@ type.uuid4: "UUID4 / GUID4"
option.count: "Nombre d'UUID/GUID"
option.hyphen: "Ajouter trait d'union"
option.guid_brackets: "Ajouter accolades pour GUID"
option.uppercase: "Générer en majuscules"
generate: "Générer"

View File

@@ -0,0 +1,52 @@
# FR - VAT Calculator
meta.title: "Calculateur de TVA"
meta.description: "Simple calculateur de TVA avec une selection de taux communs pour 32 pays/régions."
preset.label: "Taux officiel"
option.detailed: "Afficher le type de TVA"
radio.rate: "Taux: "
radio.untaxed: "<abbr title=\"Hors Taxe sur la Valeur Ajoutée\">HTVA</abbr>: "
radio.taxed: "<abbr title=\"Toutes Taxes Comprises\">TTC</abbr>: "
text.radio.explanation: "Le cercle en vert indique la valeur automatiquement calculée."
rate.option.custom: "Taux personalisé"
rate.type.standard: "Standard"
rate.type.intermediate: "Intermédiaire"
rate.type.preferential: "Préférentiel"
rate.type.reduced: "Réduit"
rate.type.reduced.super: "Super réduit"
rate.type.special: "Spécial"
option.decimal-places: "Nombre de décimales"
option.trim-zeroes: "Supprimer les zéros de fin"
rounding.mode.label: "Type d'arrondi"
rounding.mode.group.regular: "Arrondis classiques"
rounding.mode.group.half: "Demi-arrondis&emsp;(Vers le plus proche)"
rounding.mode.up: "Loin de zéro&emsp;(Arrondi au supérieur)"
rounding.mode.down: "Vers zéro&emsp;(Arrondi à l'inférieur)"
rounding.mode.ceil: "Vers l'infini&emsp;(Par plafond)"
rounding.mode.floor: "Vers moins l'infini&emsp;(Par plancher)"
rounding.mode.up.half: "Loin de zéro si équidistant&emsp;(Demi supérieur)"
rounding.mode.down.half: "Vers zéro si équidistant&emsp;(Demi inférieur)"
rounding.mode.even.half: "Vers le pair si équidistant&emsp;(Demi pair)"
rounding.mode.ceil.half: "Vers l'infini&emsp;(Demi plafond)"
rounding.mode.floor.half: "Vers moins l'infini&emsp;(Demi plancher)"
#rounding.mode.up.half: "Vers le plus proche, loin de zéro si équidistant&emsp;(Demi supérieur)"
#rounding.mode.down.half: "Vers le plus proche, vers zéro si équidistant&emsp;(Demi inférieur)"
#rounding.mode.even.half: "Vers le plus proche, vers le pair si équidistant&emsp;(Demi pair)"
#rounding.mode.ceil.half: "Vers le plus proche, vers l'infini&emsp;(Demi plafond)"
#rounding.mode.floor.half: "Vers le plus proche, vers moins l'infini&emsp;(Demi plancher)"
license.text.1: "Cet outil utilise la bibliothèque <a href=\"https://github.com/MikeMcl/decimal.js-light\">decimal.js-light</a>,
qui est distribuée sous licence <a href=\"https://github.com/MikeMcl/decimal.js-light/blob/master/LICENCE.md\">MIT</a>."
license.text.2: "Le reste du code de cet outil est placé dans le <a href=\"https://github.com/aziascreations/Web-NibblePoker\">domaine public</a>."

View File

@@ -24,7 +24,7 @@ tools:
image_url: "/resources/NibblePoker/images/tools/iban-generator/main.png"
image_alt_key: ""
general:
icon: "fa-duotone fa-solid fa-credit-card-front"
icon: "fa-duotone fa-credit-card-front"
title_key: "meta.title"
subtitle_key: "article.subtitle"
tags:

View File

@@ -24,7 +24,7 @@ tools:
image_url: "/resources/NibblePoker/images/tools/uuid-generator/main.png"
image_alt_key: ""
general:
icon: "fab fa-python"
icon: "fa-duotone fa-memo-pad"
title_key: "meta.title"
subtitle_key: "article.subtitle"
tags:

View File

@@ -0,0 +1,32 @@
tools:
- id: "vat-calculator"
applet_id: "vat-calculator"
metadata:
head:
title_key: "meta.title"
description_key: "meta.description"
opengraph:
title_key: "meta.title"
description_key: "meta.description"
type: null
url: null
image_url: "/resources/NibblePoker/images/tools/vat-calculator/main-quiet.png"
image_type: null
twitter:
title_key: "meta.title"
description_key: "meta.description"
index:
priority: 500
enable: true
title_key: "meta.title"
preamble_key: "meta.description"
image_url: "/resources/NibblePoker/images/tools/vat-calculator/main-quiet.png"
image_alt_key: ""
general:
icon: "fa-solid fa-memo-pad"
title_key: "meta.title"
subtitle_key: "article.subtitle"
tags:
- "calculator"
- "finance"

View File

@@ -93,6 +93,16 @@ call "%~dp0node_modules\.bin\rollup" png-analyser.mjs --file png-analyser.js
call "%~dp0node_modules\.bin\terser" png-analyser.js -c -m -o png-analyser.min.js
popd
:js-vatcalculator-minify
echo Minifying VAT Calculator
pushd %CD%
cd %~dp0\..\static\resources\NibblePoker\applets\vat-calculator\
echo ^> static\resources\NibblePoker\applets\vat-calculator\vat-calculator.mjs
call "%~dp0node_modules\.bin\rollup" vat-calculator.mjs --file vat-calculator.js
call "%~dp0node_modules\.bin\terser" vat-calculator.js -c -m -o vat-calculator.min.js
popd
:js-nibblepoker-end
:end

View File

@@ -5,9 +5,10 @@
"packages": {
"": {
"devDependencies": {
"browserify": "^17.0.1",
"html-minifier-terser": "^7.2.0",
"minify": "^10.2.0",
"rollup": "^3.27.2",
"rollup": "^4.48.1",
"sass": "^1.63.6",
"terser": "^5.19.0",
"typescript": "^5.1.6"

View File

@@ -1,10 +1,11 @@
{
"devDependencies": {
"minify": "^10.2.0",
"rollup": "^3.27.2",
"rollup": "^4.48.1",
"sass": "^1.63.6",
"terser": "^5.19.0",
"typescript": "^5.1.6",
"html-minifier-terser": "^7.2.0"
"html-minifier-terser": "^7.2.0",
"browserify": "^17.0.1"
}
}

1
static/resources/Externals/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.svg

View File

@@ -30,10 +30,20 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
/** @type {HTMLInputElement} */
const eOptionCount = document.querySelector("input#iban-generator-option-count");
/** @type {HTMLInputElement} */
const eOptionPrettyPrint = document.querySelector("input#iban-generator-option-pretty");
///** @type {HTMLInputElement} */
//const eOptionPreferRandom = document.querySelector("input#iban-generator-option-prefer-random");
/** @type {HTMLInputElement} */
const eOptionPreferNumbers = document.querySelector("input#iban-generator-option-prefer-numbers");
/** @type {HTMLInputElement} */
const eOptionPreferLetters = document.querySelector("input#iban-generator-option-prefer-letters");
/** @type {HTMLInputElement} */
const eOptionFormatNone = document.querySelector("input#iban-generator-option-format-none");
/** @type {HTMLInputElement} */
const eOptionFormatStandard = document.querySelector("input#iban-generator-option-format-standard");
/** @type {HTMLInputElement} */
const eOptionFormat4By4 = document.querySelector("input#iban-generator-option-format-4by4");
/** @type {HTMLElement} */
const eGenerateButton = document.querySelector("#iban-generator-generate");
@@ -75,14 +85,14 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
/** @returns {number} */
function getDesiredCount() {
return getInputCount(eOptionCount, 1, 1000);
return getInputCount(eOptionCount, 1, 10000);
}
function changeDesiredCount(difference = 0) {
if(difference !== 0) {
eOptionCount.value = getDesiredCount(eOptionCount, 1, 1000) + difference;
eOptionCount.value = getDesiredCount(eOptionCount, 1, 10000) + difference;
}
eOptionCount.value = getDesiredCount(eOptionCount, 1, 1000);
eOptionCount.value = getDesiredCount(eOptionCount, 1, 10000);
}
window.onload = function () {
@@ -108,12 +118,28 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
let desiredCount = getDesiredCount();
let preferNumbers = eOptionPreferNumbers.checked;
let prettyIban = eOptionPrettyPrint.checked;
let preferLetters = eOptionPreferLetters.checked;
let ibanFormat = (
eOptionFormatNone.checked ? 0 : (
eOptionFormatStandard.checked ? 1 : (
eOptionFormat4By4.checked ? 2 : 0
)
)
);
/** @type {IbanSpecification[]} */
let targetSpecs;
if(eOptionForEach.checked) {
targetSpecs = Object.values(countriesSpecs);
// BUGFIX: Removing unwanted specs.
if(!eOptionEnableSepa.checked) {
targetSpecs = targetSpecs.filter(ibanSpec => !ibanSpec.isSepa);
}
if(!eOptionEnableNonSepa.checked) {
targetSpecs = targetSpecs.filter(ibanSpec => ibanSpec.isSepa);
}
} else {
targetSpecs = [countriesSpecs[eOptionCountry.value]];
}
@@ -123,15 +149,27 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
return;
}
for(let i = 0; i < desiredCount; i++) {
if(prettyIban) {
if(ibanFormat === 1) {
// standard
lastIBANs.push(
spec.getFormattedIban(
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers), spec).toString()
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers, preferLetters), spec)
.toString()
)
);
} else {
} else if(ibanFormat === 2) {
// 4-by-4
lastIBANs.push(
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers), spec).toString()
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers, preferLetters), spec)
.toString()
.match(/.{1,4}/g)
.join(' ')
);
} else {
// none
lastIBANs.push(
new StandardIban(spec.countryCode, spec.generateRandomBban(preferNumbers, preferLetters), spec)
.toString()
);
}
}

View File

@@ -1,6 +1,7 @@
import {initCore} from "../../js/nibblepoker-core.mjs"
import {parsePngFile} from "../../libs/png-utils.mjs";
import {parseBmpFile} from "../../libs/bmp-utils.mjs";
{
initCore();
@@ -16,12 +17,18 @@ import {parsePngFile} from "../../libs/png-utils.mjs";
console.log(files);
if(files[0].name.endsWith(".png")) {
parsePngFile(files[0]).then(pngFile => {
console.log(pngFile);
console.log(pngFile.getImageHeaderChunk().getWidth());
console.log(pngFile.getImageHeaderChunk().getHeight());
});
} else if(files[0].name.endsWith(".bmp")) {
parseBmpFile(files[0]).then(bmpFile => {
console.log(bmpFile);
});
}
});
};
}

View File

@@ -19,6 +19,8 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
const eOptionHyphenInput = document.querySelector("input#uuid-generator-option-hyphens");
/** @type {HTMLInputElement} */
const eOptionGuidBracketsInput = document.querySelector("input#uuid-generator-option-guid-brackets");
/** @type {HTMLInputElement} */
const eOptionUppercaseInput = document.querySelector("input#uuid-generator-option-uppercase");
/** @type {HTMLElement} */
const eGenerateButton = document.querySelector("#uuid-generator-generate");
@@ -57,10 +59,16 @@ import {initCore} from "../../js/nibblepoker-core.mjs";
let addGuidBrackets = eOptionGuidBracketsInput.checked;
lastUUIDs = [];
if (eOptionUppercaseInput.checked) {
for (let i = 0; i < desiredCount; i++) {
lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets).toUpperCase());
}
} else {
for (let i = 0; i < desiredCount; i++) {
lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets));
ePreviewTextArea.value += uuidGenerator(addHyphens, addGuidBrackets) + "\n";
}
}
ePreviewTextArea.value = lastUUIDs.join("\n");
});

View File

@@ -0,0 +1,248 @@
import {initCore} from "../../js/nibblepoker-core.mjs";
//import {Decimal} from "../../../DecimalJs/10.6.0/decimal.mjs";
import {Decimal} from "../../../DecimalJs-Light/2.5.1/decimal.mjs";
import {getInputCount, getInputNumber} from "../../libs/input-utils.mjs";
// Tool-centric stuff
{
initCore();
const classesReadonly = ["bkgd-gray"];
const calcRadioGroupName = "vat_calc_target";
/** @type {HTMLLabelElement} */
const ePresetShortLabel = document.querySelector("label[for=vat-calculator-preset-short]");
/** @type {HTMLSelectElement} */
const ePresetShortSelect = document.getElementById("vat-calculator-preset-short");
/** @type {HTMLLabelElement} */
const ePresetDetailedLabel = document.querySelector("label[for=vat-calculator-preset-detailed]");
/** @type {HTMLSelectElement} */
const ePresetDetailedSelect = document.getElementById("vat-calculator-preset-detailed");
/** @type {HTMLInputElement} */
const eCheckboxDetailedPreset = document.getElementById("vat-calculator-detailed-presets");
/** @type {HTMLSpanElement} */
const ePresetEchoedCountry = document.getElementById("vat-calculator-preset-country-echo");
/** @type {HTMLButtonElement} */
const eButtonDecimalPlacesMinus = document.getElementById("vat-calculator-decimal-places-minus");
/** @type {HTMLInputElement} */
const eInputDecimalPlaces = document.getElementById("vat-calculator-option-decimal-places");
/** @type {HTMLButtonElement} */
const eButtonDecimalPlacesPlus = document.getElementById("vat-calculator-decimal-places-plus");
/* #vat-calculator-detailed-trim-zeroes */
/** @type {HTMLInputElement} */
const eCalcRateRadio = document.getElementById("vat-calculator-radio-rate");
/** @type {HTMLInputElement} */
const eCalcRateInput = document.getElementById("vat-calculator-input-rate");
/** @type {HTMLInputElement} */
const eCalcUntaxedRadio = document.getElementById("vat-calculator-radio-untaxed");
/** @type {HTMLInputElement} */
const eCalcUntaxedInput = document.getElementById("vat-calculator-input-untaxed");
/** @type {HTMLInputElement} */
const eCalcTaxedRadio = document.getElementById("vat-calculator-radio-taxed");
/** @type {HTMLInputElement} */
const eCalcTaxedInput = document.getElementById("vat-calculator-input-taxed");
/** @type {HTMLSelectElement} */
const eRoundingModeSelect = document.getElementById("vat-calculator-rounding-mode");
/**
* Handles the switch between the short and detailed standard rates selects
*/
function handlePresetDetailLevelChange() {
ePresetShortLabel.hidden = eCheckboxDetailedPreset.checked;
ePresetShortSelect.hidden = eCheckboxDetailedPreset.checked;
ePresetDetailedLabel.hidden = !eCheckboxDetailedPreset.checked;
ePresetDetailedSelect.hidden = !eCheckboxDetailedPreset.checked;
}
/** @returns {number} */
function getDecimalPlaces() {
return getInputCount(eInputDecimalPlaces, 0, 99);
}
function changeDecimalPlacesDesiredCount(difference = 0) {
if (difference !== 0) {
eInputDecimalPlaces.value = getInputCount(eInputDecimalPlaces, 0, 99) + difference;
}
eInputDecimalPlaces.value = getInputCount(eInputDecimalPlaces, 0, 99);
}
/**
* Handles the locking and unlocking of the calculator input fields.
* @param eInput {HTMLInputElement}
* @param isLocked {boolean}
*/
function setCalcFieldLockStatus(eInput, isLocked) {
eInput.readOnly = isLocked;
classesReadonly.forEach((roClass) => {
eInput.classList.remove(roClass);
if(isLocked) {
eInput.classList.add(roClass);
}
});
}
function handleCalcValueChange() {
let vatRate = getInputNumber(eCalcRateInput);
let untaxedValue = getInputNumber(eCalcUntaxedInput);
let taxedValue = getInputNumber(eCalcTaxedInput);
if(eCalcRateRadio.checked) {
if(untaxedValue === null || taxedValue === null || isNaN(untaxedValue) || isNaN(taxedValue)) {
return;
}
untaxedValue = new Decimal(eCalcUntaxedInput.value);
taxedValue = new Decimal(eCalcTaxedInput.value);
eCalcRateInput.value = taxedValue
.minus(untaxedValue)
.div(untaxedValue)
.times(100)
.toDecimalPlaces(getDecimalPlaces());
} else if(eCalcUntaxedRadio.checked) {
if(vatRate === null || taxedValue === null || isNaN(vatRate) || isNaN(taxedValue)) {
return;
}
vatRate = new Decimal(eCalcRateInput.value).dividedBy(100).plus(1);
taxedValue = new Decimal(eCalcTaxedInput.value);
eCalcUntaxedInput.value = taxedValue
.dividedBy(vatRate)
.toDecimalPlaces(getDecimalPlaces());
} else if(eCalcTaxedRadio.checked) {
if(vatRate === null || untaxedValue === null || isNaN(vatRate) || isNaN(untaxedValue)) {
return;
}
vatRate = new Decimal(eCalcRateInput.value).dividedBy(100).plus(1);
untaxedValue = new Decimal(eCalcUntaxedInput.value);
eCalcTaxedInput.value = untaxedValue
.times(vatRate)
.toDecimalPlaces(getDecimalPlaces());
}
}
function handleDecimalConfigChange() {
Decimal.set({
rounding: getInputCount(eRoundingModeSelect, 0, 8),
precision: 99,
defaults: true,
});
}
function handlePresetChange() {
if(ePresetShortSelect.value.length > 0) {
let eSelectedOption = ePresetShortSelect.querySelector('option:checked');
if(eSelectedOption === null) {
return;
}
let eSelectedOptionGroup = eSelectedOption.closest('optgroup');
if(eSelectedOptionGroup === null) {
return;
}
ePresetEchoedCountry.innerHTML = eSelectedOptionGroup.label;
} else {
ePresetEchoedCountry.innerHTML = "";
}
}
window.onload = function () {
// Handling the detailed rate toggle
eCheckboxDetailedPreset.addEventListener("click", function () {
handlePresetDetailLevelChange();
});
// Handling the rate select input
ePresetShortSelect.addEventListener("change", function () {
ePresetDetailedSelect.selectedIndex = ePresetShortSelect.selectedIndex;
eCalcRateInput.value = ePresetShortSelect.value;
handlePresetChange();
handleCalcValueChange();
});
ePresetDetailedSelect.addEventListener("change", function () {
ePresetShortSelect.selectedIndex = ePresetDetailedSelect.selectedIndex;
eCalcRateInput.value = ePresetDetailedSelect.value;
handlePresetChange();
handleCalcValueChange();
});
// Handling calc radio input change
document.addEventListener("change", (e) => {
if (e.target.type === "radio" && e.target.name === calcRadioGroupName) {
setCalcFieldLockStatus(eCalcRateInput, e.target.value === "0");
setCalcFieldLockStatus(eCalcUntaxedInput, e.target.value === "1");
setCalcFieldLockStatus(eCalcTaxedInput, e.target.value === "2");
ePresetDetailedSelect.disabled = e.target === eCalcRateRadio;
ePresetShortSelect.disabled = e.target === eCalcRateRadio;
}
});
eCalcRateRadio.addEventListener("change", function () {
ePresetShortSelect.selectedIndex = 0;
ePresetDetailedSelect.selectedIndex = 0;
handlePresetChange();
});
// Handling decimal places options
eButtonDecimalPlacesMinus.addEventListener("click", function () {
changeDecimalPlacesDesiredCount(-1);
handleDecimalConfigChange();
handleCalcValueChange();
});
eButtonDecimalPlacesPlus.addEventListener("click", function () {
changeDecimalPlacesDesiredCount(1);
handleDecimalConfigChange();
handleCalcValueChange();
});
eInputDecimalPlaces.addEventListener("change", function() {
changeDecimalPlacesDesiredCount(0);
handleDecimalConfigChange();
handleCalcValueChange();
});
eInputDecimalPlaces.addEventListener("mousewheel", function(e) {
// Handling wheel scroll on count field.
if(e.wheelDelta < 0) {
changeDecimalPlacesDesiredCount(-1);
} else {
changeDecimalPlacesDesiredCount(1);
}
handleDecimalConfigChange();
handleCalcValueChange();
});
// Handling other DecimalJs config fields
eRoundingModeSelect.addEventListener("change", function() {
handleDecimalConfigChange();
handleCalcValueChange();
});
// Handling the calculator field changes
eCalcRateInput.addEventListener("change", function() {
ePresetShortSelect.selectedIndex = 0;
ePresetDetailedSelect.selectedIndex = 0;
handleCalcValueChange();
handlePresetChange();
});
eCalcUntaxedInput.addEventListener("change", function() {
handleCalcValueChange();
});
eCalcTaxedInput.addEventListener("change", function() {
handleCalcValueChange();
});
handlePresetDetailLevelChange();
handleDecimalConfigChange();
handlePresetChange();
}
}

View File

@@ -15,22 +15,6 @@ input[type=file].np-file-input-drop {
cursor: pointer;
}
/* Nicer checkboxes, move to CSS 8 */
input[type=checkbox] {
text-align: center;
padding: 0;
&:before {
content: "✘";
}
&:checked {
&:before {
content: "✔";
}
}
}
/* Top margin trimmer for heading renderer */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,57 @@
import {loadFileAsUint8Array} from "./file-utils.mjs";
import {peekUInt32BE, peekUInt16BE} from "./data-utils.mjs";
/*export const test = {
WINDOWS: "BM",
OS2_STRUCT_BITMAP_ARRAY: "BA",
OS2_STRUCT_COLOR_ICON: "CI",
OS2_CONST_COLOR_POINTER: "CP",
OS2_STRUCT_ICON: "IC",
OS2_POINTER: "PT",
}*/
export class BmpHeader {
/** @type {Uint8Array} */
data;
/**
* @param byteArray {Uint8Array|null}
*/
constructor(byteArray) {
if(byteArray === null || byteArray === undefined) {
this.data = new Uint8Array(14);
} else {
this.data = byteArray;
}
}
getSignature() {
return peekUInt16BE(this.data, 0);
}
getFileSize() {
return peekUInt32BE(this.data, 2);
}
getReserved() {
return peekUInt32BE(this.data, 6);
}
getDataOffset() {
return peekUInt32BE(this.data, 10);
}
}
export class CrudeBmpFile {
constructor(file = null, fileData = null) {
this.originalFile = file;
}
}
export function parseBmpFile(file) {
return loadFileAsUint8Array(file).then(byteBuffer => {
return new CrudeBmpFile(file, byteBuffer);
});
}

View File

@@ -23,6 +23,34 @@ export function areUintArraysEqual(array1, array2) {
return true;
}
/**
* Peeks a UInt16 from the given data at the given offset in Big-Endian.
* @param data {Uint8Array} - Data to read from.
* @param offset {number} - Offset to read from in the given `data`.
* @return {number} The peeked number.
* @throws RangeError If the given offset is too close or over the end of the data.
*/
export function peekUInt16BE(data, offset = 0) {
if(offset + 2 > data.length) {
throw new RangeError(`Offset is too far into the given data ! (${offset} & ${data.length})`);
}
return new DataView(data.buffer, offset, 2).getUint16(0, false);
}
/**
* Peeks a UInt16 from the given data at the given offset in Little-Endian.
* @param data {Uint8Array} - Data to read from.
* @param offset {number} - Offset to read from in the given `data`.
* @return {number} The peeked number.
* @throws RangeError If the given offset is too close or over the end of the data.
*/
export function peekUInt16LE(data, offset = 0) {
if(offset + 2 > data.length) {
throw new RangeError(`Offset is too far into the given data ! (${offset} & ${data.length})`);
}
return new DataView(data.buffer, offset, 2).getUint16(0, true);
}
/**
* Peeks a UInt32 from the given data at the given offset in Big-Endian.
* @param data {Uint8Array} - Data to read from.

View File

@@ -269,7 +269,7 @@ export class IbanSpecification {
return iban.match(/.{1,4}/g).join(' ');
}
generateRandomBban(preferNumbers = false) {
generateRandomBban(preferNumbers = false, preferLetters = false) {
let returnedBban = "";
let patternParts = ("_" + this.bbanFormat + "0").split("!");
@@ -290,9 +290,13 @@ export class IbanSpecification {
case 'C':
if(preferNumbers) {
elementChoices = charsN;
} else {
if(preferLetters) {
elementChoices = charsA;
} else {
elementChoices = charsC;
}
}
break;
case 'a':
case 'A':

View File

@@ -2,21 +2,7 @@
// Author: Herwin Bozet (@NibblePoker)
// License: Public Domain (This code)
/**
* Retrieves the number from an `HTMLInputElement`
* @param eInput {HTMLInputElement} The `HTMLInputElement` from which the value will be retrieved.
* @param min {number|null} If given, sets a minimum the value can have when returned.
* @param max {number|null} If given, sets a maximum the value can have when returned.
* @returns {number} The value from the given `HTMLInputElement`, or `1` if no valid one was given.
*/
export function getInputCount(eInput, min = null, max = null) {
let desiredCount = null;
try {
desiredCount = parseInt(eInput.value);
} catch (e) {
console.error(e);
}
function postProcessNumber(desiredCount, min = null, max = null) {
if (desiredCount === null) {
desiredCount = 1;
}
@@ -34,3 +20,37 @@ export function getInputCount(eInput, min = null, max = null) {
return desiredCount;
}
/**
* Retrieves the integer number from an `HTMLInputElement`
* @param eInput {HTMLInputElement|HTMLSelectElement} The `HTMLInputElement` from which the value will be retrieved.
* @param min {number|null} If given, sets a minimum the value can have when returned.
* @param max {number|null} If given, sets a maximum the value can have when returned.
* @returns {number|NaN} The value from the given `HTMLInputElement`, or `1` if no valid one was given.
*/
export function getInputCount(eInput, min = null, max = null) {
let desiredCount = null;
try {
desiredCount = parseInt(eInput.value);
} catch (e) {
console.error(e);
}
return postProcessNumber(desiredCount, min, max);
}
/**
* Retrieves the float number from an `HTMLInputElement`
* @param eInput {HTMLInputElement|HTMLSelectElement} The `HTMLInputElement` from which the value will be retrieved.
* @param min {number|null} If given, sets a minimum the value can have when returned.
* @param max {number|null} If given, sets a maximum the value can have when returned.
* @returns {number|NaN} The value from the given `HTMLInputElement`, or `1` if no valid one was given.
*/
export function getInputNumber(eInput, min = null, max = null) {
let desiredCount = null;
try {
desiredCount = parseFloat(eInput.value);
} catch (e) {
console.error(e);
}
return postProcessNumber(desiredCount, min, max);
}

File diff suppressed because one or more lines are too long

View File

@@ -2,17 +2,12 @@
<!-- {{ render_h2(l10n("disclaimer.title", applet_data.id, user_lang)) }} -->
<label for="iban-generator-option-enable-sepa" class="mr-xxs">{{ l10n("option.sepa.enable", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-enable-sepa" class="r-m border" type="checkbox" checked>
<input id="iban-generator-option-enable-sepa" class="r-m border cb-pretty" type="checkbox" checked>
<br>
<label for="iban-generator-option-enable-non-sepa" class="mr-xxs">{{ l10n("option.non-sepa.enable", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-enable-non-sepa" class="r-m border" type="checkbox" checked>
<br>
<label for="iban-generator-option-foreach" class="mr-xxs">{{ l10n("option.for.each", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-foreach" class="r-m border" type="checkbox">
<input id="iban-generator-option-enable-non-sepa" class="r-m border cb-pretty" type="checkbox" checked>
<hr class="subtle">
@@ -113,17 +108,45 @@
<br>
<label for="iban-generator-option-count" class="mr-xs">{{ l10n("option.count", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-count" class="p-xxs border r-s" type="number" value="4" min="1" max="1000">
<input id="iban-generator-option-count" class="p-xxs border r-s" type="number" value="4" min="1" max="10000">
<br>
<label for="iban-generator-option-pretty" class="mr-xxs">{{ l10n("option.human.readable", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-pretty" class="r-m border" type="checkbox" checked>
<label for="iban-generator-option-foreach" class="mr-xxs">{{ l10n("option.for.each", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-foreach" class="r-m border cb-pretty" type="checkbox">
<hr class="subtle">
<input type="radio" id="iban-generator-option-prefer-random" name="iban_charset" value="0" class="radio-solid border mr-xxs radio-unchecked-subtle" checked>
<label for="iban-generator-option-prefer-random">{{ l10n("option.prefer.random", "iban-generator", user_lang) }}</label>
<br>
<label for="iban-generator-option-prefer-numbers" class="mr-xxs">{{ l10n("option.prefer.numbers", "iban-generator", user_lang) }}:</label>
<input id="iban-generator-option-prefer-numbers" class="r-m border" type="checkbox">
<input type="radio" id="iban-generator-option-prefer-numbers" name="iban_charset" value="0" class="radio-solid border mr-xxs radio-unchecked-subtle">
<label for="iban-generator-option-prefer-numbers">{{ l10n("option.prefer.numbers", "iban-generator", user_lang) }}</label>
<br>
<input type="radio" id="iban-generator-option-prefer-letters" name="iban_charset" value="0" class="radio-solid border mr-xxs radio-unchecked-subtle">
<label for="iban-generator-option-prefer-letters">{{ l10n("option.prefer.letters", "iban-generator", user_lang) }}</label>
<hr class="subtle">
<input type="radio" id="iban-generator-option-format-none" name="iban_format" value="none" class="radio-solid border mr-xxs radio-unchecked-subtle" checked>
<label for="iban-generator-option-format-none">{{ l10n("option.human.format.none", "iban-generator", user_lang) }}</label>
<br>
<input type="radio" id="iban-generator-option-format-standard" name="iban_format" value="standard" class="radio-solid border mr-xxs radio-unchecked-subtle">
<label for="iban-generator-option-format-standard">{{ l10n("option.human.format.standard", "iban-generator", user_lang) }}</label>
<br>
<input type="radio" id="iban-generator-option-format-4by4" name="iban_format" value="4by4" class="radio-solid border mr-xxs radio-unchecked-subtle">
<label for="iban-generator-option-format-4by4">{{ l10n("option.human.format.4by4", "iban-generator", user_lang) }}</label>
<hr class="subtle">

View File

@@ -1,3 +1,38 @@
{{ render_file_input(tool_id + "-test-input", true, ".png", true, true) }}
{{ render_file_input(tool_id + "-test-input", true, ".png, .bmp", true, true) }}
<div class="w-full ox-auto">
<table class="table-stylish table-p-s border r-m w-full table-no-wrap">
<thead>
<tr>
<th class="bkgd-grid30">Offset</th>
<th class="bkgd-grid30">Chunk Header</th>
<th class="bkgd-grid30">Chunk Data</th>
<th class="bkgd-grid30">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td class="t-monospace">0x0000</td>
<td>2</td>
<td>2</td>
<td>
<button class="p-xs r-s border btn-primary">
<i class="fa-duotone fa-solid fa-binary"></i><span class="ml-xxs mobile-hide">Hex dump</span>
</button>
<button class="p-xs r-s border btn-primary">
<i class="fa-duotone fa-solid fa-download"></i><span class="ml-xxs mobile-hide">Export</span>
</button>
</td>
</tr>
<tr>
<td class="t-monospace">0x0010</td>
<td>4</td>
<td>4</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -9,15 +9,20 @@
<label for="uuid-generator-option-count" class="mr-xs">{{ l10n("option.count", "uuid-generator", user_lang) }}:</label>
<input id="uuid-generator-option-count" class="p-xxs border r-s" type="number" value="4" min="1" max="1000">
<br>
<hr class="subtle">
<label for="uuid-generator-option-hyphens" class="mr-xxs">{{ l10n("option.hyphen", "uuid-generator", user_lang) }}:</label>
<input id="uuid-generator-option-hyphens" class="r-m border" type="checkbox" checked>
<input id="uuid-generator-option-hyphens" class="r-m border cb-pretty" type="checkbox" checked>
<br>
<label for="uuid-generator-option-guid-brackets" class="mr-xxs">{{ l10n("option.guid_brackets", "uuid-generator", user_lang) }}:</label>
<input id="uuid-generator-option-guid-brackets" class="r-m border" type="checkbox">
<input id="uuid-generator-option-guid-brackets" class="r-m border cb-pretty" type="checkbox">
<br>
<label for="uuid-generator-option-uppercase" class="mr-xxs">{{ l10n("option.uppercase", "uuid-generator", user_lang) }}:</label>
<input id="uuid-generator-option-uppercase" class="r-m border cb-pretty" type="checkbox">
<hr class="subtle">

View File

@@ -0,0 +1,295 @@
{%
set all_vat_data = [
["afghanistan",
[[10, "standard"]], [
"https://ard.gov.af/file_download/432/FAQs+of+VAT+English.pdf",
]],
["austria",
[[10, "reduced"],[13, "reduced"],[20, "standard"]], [
"https://www.usp.gv.at/en/themen/steuern-finanzen/umsatzsteuer-ueberblick/steuersaetze-und-steuerbefreiungen-der-umsatzsteuer.html",
]],
["belgium",
[[6, "reduced"],[12, "intermediate"],[21, "standard"]], [
"https://finance.belgium.be/en/enterprises/vat/vat-obligation/rates-and-calculation/vat-rates",
]],
["bulgaria",
[[9, "reduced"],[20, "standard"]], [
"https://www.bulgaria-tax-law.bg/vat-rates-eu-member-states.html"]],
["croatia",
[[5, "reduced"],[13, "reduced"],[25, "standard"]], [
"https://porezna-uprava.gov.hr/en/value-added-tax-h-e-reinafter-vat-information-on-the-general-rules-rates-and-exemptions-registering-for-and-paying-vat-obtaining-a-refund/7313",
]],
["cyprus",
[[3, "reduced"],[5, "reduced"],[9, "reduced"],[19, "standard"]], [
"https://www.mof.gov.cy/mof/tax/taxdep.nsf/All/6F2D9F654287FF02C2258251002C8130",
]],
["czechia",
[[12, "reduced"],[21, "standard"]], [
"https://portal.gov.cz/en/informace/general-rules-and-vat-rates-INF-205",
]],
["denmark",
[[25, "standard"]], [
"https://skat.dk/erhverv/moms/fradrag-for-moms",
]],
["estonia",
[[9, "reduced"],[13, "reduced"],[24, "standard"]], [
"https://www.emta.ee/en/business-client/taxes-and-payment/value-added-tax",
"https://www.e-resident.gov.ee/blog/posts/a-guide-to-vat-for-e-residents/",
]],
["finland",
[[10, "reduced"],[14, "reduced"],[25.5, "standard"]], [
"https://www.vero.fi/en/businesses-and-corporations/taxes-and-charges/vat/rates-of-vat/",
]],
["france",
[[2.1, "reduced"],[5.5, "reduced"],[10, "intermediate"],[20, "standard"]], [
"https://www.economie.gouv.fr/cedef/les-fiches-pratiques/quels-sont-les-taux-de-tva-en-vigueur-en-france-et-dans-lunion",
]],
["france.corsica",
[[0.9, "special"],[2.1, "reduced"],[5.5, "reduced"],[10, "intermediate"],[13, "special"],[20, "standard"]], [
"https://www.economie.gouv.fr/particuliers/impots-et-fiscalite/gerer-mes-autres-impots-et-taxes/tva-quels-sont-les-taux-de-votre",
]],
["germany",
[[7, "reduced"],[19, "standard"]], [
"https://www.bundesfinanzministerium.de/Content/DE/Downloads/BMF_Schreiben/Steuerarten/Umsatzsteuer/Merkblaetter/2024-03-05-Umsatzsteuer-Merkblatt-Personenbefoerderung-Kraftomnibusse-englisch.pdf",
]],
["greece",
[[6, "reduced.super"],[13, "reduced"],[24, "standard"]], [
"https://www.gov.gr/en/sdg/taxes/vat/general/basic-vat-rates",
]],
["hungary",
[[5, "preferential"],[18, "preferential"],[27, "standard"]], [
"https://nav.gov.hu/pfile/file?path=/en/taxation/taxinfo/vat-liabilities-of-foreign-marketers-in-hungary",
]],
["ireland",
[[4.8, "reduced"],[9, "reduced"],[13.5, "reduced"],[23, "standard"]], [
"https://www.revenue.ie/en/vat/vat-rates/search-vat-rates/current-vat-rates.aspx",
]],
["italy",
[[4, "reduced"],[5, "reduced"],[10, "reduced"],[22, "standard"]], [
"https://www.agenziaentrate.gov.it/portale/web/english/nse/services/vat-mini-one-stop-shop/faq/vat-rates",
"https://www.agenziaentrate.gov.it/portale/web/english/general-vat-rules-and-rates"
]],
["latvia",
[[5, "reduced"],[12, "reduced"],[21, "standard"]], [
"https://www.fm.gov.lv/lv/tax-rates",
]],
["lithuania",
[[5, "reduced"],[9, "reduced"],[21, "standard"]], [
"https://finmin.lrv.lt/en/competence-areas/taxation/main-taxes/value-added-tax/",
]],
["luxembourg",
[[3, "reduced.super"],[8, "reduced"],[14, "intermediate"],[17, "standard"]], [
"https://logistics.public.lu/en/formalities-procedures/taxes/value-added-tax/national-operations.html",
]],
["malta",
[[5, "reduced"],[7, "reduced"],[12, "reduced"],[18, "standard"]], [
"https://mtca.gov.mt/business-tax/vat1/vat-compliance/vat-rates/vat-rates",
]],
["monaco",
[[2.1, "reduced"],[5.5, "reduced"],[10, "intermediate"],[20, "standard"]], [
"https://monentreprise.gouv.mc/en/themes/accounting-obligations-and-tax/tax/vat",
"https://www.economie.gouv.fr/particuliers/impots-et-fiscalite/gerer-mes-autres-impots-et-taxes/tva-quels-sont-les-taux-de-votre"
]],
["netherlands",
[[9, "reduced"],[21, "standard"]], [
"https://business.gov.nl/regulation/vat-rates-exemptions/",
]],
["poland",
[[5, "reduced"],[8, "reduced"],[23, "standard"]], [
"https://www.podatki.gov.pl/en/value-added-tax/general-vat-rules-and-rates/list-of-vat-rates/",
]],
["portugal",
[[6, "reduced"],[13, "intermediate"],[23, "standard"]], [
"https://www2.gov.pt/en/cidadaos-europeus-viajar-viver-e-fazer-negocios-em-portugal/impostos-para-atividades-economicas-em-portugal/imposto-sobre-valor-acrescentado-iva-em-portugal",
]],
["portugal.azores",
[[4, "reduced"],[9, "intermediate"],[16, "standard"]], [
"https://www2.gov.pt/en/cidadaos-europeus-viajar-viver-e-fazer-negocios-em-portugal/impostos-para-atividades-economicas-em-portugal/imposto-sobre-valor-acrescentado-iva-em-portugal",
]],
["portugal.madeira",
[[5, "reduced"],[12, "intermediate"],[22, "standard"]], [
"https://www2.gov.pt/en/cidadaos-europeus-viajar-viver-e-fazer-negocios-em-portugal/impostos-para-atividades-economicas-em-portugal/imposto-sobre-valor-acrescentado-iva-em-portugal",
]],
["romania",
[[5, "reduced"],[9, "reduced"],[19, "standard"]], [
"https://mfinante.gov.ro/referinte-tva",
"https://www.mfinante.gov.ro/static/10/Mfp/legislatie/Ghid_TVA_parteaI.htm"
]],
["slovakia",
[[5, "reduced"],[19, "reduced"],[23, "standard"]], [
"https://www.slovensko.sk/en/life-situation/life-situation/_value-added-tax/",
]],
["slovenia",
[[9.5, "reduced"],[22, "standard"]], [
"https://www.fu.gov.si/en/taxes_and_other_duties/areas_of_work/value_added_tax_vat",
]],
["spain",
[[4, "reduced"],[10, "reduced"],[21, "standard"]], [
"https://sede.agenciatributaria.gob.es/Sede/en_gb/iva/calculo-iva-repercutido-clientes/tipos-impositivos-iva.html"
"https://sede.agenciatributaria.gob.es/Sede/iva.html",
]],
["sweden",
[[6, "reduced"],[12, "reduced"],[25, "standard"]], [
"https://www.skatteverket.se/servicelankar/otherlanguages/englishengelska/businessesandemployers/startingandrunningaswedishbusiness/declaringtaxesbusinesses/vat/vatratesandvatexemption.4.676f4884175c97df419255d.html",
]],
]
%}
<label for="vat-calculator-preset-short" class="mr-xxs">
{{ l10n("preset.label", "vat-calculator", user_lang) }}:
</label>
<select name="vat-calculator-preset-short" id="vat-calculator-preset-short" class="p-xxs border r-s">
<option value="" selected>{{ l10n("rate.option.custom", "vat-calculator", user_lang) }}</option>
<hr>
{% for country_vat_data in all_vat_data %}
<optgroup label="{{ l10n("country." + country_vat_data[0], "commons", user_lang) }}">
{% for country_vat_rate in country_vat_data[1] %}
<option value="{{ country_vat_rate[0] }}">
{{ country_vat_rate[0] }} %
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<label for="vat-calculator-preset-detailed" class="mr-xxs" hidden>
{{ l10n("preset.label", "vat-calculator", user_lang) }}:
</label>
<select name="vat-calculator-preset-detailed" id="vat-calculator-preset-detailed" class="p-xxs border r-s" hidden>
<option value="" selected>{{ l10n("rate.option.custom", "vat-calculator", user_lang) }}</option>
<hr>
{% for country_vat_data in all_vat_data %}
<optgroup label="{{ l10n("country." + country_vat_data[0], "commons", user_lang) }}">
{% for country_vat_rate in country_vat_data[1] %}
<option value="{{ country_vat_rate[0] }}">
{{ country_vat_rate[0] }} %&emsp;({{ l10n("rate.type." + country_vat_rate[1], "vat-calculator", user_lang) }})
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<span id="vat-calculator-preset-country-echo" class="t-muted ml-xs t-italic mobile-hide"></span>
<br>
<label for="vat-calculator-detailed-presets" class="mr-xxs">{{ l10n("option.detailed", "vat-calculator", user_lang) }}:</label>
<input id="vat-calculator-detailed-presets" class="r-m border cb-pretty" type="checkbox">
<hr class="subtle">
<!-- TODO: Implement iframe-able template for multi-instance applets on the same page -->
<table class="">
<tr>
<td>
<input type="radio" id="vat-calculator-radio-rate" name="vat_calc_target" value="0"
class="radio-solid border mr-xxs radio-unchecked-subtle">
<label for="vat-calculator-radio-rate">
{{ l10n("radio.rate", "vat-calculator", user_lang) }}
</label>
</td>
<td>
<label for="vat-calculator-input-rate" class="mr-xs"></label>
<input id="vat-calculator-input-rate" class="p-xxs border r-s" type="number" min="0">
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-percent ml-xxs t-muted"></i>{% else %}%{% endif %}
</td>
</tr>
<tr>
<td class="pt-xxs">
<input type="radio" id="vat-calculator-radio-untaxed" name="vat_calc_target" value="1"
class="radio-solid border mr-xxs radio-unchecked-subtle" checked>
<label for="vat-calculator-radio-untaxed">
{{ l10n("radio.untaxed", "vat-calculator", user_lang) }}
</label>
</td>
<td class="pt-xxs">
<label for="vat-calculator-input-untaxed" class="mr-xs"></label>
<input id="vat-calculator-input-untaxed" class="p-xxs border r-s bkgd-gray" type="number" min="0" readonly>
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-money-bill ml-xxs t-muted"></i>{% endif %}
</td>
</tr>
<tr>
<td class="pt-xxs">
<input type="radio" id="vat-calculator-radio-taxed" name="vat_calc_target" value="2"
class="radio-solid border mr-xxs radio-unchecked-subtle">
<label for="vat-calculator-radio-taxed">
{{ l10n("radio.taxed", "vat-calculator", user_lang) }}
</label>
</td>
<td class="pt-xxs">
<label for="vat-calculator-input-taxed" class="mr-xs"></label>
<input id="vat-calculator-input-taxed" class="p-xxs border r-s" type="number" min="0">
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-money-bill ml-xxs t-muted"></i>{% endif %}
</td>
</tr>
</table>
<p class="t-muted ml-xs mt-xs t-italic">{{ l10n("text.radio.explanation", "vat-calculator", user_lang) }}</p>
<hr class="subtle">
<label for="vat-calculator-rounding-mode" class="mr-xxs">
{{ l10n("rounding.mode.label", "vat-calculator", user_lang) }}:
</label>
<select name="vat-calculator-rounding-mode" id="vat-calculator-rounding-mode" class="p-xxs border r-s">
<optgroup label="{{ l10n("rounding.mode.group.regular", "vat-calculator", user_lang) }}">
<option value="0" selected>{{ l10n("rounding.mode.up", "vat-calculator", user_lang) }}</option>
<option value="1">{{ l10n("rounding.mode.down", "vat-calculator", user_lang) }}</option>
<option value="2">{{ l10n("rounding.mode.ceil", "vat-calculator", user_lang) }}</option>
<option value="3">{{ l10n("rounding.mode.floor", "vat-calculator", user_lang) }}</option>
</optgroup>
<optgroup label="{{ l10n("rounding.mode.group.half", "vat-calculator", user_lang) }}">
<option value="4">{{ l10n("rounding.mode.up.half", "vat-calculator", user_lang) }}</option>
<option value="5">{{ l10n("rounding.mode.down.half", "vat-calculator", user_lang) }}</option>
<option value="6">{{ l10n("rounding.mode.even.half", "vat-calculator", user_lang) }}</option>
<option value="7">{{ l10n("rounding.mode.ceil.half", "vat-calculator", user_lang) }}</option>
<option value="8">{{ l10n("rounding.mode.floor.half", "vat-calculator", user_lang) }}</option>
</optgroup>
</select>
<br>
<label for="vat-calculator-option-decimal-places" class="mr-xs">{{ l10n("option.decimal-places", "vat-calculator", user_lang) }}:</label>
<button id="vat-calculator-decimal-places-minus" class="p-xxs border br-0 rl-s {% if is_standalone %}px-xs{% endif %}">
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-minus"></i>{% else %}-{% endif %}
</button>
<input id="vat-calculator-option-decimal-places" class="p-xxs border" type="number" value="2" min="0" max="99">
<button id="vat-calculator-decimal-places-plus" class="p-xxs border bl-0 rr-s {% if is_standalone %}px-xs{% endif %}">
{% if not is_standalone %}<i class="fa-duotone fa-solid fa-plus"></i>{% else %}+{% endif %}
</button>
<br hidden>
<label for="vat-calculator-detailed-trim-zeroes" class="mr-xxs" hidden>{{ l10n("option.trim-zeroes", "vat-calculator", user_lang) }}:</label>
<input id="vat-calculator-detailed-trim-zeroes" class="r-m border cb-pretty" type="checkbox" hidden>
<!--<hr class="subtle">
<details class="border bkgd-dark r-m mt-s">
<summary class="p-xs">Click to show/hide all classes</summary>
<div class="p-xs bt bkgd-grey">
<p>
<span class="code mr-xs">p-0</span>
</p>
</div>
</details>-->
{% if is_standalone %}
<hr class="subtle">
<p class="t-half-muted">
{{ l10n("license.text.1", "vat-calculator", user_lang) }}<br>
{{ l10n("license.text.2", "vat-calculator", user_lang) }}
</p>
{% endif %}

View File

@@ -12,18 +12,17 @@
<meta name="theme-color" content="#6F2F65">
<!--<link rel="dns-prefetch" href="https://cdn.nibblepoker.lu/"/>-->
<link rel="preconnect" href="https://cdn.nibblepoker.lu/"/>
<link rel="preconnect" href="https://cdn.nibblepoker.{{ domain_tld }}/"/>
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-brands-400.woff2" as="font" />
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-duotone-900.woff2" as="font" />
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-solid-900.woff2" as="font" />
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.1.png" as="image" />
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.4.png" as="image" />
<link rel="prefetch" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/webfonts/fa-brands-400.woff2" as="font" />
<link rel="prefetch" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/webfonts/fa-duotone-900.woff2" as="font" />
<link rel="prefetch" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/webfonts/fa-solid-900.woff2" as="font" />
{% block extra_preloads %}{% endblock %}
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/FontAwesomePro/6.7.2/css/all.min.css">
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/IndevCSS/nibblepoker.min.css">
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/Quantum/Quantum.min.css">
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/NibblePoker/StandardCSS/nibblepoker.min.css">
<!--<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/Quantum/Quantum.min.css">-->
<link rel="stylesheet" href="https://cdn.nibblepoker.{{ domain_tld }}/FamFamFam/FlagsExtended/famfamfam-flags.min.css">
<link rel="stylesheet" href="{{ url_for("static", filename="resources/NibblePoker/css/extra.css") }}">
@@ -53,16 +52,37 @@
</summary>
<div class="p-xs border bkgd-surround r-m t-w-500">
<a href="{{ l10n_url_switch(request_path, "en") }}" class="a-hidden">
<p class="mb-s px-xxs">{{ l10n("english", "langs", user_lang) }}</p>
<table class="w-full table-p-xxs">
<tr>
<td>
<a href="{{ l10n_url_switch(request_path, "en") }}" class="w-full d-inline-block a-hidden">
{{ l10n("english", "langs", user_lang) }}
</a>
<a href="{{ l10n_url_switch(request_path, "fr") }}" class="a-hidden">
<p class="my-s px-xxs">{{ l10n("french", "langs", user_lang) }}</p>
</td>
<td class="t-center"><i class="famfamfam-flag-us"></i></td>
</tr>
<tr>
<td>
<a href="{{ l10n_url_switch(request_path, "fr") }}" class="w-full d-inline-block a-hidden">
{{ l10n("french", "langs", user_lang) }}
</a>
</td>
<td class="t-center"><i class="famfamfam-flag-be"></i></td>
</tr>
<tr>
<td colspan="2">
<hr class="subtle m-0">
<a href="{{ l10n_url_switch(request_path) }}" class="a-hidden">
<p class="mt-xs px-xxs">{{ l10n("automatic", "langs", user_lang) }}</p>
</td>
</tr>
<tr>
<td>
<a href="{{ l10n_url_switch(request_path) }}" class="w-full d-inline-block a-hidden">
{{ l10n("automatic", "langs", user_lang) }}
</a>
</td>
<td class="t-center"><i class="famfamfam-flag-unknown"></i></td>
</tr>
</table>
</div>
</details>
</header>

View File

@@ -12,15 +12,20 @@
{% endblock %}
{% block main_content %}
<section>
{{ render_h1(l10n("intro.title", "home", user_lang, ["NibblePoker." + domain_tld] )) }}
<div class="content-spacer">
{{ render_paragraph(l10n("intro.text.1", "home", user_lang)) }}
{{ render_paragraph(l10n("intro.text.2", "home", user_lang)) }}
</div>
</section>
<section>
{{ render_h2(l10n("updates.title", "home", user_lang)) }}
<p><i class="fad fa-calendar-alt mr-xs mt-s"></i>{{ l10n("updates.5.date", "home", user_lang) }}</p>
<div class="content-spacer">
<p><i class="fad fa-calendar-alt mr-xs"></i>{{ l10n("updates.5.date", "home", user_lang) }}</p>
{{ render_list_ul([
l10n("updates.5.text.1", "home", user_lang),
l10n("updates.5.text.2", "home", user_lang),
@@ -57,6 +62,8 @@
l10n("updates.1.text.1", "home", user_lang),
l10n("updates.text.privacy", "home", user_lang)
]) }}
</div>
</section>
{% endblock %}

View File

@@ -43,7 +43,7 @@ def reload_strings(strings_root: str) -> None:
domain_key = str(Path(lang_domain).with_suffix(''))
if lang_domain.endswith(".json"):
print(f"Loading JSON lang data from '{lang_domain_path}'...")
#print(f"Loading JSON lang data from '{lang_domain_path}'...")
L10N.add_domain(
lang_dir,
domain_key,
@@ -51,7 +51,7 @@ def reload_strings(strings_root: str) -> None:
)
if lang_domain.endswith(".yml"):
print(f"Loading YAML lang data from '{lang_domain_path}'...")
#print(f"Loading YAML lang data from '{lang_domain_path}'...")
L10N.add_domain(
lang_dir,
domain_key,