@jjlmoya/utils-drones 1.38.0 → 1.40.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.
- package/package.json +1 -1
- package/src/category/index.ts +2 -0
- package/src/entries.ts +4 -0
- package/src/index.ts +1 -0
- package/src/layouts/ProductionUtilityPage.astro +4 -4
- package/src/mfe/widget-height.ts +14 -0
- package/src/tests/locale_completeness.test.ts +2 -2
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/fpv-drone-lap-timer/audio.ts +160 -0
- package/src/tool/fpv-drone-lap-timer/bibliography.astro +6 -0
- package/src/tool/fpv-drone-lap-timer/bibliography.ts +14 -0
- package/src/tool/fpv-drone-lap-timer/bootstrap.ts +20 -0
- package/src/tool/fpv-drone-lap-timer/component.astro +136 -0
- package/src/tool/fpv-drone-lap-timer/contract.test.ts +24 -0
- package/src/tool/fpv-drone-lap-timer/controller.ts +304 -0
- package/src/tool/fpv-drone-lap-timer/dom-views.ts +213 -0
- package/src/tool/fpv-drone-lap-timer/entry.ts +27 -0
- package/src/tool/fpv-drone-lap-timer/export.ts +41 -0
- package/src/tool/fpv-drone-lap-timer/fpv-drone-lap-timer.css +705 -0
- package/src/tool/fpv-drone-lap-timer/i18n/de.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/en.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/es.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/fr.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/id.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/it.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/ja.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/ko.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/nl.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/pl.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/pt.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/ru.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/sv.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/tr.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/i18n/zh.ts +216 -0
- package/src/tool/fpv-drone-lap-timer/index.ts +10 -0
- package/src/tool/fpv-drone-lap-timer/logic.test.ts +152 -0
- package/src/tool/fpv-drone-lap-timer/logic.ts +228 -0
- package/src/tool/fpv-drone-lap-timer/seo.astro +16 -0
- package/src/tool/fpv-drone-lap-timer/storage.ts +52 -0
- package/src/tool/fpv-drone-lap-timer/ui.ts +58 -0
- package/src/tools.ts +3 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { FpvDroneLapTimerLocaleContent } from '../entry';
|
|
2
|
+
import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
|
|
3
|
+
import type { SEOSection } from '../../../types';
|
|
4
|
+
import { BIBLIOGRAPHY_ITEMS } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'fpv-dronerace-varvtidtagare';
|
|
7
|
+
const title = 'FPV Drönarracing Varv och Splittidtagare';
|
|
8
|
+
const description = 'Interaktiv varvtidtagare för FPV drönarracing med FAI akustisk startsekvens, split-delta-analys, snabbaste varv-varningar, varvkonsistensindex och hastighetstelemetri.';
|
|
9
|
+
|
|
10
|
+
const ui = {
|
|
11
|
+
setupHeading: 'Bane- och Sessionskonfiguration',
|
|
12
|
+
trackLengthLabel: 'Banlängd',
|
|
13
|
+
trackLengthUnit: 'meter',
|
|
14
|
+
targetLapsLabel: 'Målvarv',
|
|
15
|
+
targetLapsUnit: 'varv (0 för fri träning)',
|
|
16
|
+
batteryCapacityLabel: 'Batterikapacitet',
|
|
17
|
+
batteryCapacityUnit: 'mAh',
|
|
18
|
+
soundEnabledLabel: 'Aktivera Ljudsignaler',
|
|
19
|
+
debounceThresholdLabel: 'Filter mot Dubbelregistrering',
|
|
20
|
+
debounceThresholdUnit: 'sekunder',
|
|
21
|
+
presetMultiGpLabel: 'MultiGP Spec (250m / 3 Varv)',
|
|
22
|
+
presetWhoopLabel: 'Tiny Whoop (65m / 5 Varv)',
|
|
23
|
+
presetSprintLabel: 'Höghastighetssprint (400m / 2 Varv)',
|
|
24
|
+
startCountdownButton: 'Starta FAI Nedräkning',
|
|
25
|
+
pauseTimerButton: 'Pausa Session',
|
|
26
|
+
resumeTimerButton: 'Återuppta Tidtagning',
|
|
27
|
+
resetTimerButton: 'Återställ Session',
|
|
28
|
+
recordLapButton: 'REGISTRERA VARV',
|
|
29
|
+
spacebarHint: 'Tryck på MELLANSLAG eller tryck på den stora knappen vid målgång',
|
|
30
|
+
statusIdle: 'Redo för Start',
|
|
31
|
+
statusCountdown: 'FAI Nedräkning Pågår',
|
|
32
|
+
statusRunning: 'Tidtagning Aktiv',
|
|
33
|
+
statusPaused: 'Session Pausad',
|
|
34
|
+
statusFinished: 'Racet Avslutat',
|
|
35
|
+
currentLapHeading: 'Aktuell Varvtid',
|
|
36
|
+
lapNumberPrefix: 'Varv',
|
|
37
|
+
lastLapHeading: 'Senaste Varvet',
|
|
38
|
+
fastestLapHeading: 'Snabbaste Varv',
|
|
39
|
+
averageLapHeading: 'Genomsnittligt Varv',
|
|
40
|
+
deltaBestHeading: 'Skillnad mot Snabbaste',
|
|
41
|
+
consistencyIndexHeading: 'Varvkonsistensindex',
|
|
42
|
+
estimatedSpeedHeading: 'Uppskattad Medelhastighet',
|
|
43
|
+
estimatedBatteryHeading: 'Uppskattad Batteriförbrukning',
|
|
44
|
+
speedUnitKmh: 'km/h',
|
|
45
|
+
speedUnitMph: 'mph',
|
|
46
|
+
batteryUsedUnit: 'mAh',
|
|
47
|
+
batteryRemainingUnit: 'mAh kvar',
|
|
48
|
+
lapHistoryHeading: 'Varvtider och Tempofördelning',
|
|
49
|
+
lapColumnHeader: 'Varv #',
|
|
50
|
+
timeColumnHeader: 'Tid',
|
|
51
|
+
splitColumnHeader: 'Delta mot Bästa',
|
|
52
|
+
speedColumnHeader: 'Medelfart',
|
|
53
|
+
batteryColumnHeader: 'Batteriåtkomst',
|
|
54
|
+
noLapsRecordedNotice: 'Inga varv registrerade ännu. Starta nedräkningen och tryck på Mellanslag för att logga ditt första varv.',
|
|
55
|
+
consistencyRatingElite: 'Elitkonsistens',
|
|
56
|
+
consistencyRatingPro: 'Proffskonsistens',
|
|
57
|
+
consistencyRatingClub: 'Klubbkonsistens',
|
|
58
|
+
consistencyRatingNovice: 'Träningskonsistens',
|
|
59
|
+
fastestLapBadge: 'SNABBASTE VARV',
|
|
60
|
+
sessionSummaryHeading: 'Sessionsöversikt och Export',
|
|
61
|
+
totalTimeLabel: 'Total Racetid',
|
|
62
|
+
completedLapsLabel: 'Slutförda Varv',
|
|
63
|
+
exportCsvButton: 'Exportera Varv till CSV',
|
|
64
|
+
copySummaryButton: 'Kopiera Textöversikt',
|
|
65
|
+
copiedNotice: 'Sessionsöversikt kopierad till urklipp!',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const faqItems = [
|
|
69
|
+
{
|
|
70
|
+
question: 'Hur fungerar FAI akustiska startsekvens i tidtagaren?',
|
|
71
|
+
answer: 'Startsekvensen återspeglar officiella FAI CIAM F9U-regler för drönarracing. Fyra förberedande pipljud med en sekunds mellanrum varnar piloten, följt av en distinkt högfrekvent startsignal som sätter igång tidtagningen på exakt noll.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
question: 'Hur beräknas Varvkonsistensindexet?',
|
|
75
|
+
answer: 'Indexet mäter standardavvikelsen för dina slutförda varvtider i relation till sessionens genomsnittsvarv. Ett värde över 95 procent indikerar exceptionell flyglinje och gasreglering.',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
question: 'Kan man använda fotpedal eller en sändarknapp?',
|
|
79
|
+
answer: 'Ja. Alla trådlösa tangentbord, Bluetooth-fotpedaler eller radiokontroller som skickar ett mellanslagskommando registrerar varvet direkt utan att du behöver släppa blicken från videoglasögonen.',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
question: 'Varför finns det ett skyddsintervall mot dubbelregistrering?',
|
|
83
|
+
answer: 'Portarna passeras i hög fart, men oavsiktliga dubbeltryckningar kan skapa falska varv på bråkdelen av en sekund. Filtret avvisar tryckningar under den inställda tidsgränsen (standard 3 sekunder).',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
question: 'Hur tillförlitlig är den uppskattade medelhastigheten?',
|
|
87
|
+
answer: 'Hastigheten baseras på den angivna banlängden delad med varvtiden. Faktisk hastighet i kurvor varierar beroende på vald flyglinje och lutningsvinkel.',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
const howToSteps = [
|
|
92
|
+
{
|
|
93
|
+
name: 'Ställ in banlängd och önskat antal varv',
|
|
94
|
+
text: 'Ange banans längd i meter och målet för antal varv eller välj en förinställning som MultiGP Spec.',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'Starta FAI akustisk nedräkning',
|
|
98
|
+
text: 'Klicka på startknappen. Lyssna på förberedelsetonerna och den höga starttonen.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'Registrera varv vid målporten',
|
|
102
|
+
text: 'Tryck på mellanslagstangenten eller den stora knappen varje gång drönaren flyger igenom start/målporten.',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'Granska telemetri, deltatider och konsistens',
|
|
106
|
+
text: 'Analysera stapeldiagrammet, jämför tider mot snabbaste varvet och exportera resultaten till CSV.',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const seoSections: SEOSection[] = [
|
|
111
|
+
{
|
|
112
|
+
type: 'title',
|
|
113
|
+
text: 'Principer för högprecisions tidtagning i FPV drönarracing',
|
|
114
|
+
level: 2,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'paragraph',
|
|
118
|
+
html: 'Tävlingar i FPV drönarracing ställer hårda krav på millisekundprecision och exakta flyglinjer. 5-tums multikopterdrönare når över 140 km/h mellan portar och flaggor. Målmedveten träning kräver akustisk start, snabb varvregistrering och analys av tempoförluster över flera heat.',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: 'title',
|
|
122
|
+
text: 'Jämförelse av racingklasser och tidtagningsparametrar',
|
|
123
|
+
level: 2,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'table',
|
|
127
|
+
headers: ['Klass / Specifikation', 'Typisk Banlängd', 'Varv per Heat', 'Genomsnittlig Varvtid', 'Toppfart', 'Rekommenderat Filter'],
|
|
128
|
+
rows: [
|
|
129
|
+
['Tiny Whoop (65mm 1S)', '50m till 80m', '5 varv', '8.5s till 13.0s', '35 till 55 km/h', '2.0 sekunder'],
|
|
130
|
+
['Micro 3.5 Tum (4S)', '120m till 180m', '4 varv', '12.0s till 18.0s', '70 till 110 km/h', '2.5 sekunder'],
|
|
131
|
+
['MultiGP Spec 5 Tum (6S)', '200m till 300m', '3 varv', '14.0s till 22.0s', '100 till 150 km/h', '3.0 sekunder'],
|
|
132
|
+
['Öppet Fältsprint (6S/8S)', '350m till 500m', '2 varv', '20.0s till 32.0s', '130 till 180 km/h', '4.0 sekunder'],
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
type: 'title',
|
|
137
|
+
text: 'Akustiska startsekvenser och FAI F9U tävlingsregler',
|
|
138
|
+
level: 2,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'paragraph',
|
|
142
|
+
html: 'Enligt FAI CIAM Sektion 4 för drönarracing inleds heat med standardiserade ljudsignaler istället för flaggor för att garantera rättvisa reaktionstider i videoglasögonen. Sekvensen innehåller 440 Hz toner med en sekunds mellanrum och avslutas med 880 Hz startton.',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'list',
|
|
146
|
+
items: [
|
|
147
|
+
'Förberedelsetoner: Ljudsignaler för att stabilisera gasreglaget och fokusera blicken på första svängen.',
|
|
148
|
+
'Startsignal (Go): Direkt startimpuls då tidtagningen startar exakt vid t = 0.',
|
|
149
|
+
'Akustisk bekräftelse: Ljudsignal som bekräftar varvet utan att man tappar fokus från FPV-bilden.',
|
|
150
|
+
'Varvrekord-signal: Harmonisk ton när det aktuella varvet slår sessionens tidigare bästa tid.',
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'title',
|
|
155
|
+
text: 'Varvkonsistens och racestrategi',
|
|
156
|
+
level: 2,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
type: 'paragraph',
|
|
160
|
+
html: 'Ett enskilt snabbt varv är imponerande, men mästerskap vinns på jämnhet. Indexet belyser avvikelser: en pilot med under 0.3 sekunders spridning minskar risken för turbulens och sparar batterispänning till slutspurten.',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'tip',
|
|
164
|
+
title: 'Praktiskt fälttips',
|
|
165
|
+
html: 'Placera surfplattan på bra volym nära pilotstolen. Använd en Bluetooth-fotpedal eller ett litet trådlöst tangentbord för att registrera varv med foten utan att släppa spakarna.',
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
const schemas: FpvDroneLapTimerLocaleContent['schemas'] = [
|
|
170
|
+
{
|
|
171
|
+
'@context': 'https://schema.org',
|
|
172
|
+
'@type': 'FAQPage',
|
|
173
|
+
mainEntity: faqItems.map((item) => ({
|
|
174
|
+
'@type': 'Question',
|
|
175
|
+
name: item.question,
|
|
176
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
177
|
+
})),
|
|
178
|
+
} as WithContext<FAQPage>,
|
|
179
|
+
{
|
|
180
|
+
'@context': 'https://schema.org',
|
|
181
|
+
'@type': 'HowTo',
|
|
182
|
+
name: title,
|
|
183
|
+
description,
|
|
184
|
+
step: howToSteps.map((s, index) => ({
|
|
185
|
+
'@type': 'HowToStep',
|
|
186
|
+
position: index + 1,
|
|
187
|
+
name: s.name,
|
|
188
|
+
text: s.text,
|
|
189
|
+
})),
|
|
190
|
+
} as WithContext<HowTo>,
|
|
191
|
+
{
|
|
192
|
+
'@context': 'https://schema.org',
|
|
193
|
+
'@type': 'SoftwareApplication',
|
|
194
|
+
name: title,
|
|
195
|
+
description,
|
|
196
|
+
applicationCategory: 'UtilityApplication',
|
|
197
|
+
operatingSystem: 'All',
|
|
198
|
+
offers: {
|
|
199
|
+
'@type': 'Offer',
|
|
200
|
+
price: '0',
|
|
201
|
+
priceCurrency: 'SEK',
|
|
202
|
+
},
|
|
203
|
+
} as WithContext<SoftwareApplication>,
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
export const content: FpvDroneLapTimerLocaleContent = {
|
|
207
|
+
slug,
|
|
208
|
+
title,
|
|
209
|
+
description,
|
|
210
|
+
ui,
|
|
211
|
+
seo: seoSections,
|
|
212
|
+
faq: faqItems,
|
|
213
|
+
howTo: howToSteps,
|
|
214
|
+
bibliography: BIBLIOGRAPHY_ITEMS,
|
|
215
|
+
schemas,
|
|
216
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { FpvDroneLapTimerLocaleContent } from '../entry';
|
|
2
|
+
import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
|
|
3
|
+
import type { SEOSection } from '../../../types';
|
|
4
|
+
import { BIBLIOGRAPHY_ITEMS } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'fpv-dron-yarisi-tur-kronometresi';
|
|
7
|
+
const title = 'FPV Dron Yarışı Tur ve Sektör Kronometresi';
|
|
8
|
+
const description = 'FPV dron yarışları için FAI sesli başlangıç dizisi, sektör farkı analizi, en hızlı tur uyarıları, tur tutarlılık endeksi ve hız telemetrisi içeren interaktif kronometre.';
|
|
9
|
+
|
|
10
|
+
const ui = {
|
|
11
|
+
setupHeading: 'Pist ve Seans Yapılandırması',
|
|
12
|
+
trackLengthLabel: 'Pist Uzunluğu',
|
|
13
|
+
trackLengthUnit: 'metre',
|
|
14
|
+
targetLapsLabel: 'Hedef Tur Sayısı',
|
|
15
|
+
targetLapsUnit: 'tur (0 serbest antrenman)',
|
|
16
|
+
batteryCapacityLabel: 'Batarya Kapasitesi',
|
|
17
|
+
batteryCapacityUnit: 'mAh',
|
|
18
|
+
soundEnabledLabel: 'Sesli Sinyalleri Etkinleştir',
|
|
19
|
+
debounceThresholdLabel: 'Yanlış Tetikleme Önleme Eşiği',
|
|
20
|
+
debounceThresholdUnit: 'saniye',
|
|
21
|
+
presetMultiGpLabel: 'MultiGP Özelliği (250m / 3 Tur)',
|
|
22
|
+
presetWhoopLabel: 'Tiny Whoop (65m / 5 Tur)',
|
|
23
|
+
presetSprintLabel: 'Yüksek Hızlı Sprint (400m / 2 Tur)',
|
|
24
|
+
startCountdownButton: 'FAI Geri Sayımını Başlat',
|
|
25
|
+
pauseTimerButton: 'Seansı Duraklat',
|
|
26
|
+
resumeTimerButton: 'Zamanlayıcıyı Sürdür',
|
|
27
|
+
resetTimerButton: 'Seansı Sıfırla',
|
|
28
|
+
recordLapButton: 'TURU KAYDET',
|
|
29
|
+
spacebarHint: 'Bitiş kapısından geçerken BOŞLUK tuşuna basın veya dev butona dokunun',
|
|
30
|
+
statusIdle: 'Çıkışa Hazır',
|
|
31
|
+
statusCountdown: 'FAI Geri Sayımı Sürüyor',
|
|
32
|
+
statusRunning: 'Yarış Kronometresi Aktif',
|
|
33
|
+
statusPaused: 'Seans Duraklatıldı',
|
|
34
|
+
statusFinished: 'Yarış Tamamlandı',
|
|
35
|
+
currentLapHeading: 'Geçerli Tur Süresi',
|
|
36
|
+
lapNumberPrefix: 'Tur',
|
|
37
|
+
lastLapHeading: 'Son Tur',
|
|
38
|
+
fastestLapHeading: 'En Hızlı Tur',
|
|
39
|
+
averageLapHeading: 'Ortalama Tur',
|
|
40
|
+
deltaBestHeading: 'En İyiye Göre Fark',
|
|
41
|
+
consistencyIndexHeading: 'Tur Tutarlılık Endeksi',
|
|
42
|
+
estimatedSpeedHeading: 'Tahmini Ortalama Hız',
|
|
43
|
+
estimatedBatteryHeading: 'Tahmini Batarya Tüketimi',
|
|
44
|
+
speedUnitKmh: 'km/s',
|
|
45
|
+
speedUnitMph: 'mil/s',
|
|
46
|
+
batteryUsedUnit: 'mAh',
|
|
47
|
+
batteryRemainingUnit: 'mAh kalan',
|
|
48
|
+
lapHistoryHeading: 'Tur Zamanları ve Tempo Kıyaslaması',
|
|
49
|
+
lapColumnHeader: 'Tur #',
|
|
50
|
+
timeColumnHeader: 'Süre',
|
|
51
|
+
splitColumnHeader: 'En İyi Farkı',
|
|
52
|
+
speedColumnHeader: 'Ort. Hız',
|
|
53
|
+
batteryColumnHeader: 'Batarya Tüketimi',
|
|
54
|
+
noLapsRecordedNotice: 'Henüz tur kaydedilmedi. Geri sayımı başlatın ve ilk turu kaydetmek için Boşluk tuşuna basın.',
|
|
55
|
+
consistencyRatingElite: 'Seçkin Tutarlılık',
|
|
56
|
+
consistencyRatingPro: 'Profesyonel Pilot Tutarlılığı',
|
|
57
|
+
consistencyRatingClub: 'Kulüp Pilotu Tutarlılığı',
|
|
58
|
+
consistencyRatingNovice: 'Gelişme Düzeyi Tutarlılık',
|
|
59
|
+
fastestLapBadge: 'EN HIZLI TUR',
|
|
60
|
+
sessionSummaryHeading: 'Seans Özeti ve Dışa Aktarma',
|
|
61
|
+
totalTimeLabel: 'Toplam Yarış Süresi',
|
|
62
|
+
completedLapsLabel: 'Tamamlanan Tur',
|
|
63
|
+
exportCsvButton: 'Turları CSV Olarak Aktar',
|
|
64
|
+
copySummaryButton: 'Metin Özetini Kopyala',
|
|
65
|
+
copiedNotice: 'Seans özeti panoya kopyalandı!',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const faqItems = [
|
|
69
|
+
{
|
|
70
|
+
question: 'Bu kronometredeki FAI akustik başlangıç dizisi nasıl çalışır?',
|
|
71
|
+
answer: 'Başlangıç dizisi, Uluslararası Havacılık Federasyonu (FAI) CIAM F9U dron yarış kurallarını birebir uygular. Birer saniye aralıklarla çalan dört uyarı tonunun ardından yüksek frekanslı start tonu verilir ve kronometre tam sıfırdan başlar.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
question: 'Tur Tutarlılık Endeksi nasıl hesaplanır?',
|
|
75
|
+
answer: 'Puanlama, tamamlanan turların seans ortalamasına göre standart sapmasını değerlendirir. Yüzde 95 üzerindeki değerler olağanüstü hat tutarlılığı ve gaz kontrolü anlamına gelir.',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
question: 'Tur kaydı için ayak pedalı veya kumanda anahtarı kullanılabilir mi?',
|
|
79
|
+
answer: 'Evet. Boşluk tuşu sinyali gönderen herhangi bir kablosuz klavye, Bluetooth ayak pedalı veya gamepad düğmesi ekrana dokunmaya gerek kalmadan turu kaydeder.',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
question: 'Tur butonunda neden bir önleme eşiği bulunuyor?',
|
|
83
|
+
answer: 'Dron kapıları yüksek hızla geçilir ancak yanlışlıkla iki kez dokunulması hatalı salise turları kaydedebilir. Filtre, belirlenen sürenin (varsayılan 3 saniye) altındaki tetiklemeleri reddeder.',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
question: 'Tahmini ortalama hız ne kadar doğrudur?',
|
|
87
|
+
answer: 'Hesaplama, pistin beyan edilen merkez hat uzunluğunun tur süresine bölünmesiyle yapılır. Virajlardaki gerçek hız dönüş yarıçapına ve yatış açısına göre farklılık gösterir.',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
const howToSteps = [
|
|
92
|
+
{
|
|
93
|
+
name: 'Pist mesafesini ve tur hedefini belirleyin',
|
|
94
|
+
text: 'Pist uzunluğunu metre cinsinden ve tur hedefini girin veya MultiGP Spec gibi bir hazır ayar seçin.',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'FAI sesli geri sayımını başlatın',
|
|
98
|
+
text: 'Geri sayımı başlat düğmesine basın. Hazırlık tonlarını ve kalkış start sinyalini dinleyin.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'Bitiş kapısından geçerken turları kaydedin',
|
|
102
|
+
text: 'Dron başlangıç/bitiş kapısını her aştığında Boşluk tuşuna veya büyük butona basın.',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'Telemetriyi, farkları ve tutarlılığı inceleyin',
|
|
106
|
+
text: 'Tempo çubuk grafiğini, en iyi tura göre farkları ve tutarlılık endeksini analiz edip CSV çıktısı alın.',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const seoSections: SEOSection[] = [
|
|
111
|
+
{
|
|
112
|
+
type: 'title',
|
|
113
|
+
text: 'FPV yarış dronlarında yüksek hassasiyetli tur zamanlaması ilkeleri',
|
|
114
|
+
level: 2,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'paragraph',
|
|
118
|
+
html: 'Rekabetçi FPV yarışlarında milisaniye düzeyinde hassasiyet ve sarsılmaz hat istikrarı gerekir. 5 inçlik yarış dronları engeller arasında 140 km/s hızın üzerine çıkar. Doğru antrenman, sesli kalkış bildirimleri, anlık kapı geçiş kaydı ve seans temposundaki gerilemelerin analizini zorunlu kılar.',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: 'title',
|
|
122
|
+
text: 'Dron yarış sınıfları ve zamanlama parametreleri karşılaştırması',
|
|
123
|
+
level: 2,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'table',
|
|
127
|
+
headers: ['Sınıf / Standart', 'Tipik Pist Boyu', 'Yarış Tur Sayısı', 'Ortalama Tur Süresi', 'Azami Hız', 'Önerilen Eşik'],
|
|
128
|
+
rows: [
|
|
129
|
+
['Tiny Whoop (65mm 1S)', '50m - 80m', '5 tur', '8.5s - 13.0s', '35 - 55 km/s', '2.0 saniye'],
|
|
130
|
+
['Micro 3.5 İnç (4S)', '120m - 180m', '4 tur', '12.0s - 18.0s', '70 - 110 km/s', '2.5 saniye'],
|
|
131
|
+
['MultiGP Spec 5 İnç (6S)', '200m - 300m', '3 tur', '14.0s - 22.0s', '100 - 150 km/s', '3.0 saniye'],
|
|
132
|
+
['Açık Arazi Sprinti (6S/8S)', '350m - 500m', '2 tur', '20.0s - 32.0s', '130 - 180 km/s', '4.0 saniye'],
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
type: 'title',
|
|
137
|
+
text: 'Akustik başlangıç dizileri ve FAI F9U spor kuralları',
|
|
138
|
+
level: 2,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'paragraph',
|
|
142
|
+
html: 'FAI CIAM Bölüm 4 kuralları gereğince, FPV gözlükleri takan pilotlar arasında eşit tepki süresi sağlamak amacıyla görsel bayraklar yerine standart ses tonları kullanılır. Dizi, saniyede bir verilen 440 Hz tonlar ve kalkış anını belirten 880 Hz ton ile tamamlanır.',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'list',
|
|
146
|
+
items: [
|
|
147
|
+
'Hazırlık Tonları: Gaz kolunu sabitlemek ve ilk viraja odaklanmak için sesli uyarılar.',
|
|
148
|
+
'Kalkış Sinyali (Go): Kronometrenin tam t = 0 anında çalışmasını sağlayan anlık ton.',
|
|
149
|
+
'Sesli Onay: Gözlüğü çıkarmadan turun kaydedildiğini doğrulayan net bildirim sesi.',
|
|
150
|
+
'Rekor Tur Akordu: Seansın en hızlı turu aşıldığında çalan özel armonik ton.',
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'title',
|
|
155
|
+
text: 'Tur Tutarlılık Endeksinin önemi ve yarış taktiği',
|
|
156
|
+
level: 2,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
type: 'paragraph',
|
|
160
|
+
html: 'Tek bir rekor tur atmak heyecan vericidir ancak şampiyonlukları tutarlılık kazandırır. Endeks, turlar arasındaki dalgalanmayı ölçer: 0.3 saniyeden az sapan bir pilot türbülanstan kaçınır ve batarya voltajını son tura saklar.',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'tip',
|
|
164
|
+
title: 'Uçuş sahası için pratik ipucu',
|
|
165
|
+
html: 'Kronometre cihazınızı duyulabilir bir ses düzeyinde yakınınızda bulundurun. Ayak altına yerleştirilen bir Bluetooth pedal ile ellerinizi kumandadan çekmeden turları kolayca kaydedebilirsiniz.',
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
const schemas: FpvDroneLapTimerLocaleContent['schemas'] = [
|
|
170
|
+
{
|
|
171
|
+
'@context': 'https://schema.org',
|
|
172
|
+
'@type': 'FAQPage',
|
|
173
|
+
mainEntity: faqItems.map((item) => ({
|
|
174
|
+
'@type': 'Question',
|
|
175
|
+
name: item.question,
|
|
176
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
177
|
+
})),
|
|
178
|
+
} as WithContext<FAQPage>,
|
|
179
|
+
{
|
|
180
|
+
'@context': 'https://schema.org',
|
|
181
|
+
'@type': 'HowTo',
|
|
182
|
+
name: title,
|
|
183
|
+
description,
|
|
184
|
+
step: howToSteps.map((s, index) => ({
|
|
185
|
+
'@type': 'HowToStep',
|
|
186
|
+
position: index + 1,
|
|
187
|
+
name: s.name,
|
|
188
|
+
text: s.text,
|
|
189
|
+
})),
|
|
190
|
+
} as WithContext<HowTo>,
|
|
191
|
+
{
|
|
192
|
+
'@context': 'https://schema.org',
|
|
193
|
+
'@type': 'SoftwareApplication',
|
|
194
|
+
name: title,
|
|
195
|
+
description,
|
|
196
|
+
applicationCategory: 'UtilityApplication',
|
|
197
|
+
operatingSystem: 'All',
|
|
198
|
+
offers: {
|
|
199
|
+
'@type': 'Offer',
|
|
200
|
+
price: '0',
|
|
201
|
+
priceCurrency: 'TRY',
|
|
202
|
+
},
|
|
203
|
+
} as WithContext<SoftwareApplication>,
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
export const content: FpvDroneLapTimerLocaleContent = {
|
|
207
|
+
slug,
|
|
208
|
+
title,
|
|
209
|
+
description,
|
|
210
|
+
ui,
|
|
211
|
+
seo: seoSections,
|
|
212
|
+
faq: faqItems,
|
|
213
|
+
howTo: howToSteps,
|
|
214
|
+
bibliography: BIBLIOGRAPHY_ITEMS,
|
|
215
|
+
schemas,
|
|
216
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { FpvDroneLapTimerLocaleContent } from '../entry';
|
|
2
|
+
import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
|
|
3
|
+
import type { SEOSection } from '../../../types';
|
|
4
|
+
import { BIBLIOGRAPHY_ITEMS } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'fpv-drone-lap-timer';
|
|
7
|
+
const title = 'FPV无人机竞速圈速与分段计时器';
|
|
8
|
+
const description = '适用于FPV穿越机竞速的交互式计时器,支持FAI声学发车倒计时、分段差值比对、最快圈速提醒、圈速一致性指数与速度遥测。';
|
|
9
|
+
|
|
10
|
+
const ui = {
|
|
11
|
+
setupHeading: '赛道与比赛设置',
|
|
12
|
+
trackLengthLabel: '赛道单圈长度',
|
|
13
|
+
trackLengthUnit: '米',
|
|
14
|
+
targetLapsLabel: '目标圈数',
|
|
15
|
+
targetLapsUnit: '圈 (设为0进行自由练习)',
|
|
16
|
+
batteryCapacityLabel: '电池组容量',
|
|
17
|
+
batteryCapacityUnit: 'mAh',
|
|
18
|
+
soundEnabledLabel: '启用声学提示音',
|
|
19
|
+
debounceThresholdLabel: '防重触发屏蔽时间',
|
|
20
|
+
debounceThresholdUnit: '秒',
|
|
21
|
+
presetMultiGpLabel: 'MultiGP标准赛道 (250米 / 3圈)',
|
|
22
|
+
presetWhoopLabel: 'Tiny Whoop微型穿越机 (65米 / 5圈)',
|
|
23
|
+
presetSprintLabel: '高速直线冲刺 (400米 / 2圈)',
|
|
24
|
+
startCountdownButton: '启动FAI倒计时',
|
|
25
|
+
pauseTimerButton: '暂停比赛',
|
|
26
|
+
resumeTimerButton: '继续计时',
|
|
27
|
+
resetTimerButton: '重置赛局',
|
|
28
|
+
recordLapButton: '记录圈速',
|
|
29
|
+
spacebarHint: '穿越终点龙门架时按下空格键或点击巨大按钮记录',
|
|
30
|
+
statusIdle: '准备起飞',
|
|
31
|
+
statusCountdown: 'FAI倒计时进行中',
|
|
32
|
+
statusRunning: '比赛计时进行中',
|
|
33
|
+
statusPaused: '已暂停',
|
|
34
|
+
statusFinished: '比赛完成',
|
|
35
|
+
currentLapHeading: '当前圈用时',
|
|
36
|
+
lapNumberPrefix: '第',
|
|
37
|
+
lastLapHeading: '上一圈',
|
|
38
|
+
fastestLapHeading: '最快单圈',
|
|
39
|
+
averageLapHeading: '平均单圈',
|
|
40
|
+
deltaBestHeading: '与最快圈差距',
|
|
41
|
+
consistencyIndexHeading: '圈速一致性指数',
|
|
42
|
+
estimatedSpeedHeading: '预估平均时速',
|
|
43
|
+
estimatedBatteryHeading: '预估电量消耗',
|
|
44
|
+
speedUnitKmh: 'km/h',
|
|
45
|
+
speedUnitMph: 'mph',
|
|
46
|
+
batteryUsedUnit: 'mAh',
|
|
47
|
+
batteryRemainingUnit: 'mAh 剩余',
|
|
48
|
+
lapHistoryHeading: '圈速记录与配速分析',
|
|
49
|
+
lapColumnHeader: '圈数 #',
|
|
50
|
+
timeColumnHeader: '用时',
|
|
51
|
+
splitColumnHeader: '最快圈差距',
|
|
52
|
+
speedColumnHeader: '平均速度',
|
|
53
|
+
batteryColumnHeader: '电池消耗',
|
|
54
|
+
noLapsRecordedNotice: '暂无圈速记录。启动倒计时并在每次通过终点时按下空格键。',
|
|
55
|
+
consistencyRatingElite: '顶级一致性',
|
|
56
|
+
consistencyRatingPro: '职业飞手一致性',
|
|
57
|
+
consistencyRatingClub: '俱乐部选手一致性',
|
|
58
|
+
consistencyRatingNovice: '练习阶段一致性',
|
|
59
|
+
fastestLapBadge: '最快圈',
|
|
60
|
+
sessionSummaryHeading: '赛局总结与导出',
|
|
61
|
+
totalTimeLabel: '比赛总用时',
|
|
62
|
+
completedLapsLabel: '已完成圈数',
|
|
63
|
+
exportCsvButton: '导出圈速数据为CSV',
|
|
64
|
+
copySummaryButton: '复制文本摘要',
|
|
65
|
+
copiedNotice: '赛局摘要已复制到剪贴板!',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const faqItems = [
|
|
69
|
+
{
|
|
70
|
+
question: '本计时器中的FAI声学发车流程如何运作?',
|
|
71
|
+
answer: '发车流程完全遵循国际航空运动联合会(FAI)CIAM F9U无人机竞速官方竞赛规则。先以一秒为间隔发出四声准备提示音,随后发出高频起飞蜂鸣,计时器在极准的零时刻同步启动。',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
question: '圈速一致性指数是如何计算的?',
|
|
75
|
+
answer: '该指数通过计算已完成圈速相对于赛局平均圈速的标准差得出。得分超过95%表明飞手具备极致精准的走线轨迹控制与细腻的油门管理。',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
question: '可以使用脚踏板或遥控器开关打圈吗?',
|
|
79
|
+
answer: '可以。任何能够发送空格键信号的无线键盘、蓝牙脚踏开关或遥控器按键映射,都可以在无需注视或触摸屏幕的情况下瞬间记录圈速。',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
question: '为什么记录圈速需要设置防重触发屏蔽?',
|
|
83
|
+
answer: '无人机穿越龙门架时速度极高,但不经意的双击或按键机械抖动可能误记毫秒级的虚假圈速。防重触发器会自动忽略短于预设时间(默认3秒)的重复触发。',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
question: '预估的平均飞行时速准确吗?',
|
|
87
|
+
answer: '速度根据赛道中心线长度除以圈速计算得出。弯道中的实际飞行速度会根据走线半径和无人机的横滚倾斜角有所浮动。',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
const howToSteps = [
|
|
92
|
+
{
|
|
93
|
+
name: '配置赛道距离与比赛圈数',
|
|
94
|
+
text: '输入赛道单圈米数和目标圈数,或选择MultiGP等现成预设。',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: '启动FAI声学发车倒计时',
|
|
98
|
+
text: '点击启动倒计时,聆听预备提示音并在发车高频音响起时油门全开。',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: '穿越终点龙门架时记录圈速',
|
|
102
|
+
text: '每次无人机穿过起终点龙门架时按下空格键或点击屏幕按钮。',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: '分析遥测数据、分段与一致性',
|
|
106
|
+
text: '查看配速对比柱状图、与最快圈差距及一致性评分,并将数据导出为CSV。',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const seoSections: SEOSection[] = [
|
|
111
|
+
{
|
|
112
|
+
type: 'title',
|
|
113
|
+
text: 'FPV多旋翼无人机竞速中的高精度圈速测量准则',
|
|
114
|
+
level: 2,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'paragraph',
|
|
118
|
+
html: '专业FPV穿越机竞速对毫秒级计时与精准走线有着严苛要求。5英寸竞速机飞行时速超过140公里,穿梭于三维龙门架与障碍旗门之间。高水平训练必须依靠标准化的发车声学信号、瞬时过门记录以及多圈比赛中配速衰减的科学分析。',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: 'title',
|
|
122
|
+
text: '各类穿越机竞速组别与计时核心参数对比',
|
|
123
|
+
level: 2,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'table',
|
|
127
|
+
headers: ['竞赛规格 / 组别', '常见赛道单圈长度', '单轮圈数', '平均圈速范围', '最高时速区间', '建议防抖时间'],
|
|
128
|
+
rows: [
|
|
129
|
+
['Tiny Whoop微型机 (65mm 1S)', '50米 - 80米', '5圈', '8.5秒 - 13.0秒', '35 - 55 km/h', '2.0秒'],
|
|
130
|
+
['Micro小轴距机 (3.5英寸 4S)', '120米 - 180米', '4圈', '12.0秒 - 18.0秒', '70 - 110 km/h', '2.5秒'],
|
|
131
|
+
['MultiGP 5英寸主流赛机 (6S)', '200米 - 300米', '3圈', '14.0秒 - 22.0秒', '100 - 150 km/h', '3.0秒'],
|
|
132
|
+
['开阔场地冲刺赛 (6S/8S)', '350米 - 500米', '2圈', '20.0秒 - 32.0秒', '130 - 180 km/h', '4.0秒'],
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
type: 'title',
|
|
137
|
+
text: '发车声学信号规则与FAI F9U竞技准则',
|
|
138
|
+
level: 2,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'paragraph',
|
|
142
|
+
html: '根据国际航空运动联合会(FAI)CIAM Section 4关于无人机竞速的规则,比赛采用标准化音频信号而非视觉旗帜启动发车,以确保佩戴FPV飞行眼镜的选手拥有平等的反应时间。音响序列包含间隔1秒的440Hz提示音与起飞时的880Hz鸣响。',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'list',
|
|
146
|
+
items: [
|
|
147
|
+
'预备提示音:飞手稳定初始油门并注视第一个拐角进气流的听觉准备信号。',
|
|
148
|
+
'发车音 (Go):发车瞬间信号,比赛计时从t = 0开始极速流转。',
|
|
149
|
+
'过门确认音:清晰的声响回馈让飞手无需将视线移出FPV画面即可确知圈速已入库。',
|
|
150
|
+
'破纪录和弦音:当前圈速刷新本局最快成绩时触发的特殊提示音。',
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'title',
|
|
155
|
+
text: '圈速一致性指数与竞速战术把控',
|
|
156
|
+
level: 2,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
type: 'paragraph',
|
|
160
|
+
html: '单圈极速固然亮眼,但冠军往往属于走线稳定的选手。一致性指数直观展现波动幅度:圈速差距维持在0.3秒以内的飞手能有效避免气流翻滚干扰,并为最后一圈冲刺储备电池放电电压。',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'tip',
|
|
164
|
+
title: '飞行场地实战技巧',
|
|
165
|
+
html: '将计时平板或手机置于飞手席旁并开大音量。在地面脚边放置蓝牙脚踏开关,无需松开遥控器摇杆,每圈飞过终点时用脚轻踩即可从容打圈。',
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
const schemas: FpvDroneLapTimerLocaleContent['schemas'] = [
|
|
170
|
+
{
|
|
171
|
+
'@context': 'https://schema.org',
|
|
172
|
+
'@type': 'FAQPage',
|
|
173
|
+
mainEntity: faqItems.map((item) => ({
|
|
174
|
+
'@type': 'Question',
|
|
175
|
+
name: item.question,
|
|
176
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
177
|
+
})),
|
|
178
|
+
} as WithContext<FAQPage>,
|
|
179
|
+
{
|
|
180
|
+
'@context': 'https://schema.org',
|
|
181
|
+
'@type': 'HowTo',
|
|
182
|
+
name: title,
|
|
183
|
+
description,
|
|
184
|
+
step: howToSteps.map((s, index) => ({
|
|
185
|
+
'@type': 'HowToStep',
|
|
186
|
+
position: index + 1,
|
|
187
|
+
name: s.name,
|
|
188
|
+
text: s.text,
|
|
189
|
+
})),
|
|
190
|
+
} as WithContext<HowTo>,
|
|
191
|
+
{
|
|
192
|
+
'@context': 'https://schema.org',
|
|
193
|
+
'@type': 'SoftwareApplication',
|
|
194
|
+
name: title,
|
|
195
|
+
description,
|
|
196
|
+
applicationCategory: 'UtilityApplication',
|
|
197
|
+
operatingSystem: 'All',
|
|
198
|
+
offers: {
|
|
199
|
+
'@type': 'Offer',
|
|
200
|
+
price: '0',
|
|
201
|
+
priceCurrency: 'CNY',
|
|
202
|
+
},
|
|
203
|
+
} as WithContext<SoftwareApplication>,
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
export const content: FpvDroneLapTimerLocaleContent = {
|
|
207
|
+
slug,
|
|
208
|
+
title,
|
|
209
|
+
description,
|
|
210
|
+
ui,
|
|
211
|
+
seo: seoSections,
|
|
212
|
+
faq: faqItems,
|
|
213
|
+
howTo: howToSteps,
|
|
214
|
+
bibliography: BIBLIOGRAPHY_ITEMS,
|
|
215
|
+
schemas,
|
|
216
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { fpvDroneLapTimer } from './entry';
|
|
2
|
+
import type { ToolDefinition } from '../../types';
|
|
3
|
+
export * from './entry';
|
|
4
|
+
|
|
5
|
+
export const FPV_DRONE_LAP_TIMER_TOOL: ToolDefinition = {
|
|
6
|
+
entry: fpvDroneLapTimer,
|
|
7
|
+
Component: () => import('./component.astro'),
|
|
8
|
+
SEOComponent: () => import('./seo.astro'),
|
|
9
|
+
BibliographyComponent: () => import('./bibliography.astro'),
|
|
10
|
+
};
|