@jjlmoya/utils-motor 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/package.json +68 -0
  2. package/scripts/postinstall.mjs +27 -0
  3. package/src/category/i18n/de.ts +17 -0
  4. package/src/category/i18n/en.ts +17 -0
  5. package/src/category/i18n/es.ts +17 -0
  6. package/src/category/i18n/fr.ts +17 -0
  7. package/src/category/i18n/id.ts +17 -0
  8. package/src/category/i18n/it.ts +17 -0
  9. package/src/category/i18n/ja.ts +17 -0
  10. package/src/category/i18n/ko.ts +17 -0
  11. package/src/category/i18n/nl.ts +17 -0
  12. package/src/category/i18n/pl.ts +17 -0
  13. package/src/category/i18n/pt.ts +17 -0
  14. package/src/category/i18n/ru.ts +17 -0
  15. package/src/category/i18n/sv.ts +17 -0
  16. package/src/category/i18n/tr.ts +17 -0
  17. package/src/category/i18n/zh.ts +17 -0
  18. package/src/category/index.ts +24 -0
  19. package/src/category/seo.astro +15 -0
  20. package/src/components/PreviewNavSidebar.astro +116 -0
  21. package/src/components/PreviewToolbar.astro +143 -0
  22. package/src/data.ts +11 -0
  23. package/src/entries.ts +7 -0
  24. package/src/env.d.ts +5 -0
  25. package/src/index.ts +23 -0
  26. package/src/layouts/PreviewLayout.astro +117 -0
  27. package/src/pages/[locale]/[slug].astro +153 -0
  28. package/src/pages/[locale].astro +251 -0
  29. package/src/pages/index.astro +4 -0
  30. package/src/tests/diacritics_density.test.ts +118 -0
  31. package/src/tests/faq_count.test.ts +19 -0
  32. package/src/tests/i18n_coverage.test.ts +36 -0
  33. package/src/tests/inverted_punctuation.test.ts +84 -0
  34. package/src/tests/locale_completeness.test.ts +29 -0
  35. package/src/tests/mocks/astro_mock.js +2 -0
  36. package/src/tests/no_en_dash.test.ts +70 -0
  37. package/src/tests/no_h1_in_components.test.ts +48 -0
  38. package/src/tests/pagespeed_best_practices.test.ts +198 -0
  39. package/src/tests/schemas_fulfillment.test.ts +23 -0
  40. package/src/tests/script_density.test.ts +94 -0
  41. package/src/tests/seo_length.test.ts +23 -0
  42. package/src/tests/seo_parity.test.ts +60 -0
  43. package/src/tests/shared-test-helpers.ts +56 -0
  44. package/src/tests/slug_language_code_format.test.ts +23 -0
  45. package/src/tests/slug_uniqueness.test.ts +81 -0
  46. package/src/tests/spanish_leakage.test.ts +177 -0
  47. package/src/tests/title_quality.test.ts +55 -0
  48. package/src/tests/tool_exports.test.ts +34 -0
  49. package/src/tests/tool_validation.test.ts +17 -0
  50. package/src/tests/translation_copy.test.ts +125 -0
  51. package/src/tool/brakingDistanceCalculator/bibliography.astro +6 -0
  52. package/src/tool/brakingDistanceCalculator/bibliography.ts +12 -0
  53. package/src/tool/brakingDistanceCalculator/braking-distance-calculator.css +601 -0
  54. package/src/tool/brakingDistanceCalculator/component.astro +117 -0
  55. package/src/tool/brakingDistanceCalculator/controller.ts +114 -0
  56. package/src/tool/brakingDistanceCalculator/dom-views.ts +58 -0
  57. package/src/tool/brakingDistanceCalculator/entry.ts +30 -0
  58. package/src/tool/brakingDistanceCalculator/evaluator.ts +45 -0
  59. package/src/tool/brakingDistanceCalculator/i18n/de.ts +45 -0
  60. package/src/tool/brakingDistanceCalculator/i18n/en.ts +208 -0
  61. package/src/tool/brakingDistanceCalculator/i18n/es.ts +46 -0
  62. package/src/tool/brakingDistanceCalculator/i18n/factory.ts +114 -0
  63. package/src/tool/brakingDistanceCalculator/i18n/fr.ts +40 -0
  64. package/src/tool/brakingDistanceCalculator/i18n/id.ts +38 -0
  65. package/src/tool/brakingDistanceCalculator/i18n/it.ts +39 -0
  66. package/src/tool/brakingDistanceCalculator/i18n/ja.ts +38 -0
  67. package/src/tool/brakingDistanceCalculator/i18n/ko.ts +38 -0
  68. package/src/tool/brakingDistanceCalculator/i18n/nl.ts +38 -0
  69. package/src/tool/brakingDistanceCalculator/i18n/pl.ts +38 -0
  70. package/src/tool/brakingDistanceCalculator/i18n/pt.ts +39 -0
  71. package/src/tool/brakingDistanceCalculator/i18n/ru.ts +38 -0
  72. package/src/tool/brakingDistanceCalculator/i18n/sv.ts +38 -0
  73. package/src/tool/brakingDistanceCalculator/i18n/tr.ts +38 -0
  74. package/src/tool/brakingDistanceCalculator/i18n/zh.ts +38 -0
  75. package/src/tool/brakingDistanceCalculator/index.ts +10 -0
  76. package/src/tool/brakingDistanceCalculator/logic.test.ts +84 -0
  77. package/src/tool/brakingDistanceCalculator/logic.ts +82 -0
  78. package/src/tool/brakingDistanceCalculator/seo.astro +15 -0
  79. package/src/tool/brakingDistanceCalculator/storage.ts +28 -0
  80. package/src/tool/brakingDistanceCalculator/ui.ts +42 -0
  81. package/src/tools.ts +4 -0
  82. package/src/types.ts +72 -0
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@jjlmoya/utils-motor",
3
+ "version": "1.1.0",
4
+ "type": "module",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./data": "./src/data.ts",
10
+ "./entries": "./src/entries.ts",
11
+ "./runtime/*": "./src/tool/*/index.ts",
12
+ "./category-seo": "./src/category/seo.astro"
13
+ },
14
+ "files": [
15
+ "src",
16
+ "scripts"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "scripts": {
22
+ "dev": "astro dev",
23
+ "start": "astro dev",
24
+ "build": "astro build",
25
+ "preview": "astro preview",
26
+ "astro": "astro",
27
+ "lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
28
+ "check": "astro check",
29
+ "type-check": "astro check",
30
+ "test": "vitest run",
31
+ "preversion": "npm run lint && npm run test && npm run build",
32
+ "postversion": "git push && git push --tags",
33
+ "patch": "npm version patch",
34
+ "minor": "npm version minor",
35
+ "major": "npm version major",
36
+ "postinstall": "node scripts/postinstall.mjs"
37
+ },
38
+ "lint-staged": {
39
+ "*.{ts,tsx,astro}": [
40
+ "eslint --fix"
41
+ ]
42
+ },
43
+ "dependencies": {
44
+ "@iconify-json/mdi": "^1.2.3",
45
+ "@jjlmoya/prompagate": "^1.1.0",
46
+ "@jjlmoya/utils-shared": "1.2.0",
47
+ "astro": "^6.1.2",
48
+ "astro-icon": "^1.1.0",
49
+ "lz-string": "^1.5.0"
50
+ },
51
+ "devDependencies": {
52
+ "@astrojs/check": "^0.9.8",
53
+ "@types/lz-string": "^1.3.34",
54
+ "eslint": "^9.39.4",
55
+ "eslint-plugin-astro": "^1.6.0",
56
+ "eslint-plugin-no-comments": "^1.1.10",
57
+ "husky": "^9.1.7",
58
+ "lint-staged": "^16.4.0",
59
+ "postcss-html": "^1.8.1",
60
+ "schema-dts": "^1.1.2",
61
+ "stylelint": "^17.6.0",
62
+ "stylelint-config-standard": "^40.0.0",
63
+ "stylelint-declaration-strict-value": "^1.11.1",
64
+ "typescript": "^5.4.0",
65
+ "typescript-eslint": "^8.58.0",
66
+ "vitest": "^4.1.2"
67
+ }
68
+ }
@@ -0,0 +1,27 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const libDir = dirname(fileURLToPath(import.meta.url));
6
+ const toolsDir = join(libDir, '../src/tool');
7
+
8
+ const inNodeModules = libDir.includes('node_modules');
9
+ if (!inNodeModules) process.exit(0);
10
+
11
+ const projectRoot = join(libDir, '../../../..');
12
+ const categoryKey = JSON.parse(readFileSync(join(libDir, '../package.json'), 'utf8')).name.replace('@jjlmoya/utils-', '');
13
+ const destDir = join(projectRoot, `public/styles/lib/${categoryKey}`);
14
+
15
+ mkdirSync(destDir, { recursive: true });
16
+
17
+ const tools = readdirSync(toolsDir, { withFileTypes: true }).filter(d => d.isDirectory());
18
+ for (const tool of tools) {
19
+ const toolDir = join(toolsDir, tool.name);
20
+ let files;
21
+ try { files = readdirSync(toolDir).filter(f => f.endsWith('.css')); }
22
+ catch { continue; }
23
+ for (const file of files) {
24
+ writeFileSync(join(destDir, file), readFileSync(join(toolDir, file)));
25
+ console.log(`[@jjlmoya/utils-${categoryKey}] copied ${file}`);
26
+ }
27
+ }
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'kraftfahrzeuge',
5
+ title: 'Werkzeuge und Rechner fur Kraftfahrzeuge',
6
+ description: 'Praktische Rechner fur Autos und Motorräder zu Bremsweg, Verbrauch, Kosten, Reifen und Antrieb.',
7
+ seo: [
8
+ { type: 'title', text: 'Die Zahlen Hinter Jeder Fahrt Verstehen', level: 2 },
9
+ { type: 'paragraph', html: 'Fahrzeuge verwandeln Energie, Haftung, Übersetzung und menschliche Entscheidungen in Bewegung. Diese <strong>kostenlosen Rechner fur Auto und Motorrad</strong> machen den Zusammenhang sichtbar, ohne Fahrzeugdaten an einen Server zu senden.' },
10
+ { type: 'title', text: 'Sicherheit und Fahrzeugdynamik', level: 2 },
11
+ { type: 'paragraph', html: 'Untersuche Anhalteweg, Reaktionszeit, Steigung und Haftung mit transparenten Schätzungen. Jedes Ergebnis trennt das physikalische Modell von echter Sicherheitsberatung und nennt seine Annahmen.' },
12
+ { type: 'title', text: 'Betriebskosten und Effizienz', level: 2 },
13
+ { type: 'paragraph', html: 'Vergleiche Verbrauch, Fahrtkosten, Wartung, Wertverlust und Kosten pro Kilometer mit eigenen Eingaben. Kein Werkzeug behauptet, unbekannte Livepreise zu kennen.' },
14
+ { type: 'list', items: ['<strong>Klare Formeln:</strong> Erkenne, welche Variablen das Ergebnis ändern.', '<strong>Autos und Motorräder:</strong> Nutze passende Bedienelemente und Hinweise.', '<strong>Lokale Verarbeitung:</strong> Behalte Routen, Kosten und Fahrzeugdaten im Browser.', '<strong>Nützliche Einheiten:</strong> Arbeite metrisch oder imperial.'] },
15
+ { type: 'tip', title: 'Schätzungen Sind Nur der Anfang', html: 'Nutze Herstellerangaben, Verkehrsregeln, fachkundige Prüfung und einen großen Sicherheitsabstand, wenn eine Entscheidung die Sicherheit betrifft.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motor',
5
+ title: 'Motor Vehicle Tools and Calculators',
6
+ description: 'Practical calculators for cars and motorcycles covering braking, consumption, costs, tires, and drivetrain behavior.',
7
+ seo: [
8
+ { type: 'title', text: 'Understand the Numbers Behind Every Journey', level: 2 },
9
+ { type: 'paragraph', html: 'Motor vehicles turn energy, grip, gearing, and human decisions into motion. These <strong>free car and motorcycle calculators</strong> make that relationship visible without sending vehicle or trip data to a server.' },
10
+ { type: 'title', text: 'Safety and Vehicle Dynamics', level: 2 },
11
+ { type: 'paragraph', html: 'Explore stopping distance, reaction time, road gradient, and grip as transparent estimates. Each result separates the physical model from real world safety advice and states the assumptions that shape it.' },
12
+ { type: 'title', text: 'Running Costs and Efficiency', level: 2 },
13
+ { type: 'paragraph', html: 'Compare fuel or electricity consumption, trip cost, maintenance, depreciation, and cost per kilometer with inputs you control. No calculator pretends to know live prices that you did not provide.' },
14
+ { type: 'list', items: ['<strong>Clear formulas:</strong> See which variables change the result.', '<strong>Cars and motorcycles:</strong> Use vehicle appropriate controls and cautions.', '<strong>Local processing:</strong> Keep routes, costs, and vehicle details in your browser.', '<strong>Useful units:</strong> Work with metric and imperial measurements.'] },
15
+ { type: 'tip', title: 'Treat Estimates as a Starting Point', html: 'Use manufacturer specifications, road rules, professional inspection, and a generous safety margin whenever a decision affects vehicle safety.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motor',
5
+ title: 'Herramientas y Calculadoras de Motor',
6
+ description: 'Calculadoras prácticas para coches y motos sobre frenado, consumo, costes, neumáticos y transmisión.',
7
+ seo: [
8
+ { type: 'title', text: 'Comprende los Números de Cada Trayecto', level: 2 },
9
+ { type: 'paragraph', html: 'Los vehículos convierten energía, adherencia, transmisión y decisiones humanas en movimiento. Estas <strong>calculadoras gratuitas para coches y motos</strong> hacen visible esa relación sin enviar datos del vehículo ni del trayecto a un servidor.' },
10
+ { type: 'title', text: 'Seguridad y Dinámica del Vehículo', level: 2 },
11
+ { type: 'paragraph', html: 'Explora distancia de frenado, tiempo de reacción, pendiente y adherencia mediante estimaciones transparentes. Cada resultado separa el modelo físico de los consejos reales de seguridad y muestra los supuestos utilizados.' },
12
+ { type: 'title', text: 'Costes de Uso y Eficiencia', level: 2 },
13
+ { type: 'paragraph', html: 'Compara consumo de combustible o electricidad, coste del viaje, mantenimiento, depreciación y coste por kilómetro con datos que tú controlas. Ninguna herramienta finge conocer precios en directo que no hayas indicado.' },
14
+ { type: 'list', items: ['<strong>Fórmulas claras:</strong> Comprueba qué variables cambian el resultado.', '<strong>Coches y motos:</strong> Usa controles y avisos adecuados para cada vehículo.', '<strong>Procesamiento local:</strong> Conserva rutas, costes y datos del vehículo en tu navegador.', '<strong>Unidades útiles:</strong> Trabaja con medidas métricas e imperiales.'] },
15
+ { type: 'tip', title: 'Usa las Estimaciones como Punto de Partida', html: 'Consulta las especificaciones del fabricante, las normas de circulación y una inspección profesional, y aplica un margen amplio cuando una decisión afecte a la seguridad.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'automobile',
5
+ title: 'Outils et Calculateurs Automobiles',
6
+ description: 'Des calculateurs pratiques pour voitures et motos sur le freinage, la consommation, les couts, les pneus et la transmission.',
7
+ seo: [
8
+ { type: 'title', text: 'Comprendre les Chiffres de Chaque Trajet', level: 2 },
9
+ { type: 'paragraph', html: 'Les vehicules transforment energie, adherence, transmission et decisions humaines en mouvement. Ces <strong>calculateurs gratuits pour voitures et motos</strong> rendent cette relation visible sans envoyer vos donnees a un serveur.' },
10
+ { type: 'title', text: 'Securite et Dynamique du Vehicule', level: 2 },
11
+ { type: 'paragraph', html: 'Explorez la distance d arret, le temps de reaction, la pente et l adherence avec des estimations transparentes. Chaque resultat distingue le modele physique des conseils reels de securite et expose ses hypotheses.' },
12
+ { type: 'title', text: 'Couts d Utilisation et Efficacite', level: 2 },
13
+ { type: 'paragraph', html: 'Comparez consommation, cout du trajet, entretien, depreciation et cout par kilometre avec les valeurs que vous choisissez. Aucun outil ne pretend connaitre un prix en direct que vous n avez pas fourni.' },
14
+ { type: 'list', items: ['<strong>Formules claires:</strong> Identifiez les variables qui modifient le resultat.', '<strong>Voitures et motos:</strong> Utilisez des controles et avertissements adaptes.', '<strong>Traitement local:</strong> Gardez trajets et donnees du vehicule dans le navigateur.', '<strong>Unites utiles:</strong> Travaillez en systeme metrique ou imperial.'] },
15
+ { type: 'tip', title: 'Une Estimation Reste un Point de Depart', html: 'Consultez le constructeur, le code de la route et un professionnel, puis gardez une marge genereuse pour toute decision de securite.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'otomotif',
5
+ title: 'Alat dan Kalkulator Kendaraan Bermotor',
6
+ description: 'Kalkulator praktis untuk mobil dan sepeda motor tentang pengereman, konsumsi, biaya, ban, dan transmisi.',
7
+ seo: [
8
+ { type: 'title', text: 'Pahami Angka di Balik Setiap Perjalanan', level: 2 },
9
+ { type: 'paragraph', html: 'Kendaraan mengubah energi, daya cengkeram, rasio gigi, dan keputusan manusia menjadi gerak. <strong>Kalkulator mobil dan sepeda motor gratis</strong> ini menjelaskan hubungan tersebut tanpa mengirim data kendaraan ke server.' },
10
+ { type: 'title', text: 'Keselamatan dan Dinamika Kendaraan', level: 2 },
11
+ { type: 'paragraph', html: 'Jelajahi jarak berhenti, waktu reaksi, kemiringan jalan, dan cengkeraman melalui perkiraan yang transparan. Setiap hasil memisahkan model fisika dari saran keselamatan nyata serta menunjukkan asumsi yang digunakan.' },
12
+ { type: 'title', text: 'Biaya Pemakaian dan Efisiensi', level: 2 },
13
+ { type: 'paragraph', html: 'Bandingkan konsumsi, biaya perjalanan, perawatan, penyusutan, dan biaya per kilometer menggunakan angka pilihan Anda. Alat ini tidak mengaku mengetahui harga langsung yang tidak Anda masukkan.' },
14
+ { type: 'list', items: ['<strong>Rumus jelas:</strong> Lihat variabel yang mengubah hasil.', '<strong>Mobil dan sepeda motor:</strong> Gunakan kontrol dan peringatan yang sesuai.', '<strong>Pemrosesan lokal:</strong> Simpan rute, biaya, dan data kendaraan di browser.', '<strong>Satuan berguna:</strong> Gunakan ukuran metrik atau imperial.'] },
15
+ { type: 'tip', title: 'Gunakan Perkiraan sebagai Titik Awal', html: 'Ikuti spesifikasi pabrikan, aturan jalan, pemeriksaan profesional, dan margin besar saat keputusan memengaruhi keselamatan.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motori',
5
+ title: 'Strumenti e Calcolatori per Veicoli a Motore',
6
+ description: 'Calcolatori pratici per auto e moto dedicati a frenata, consumi, costi, pneumatici e trasmissione.',
7
+ seo: [
8
+ { type: 'title', text: 'Capire i Numeri Dietro Ogni Viaggio', level: 2 },
9
+ { type: 'paragraph', html: 'I veicoli trasformano energia, aderenza, rapporti e decisioni umane in movimento. Questi <strong>calcolatori gratuiti per auto e moto</strong> mostrano tale relazione senza inviare dati del veicolo a un server.' },
10
+ { type: 'title', text: 'Sicurezza e Dinamica del Veicolo', level: 2 },
11
+ { type: 'paragraph', html: 'Esplora distanza di arresto, tempo di reazione, pendenza e aderenza con stime trasparenti. Ogni risultato distingue il modello fisico dai consigli reali di sicurezza e dichiara le ipotesi utilizzate.' },
12
+ { type: 'title', text: 'Costi di Utilizzo ed Efficienza', level: 2 },
13
+ { type: 'paragraph', html: 'Confronta consumo, costo del viaggio, manutenzione, svalutazione e costo per chilometro con valori scelti da te. Nessuno strumento finge di conoscere prezzi in tempo reale non forniti.' },
14
+ { type: 'list', items: ['<strong>Formule chiare:</strong> Scopri quali variabili modificano il risultato.', '<strong>Auto e moto:</strong> Usa controlli e avvisi adatti al veicolo.', '<strong>Elaborazione locale:</strong> Mantieni percorsi, costi e dati nel browser.', '<strong>Unità utili:</strong> Lavora con misure metriche o imperiali.'] },
15
+ { type: 'tip', title: 'Le Stime Sono un Punto di Partenza', html: 'Consulta le specifiche del produttore, le norme stradali e un professionista, mantenendo un ampio margine per ogni decisione di sicurezza.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motor',
5
+ title: '自動車とオートバイの計算ツール',
6
+ description: '制動距離、燃費、費用、タイヤ、変速比を調べる自動車とオートバイ向けの実用的な計算ツールです。',
7
+ seo: [
8
+ { type: 'title', text: '移動を支える数値を理解する', level: 2 },
9
+ { type: 'paragraph', html: '車両はエネルギー、路面のグリップ、変速比、人の判断を運動へ変換します。これらの<strong>無料の自動車計算ツール</strong>は、車両や移動のデータをサーバーへ送らずに関係を見える形にします。' },
10
+ { type: 'title', text: '安全性と車両運動', level: 2 },
11
+ { type: 'paragraph', html: '停止距離、反応時間、勾配、路面のグリップを透明な推定で確認できます。各結果は物理モデルと実際の安全助言を区別し、計算に使った前提を示します。' },
12
+ { type: 'title', text: '維持費と効率', level: 2 },
13
+ { type: 'paragraph', html: '自分で入力した値から、燃料や電力の消費、移動費、整備費、減価、距離当たりの費用を比較できます。入力していないリアルタイム価格を知っているように装うことはありません。' },
14
+ { type: 'list', items: ['<strong>明確な式:</strong> 結果を変える変数を確認できます。', '<strong>自動車とオートバイ:</strong> 車両に合う操作と注意を使えます。', '<strong>端末内の処理:</strong> 経路、費用、車両情報をブラウザー内に保ちます。', '<strong>実用的な単位:</strong> メートル法とヤードポンド法に対応します。'] },
15
+ { type: 'tip', title: '推定値は出発点です', html: '安全に関わる判断では、メーカー仕様、交通規則、専門家の点検を確認し、十分な余裕を取ってください。' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motor',
5
+ title: '자동차와 오토바이 도구 및 계산기',
6
+ description: '제동, 연비, 비용, 타이어, 구동계를 살펴보는 자동차와 오토바이용 실용 계산기입니다.',
7
+ seo: [
8
+ { type: 'title', text: '모든 이동 뒤의 숫자를 이해하세요', level: 2 },
9
+ { type: 'paragraph', html: '차량은 에너지, 노면 접지력, 기어비, 사람의 판단을 움직임으로 바꿉니다. 이 <strong>무료 자동차와 오토바이 계산기</strong>는 차량이나 이동 데이터를 서버로 보내지 않고 그 관계를 보여 줍니다.' },
10
+ { type: 'title', text: '안전과 차량 동역학', level: 2 },
11
+ { type: 'paragraph', html: '정지 거리, 반응 시간, 도로 경사, 접지력을 투명한 추정값으로 탐색합니다. 각 결과는 물리 모델과 실제 안전 조언을 구분하고 계산에 사용한 가정을 밝힙니다.' },
12
+ { type: 'title', text: '운행 비용과 효율', level: 2 },
13
+ { type: 'paragraph', html: '직접 입력한 값으로 연료나 전력 소비, 이동 비용, 정비, 감가상각, 거리당 비용을 비교합니다. 입력하지 않은 실시간 가격을 안다고 가장하지 않습니다.' },
14
+ { type: 'list', items: ['<strong>명확한 공식:</strong> 어떤 변수가 결과를 바꾸는지 확인합니다.', '<strong>자동차와 오토바이:</strong> 차량에 맞는 조작과 주의 사항을 제공합니다.', '<strong>로컬 처리:</strong> 경로, 비용, 차량 데이터를 브라우저에 보관합니다.', '<strong>유용한 단위:</strong> 미터법과 야드파운드법을 사용할 수 있습니다.'] },
15
+ { type: 'tip', title: '추정값은 출발점입니다', html: '안전에 영향을 주는 판단에서는 제조사 사양, 교통 규칙, 전문가 점검을 따르고 충분한 여유를 두세요.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'auto',
5
+ title: 'Gereedschappen en Rekentools voor Motorvoertuigen',
6
+ description: 'Praktische rekentools voor auto en motor over remmen, verbruik, kosten, banden en aandrijving.',
7
+ seo: [
8
+ { type: 'title', text: 'Begrijp de Cijfers Achter Elke Rit', level: 2 },
9
+ { type: 'paragraph', html: 'Voertuigen zetten energie, grip, overbrenging en menselijke beslissingen om in beweging. Deze <strong>gratis rekentools voor auto en motor</strong> maken dat zichtbaar zonder voertuiggegevens naar een server te sturen.' },
10
+ { type: 'title', text: 'Veiligheid en Voertuigdynamiek', level: 2 },
11
+ { type: 'paragraph', html: 'Onderzoek stopafstand, reactietijd, helling en grip met transparante schattingen. Elk resultaat onderscheidt het natuurkundige model van echt veiligheidsadvies en toont de gebruikte aannames.' },
12
+ { type: 'title', text: 'Gebruikskosten en Efficiëntie', level: 2 },
13
+ { type: 'paragraph', html: 'Vergelijk verbruik, ritkosten, onderhoud, afschrijving en kosten per kilometer met eigen invoer. Geen enkel hulpmiddel beweert onbekende actuele prijzen te kennen.' },
14
+ { type: 'list', items: ['<strong>Duidelijke formules:</strong> Zie welke variabelen het resultaat veranderen.', '<strong>Auto en motor:</strong> Gebruik passende bediening en waarschuwingen.', '<strong>Lokale verwerking:</strong> Houd routes, kosten en voertuigdata in de browser.', '<strong>Bruikbare eenheden:</strong> Werk metrisch of imperiaal.'] },
15
+ { type: 'tip', title: 'Een Schatting Is het Beginpunt', html: 'Gebruik fabrieksspecificaties, verkeersregels, deskundige controle en een ruime marge wanneer veiligheid meespeelt.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motoryzacja',
5
+ title: 'Narzędzia i Kalkulatory Motoryzacyjne',
6
+ description: 'Praktyczne kalkulatory dla samochodów i motocykli dotyczące hamowania, zużycia, kosztów, opon i napędu.',
7
+ seo: [
8
+ { type: 'title', text: 'Poznaj Liczby Kryjące się za Każdą Podróżą', level: 2 },
9
+ { type: 'paragraph', html: 'Pojazdy zamieniają energię, przyczepność, przełożenia i decyzje człowieka w ruch. Te <strong>bezpłatne kalkulatory samochodowe i motocyklowe</strong> pokazują tę zależność bez wysyłania danych pojazdu na serwer.' },
10
+ { type: 'title', text: 'Bezpieczeństwo i Dynamika Pojazdu', level: 2 },
11
+ { type: 'paragraph', html: 'Analizuj drogę zatrzymania, czas reakcji, nachylenie i przyczepność za pomocą przejrzystych oszacowań. Każdy wynik oddziela model fizyczny od rzeczywistych zaleceń bezpieczeństwa i podaje założenia.' },
12
+ { type: 'title', text: 'Koszty Użytkowania i Wydajność', level: 2 },
13
+ { type: 'paragraph', html: 'Porównuj zużycie, koszt podróży, serwis, utratę wartości i koszt kilometra na podstawie własnych danych. Narzędzia nie udają, że znają ceny, których nie podano.' },
14
+ { type: 'list', items: ['<strong>Jasne wzory:</strong> Sprawdź, które zmienne wpływają na wynik.', '<strong>Samochody i motocykle:</strong> Korzystaj z właściwych ustawień i ostrzeżeń.', '<strong>Lokalne obliczenia:</strong> Zachowaj trasy, koszty i dane pojazdu w przeglądarce.', '<strong>Praktyczne jednostki:</strong> Używaj miar metrycznych lub imperialnych.'] },
15
+ { type: 'tip', title: 'Oszacowanie Jest Punktem Wyjścia', html: 'Sprawdzaj dane producenta, przepisy, opinię specjalisty i zachowuj duży margines przy decyzjach dotyczących bezpieczeństwa.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'automovel',
5
+ title: 'Ferramentas e Calculadoras para Veículos Motorizados',
6
+ description: 'Calculadoras práticas para carros e motos sobre travagem, consumo, custos, pneus e transmissão.',
7
+ seo: [
8
+ { type: 'title', text: 'Compreenda os Números de Cada Viagem', level: 2 },
9
+ { type: 'paragraph', html: 'Os veículos transformam energia, aderência, relações de transmissão e decisões humanas em movimento. Estas <strong>calculadoras gratuitas para carros e motos</strong> tornam essa relação visível sem enviar dados do veículo para um servidor.' },
10
+ { type: 'title', text: 'Segurança e Dinâmica do Veículo', level: 2 },
11
+ { type: 'paragraph', html: 'Explore distância de paragem, tempo de reação, inclinação e aderência através de estimativas transparentes. Cada resultado separa o modelo físico dos conselhos reais de segurança e apresenta as suas hipóteses.' },
12
+ { type: 'title', text: 'Custos de Utilização e Eficiência', level: 2 },
13
+ { type: 'paragraph', html: 'Compare consumo, custo da viagem, manutenção, depreciação e custo por quilómetro com valores escolhidos por si. Nenhuma ferramenta finge conhecer preços em direto que não forneceu.' },
14
+ { type: 'list', items: ['<strong>Fórmulas claras:</strong> Veja quais variáveis alteram o resultado.', '<strong>Carros e motos:</strong> Utilize controlos e avisos adequados.', '<strong>Processamento local:</strong> Mantenha rotas, custos e dados no navegador.', '<strong>Unidades úteis:</strong> Trabalhe com medidas métricas ou imperiais.'] },
15
+ { type: 'tip', title: 'Uma Estimativa É Apenas o Início', html: 'Consulte as especificações do fabricante, as regras de trânsito e um profissional, mantendo uma margem ampla em decisões de segurança.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'avto',
5
+ title: 'Инструменты и Калькуляторы для Автомобилей и Мотоциклов',
6
+ description: 'Практические калькуляторы торможения, расхода, затрат, шин и трансмиссии для автомобилей и мотоциклов.',
7
+ seo: [
8
+ { type: 'title', text: 'Понимайте Числа за Каждой Поездкой', level: 2 },
9
+ { type: 'paragraph', html: 'Транспорт превращает энергию, сцепление, передаточные отношения и решения человека в движение. Эти <strong>бесплатные калькуляторы для автомобилей и мотоциклов</strong> показывают связь, не отправляя данные на сервер.' },
10
+ { type: 'title', text: 'Безопасность и Динамика Транспорта', level: 2 },
11
+ { type: 'paragraph', html: 'Исследуйте остановочный путь, время реакции, уклон и сцепление с помощью прозрачных оценок. Каждый результат отделяет физическую модель от реальных правил безопасности и показывает принятые допущения.' },
12
+ { type: 'title', text: 'Расходы и Эффективность', level: 2 },
13
+ { type: 'paragraph', html: 'Сравнивайте расход топлива или энергии, стоимость поездки, обслуживание, амортизацию и цену километра по собственным данным. Инструменты не выдают неизвестные цены за актуальные.' },
14
+ { type: 'list', items: ['<strong>Понятные формулы:</strong> Смотрите, какие переменные меняют результат.', '<strong>Автомобили и мотоциклы:</strong> Используйте подходящие настройки и предупреждения.', '<strong>Локальная обработка:</strong> Храните маршруты, затраты и данные транспорта в браузере.', '<strong>Удобные единицы:</strong> Работайте с метрическими и имперскими мерами.'] },
15
+ { type: 'tip', title: 'Оценка Является Только Началом', html: 'Сверяйтесь с данными производителя, правилами движения и специалистом, сохраняя большой запас в вопросах безопасности.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motor',
5
+ title: 'Verktyg och Räknare för Motorfordon',
6
+ description: 'Praktiska räknare för bilar och motorcyklar om bromsning, förbrukning, kostnader, däck och drivlina.',
7
+ seo: [
8
+ { type: 'title', text: 'Förstå Siffrorna Bakom Varje Resa', level: 2 },
9
+ { type: 'paragraph', html: 'Fordon omvandlar energi, väggrepp, utväxling och mänskliga beslut till rörelse. Dessa <strong>kostnadsfria räknare för bil och motorcykel</strong> visar sambandet utan att skicka fordonsdata till en server.' },
10
+ { type: 'title', text: 'Säkerhet och Fordonsdynamik', level: 2 },
11
+ { type: 'paragraph', html: 'Utforska stoppsträcka, reaktionstid, lutning och grepp med öppna uppskattningar. Varje resultat skiljer den fysiska modellen från verkliga säkerhetsråd och visar vilka antaganden som används.' },
12
+ { type: 'title', text: 'Driftskostnad och Effektivitet', level: 2 },
13
+ { type: 'paragraph', html: 'Jämför förbrukning, resekostnad, underhåll, värdeminskning och kostnad per kilometer med egna värden. Inget verktyg låtsas känna till aktuella priser som du inte har angett.' },
14
+ { type: 'list', items: ['<strong>Tydliga formler:</strong> Se vilka variabler som ändrar resultatet.', '<strong>Bil och motorcykel:</strong> Använd lämpliga kontroller och varningar.', '<strong>Lokal bearbetning:</strong> Behåll rutter, kostnader och fordonsdata i webbläsaren.', '<strong>Användbara enheter:</strong> Arbeta metriskt eller imperialt.'] },
15
+ { type: 'tip', title: 'En Uppskattning Är en Startpunkt', html: 'Använd tillverkarens uppgifter, trafikregler, professionell kontroll och en stor marginal när ett beslut påverkar säkerheten.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motorlu-araclar',
5
+ title: 'Motorlu Araç Araçları ve Hesaplayıcıları',
6
+ description: 'Otomobil ve motosikletler için frenleme, tüketim, maliyet, lastik ve aktarma sistemi hesaplayıcıları.',
7
+ seo: [
8
+ { type: 'title', text: 'Her Yolculuğun Ardındaki Sayıları Anlayın', level: 2 },
9
+ { type: 'paragraph', html: 'Araçlar enerji, yol tutuşu, dişli oranı ve insan kararlarını harekete dönüştürür. Bu <strong>ücretsiz otomobil ve motosiklet hesaplayıcıları</strong>, araç verilerini sunucuya göndermeden ilişkiyi görünür kılar.' },
10
+ { type: 'title', text: 'Güvenlik ve Araç Dinamiği', level: 2 },
11
+ { type: 'paragraph', html: 'Durma mesafesi, tepki süresi, yol eğimi ve tutuşu şeffaf tahminlerle inceleyin. Her sonuç fizik modelini gerçek güvenlik tavsiyesinden ayırır ve kullanılan varsayımları açıklar.' },
12
+ { type: 'title', text: 'Kullanım Maliyeti ve Verimlilik', level: 2 },
13
+ { type: 'paragraph', html: 'Kendi değerlerinizle yakıt veya elektrik tüketimini, yolculuk maliyetini, bakımı, değer kaybını ve kilometre maliyetini karşılaştırın. Hiçbir araç girmediğiniz güncel fiyatları bildiğini iddia etmez.' },
14
+ { type: 'list', items: ['<strong>Açık formüller:</strong> Sonucu hangi değişkenlerin etkilediğini görün.', '<strong>Otomobil ve motosiklet:</strong> Uygun kontrolleri ve uyarıları kullanın.', '<strong>Yerel işleme:</strong> Rota, maliyet ve araç bilgilerini tarayıcıda tutun.', '<strong>Kullanışlı birimler:</strong> Metrik veya emperyal ölçülerle çalışın.'] },
15
+ { type: 'tip', title: 'Tahmin Yalnızca Başlangıçtır', html: 'Güvenliği etkileyen kararlarda üretici özelliklerini, trafik kurallarını ve uzman incelemesini kullanın, geniş bir pay bırakın.' },
16
+ ],
17
+ };
@@ -0,0 +1,17 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'motor',
5
+ title: '汽车与摩托车工具和计算器',
6
+ description: '用于制动、能耗、成本、轮胎和传动系统的实用汽车与摩托车计算器。',
7
+ seo: [
8
+ { type: 'title', text: '理解每次出行背后的数字', level: 2 },
9
+ { type: 'paragraph', html: '车辆把能量、抓地力、传动比和人的决定转化为运动。这些<strong>免费汽车与摩托车计算器</strong>无需把车辆或行程数据发送到服务器,即可清楚展示其中的关系。' },
10
+ { type: 'title', text: '安全与车辆动态', level: 2 },
11
+ { type: 'paragraph', html: '通过透明的估算探索停车距离、反应时间、道路坡度和抓地力。每个结果都会区分物理模型与真实安全建议,并说明计算采用的假设。' },
12
+ { type: 'title', text: '使用成本与效率', level: 2 },
13
+ { type: 'paragraph', html: '使用你提供的数据比较燃油或电力消耗、行程成本、维护、折旧和每公里成本。工具不会假装知道你没有输入的实时价格。' },
14
+ { type: 'list', items: ['<strong>公式清晰:</strong> 查看哪些变量会改变结果。', '<strong>汽车与摩托车:</strong> 使用适合车辆的控制和提醒。', '<strong>本地处理:</strong> 路线、成本和车辆数据保留在浏览器中。', '<strong>实用单位:</strong> 支持公制和英制测量。'] },
15
+ { type: 'tip', title: '估算只是起点', html: '当决定涉及安全时,请参考制造商规格、交通规则和专业检查,并始终保留充足余量。' },
16
+ ],
17
+ };
@@ -0,0 +1,24 @@
1
+ import type { MotorCategoryEntry, MotorToolEntry } from '../types';
2
+ import { brakingDistanceCalculator } from '../tool/brakingDistanceCalculator/entry';
3
+
4
+ export const motorCategory: MotorCategoryEntry = {
5
+ icon: 'mdi:car-cog',
6
+ tools: [brakingDistanceCalculator] as unknown as MotorToolEntry<Record<string, string>>[],
7
+ i18n: {
8
+ es: () => import('./i18n/es').then((module) => module.content),
9
+ en: () => import('./i18n/en').then((module) => module.content),
10
+ fr: () => import('./i18n/fr').then((module) => module.content),
11
+ de: () => import('./i18n/de').then((module) => module.content),
12
+ id: () => import('./i18n/id').then((module) => module.content),
13
+ it: () => import('./i18n/it').then((module) => module.content),
14
+ ja: () => import('./i18n/ja').then((module) => module.content),
15
+ ko: () => import('./i18n/ko').then((module) => module.content),
16
+ nl: () => import('./i18n/nl').then((module) => module.content),
17
+ pl: () => import('./i18n/pl').then((module) => module.content),
18
+ pt: () => import('./i18n/pt').then((module) => module.content),
19
+ ru: () => import('./i18n/ru').then((module) => module.content),
20
+ sv: () => import('./i18n/sv').then((module) => module.content),
21
+ tr: () => import('./i18n/tr').then((module) => module.content),
22
+ zh: () => import('./i18n/zh').then((module) => module.content),
23
+ },
24
+ };
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { motorCategory } from './index';
4
+ import type { KnownLocale } from '../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'es' } = Astro.props;
11
+ const content = await motorCategory.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SEORenderer content={{ locale, sections: content.seo }} />}
15
+
@@ -0,0 +1,116 @@
1
+ ---
2
+ interface NavItem {
3
+ id: string;
4
+ title: string;
5
+ href: string;
6
+ isActive?: boolean;
7
+ }
8
+
9
+ interface Props {
10
+ categoryTitle: string;
11
+ tools?: NavItem[];
12
+ }
13
+
14
+ const { categoryTitle, tools = [] } = Astro.props;
15
+ ---
16
+
17
+ <nav class="preview-nav-sidebar">
18
+ <div class="sidebar-header">
19
+ <h3>{categoryTitle}</h3>
20
+ </div>
21
+
22
+ <ul class="tools-list">
23
+ {tools.map((tool) => (
24
+ <li>
25
+ <a
26
+ href={tool.href}
27
+ class:list={['tool-link', { active: tool.isActive }]}
28
+ >
29
+ <span class="tool-title">{tool.title}</span>
30
+ </a>
31
+ </li>
32
+ ))}
33
+ </ul>
34
+ </nav>
35
+
36
+ <style>
37
+ .preview-nav-sidebar {
38
+ display: flex;
39
+ flex-direction: column;
40
+ height: 100%;
41
+ background: var(--bg-surface, #0f172a);
42
+ }
43
+
44
+ .sidebar-header {
45
+ padding: 2rem 1.5rem 1.5rem;
46
+ border-bottom: 1px solid var(--border-color, #1e293b);
47
+ }
48
+
49
+ .sidebar-header h3 {
50
+ margin: 0;
51
+ font-size: 0.75rem;
52
+ font-weight: 900;
53
+ text-transform: uppercase;
54
+ letter-spacing: 0.1em;
55
+ color: var(--text-muted, #94a3b8);
56
+ }
57
+
58
+ .tools-list {
59
+ list-style: none;
60
+ margin: 0;
61
+ padding: 0.5rem 0;
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 0.25rem;
65
+ }
66
+
67
+ .tools-list li {
68
+ margin: 0;
69
+ }
70
+
71
+ .tool-link {
72
+ display: flex;
73
+ align-items: center;
74
+ padding: 0.75rem 1.5rem;
75
+ color: var(--text-muted, #94a3b8);
76
+ text-decoration: none;
77
+ font-size: 0.9375rem;
78
+ font-weight: 500;
79
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
80
+ border-left: 3px solid transparent;
81
+ position: relative;
82
+ }
83
+
84
+ .tool-link:hover {
85
+ color: var(--text-base, #f1f5f9);
86
+ background: rgba(255, 255, 255, 0.08);
87
+ padding-left: 1.75rem;
88
+ }
89
+
90
+ .tool-link.active {
91
+ color: var(--accent, #f43f5e);
92
+ background: rgba(244, 63, 94, 0.15);
93
+ border-left-color: var(--accent, #f43f5e);
94
+ font-weight: 600;
95
+ }
96
+
97
+ .tool-link.active::before {
98
+ content: '';
99
+ position: absolute;
100
+ left: 0;
101
+ top: 50%;
102
+ transform: translateY(-50%);
103
+ width: 3px;
104
+ height: 24px;
105
+ background: var(--accent, #f43f5e);
106
+ border-radius: 0 2px 2px 0;
107
+ }
108
+
109
+ .tool-title {
110
+ display: block;
111
+ overflow: hidden;
112
+ text-overflow: ellipsis;
113
+ white-space: nowrap;
114
+ }
115
+ </style>
116
+