@jjlmoya/utils-diy 1.15.0 → 1.16.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 (30) hide show
  1. package/package.json +1 -1
  2. package/src/entries.ts +3 -1
  3. package/src/index.ts +2 -0
  4. package/src/tests/locale_completeness.test.ts +2 -2
  5. package/src/tests/tool_validation.test.ts +2 -2
  6. package/src/tool/twoStrokeMixtureCalculator/bibliography.astro +6 -0
  7. package/src/tool/twoStrokeMixtureCalculator/bibliography.ts +12 -0
  8. package/src/tool/twoStrokeMixtureCalculator/component.astro +266 -0
  9. package/src/tool/twoStrokeMixtureCalculator/entry.ts +24 -0
  10. package/src/tool/twoStrokeMixtureCalculator/i18n/de.ts +194 -0
  11. package/src/tool/twoStrokeMixtureCalculator/i18n/en.ts +194 -0
  12. package/src/tool/twoStrokeMixtureCalculator/i18n/es.ts +194 -0
  13. package/src/tool/twoStrokeMixtureCalculator/i18n/fr.ts +194 -0
  14. package/src/tool/twoStrokeMixtureCalculator/i18n/id.ts +194 -0
  15. package/src/tool/twoStrokeMixtureCalculator/i18n/it.ts +194 -0
  16. package/src/tool/twoStrokeMixtureCalculator/i18n/ja.ts +194 -0
  17. package/src/tool/twoStrokeMixtureCalculator/i18n/ko.ts +194 -0
  18. package/src/tool/twoStrokeMixtureCalculator/i18n/nl.ts +194 -0
  19. package/src/tool/twoStrokeMixtureCalculator/i18n/pl.ts +194 -0
  20. package/src/tool/twoStrokeMixtureCalculator/i18n/pt.ts +194 -0
  21. package/src/tool/twoStrokeMixtureCalculator/i18n/ru.ts +194 -0
  22. package/src/tool/twoStrokeMixtureCalculator/i18n/sv.ts +194 -0
  23. package/src/tool/twoStrokeMixtureCalculator/i18n/tr.ts +194 -0
  24. package/src/tool/twoStrokeMixtureCalculator/i18n/zh.ts +194 -0
  25. package/src/tool/twoStrokeMixtureCalculator/index.ts +11 -0
  26. package/src/tool/twoStrokeMixtureCalculator/logic.ts +92 -0
  27. package/src/tool/twoStrokeMixtureCalculator/seo.astro +15 -0
  28. package/src/tool/twoStrokeMixtureCalculator/two-stroke-fuel-mixture-calculator.css +405 -0
  29. package/src/tool/twoStrokeMixtureCalculator/ui.ts +81 -0
  30. package/src/tools.ts +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-diy",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/entries.ts CHANGED
@@ -16,6 +16,7 @@ export { thermalExpansionCalculator } from './tool/thermalExpansionCalculator/en
16
16
  export { voltageDropCalculator } from './tool/voltageDropCalculator/entry';
17
17
  export { workshopFractionConverter } from './tool/workshopFractionConverter/entry';
18
18
  export { pythagoreanRightAngleCalculator } from './tool/pythagoreanRightAngleCalculator/entry';
19
+ export { twoStrokeMixtureCalculator } from './tool/twoStrokeMixtureCalculator/entry';
19
20
  export { diyCategory } from './category';
20
21
  import { balusterCalculator } from './tool/balusterCalculator/entry';
21
22
  import { clayCalculator } from './tool/clayCalculator/entry';
@@ -32,4 +33,5 @@ import { thermalExpansionCalculator } from './tool/thermalExpansionCalculator/en
32
33
  import { voltageDropCalculator } from './tool/voltageDropCalculator/entry';
33
34
  import { workshopFractionConverter } from './tool/workshopFractionConverter/entry';
34
35
  import { pythagoreanRightAngleCalculator } from './tool/pythagoreanRightAngleCalculator/entry';
35
- export const ALL_ENTRIES = [balusterCalculator, clayCalculator, concreteCalculator, cutOptimizer, drillCalculator, drillSharpener, epoxyCalculator, furnitureFit, mortarCalculator, passepartoutCalculator, stairCalculator, thermalExpansionCalculator, voltageDropCalculator, workshopFractionConverter, pythagoreanRightAngleCalculator];
36
+ import { twoStrokeMixtureCalculator } from './tool/twoStrokeMixtureCalculator/entry';
37
+ export const ALL_ENTRIES = [balusterCalculator, clayCalculator, concreteCalculator, cutOptimizer, drillCalculator, drillSharpener, epoxyCalculator, furnitureFit, mortarCalculator, passepartoutCalculator, stairCalculator, thermalExpansionCalculator, voltageDropCalculator, workshopFractionConverter, pythagoreanRightAngleCalculator, twoStrokeMixtureCalculator];
package/src/index.ts CHANGED
@@ -46,3 +46,5 @@ export { DRILL_SHARPENER_TOOL } from './tool/drillSharpener/index';
46
46
  export { WORKSHOP_FRACTION_CONVERTER_TOOL } from './tool/workshopFractionConverter/index';
47
47
 
48
48
  export { PYTHAGOREAN_RIGHT_ANGLE_CALCULATOR_TOOL } from './tool/pythagoreanRightAngleCalculator/index';
49
+
50
+ export { TWO_STROKE_MIXTURE_CALCULATOR_TOOL } from './tool/twoStrokeMixtureCalculator/index';
@@ -33,8 +33,8 @@ describe('Locale Completeness Validation', () => {
33
33
  });
34
34
  });
35
35
 
36
- it('all 15 tools registered', () => {
37
- expect(ALL_TOOLS.length).toBe(15);
36
+ it('all 16 tools registered', () => {
37
+ expect(ALL_TOOLS.length).toBe(16);
38
38
  });
39
39
  });
40
40
 
@@ -4,8 +4,8 @@ import { diyCategory } from '../data';
4
4
 
5
5
  describe('Tool Validation Suite', () => {
6
6
  describe('Library Registration', () => {
7
- it('should have 15 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(15);
7
+ it('should have 16 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(16);
9
9
  });
10
10
 
11
11
  it('diyCategory should be defined', () => {
@@ -0,0 +1,6 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { bibliography } from './bibliography';
4
+ ---
5
+
6
+ <SharedBibliography links={bibliography} />
@@ -0,0 +1,12 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'Two-Stroke Engine Fuel Mixture Ratios',
6
+ url: 'https://en.wikipedia.org/wiki/Two-stroke_engine',
7
+ },
8
+ {
9
+ name: 'Gasoline and Oil Mix Ratios for Small Engines',
10
+ url: 'https://homelivinghandbook.com/how-much-oil-should-you-mix-with-gas-for-small-engine-tools',
11
+ },
12
+ ];
@@ -0,0 +1,266 @@
1
+ ---
2
+ import { Icon } from 'astro-icon/components';
3
+ import type { TwoStrokeMixtureCalculatorUI } from './ui';
4
+
5
+ interface Props { ui?: TwoStrokeMixtureCalculatorUI; }
6
+ const { ui } = Astro.props;
7
+ const t = (ui ?? {}) as TwoStrokeMixtureCalculatorUI;
8
+ ---
9
+
10
+ <div class="tsmc-root" data-tsmc-root data-ui={JSON.stringify(t)}>
11
+ <div class="tsmc-mission-selector">
12
+ <button class="tsmc-mission-btn active" data-mission="fuel">
13
+ <Icon name="mdi:gas-cylinder" />
14
+ <span>{t.copyTextFuel}</span>
15
+ </button>
16
+ <button class="tsmc-mission-btn" data-mission="oil">
17
+ <Icon name="mdi:beaker-outline" />
18
+ <span>{t.copyTextOil}</span>
19
+ </button>
20
+ </div>
21
+
22
+ <div class="tsmc-container">
23
+ <div class="tsmc-input-section">
24
+ <label id="tsmc-volume-label" class="tsmc-section-label">{t.labelVolume}</label>
25
+
26
+ <div class="tsmc-slider-container">
27
+ <input
28
+ type="range"
29
+ id="tsmc-slider"
30
+ min="1"
31
+ max="50"
32
+ step="1"
33
+ value="5"
34
+ class="tsmc-slider"
35
+ >
36
+ <div class="tsmc-slider-value-display">
37
+ <span id="tsmc-slider-value">5</span><span id="tsmc-slider-unit" class="tsmc-unit">L</span>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="tsmc-quick-buttons">
42
+ <button class="tsmc-quick-btn fuel-btn" data-volume="2">2L</button>
43
+ <button class="tsmc-quick-btn fuel-btn active" data-volume="5">5L</button>
44
+ <button class="tsmc-quick-btn fuel-btn" data-volume="10">10L</button>
45
+ <button class="tsmc-quick-btn fuel-btn" data-volume="20">20L</button>
46
+
47
+ <button class="tsmc-quick-btn oil-btn hidden" data-volume="125">125ml</button>
48
+ <button class="tsmc-quick-btn oil-btn hidden" data-volume="250">250ml</button>
49
+ <button class="tsmc-quick-btn oil-btn hidden" data-volume="500">500ml</button>
50
+ <button class="tsmc-quick-btn oil-btn hidden" data-volume="1000">1L</button>
51
+ </div>
52
+ </div>
53
+
54
+ <div class="tsmc-ratio-section">
55
+ <label class="tsmc-section-label">{t.labelPresets}</label>
56
+ <div class="tsmc-ratio-cards">
57
+ <button class="tsmc-ratio-card" data-ratio="25">
58
+ <span class="tsmc-ratio-value">1:25</span>
59
+ <span class="tsmc-ratio-desc">{t.ratio25Desc}</span>
60
+ </button>
61
+ <button class="tsmc-ratio-card" data-ratio="33">
62
+ <span class="tsmc-ratio-value">1:33</span>
63
+ <span class="tsmc-ratio-desc">{t.ratio33Desc}</span>
64
+ </button>
65
+ <button class="tsmc-ratio-card active" data-ratio="40">
66
+ <span class="tsmc-ratio-value">1:40</span>
67
+ <span class="tsmc-ratio-desc">{t.ratio40Desc}</span>
68
+ </button>
69
+ <button class="tsmc-ratio-card" data-ratio="50">
70
+ <span class="tsmc-ratio-value">1:50</span>
71
+ <span class="tsmc-ratio-desc">{t.ratio50Desc}</span>
72
+ </button>
73
+ </div>
74
+ </div>
75
+
76
+ <div class="tsmc-mega-result">
77
+ <div class="tsmc-result-label">{t.labelOilRequired}</div>
78
+ <div class="tsmc-result-display">
79
+ <span id="tsmc-result-value" class="tsmc-result-big">--</span>
80
+ <span id="tsmc-result-unit" class="tsmc-result-unit">ml</span>
81
+ </div>
82
+
83
+ <svg id="tsmc-container-visual" class="tsmc-container-visual" viewBox="0 0 200 240">
84
+ <rect x="65" y="30" width="70" height="12" fill="#64748b" rx="3"/>
85
+ <rect x="70" y="22" width="60" height="8" fill="#475569" rx="2"/>
86
+ <path d="M 50 42 Q 45 50 45 70 L 45 160 Q 45 175 60 180 L 140 180 Q 155 175 155 160 L 155 70 Q 155 50 150 42 Z"
87
+ fill="none" stroke="#64748b" stroke-width="3" stroke-linejoin="round"/>
88
+ <rect id="tsmc-fuel-fill" x="50" y="160" width="100" height="0" fill="#fbbf24"/>
89
+ <rect id="tsmc-oil-fill" x="50" y="160" width="100" height="0" fill="#dc2626"/>
90
+ <text id="tsmc-ratio-display" x="100" y="105" text-anchor="middle" dominant-baseline="middle"
91
+ font-size="20" font-weight="bold" fill="#1e293b" />
92
+ </svg>
93
+
94
+ <button id="tsmc-share" class="tsmc-share-btn" title="Share">
95
+ <Icon name="mdi:share-variant" />
96
+ </button>
97
+ </div>
98
+ </div>
99
+ </div>
100
+
101
+ <style>
102
+ @import './two-stroke-fuel-mixture-calculator.css';
103
+ </style>
104
+
105
+ <script>
106
+ import { calculateMixture } from './logic';
107
+
108
+ const root = document.querySelector('.tsmc-root') as HTMLElement;
109
+ const ui = root ? JSON.parse(root.dataset.ui || '{}') : {};
110
+
111
+ const slider = document.getElementById('tsmc-slider') as HTMLInputElement;
112
+ const missionBtns = document.querySelectorAll('.tsmc-mission-btn');
113
+ const sliderUnit = document.getElementById('tsmc-slider-unit')!;
114
+ const sliderValue = document.getElementById('tsmc-slider-value')!;
115
+ const quickBtns = document.querySelectorAll('.tsmc-quick-btn');
116
+ const fuelBtns = document.querySelectorAll('.fuel-btn');
117
+ const oilBtns = document.querySelectorAll('.oil-btn');
118
+ const ratioCards = document.querySelectorAll('.tsmc-ratio-card');
119
+ const resultLabel = document.querySelector('.tsmc-result-label')!;
120
+ const resultValue = document.getElementById('tsmc-result-value')!;
121
+ const resultUnit = document.getElementById('tsmc-result-unit')!;
122
+ const fuelFill = document.getElementById('tsmc-fuel-fill')!;
123
+ const oilFill = document.getElementById('tsmc-oil-fill')!;
124
+ const ratioDisplay = document.getElementById('tsmc-ratio-display')!;
125
+ const shareBtn = document.getElementById('tsmc-share')!;
126
+ const volumeLabel = document.getElementById('tsmc-volume-label')!;
127
+ const container = document.querySelector('.tsmc-container')!;
128
+
129
+ const params = new URLSearchParams(window.location.search);
130
+ let currentMission: 'fuel' | 'oil' = (params.get('mode') as 'fuel' | 'oil') || 'fuel';
131
+ let currentVolume = parseFloat(params.get('volume') || '5');
132
+ let currentRatio = parseInt(params.get('ratio') || '40');
133
+
134
+ function setFuelMode(skipSliderUpdate: boolean) {
135
+ container.classList.remove('tsmc-oil-mode');
136
+ slider.min = '1';
137
+ slider.max = '50';
138
+ slider.step = '1';
139
+ if (!skipSliderUpdate) slider.value = '5';
140
+ sliderUnit.textContent = 'L';
141
+ volumeLabel.textContent = ui.labelVolume || 'Volume';
142
+ resultLabel.textContent = ui.labelOilRequired || 'Oil Required';
143
+ fuelBtns.forEach(btn => btn.classList.remove('hidden'));
144
+ oilBtns.forEach(btn => btn.classList.add('hidden'));
145
+ }
146
+
147
+ function setOilMode(skipSliderUpdate: boolean) {
148
+ container.classList.add('tsmc-oil-mode');
149
+ slider.min = '20';
150
+ slider.max = '1000';
151
+ slider.step = '10';
152
+ if (!skipSliderUpdate) slider.value = '125';
153
+ sliderUnit.textContent = 'ml';
154
+ volumeLabel.textContent = ui.labelOilRequired || 'Oil';
155
+ resultLabel.textContent = ui.labelFuelVolume || 'Fuel Required';
156
+ fuelBtns.forEach(btn => btn.classList.add('hidden'));
157
+ oilBtns.forEach(btn => btn.classList.remove('hidden'));
158
+ }
159
+
160
+ function setMission(mission: 'fuel' | 'oil', skipSliderUpdate = false) {
161
+ currentMission = mission;
162
+ missionBtns.forEach(btn => {
163
+ btn.classList.toggle('active', (btn as HTMLElement).getAttribute('data-mission') === mission);
164
+ });
165
+ if (mission === 'fuel') {
166
+ setFuelMode(skipSliderUpdate);
167
+ } else {
168
+ setOilMode(skipSliderUpdate);
169
+ }
170
+ sliderValue.textContent = currentVolume.toString();
171
+ }
172
+
173
+ function setVolume(volume: number) {
174
+ currentVolume = volume;
175
+ slider.value = String(volume);
176
+ sliderValue.textContent = volume.toFixed(1);
177
+ quickBtns.forEach(btn => {
178
+ btn.classList.toggle('active', parseFloat((btn as HTMLElement).getAttribute('data-volume') || '0') === volume);
179
+ });
180
+ calculate();
181
+ }
182
+
183
+ function setRatio(ratio: number) {
184
+ currentRatio = ratio;
185
+ ratioCards.forEach(card => {
186
+ card.classList.toggle('active', parseInt((card as HTMLElement).getAttribute('data-ratio') || '40') === ratio);
187
+ });
188
+ calculate();
189
+ }
190
+
191
+ function calculate() {
192
+ const calc = calculateMixture(currentVolume, currentRatio, ui);
193
+
194
+ if (calc.status === 'calculated') {
195
+ const oilMl = calc.oilRequired * (calc.displayUnit === 'ml' ? 1 : 1000);
196
+
197
+ if (oilMl < 1000) {
198
+ resultValue.textContent = oilMl.toFixed(0);
199
+ resultUnit.textContent = 'ml';
200
+ } else if (oilMl % 1000 === 0) {
201
+ resultValue.textContent = (oilMl / 1000).toFixed(0);
202
+ resultUnit.textContent = 'L';
203
+ } else {
204
+ resultValue.textContent = oilMl.toFixed(0);
205
+ resultUnit.textContent = 'ml';
206
+ }
207
+
208
+ ratioDisplay.textContent = `1:${currentRatio}`;
209
+
210
+ const containerHeight = 120;
211
+ const oilRatioHeight = (1 / (1 + currentRatio)) * containerHeight;
212
+
213
+ fuelFill.setAttribute('y', (160 - containerHeight).toString());
214
+ fuelFill.setAttribute('height', containerHeight.toString());
215
+
216
+ oilFill.setAttribute('y', (160 - oilRatioHeight).toString());
217
+ oilFill.setAttribute('height', oilRatioHeight.toString());
218
+ } else {
219
+ resultValue.textContent = '--';
220
+ resultUnit.textContent = 'ml';
221
+ ratioDisplay.textContent = '';
222
+ fuelFill.setAttribute('height', '0');
223
+ oilFill.setAttribute('height', '0');
224
+ }
225
+ }
226
+
227
+ missionBtns.forEach(btn => {
228
+ btn.addEventListener('click', () => {
229
+ setMission((btn as HTMLElement).getAttribute('data-mission') as 'fuel' | 'oil');
230
+ });
231
+ });
232
+
233
+ slider.addEventListener('input', (e) => {
234
+ setVolume(parseFloat((e.target as HTMLInputElement).value));
235
+ });
236
+
237
+ quickBtns.forEach(btn => {
238
+ btn.addEventListener('click', () => {
239
+ setVolume(parseFloat((btn as HTMLElement).getAttribute('data-volume') || '5'));
240
+ });
241
+ });
242
+
243
+ ratioCards.forEach(card => {
244
+ card.addEventListener('click', () => {
245
+ setRatio(parseInt((card as HTMLElement).getAttribute('data-ratio') || '40'));
246
+ });
247
+ });
248
+
249
+ shareBtn.addEventListener('click', () => {
250
+ const url = new URL(window.location.href);
251
+ url.searchParams.set('mode', currentMission);
252
+ url.searchParams.set('volume', String(currentVolume));
253
+ url.searchParams.set('ratio', String(currentRatio));
254
+ navigator.clipboard.writeText(url.toString()).then(() => {
255
+ const originalHTML = shareBtn.innerHTML;
256
+ shareBtn.innerHTML = '<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"/></svg>';
257
+ setTimeout(() => (shareBtn.innerHTML = originalHTML), 1500);
258
+ });
259
+ });
260
+
261
+ setMission(currentMission, true);
262
+ setRatio(currentRatio);
263
+ slider.value = String(currentVolume);
264
+ sliderValue.textContent = currentVolume.toString();
265
+ calculate();
266
+ </script>
@@ -0,0 +1,24 @@
1
+ import type { DiyToolEntry } from '../../types';
2
+ import type { TwoStrokeMixtureCalculatorUI } from './ui';
3
+
4
+ export const twoStrokeMixtureCalculator: DiyToolEntry<TwoStrokeMixtureCalculatorUI> = {
5
+ id: 'two-stroke-fuel-mixture-calculator',
6
+ icons: { bg: 'mdi:gas-cylinder', fg: 'mdi:beaker-outline' },
7
+ i18n: {
8
+ de: () => import('./i18n/de').then((m) => m.content),
9
+ en: () => import('./i18n/en').then((m) => m.content),
10
+ es: () => import('./i18n/es').then((m) => m.content),
11
+ fr: () => import('./i18n/fr').then((m) => m.content),
12
+ id: () => import('./i18n/id').then((m) => m.content),
13
+ it: () => import('./i18n/it').then((m) => m.content),
14
+ ja: () => import('./i18n/ja').then((m) => m.content),
15
+ ko: () => import('./i18n/ko').then((m) => m.content),
16
+ nl: () => import('./i18n/nl').then((m) => m.content),
17
+ pl: () => import('./i18n/pl').then((m) => m.content),
18
+ pt: () => import('./i18n/pt').then((m) => m.content),
19
+ ru: () => import('./i18n/ru').then((m) => m.content),
20
+ sv: () => import('./i18n/sv').then((m) => m.content),
21
+ tr: () => import('./i18n/tr').then((m) => m.content),
22
+ zh: () => import('./i18n/zh').then((m) => m.content),
23
+ },
24
+ };
@@ -0,0 +1,194 @@
1
+ import type { WithContext, FAQPage, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { TwoStrokeMixtureCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
5
+
6
+ const slug = 'zweitakt-gemischrechner';
7
+ const title = 'Zweitakt Gemischrechner: Präzise Öl und Kraftstoff Verhältnisse';
8
+ const description = 'Berechnen Sie sofort präzise 2-Takt-Mischungsverhältnisse. Unverzichtbares Werkzeug für Motorsägen, Mofas, Motorräder und Kleinmotoren. Unterstützt 1:25, 1:33, 1:40 und 1:50.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Was ist ein Zweitaktmotor?',
13
+ answer: 'Ein Zweitaktmotor kombiniert Ansaugen und Verdichten in zwei Kolbenhüben, was ihn einfacher und leichter als Viertaktmotoren macht. Sie treiben Motorsägen, Laubbläser, Mofas und einige Motorräder an. Sie benötigen zur Schmierung Öl, das dem Kraftstoff beigemischt wird.',
14
+ },
15
+ {
16
+ question: 'Was sind gängige Kraftstoff-Öl-Mischungsverhältnisse?',
17
+ answer: 'Gängige Verhältnisse sind 1:25 (fett, schützend), 1:33 (ältere Geräte), 1:40 (Standard) und 1:50 (mager, moderne Motoren). Prüfen Sie das Handbuch Ihres Motors – ein falsches Verhältnis kann den Motor beschädigen.',
18
+ },
19
+ {
20
+ question: 'Was passiert bei falschem Mischungsverhältnis?',
21
+ answer: 'Zu viel Öl (fettes Gemisch) führt zu übermäßiger Rauchentwicklung, verrußten Zündkerzen und schlechter Leistung. Zu wenig Öl (mageres Gemisch) führt zum Kolbenfresser, Kolbenschäden und Motorausfall.',
22
+ },
23
+ {
24
+ question: 'Welches Öl soll ich verwenden?',
25
+ answer: 'Verwenden Sie Zweitaktöl, das für Ihr Gerät zugelassen ist. Hochwertige synthetische Zweitaktöle bieten besseren Schutz und verbrennen sauberer als herkömmliche Öle. Verwenden Sie niemals Viertaktöl – es führt zu Motorschäden.',
26
+ },
27
+ {
28
+ question: 'Wie mische ich Kraftstoff und Öl?',
29
+ answer: 'Gießen Sie einen Teil des Benzins in einen sauberen Behälter, geben Sie die berechnete Menge Öl hinzu und füllen Sie das restliche Benzin auf. Mischen Sie gründlich durch 1-2 Minuten langes Schütteln. Beschriften Sie den Behälter mit dem Mischdatum.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ { name: 'Verhältnis kennen', text: 'Suchen Sie das Handbuch Ihres Motors oder die Gerätedokumentation. Gängige Verhältnisse: Motorsägen (1:40 oder 1:50), Mofas (1:33), ältere Motorräder (1:25). Ein falsches Verhältnis schadet dem Motor.' },
35
+ { name: 'Kraftstoffmenge messen', text: 'Entscheiden Sie, wie viel Benzin Sie benötigen. Dieses Tool verarbeitet Liter, Gallonen oder jede Volumeneinheit. Genaue Kraftstoffmessung = genaue Ölmenge.' },
36
+ { name: 'Ölbedarf berechnen', text: 'Geben Sie Kraftstoffmenge und Verhältnis ein. Dieser Rechner zeigt genau, wie viel Öl (in ml oder Litern) Sie für eine perfekte Mischung benötigen.' },
37
+ { name: 'Sorgfältig mischen', text: 'Benzin in einen sauberen Behälter füllen, berechnetes Öl zugeben, dann Restbenzin einfüllen. 1-2 Minuten kräftig schütteln.' },
38
+ { name: 'Beschriften und verwenden', text: 'Behälter mit Datum und Verhältnis markieren. Mischung für beste Ergebnisse innerhalb von 30 Tagen verbrauchen (besonders bei synthetischen Ölen).' },
39
+ ];
40
+
41
+ const faqSchema: WithContext<FAQPage> = {
42
+ '@context': 'https://schema.org',
43
+ '@type': 'FAQPage',
44
+ mainEntity: faqData.map((item) => ({
45
+ '@type': 'Question',
46
+ name: item.question,
47
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
48
+ })),
49
+ };
50
+
51
+ const howToSchema: WithContext<any> = {
52
+ '@context': 'https://schema.org',
53
+ '@type': 'HowTo',
54
+ name: title,
55
+ description,
56
+ step: howToData.map((step, i) => ({
57
+ '@type': 'HowToStep',
58
+ position: i + 1,
59
+ name: step.name,
60
+ text: step.text,
61
+ })),
62
+ };
63
+
64
+ const appSchema: WithContext<SoftwareApplication> = {
65
+ '@context': 'https://schema.org',
66
+ '@type': 'SoftwareApplication',
67
+ name: title,
68
+ description,
69
+ applicationCategory: 'UtilityApplication',
70
+ operatingSystem: 'All',
71
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
72
+ inLanguage: 'de',
73
+ };
74
+
75
+ export const content: ToolLocaleContent<TwoStrokeMixtureCalculatorUI> = {
76
+ slug,
77
+ title,
78
+ description,
79
+ faqTitle: 'Häufig gestellte Fragen',
80
+ faq: faqData,
81
+ bibliography,
82
+ howTo: howToData,
83
+ schemas: [faqSchema, howToSchema, appSchema],
84
+ seo: [
85
+ { type: 'title', text: 'Zweitakt-Gemischrechner: Präzise Öl-Kraftstoff-Verhältnisse für Motorsägen und Mofas', level: 2 },
86
+ { type: 'paragraph', html: 'Zweitaktmotoren benötigen ein präzises Kraftstoff-Öl-Gemisch zum Überleben. Eine falsche Mischung kann Ihren Motor in wenigen Minuten zerstören. Dieser Rechner ermittelt sofort die exakte Ölmenge für Ihre Kraftstoffmenge und Ihren Motortyp – Schluss mit dem Rätselraten in der Werkstatt.' },
87
+
88
+ { type: 'title', text: 'Warum Zweitaktmotoren Öl im Kraftstoff benötigen', level: 3 },
89
+ { type: 'card', icon: 'mdi:engine', title: 'Der entscheidende Unterschied', html: 'Im Gegensatz zu Viertaktmotoren mit separaten Öltanks mischen Zweitaktmotoren das Öl direkt in den Kraftstoff. Bei jedem Arbeitstakt verbrennt der Motor das Gemisch sowohl für Energie als auch zur Schmierung. Es gibt keine Ölwanne, keine separate Ölpumpe – nur das Mischbenzin hält die Kolben am Leben.' },
90
+
91
+ { type: 'title', text: 'Schnellreferenz für Zweitakt-Verhältnisse', level: 3 },
92
+ { type: 'table', headers: ['Verhältnis', 'Öl %', 'Einsatzzweck', 'Motortyp', 'Eigenschaften'], rows: [
93
+ ['1:25', '3,85%', 'Maximaler Schutz', 'Geräte vor 1980, Hochlast, Oldtimer-Motorräder', 'Fettes Gemisch: mehr Rauch, mehr Ölkohle, maximaler Schutz gegen Fresser'],
94
+ ['1:33', '2,94%', 'Klassische Geräte', 'Kleinmotoren der 80er-90er, ältere Motorsägen', 'Moderate Fettigkeit: Balance zwischen Schutz und Effizienz'],
95
+ ['1:40', '2,44%', 'Industriestandard', 'Die meisten modernen Sägen, Mofas, moderne Kleinmotoren', 'Standardempfehlung: ausgelegt für heutige synthetische Öle'],
96
+ ['1:50', '1,96%', 'Moderne Effizienz', 'Neueste Motorsägen, Hochleistungsmofas, neue Motorräder', 'Mageres Gemisch: weniger Rauch, saubere Verbrennung, für Premium-Synthetiköle']
97
+ ] },
98
+
99
+ { type: 'title', text: 'Folgen falscher Verhältnisse', level: 3 },
100
+ { type: 'proscons', items: [
101
+ { pro: 'Zu viel Öl (Fettes Gemisch)', con: 'Übermäßiger weißer Rauch, verrußte Kerzen, Ölkohlebildung, schlechte Beschleunigung, Motorausfall' },
102
+ { pro: 'Zu wenig Öl (Mageres Gemisch)', con: 'Kolbenfresser binnen Sekunden, riefige Zylinderwände, katastrophaler Motorschaden' },
103
+ { pro: 'Korrektes Verhältnis', con: 'Ruhiger Lauf, ordnungsgemäße Schmierung, optimale Verbrennung, längere Lebensdauer, zuverlässiger Start' }
104
+ ] },
105
+
106
+ { type: 'title', text: 'Gängige Geräte-Verhältnisse', level: 3 },
107
+ { type: 'card', icon: 'mdi:tree', title: 'Motorsägen', html: '<strong>Stihl, Husqvarna, Echo:</strong> Moderne Modelle benötigen typischerweise 1:40 oder 1:50. Prüfen Sie immer Ihr Handbuch – 1:25 bei einer modernen Säge riskiert verrußte Kerzen. Ältere Stihl-Maschinen (90er und früher) können 1:25 oder 1:33 vorschreiben.' },
108
+ { type: 'card', icon: 'mdi:motorcycle', title: 'Mofas & Motorräder', html: '<strong>Vespa, Honda, Yamaha:</strong> Die meisten benötigen 1:33 bei älteren Modellen, 1:40–1:50 bei modernen Versionen. Hochleistungs-Mofas und Straßenmaschinen schreiben oft 1:50 vor. Das Werkstatthandbuch ist die einzige Wahrheit.' },
109
+ { type: 'card', icon: 'mdi:tools', title: 'Laubbläser & Trimmer', html: '<strong>Stihl, Husqvarna, DeWalt:</strong> Typischerweise 1:50 (modern) oder 1:40 (etwas älter). Diese Geräte sind für kurzen saisonalen Einsatz konzipiert, magere Mischungen sparen Rauch ohne Zuverlässigkeitsverlust.' },
110
+
111
+ { type: 'title', text: 'Ölsorte ist so wichtig wie das Verhältnis', level: 3 },
112
+ { type: 'comparative', items: [
113
+ { title: 'Mineralisches Zweitaktöl', description: 'Günstige Option für gelegentliche Nutzung. Höherer Aschegehalt, mehr Rauch, ausreichender Schutz für Standardverhältnisse.', icon: 'mdi:beaker', points: ['Günstiger Preis', 'Sichtbarer Rauch', 'Höhere Ablagerungen', 'Gut für 1:40 Verhältnisse'] },
114
+ { title: 'Synthetisches Zweitaktöl', description: 'Premium-Wahl für Vielnutzer. Sauberere Verbrennung, besserer Schutz, ermöglicht magerere Mischungen. Temperaturstabil.', icon: 'mdi:flame', points: ['Geringere Rauchentwicklung', 'Bester Motorschutz', 'Ermöglicht sicheres 1:50', 'Längere Lagerstabilität'], highlight: true },
115
+ { title: 'Teilsynthetisches Öl', description: 'Mittelweg zwischen mineralisch und vollsynthetisch. Guter Schutz bei moderaten Kosten. Oft von Herstellern empfohlen.', icon: 'mdi:beaker-outline', points: ['Ausgewogene Leistung', 'Moderate Kosten', 'Gut für 1:40 Verhältnisse', 'Weniger Rauch als mineralisch'] }
116
+ ], columns: 3 },
117
+
118
+ { type: 'title', text: 'Schritt-für-Schritt Mischvorgang', level: 3 },
119
+ { type: 'card', icon: 'mdi:check-circle', title: 'Der richtige Weg zum Mischen', html: '<ol style="margin: 1rem 0; padding-left: 1.5rem;"><li><strong>Verwenden Sie einen speziellen Behälter</strong> nur für Kraftstoffmischungen. Sauber, trocken, markiert.</li><li><strong>Gießen Sie zuerst die Hälfte des Benzins</strong> ein.</li><li><strong>Geben Sie die berechnete Ölmenge zu</strong> (nutzen Sie diesen Rechner für Präzision).</li><li><strong>Füllen Sie das restliche Benzin auf</strong>, um die Zielmenge zu erreichen.</li><li><strong>Schütteln Sie kräftig für 1–2 Minuten</strong>, bis die Farbe gleichmäßig ist. Ein homogenes Gemisch = gleichmäßige Schmierung.</li><li><strong>Beschriften Sie den Behälter</strong> mit Datum, Verhältnis und Kraftstoffart.</li><li><strong>Innerhalb von 30 Tagen verbrauchen</strong> (Synthetiköle halten bis zu 60 Tage).</li></ol>' },
120
+
121
+ { type: 'title', text: 'Wann Sie das Handbuch infrage stellen sollten', level: 3 },
122
+ { type: 'tip', html: '<strong>Prüfen Sie immer zuerst das Verhältnis im Gerätehandbuch.</strong> Wenn Sie es nicht finden, besuchen Sie die Website des Herstellers oder kontaktieren Sie den Support. Niemals raten – ein falsches Verhältnis führt zum Erlöschen der Garantie und riskiert einen Motorschaden.' },
123
+
124
+ { type: 'title', text: 'Glossar: Zweitakt-Begriffe erklärt', level: 3 },
125
+ { type: 'glossary', items: [
126
+ { term: 'Mageres Gemisch', definition: 'Kraftstoff mit zu wenig Öl (hohes Verhältnis wie 1:50). Gefahr von Kolbenfressern durch mangelnde Schmierung.' },
127
+ { term: 'Fettes Gemisch', definition: 'Kraftstoff mit zu viel Öl (niedriges Verhältnis wie 1:25). Verursacht Rauch, verrußte Kerzen und Ablagerungen.' },
128
+ { term: 'Homogenes Gemisch', definition: 'Gleichmäßige Mischung von Benzin und Öl, erreicht durch gründliches Schütteln. Lebenswichtig für Schmierung und Verbrennung.' },
129
+ { term: 'Kolbenfresser', definition: 'Wenn der Kolben im Zylinder aufgrund mangelnder Schmierung und Reibung festbrennt. Führt zum totalen Motorschaden.' },
130
+ { term: 'Synthetiköl', definition: 'Laborformuliertes Öl für überlegenen Schutz, sauberere Verbrennung und Temperaturstabilität im Vergleich zu Mineralölen.' },
131
+ { term: 'Zweitaktmotor', definition: 'Motor, der den Verbrennungszyklus in zwei Kolbenbewegungen abschließt. Leichter und einfacher als Viertaktmotoren.' },
132
+ { term: 'Viertaktmotor', definition: 'Motor mit separatem Ölkreislauf und vier Arbeitstakten. Öl wird nicht dem Kraftstoff beigemischt. Schwerer, aber effizienter.' }
133
+ ] },
134
+
135
+ { type: 'title', text: 'Wie dieser Rechner Zeit & Geld spart', level: 3 },
136
+ { type: 'stats', items: [
137
+ { value: '100%', label: 'Genaue Berechnungen, keine Messfehler', icon: 'mdi:check-circle' },
138
+ { value: 'Sofort', label: 'Exakte Mengen in Sekunden statt Schätzen', icon: 'mdi:flash' },
139
+ { value: '4 Ratios', label: '1:25, 1:33, 1:40, 1:50 abgedeckt', icon: 'mdi:counter', trend: { value: 'Plus eigene Verhältnisse', positive: true } },
140
+ { value: 'Teilbar', label: 'Teilen Sie Ihr Misch-Setup per URL', icon: 'mdi:share-variant' }
141
+ ], columns: 2 },
142
+
143
+ { type: 'title', text: 'Häufige Fehler, die Motoren töten', level: 3 },
144
+ { type: 'diagnostic', variant: 'error', title: 'Viertaktöl in Zweitaktmotoren verwenden', icon: 'mdi:alert', badge: 'Motortod', html: 'Viertaktöle sind für die Zirkulation im Motorblock gedacht. Im Zweitakter verbrennen sie nicht sauber und zerstören den Motor binnen Stunden.' },
145
+ { type: 'diagnostic', variant: 'warning', title: 'Gründliches Mischen vergessen', icon: 'mdi:alert', badge: 'Fresser-Risiko', html: 'Wenn sich Öl und Benzin trennen, laufen Teile Ihres Motors ohne Schmierung. Mindestens 1–2 Minuten lang kräftig schütteln.' },
146
+ { type: 'diagnostic', variant: 'warning', title: 'Alten Kraftstoff verwenden (über 60 Tage)', icon: 'mdi:alert', badge: 'Verharzungsgefahr', html: 'Ethanol-Benzin zersetzt sich mit der Zeit. Alte Mischung hinterlässt Harzablagerungen im Vergaser. Nur mischen, was in 30 Tagen verbraucht wird.' },
147
+
148
+ { type: 'title', text: 'FAQ Zusammenfassung', level: 3 },
149
+ { type: 'summary', title: 'Vor dem Mischen', items: [
150
+ 'Prüfen Sie das Handbuch auf das exakte Verhältnis – das ist die Vorgabe des Herstellers.',
151
+ 'Sicherstellen, dass Sie Zweitaktöl verwenden, kein Viertakt- oder sonstiges Öl.',
152
+ 'Verwenden Sie einen sauberen, speziellen Behälter nur zum Mischen.',
153
+ 'Frisches Benzin (nicht monatelang gelagert) und passendes Öl verwenden.',
154
+ 'Gründlich mischen und mit Datum, Verhältnis und Kraftstoffart beschriften.',
155
+ 'Mischung innerhalb von 30 Tagen verbrauchen.'
156
+ ] },
157
+ ],
158
+ ui: {
159
+ titleMain: 'Zweitakt-Gemischrechner',
160
+ labelFuelVolume: 'Kraftstoffmenge',
161
+ labelRatio: 'Mischungsverhältnis',
162
+ labelOilRequired: 'Ölbedarf',
163
+ labelTotalMixture: 'Gesamtgemisch',
164
+ labelRichness: 'Gemisch-Fettigkeit',
165
+ labelPresets: 'Gängige Verhältnisse',
166
+ labelCustomRatio: 'Eigener Wert (1:X)',
167
+ btnClear: 'Leeren',
168
+ btnCopyResults: 'Ergebnisse kopieren',
169
+ btnSwitchMode: 'Modus wechseln',
170
+ unitLiters: 'L',
171
+ unitMilliliters: 'ml',
172
+ richLean: 'Mager (weniger Öl, Fresser-Risiko)',
173
+ richBalanced: 'Ausgewogen (Standard-Mix)',
174
+ richRich: 'Fett (mehr Öl, mehr Rauch, Motorschutz)',
175
+ msgReady: 'Bereit',
176
+ msgMixtureReady: 'Gemisch berechnet',
177
+ tooltipFuelVolume: 'Geben Sie die Benzinmenge in Litern ein',
178
+ tooltipRatio: 'Geben Sie den Wert als 25, 33, 40 oder 50 ein (für 1:25, 1:33 etc.)',
179
+ recipientLabel: 'Mischbehälter',
180
+ oilPercentage: 'Öl %',
181
+ labelVolume: 'Volumen',
182
+ labelRatioShort: 'Verhältnis',
183
+ labelOilTip: '2% Öl-Mix = 1:50 Verhältnis',
184
+ labelMixingTips: 'Tipps zum Mischen',
185
+ labelMixingTipsDesc: 'In sauberem Behälter mischen – erst Benzin, dann Öl, dann Restbenzin. 1-2 Minuten kräftig schütteln. Mit Datum und Verhältnis beschriften.',
186
+ recipePrefix: 'Für',
187
+ recipeAt: 'Benzin bei',
188
+ recipeAdd: 'fügen Sie genau',
189
+ recipeOfOil: 'Zweitaktöl hinzu.',
190
+ copyTextPrefix: '2-Takt Mix',
191
+ copyTextFuel: 'Benzin',
192
+ copyTextOil: 'Öl',
193
+ },
194
+ };