step-overflow 0.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.
- package/LICENSE +21 -0
- package/README.ja.md +111 -0
- package/README.md +111 -0
- package/dist/cli.js +28 -0
- package/dist/commands/add.js +188 -0
- package/dist/commands/config.js +92 -0
- package/dist/commands/init.js +193 -0
- package/dist/commands/log.js +41 -0
- package/dist/commands/open.js +78 -0
- package/dist/commands/status.js +55 -0
- package/dist/commands/sync.js +25 -0
- package/dist/lib/achievements.js +322 -0
- package/dist/lib/animation.js +70 -0
- package/dist/lib/calories.js +32 -0
- package/dist/lib/config.js +38 -0
- package/dist/lib/csv.js +55 -0
- package/dist/lib/git.js +97 -0
- package/dist/lib/html.js +437 -0
- package/dist/lib/open-url.js +15 -0
- package/dist/lib/prompt.js +19 -0
- package/dist/lib/routes.js +348 -0
- package/package.json +51 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
export const ROUTES = [
|
|
2
|
+
{
|
|
3
|
+
id: "tmb",
|
|
4
|
+
name: "Tour du Mont Blanc",
|
|
5
|
+
description: "Circle the highest peak in the Alps through three countries in one spectacular loop",
|
|
6
|
+
from: "Chamonix",
|
|
7
|
+
to: "Chamonix",
|
|
8
|
+
total_km: 170,
|
|
9
|
+
emoji: "\u{26F7}\u{FE0F}",
|
|
10
|
+
difficulty: 1,
|
|
11
|
+
waypoints: [
|
|
12
|
+
{ name: "Chamonix", km: 0, description: "Alpine capital at the foot of Mont Blanc" },
|
|
13
|
+
{ name: "Les Houches", km: 8, description: "Gateway to the TMB" },
|
|
14
|
+
{ name: "Les Contamines", km: 25, description: "Quiet village in the Montjoie valley" },
|
|
15
|
+
{ name: "Col de la Croix du Bonhomme", km: 40, description: "First major Alpine pass" },
|
|
16
|
+
{ name: "Courmayeur", km: 65, description: "Italian side of Mont Blanc" },
|
|
17
|
+
{ name: "Rif. Bonatti", km: 80, description: "Panoramic hut facing the Grand Jorasses" },
|
|
18
|
+
{ name: "La Fouly", km: 100, description: "Welcome to Switzerland" },
|
|
19
|
+
{ name: "Champex-Lac", km: 115, description: "The little Canadian lake" },
|
|
20
|
+
{ name: "Col de la Forclaz", km: 130, description: "Swiss-French border pass" },
|
|
21
|
+
{ name: "Tr\u00E9-le-Champ", km: 150, description: "Final descent begins" },
|
|
22
|
+
{ name: "Chamonix", km: 170, description: "Full circle complete" },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "tokaido",
|
|
27
|
+
name: "Tokaido",
|
|
28
|
+
description: "Walk the ancient highway where samurai and merchants once traveled between two great cities",
|
|
29
|
+
from: "Tokyo",
|
|
30
|
+
to: "Osaka",
|
|
31
|
+
total_km: 495,
|
|
32
|
+
emoji: "\u{1F3EF}",
|
|
33
|
+
difficulty: 1,
|
|
34
|
+
waypoints: [
|
|
35
|
+
{ name: "Tokyo", km: 0, description: "Capital of Japan" },
|
|
36
|
+
{ name: "Yokohama", km: 28, description: "Japan's largest port city" },
|
|
37
|
+
{ name: "Odawara", km: 83, description: "Castle town, gateway to Hakone" },
|
|
38
|
+
{ name: "Atami", km: 105, description: "Famous hot spring resort" },
|
|
39
|
+
{ name: "Numazu", km: 130, description: "Gateway to Mt. Fuji views" },
|
|
40
|
+
{ name: "Shizuoka", km: 180, description: "City of tea and Mt. Fuji" },
|
|
41
|
+
{ name: "Hamamatsu", km: 257, description: "City of music and motorcycles" },
|
|
42
|
+
{ name: "Okazaki", km: 330, description: "Birthplace of Tokugawa Ieyasu" },
|
|
43
|
+
{ name: "Nagoya", km: 366, description: "Heart of Japan's industry" },
|
|
44
|
+
{ name: "Suzuka", km: 395, description: "Home of the F1 Grand Prix" },
|
|
45
|
+
{ name: "Kyoto", km: 476, description: "Ancient capital of Japan" },
|
|
46
|
+
{ name: "Osaka", km: 495, description: "Japan's kitchen" },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "nile_valley",
|
|
51
|
+
name: "Nile Valley",
|
|
52
|
+
description: "Walk upstream along the world's longest river through 5,000 years of civilization",
|
|
53
|
+
from: "Aswan",
|
|
54
|
+
to: "Cairo",
|
|
55
|
+
total_km: 1100,
|
|
56
|
+
emoji: "\u{1F3DB}\u{FE0F}",
|
|
57
|
+
difficulty: 2,
|
|
58
|
+
waypoints: [
|
|
59
|
+
{ name: "Aswan", km: 0, description: "Gateway to Nubia" },
|
|
60
|
+
{ name: "Kom Ombo", km: 50, description: "Temple of the crocodile god" },
|
|
61
|
+
{ name: "Edfu", km: 110, description: "Best-preserved temple in Egypt" },
|
|
62
|
+
{ name: "Luxor", km: 220, description: "World's greatest open-air museum" },
|
|
63
|
+
{ name: "Qena", km: 280, description: "Gateway to the Valley of the Kings" },
|
|
64
|
+
{ name: "Abydos", km: 380, description: "Sacred burial ground of Osiris" },
|
|
65
|
+
{ name: "Sohag", km: 430, description: "Heart of Upper Egypt" },
|
|
66
|
+
{ name: "Asyut", km: 550, description: "Ancient crossroads of the Nile" },
|
|
67
|
+
{ name: "Minya", km: 700, description: "Gateway to Amarna" },
|
|
68
|
+
{ name: "Beni Suef", km: 850, description: "Edge of the Fayoum oasis" },
|
|
69
|
+
{ name: "Giza", km: 1050, description: "Home of the Great Pyramids" },
|
|
70
|
+
{ name: "Cairo", km: 1100, description: "City of a thousand minarets" },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "hannibal",
|
|
75
|
+
name: "Hannibal's March",
|
|
76
|
+
description: "March with elephants from Iberia across the Alps to challenge the Roman Republic",
|
|
77
|
+
from: "Cartagena",
|
|
78
|
+
to: "Rome",
|
|
79
|
+
total_km: 1500,
|
|
80
|
+
emoji: "\u{1F418}",
|
|
81
|
+
difficulty: 2,
|
|
82
|
+
waypoints: [
|
|
83
|
+
{ name: "Cartagena", km: 0, description: "Carthaginian stronghold in Iberia" },
|
|
84
|
+
{ name: "Valencia", km: 250, description: "City on the Mediterranean coast" },
|
|
85
|
+
{ name: "Barcelona", km: 500, description: "Gateway to the Pyrenees" },
|
|
86
|
+
{ name: "Perpignan", km: 650, description: "Last stop before Gaul" },
|
|
87
|
+
{ name: "Narbonne", km: 750, description: "Roman crossroads of Gaul" },
|
|
88
|
+
{ name: "N\u00EEmes", km: 900, description: "Rome of France" },
|
|
89
|
+
{ name: "Avignon", km: 950, description: "City of Popes" },
|
|
90
|
+
{ name: "Gap", km: 1050, description: "Foothills of the Alps" },
|
|
91
|
+
{ name: "Turin", km: 1200, description: "First city beyond the Alps" },
|
|
92
|
+
{ name: "Piacenza", km: 1350, description: "Crossing the Po Valley" },
|
|
93
|
+
{ name: "Rome", km: 1500, description: "Heart of the Roman Republic" },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: "via_francigena",
|
|
98
|
+
name: "Via Francigena",
|
|
99
|
+
description: "Walk the medieval pilgrimage from Canterbury Cathedral across the Alps to the Eternal City",
|
|
100
|
+
from: "Canterbury",
|
|
101
|
+
to: "Rome",
|
|
102
|
+
total_km: 1900,
|
|
103
|
+
emoji: "\u26EA",
|
|
104
|
+
difficulty: 3,
|
|
105
|
+
waypoints: [
|
|
106
|
+
{ name: "Canterbury", km: 0, description: "Where the pilgrimage begins" },
|
|
107
|
+
{ name: "Calais", km: 130, description: "Gateway to the continent" },
|
|
108
|
+
{ name: "Reims", km: 350, description: "City of coronations" },
|
|
109
|
+
{ name: "Besan\u00E7on", km: 650, description: "Gateway to the Jura" },
|
|
110
|
+
{ name: "Lausanne", km: 800, description: "Pearl of Lake Geneva" },
|
|
111
|
+
{ name: "Great St Bernard Pass", km: 900, description: "Alpine crossing" },
|
|
112
|
+
{ name: "Aosta", km: 950, description: "Roman gateway to Italy" },
|
|
113
|
+
{ name: "Pavia", km: 1150, description: "Medieval capital of Lombardy" },
|
|
114
|
+
{ name: "Lucca", km: 1400, description: "City of 100 churches" },
|
|
115
|
+
{ name: "Siena", km: 1550, description: "Heart of Tuscany" },
|
|
116
|
+
{ name: "Bolsena", km: 1700, description: "City of the miracle" },
|
|
117
|
+
{ name: "Rome", km: 1900, description: "The Eternal City" },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "camino",
|
|
122
|
+
name: "Camino de Santiago",
|
|
123
|
+
description: "Follow the ancient pilgrimage from Lisbon through port wine country to the sacred cathedral",
|
|
124
|
+
from: "Lisbon",
|
|
125
|
+
to: "Santiago de Compostela",
|
|
126
|
+
total_km: 620,
|
|
127
|
+
emoji: "\u{1F54A}\u{FE0F}",
|
|
128
|
+
difficulty: 2,
|
|
129
|
+
waypoints: [
|
|
130
|
+
{ name: "Lisbon", km: 0, description: "Capital of Portugal" },
|
|
131
|
+
{ name: "Santar\u00E9m", km: 78, description: "Gothic architecture capital" },
|
|
132
|
+
{ name: "Tomar", km: 120, description: "City of the Knights Templar" },
|
|
133
|
+
{ name: "Coimbra", km: 200, description: "Oldest university in Portugal" },
|
|
134
|
+
{ name: "Aveiro", km: 260, description: "Venice of Portugal" },
|
|
135
|
+
{ name: "Porto", km: 310, description: "Home of port wine, UNESCO World Heritage" },
|
|
136
|
+
{ name: "Barcelos", km: 370, description: "City of the Rooster" },
|
|
137
|
+
{ name: "Ponte de Lima", km: 400, description: "Oldest town in Portugal" },
|
|
138
|
+
{ name: "Valen\u00E7a", km: 430, description: "Fortress on the Spanish border" },
|
|
139
|
+
{ name: "Pontevedra", km: 490, description: "Pedestrian-friendly city of Galicia" },
|
|
140
|
+
{ name: "Santiago de Compostela", km: 620, description: "End of the Camino" },
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: "route66",
|
|
145
|
+
name: "Route 66",
|
|
146
|
+
description: "Get your kicks on the Mother Road, from the Windy City to the California coast",
|
|
147
|
+
from: "Chicago",
|
|
148
|
+
to: "Los Angeles",
|
|
149
|
+
total_km: 3940,
|
|
150
|
+
emoji: "\u{1F1FA}\u{1F1F8}",
|
|
151
|
+
difficulty: 3,
|
|
152
|
+
waypoints: [
|
|
153
|
+
{ name: "Chicago", km: 0, description: "The Windy City" },
|
|
154
|
+
{ name: "Bloomington", km: 200, description: "Crossroads of middle America" },
|
|
155
|
+
{ name: "Springfield", km: 320, description: "Lincoln's hometown" },
|
|
156
|
+
{ name: "St. Louis", km: 480, description: "Gateway to the West" },
|
|
157
|
+
{ name: "Joplin", km: 700, description: "Mining town on the Mother Road" },
|
|
158
|
+
{ name: "Tulsa", km: 910, description: "Art Deco capital" },
|
|
159
|
+
{ name: "Oklahoma City", km: 1290, description: "2025 NBA Champion" },
|
|
160
|
+
{ name: "Amarillo", km: 1730, description: "Home of Cadillac Ranch" },
|
|
161
|
+
{ name: "Tucumcari", km: 1900, description: "Tucumcari Tonite!" },
|
|
162
|
+
{ name: "Santa Fe", km: 2050, description: "Art capital of the Southwest" },
|
|
163
|
+
{ name: "Gallup", km: 2530, description: "Heart of Native American culture" },
|
|
164
|
+
{ name: "Winslow", km: 2700, description: "Standin' on the Corner" },
|
|
165
|
+
{ name: "Flagstaff", km: 2900, description: "Gateway to the Grand Canyon" },
|
|
166
|
+
{ name: "Kingman", km: 3120, description: "Heart of Historic Route 66" },
|
|
167
|
+
{ name: "Needles", km: 3300, description: "Hottest town on Route 66" },
|
|
168
|
+
{ name: "Barstow", km: 3500, description: "Desert crossroads" },
|
|
169
|
+
{ name: "San Bernardino", km: 3750, description: "Gateway to Southern California" },
|
|
170
|
+
{ name: "Los Angeles", km: 3940, description: "City of Angels" },
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: "trans_sahara",
|
|
175
|
+
name: "Trans-Saharan Trade Route",
|
|
176
|
+
description: "Cross the greatest desert on Earth with the caravans that traded gold for salt",
|
|
177
|
+
from: "Timbuktu",
|
|
178
|
+
to: "Marrakech",
|
|
179
|
+
total_km: 2200,
|
|
180
|
+
emoji: "\u{1F3DC}\u{FE0F}",
|
|
181
|
+
difficulty: 3,
|
|
182
|
+
waypoints: [
|
|
183
|
+
{ name: "Timbuktu", km: 0, description: "City of 333 saints" },
|
|
184
|
+
{ name: "Oualata", km: 500, description: "Ancient gateway to the Sahara" },
|
|
185
|
+
{ name: "Taghaza", km: 1200, description: "Salt mines of the desert" },
|
|
186
|
+
{ name: "Sijilmasa", km: 1800, description: "Oasis terminus of the caravan route" },
|
|
187
|
+
{ name: "Marrakech", km: 2200, description: "Red city of Morocco" },
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "qhapaq_nan",
|
|
192
|
+
name: "Qhapaq \u00D1an",
|
|
193
|
+
description: "Walk the Royal Road of the Incas through mountain passes and imperial way stations",
|
|
194
|
+
from: "Quito",
|
|
195
|
+
to: "Cusco",
|
|
196
|
+
total_km: 2500,
|
|
197
|
+
emoji: "\u{1F3D4}\u{FE0F}",
|
|
198
|
+
difficulty: 3,
|
|
199
|
+
waypoints: [
|
|
200
|
+
{ name: "Quito", km: 0, description: "Northern capital of the Inca Empire" },
|
|
201
|
+
{ name: "Riobamba", km: 200, description: "At the foot of Chimborazo" },
|
|
202
|
+
{ name: "Cuenca", km: 400, description: "UNESCO World Heritage colonial city" },
|
|
203
|
+
{ name: "Loja", km: 600, description: "Gateway between Andes and Amazon" },
|
|
204
|
+
{ name: "Cajamarca", km: 1000, description: "Where the Inca Empire fell" },
|
|
205
|
+
{ name: "Huamachuco", km: 1250, description: "Ancient highland citadel" },
|
|
206
|
+
{ name: "Hu\u00E1nuco Pampa", km: 1500, description: "Imperial way station" },
|
|
207
|
+
{ name: "Jauja", km: 1750, description: "First Spanish capital of Peru" },
|
|
208
|
+
{ name: "Ayacucho", km: 2000, description: "City of churches and battlefields" },
|
|
209
|
+
{ name: "Abancay", km: 2250, description: "Gateway to Cusco" },
|
|
210
|
+
{ name: "Cusco", km: 2500, description: "Navel of the Inca world" },
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: "spice_trader",
|
|
215
|
+
name: "Spice Route",
|
|
216
|
+
description: "Sail from the nutmeg islands through the spice archipelago to the gateway of world trade",
|
|
217
|
+
from: "Banda Neira",
|
|
218
|
+
to: "Singapore",
|
|
219
|
+
total_km: 3500,
|
|
220
|
+
emoji: "\u26F5",
|
|
221
|
+
difficulty: 3,
|
|
222
|
+
waypoints: [
|
|
223
|
+
{ name: "Banda Neira", km: 0, description: "Birthplace of the nutmeg trade" },
|
|
224
|
+
{ name: "Ambon", km: 200, description: "Clove island capital" },
|
|
225
|
+
{ name: "Makassar", km: 900, description: "Maritime crossroads of the archipelago" },
|
|
226
|
+
{ name: "Surabaya", km: 1200, description: "Indonesia's city of heroes" },
|
|
227
|
+
{ name: "Semarang", km: 1450, description: "Port of the Javanese north coast" },
|
|
228
|
+
{ name: "Batavia", km: 1700, description: "Heart of the Dutch East Indies" },
|
|
229
|
+
{ name: "Palembang", km: 2100, description: "Ancient capital of Srivijaya" },
|
|
230
|
+
{ name: "Malacca", km: 2600, description: "Gateway between two oceans" },
|
|
231
|
+
{ name: "Kuala Lumpur", km: 2800, description: "Capital of Malaysia" },
|
|
232
|
+
{ name: "Penang", km: 3000, description: "Pearl of the Orient" },
|
|
233
|
+
{ name: "Singapore", km: 3500, description: "The Lion City" },
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
id: "silk_road",
|
|
238
|
+
name: "Silk Road",
|
|
239
|
+
description: "Trace the legendary route where silk and ideas crossed deserts and oases to reach the Mediterranean",
|
|
240
|
+
from: "Xi'an",
|
|
241
|
+
to: "Constantinople",
|
|
242
|
+
total_km: 7000,
|
|
243
|
+
emoji: "\u{1F42B}",
|
|
244
|
+
difficulty: 4,
|
|
245
|
+
waypoints: [
|
|
246
|
+
{ name: "Xi'an", km: 0, description: "Ancient capital, start of the Silk Road" },
|
|
247
|
+
{ name: "Tianshui", km: 350, description: "Home of Maiji Mountain Grottoes" },
|
|
248
|
+
{ name: "Lanzhou", km: 650, description: "Gateway to the Hexi Corridor" },
|
|
249
|
+
{ name: "Zhangye", km: 950, description: "Rainbow Mountains of the Silk Road" },
|
|
250
|
+
{ name: "Jiayuguan", km: 1150, description: "Westernmost fortress of the Great Wall" },
|
|
251
|
+
{ name: "Dunhuang", km: 1500, description: "Oasis city of the Mogao Caves" },
|
|
252
|
+
{ name: "Hami", km: 1800, description: "Oasis of sweet melons" },
|
|
253
|
+
{ name: "Turpan", km: 2100, description: "Oasis below sea level in the Taklamakan" },
|
|
254
|
+
{ name: "Kucha", km: 2400, description: "Ancient Buddhist kingdom" },
|
|
255
|
+
{ name: "Kashgar", km: 2800, description: "Crossroads of Central Asia" },
|
|
256
|
+
{ name: "Osh", km: 3100, description: "Oldest city in Central Asia" },
|
|
257
|
+
{ name: "Fergana", km: 3400, description: "Heart of the fertile valley" },
|
|
258
|
+
{ name: "Samarkand", km: 3800, description: "Jewel of the Silk Road" },
|
|
259
|
+
{ name: "Bukhara", km: 4100, description: "City of scholars and merchants" },
|
|
260
|
+
{ name: "Turkmenabat", km: 4400, description: "Crossroads of Turkmenistan" },
|
|
261
|
+
{ name: "Merv", km: 4700, description: "Once the world's largest city" },
|
|
262
|
+
{ name: "Mashhad", km: 5100, description: "Iran's holiest city" },
|
|
263
|
+
{ name: "Tehran", km: 5400, description: "Capital of Iran" },
|
|
264
|
+
{ name: "Tabriz", km: 5800, description: "Gateway to the Persian highlands" },
|
|
265
|
+
{ name: "Erzurum", km: 6200, description: "Fortress of eastern Anatolia" },
|
|
266
|
+
{ name: "Konya", km: 6600, description: "City of the Whirling Dervishes" },
|
|
267
|
+
{ name: "Constantinople", km: 7000, description: "Where East meets West" },
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "around",
|
|
272
|
+
name: "Around the World",
|
|
273
|
+
description: "Circle the entire globe, crossing every continent and ocean along the way",
|
|
274
|
+
from: "London",
|
|
275
|
+
to: "London",
|
|
276
|
+
total_km: 40075,
|
|
277
|
+
emoji: "\u{1F30D}",
|
|
278
|
+
difficulty: 5,
|
|
279
|
+
waypoints: [
|
|
280
|
+
{ name: "London", km: 0, description: "Capital of the United Kingdom" },
|
|
281
|
+
{ name: "Paris", km: 500, description: "City of Light" },
|
|
282
|
+
{ name: "Brussels", km: 700, description: "Capital of the European Union" },
|
|
283
|
+
{ name: "Berlin", km: 1400, description: "Capital of Germany" },
|
|
284
|
+
{ name: "Warsaw", km: 1800, description: "Capital of Poland" },
|
|
285
|
+
{ name: "Budapest", km: 2100, description: "Pearl of the Danube" },
|
|
286
|
+
{ name: "Istanbul", km: 2500, description: "Where Europe meets Asia" },
|
|
287
|
+
{ name: "Cairo", km: 3500, description: "City of the Pyramids" },
|
|
288
|
+
{ name: "Riyadh", km: 4300, description: "Capital of Saudi Arabia" },
|
|
289
|
+
{ name: "Dubai", km: 5000, description: "City of the Future" },
|
|
290
|
+
{ name: "Karachi", km: 5500, description: "Pakistan's port metropolis" },
|
|
291
|
+
{ name: "Delhi", km: 6000, description: "Capital of India" },
|
|
292
|
+
{ name: "Mumbai", km: 7000, description: "Bollywood capital" },
|
|
293
|
+
{ name: "Hyderabad", km: 7800, description: "City of pearls" },
|
|
294
|
+
{ name: "Kolkata", km: 8800, description: "City of Joy" },
|
|
295
|
+
{ name: "Dhaka", km: 9300, description: "Capital of Bangladesh" },
|
|
296
|
+
{ name: "Yangon", km: 10000, description: "City of the golden pagoda" },
|
|
297
|
+
{ name: "Bangkok", km: 11000, description: "City of Angels" },
|
|
298
|
+
{ name: "Kuala Lumpur", km: 12000, description: "Capital of Malaysia" },
|
|
299
|
+
{ name: "Singapore", km: 12500, description: "The Lion City" },
|
|
300
|
+
{ name: "Ho Chi Minh City", km: 13000, description: "Vietnam's vibrant heart" },
|
|
301
|
+
{ name: "Hong Kong", km: 13500, description: "Pearl of the Orient" },
|
|
302
|
+
{ name: "Shanghai", km: 14200, description: "China's largest city" },
|
|
303
|
+
{ name: "Tokyo", km: 15000, description: "Capital of Japan" },
|
|
304
|
+
{ name: "Honolulu", km: 21500, description: "Paradise of the Pacific" },
|
|
305
|
+
{ name: "San Francisco", km: 25800, description: "City by the Bay" },
|
|
306
|
+
{ name: "Las Vegas", km: 26500, description: "Entertainment capital of the world" },
|
|
307
|
+
{ name: "Denver", km: 27500, description: "Mile High City" },
|
|
308
|
+
{ name: "Kansas City", km: 28200, description: "Heart of America" },
|
|
309
|
+
{ name: "Chicago", km: 29000, description: "The Windy City" },
|
|
310
|
+
{ name: "Washington DC", km: 30000, description: "Capital of the United States" },
|
|
311
|
+
{ name: "New York", km: 30500, description: "The Big Apple" },
|
|
312
|
+
{ name: "Reykjavik", km: 35000, description: "World's northernmost capital" },
|
|
313
|
+
{ name: "London", km: 40075, description: "Journey complete" },
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
];
|
|
317
|
+
export function getRoute(id) {
|
|
318
|
+
return ROUTES.find((r) => r.id === id);
|
|
319
|
+
}
|
|
320
|
+
export function getProgress(route, walkedKm) {
|
|
321
|
+
const clamped = Math.min(walkedKm, route.total_km);
|
|
322
|
+
const percent = (clamped / route.total_km) * 100;
|
|
323
|
+
const passed = route.waypoints.filter((w) => walkedKm >= w.km);
|
|
324
|
+
const next = route.waypoints.find((w) => walkedKm < w.km);
|
|
325
|
+
return {
|
|
326
|
+
walkedKm: clamped,
|
|
327
|
+
percent,
|
|
328
|
+
completed: walkedKm >= route.total_km,
|
|
329
|
+
passed,
|
|
330
|
+
next,
|
|
331
|
+
nextDistance: next ? next.km - walkedKm : 0,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
export function getNewlyPassedWaypoints(route, prevKm, currentKm) {
|
|
335
|
+
return route.waypoints.filter((w) => w.km > 0 && prevKm < w.km && currentKm >= w.km);
|
|
336
|
+
}
|
|
337
|
+
export function formatRouteOption(route) {
|
|
338
|
+
const stars = "\u2605".repeat(route.difficulty) +
|
|
339
|
+
"\u2606".repeat(5 - route.difficulty);
|
|
340
|
+
const km = route.total_km.toLocaleString();
|
|
341
|
+
return `${route.emoji} ${route.from} \u2192 ${route.to} (${km} km) ${stars}\n ${route.description}`;
|
|
342
|
+
}
|
|
343
|
+
export function progressBar(percent, width = 20) {
|
|
344
|
+
const clamped = Math.min(Math.max(percent, 0), 100);
|
|
345
|
+
const filled = Math.round((clamped / 100) * width);
|
|
346
|
+
const empty = width - filled;
|
|
347
|
+
return "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
348
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "step-overflow",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI walking log tool - record walks, sync to GitHub, visualize on GitHub Pages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cli.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"stp": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "tsx src/cli.ts",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/qiichos/step-overflow.git"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"walking",
|
|
27
|
+
"fitness",
|
|
28
|
+
"cli",
|
|
29
|
+
"github-pages",
|
|
30
|
+
"journey",
|
|
31
|
+
"achievements",
|
|
32
|
+
"gamification",
|
|
33
|
+
"walking-tracker"
|
|
34
|
+
],
|
|
35
|
+
"author": "qiichos",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/qiichos/step-overflow/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/qiichos/step-overflow#readme",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"citty": "^0.2.1",
|
|
43
|
+
"consola": "^3.4.2",
|
|
44
|
+
"log-update": "^7.2.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^25.3.5",
|
|
48
|
+
"tsx": "^4.21.0",
|
|
49
|
+
"typescript": "^5.9.3"
|
|
50
|
+
}
|
|
51
|
+
}
|