@minicode-dev/chat 0.1.14 → 0.1.16

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 (66) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/chunks/{BattleshipGameCard-B-B4r7lK.js → BattleshipGameCard-DwNzgH5G.js} +199 -199
  3. package/dist/chunks/{BattleshipGameCard-B-B4r7lK.js.map → BattleshipGameCard-DwNzgH5G.js.map} +1 -1
  4. package/dist/chunks/{BattleshipPrototype-CmQd5AUO.js → BattleshipPrototype-CSQxQJt5.js} +52 -52
  5. package/dist/chunks/{BattleshipPrototype-CmQd5AUO.js.map → BattleshipPrototype-CSQxQJt5.js.map} +1 -1
  6. package/dist/chunks/{ChatContext-DQtKsR6Z.js → ChatContext-D5rqvt5D.js} +2 -2
  7. package/dist/chunks/{ChatContext-DQtKsR6Z.js.map → ChatContext-D5rqvt5D.js.map} +1 -1
  8. package/dist/chunks/RacingLiveGameCard-_wvhDRlG.js +1873 -0
  9. package/dist/chunks/RacingLiveGameCard-_wvhDRlG.js.map +1 -0
  10. package/dist/chunks/{TanksGameCard-CvTaF7tu.js → TanksGameCard-B-gtDYYg.js} +144 -144
  11. package/dist/chunks/{TanksGameCard-CvTaF7tu.js.map → TanksGameCard-B-gtDYYg.js.map} +1 -1
  12. package/dist/chunks/TanksLiveGameCard-DXgd1J2Y.js +1274 -0
  13. package/dist/chunks/TanksLiveGameCard-DXgd1J2Y.js.map +1 -0
  14. package/dist/chunks/{avalancheScene3d-Z5QyZIid.js → avalancheScene3d-CNbQyGUd.js} +51 -50
  15. package/dist/chunks/{avalancheScene3d-Z5QyZIid.js.map → avalancheScene3d-CNbQyGUd.js.map} +1 -1
  16. package/dist/chunks/cars-D1PM7mVD.js +340 -0
  17. package/dist/chunks/cars-D1PM7mVD.js.map +1 -0
  18. package/dist/chunks/{connect4Sounds-DmD-E9kX.js → connect4Sounds-3a6h7gUC.js} +8 -8
  19. package/dist/chunks/{connect4Sounds-DmD-E9kX.js.map → connect4Sounds-3a6h7gUC.js.map} +1 -1
  20. package/dist/chunks/createLiveScene-jrzyQogh.js +756 -0
  21. package/dist/chunks/createLiveScene-jrzyQogh.js.map +1 -0
  22. package/dist/chunks/createRaceScene-C-aw0dlX.js +291 -0
  23. package/dist/chunks/createRaceScene-C-aw0dlX.js.map +1 -0
  24. package/dist/chunks/{createTankScene-yhX6la27.js → createTankScene-6asWHKFf.js} +123 -125
  25. package/dist/chunks/{createTankScene-yhX6la27.js.map → createTankScene-6asWHKFf.js.map} +1 -1
  26. package/dist/chunks/fx-BNJvJYOu.js +871 -0
  27. package/dist/chunks/fx-BNJvJYOu.js.map +1 -0
  28. package/dist/chunks/fx-DhXerGyt.js +248 -0
  29. package/dist/chunks/fx-DhXerGyt.js.map +1 -0
  30. package/dist/chunks/{games-BvYTWgaR.js → games-D_9SiSBT.js} +1261 -677
  31. package/dist/chunks/games-D_9SiSBT.js.map +1 -0
  32. package/dist/chunks/tank-DIn6Jyt8.js +605 -0
  33. package/dist/chunks/tank-DIn6Jyt8.js.map +1 -0
  34. package/dist/chunks/{tanks-live-BcKmrhnV.js → tanks-live-BRhYW4MG.js} +36 -36
  35. package/dist/chunks/{tanks-live-BcKmrhnV.js.map → tanks-live-BRhYW4MG.js.map} +1 -1
  36. package/dist/chunks/{tanksSounds-DwjfSp3W.js → tanksSounds-tYPzje61.js} +5 -5
  37. package/dist/chunks/{tanksSounds-DwjfSp3W.js.map → tanksSounds-tYPzje61.js.map} +1 -1
  38. package/dist/chunks/track-C1TWWT19.js +557 -0
  39. package/dist/chunks/track-C1TWWT19.js.map +1 -0
  40. package/dist/index.js +4244 -4028
  41. package/dist/index.js.map +1 -1
  42. package/dist/styles.css +1 -1
  43. package/index.d.ts +2 -0
  44. package/package.json +1 -1
  45. package/dist/chunks/RacingLiveGameCard-c1G7uoDI.js +0 -1654
  46. package/dist/chunks/RacingLiveGameCard-c1G7uoDI.js.map +0 -1
  47. package/dist/chunks/TanksLiveGameCard-COr9Oay5.js +0 -1011
  48. package/dist/chunks/TanksLiveGameCard-COr9Oay5.js.map +0 -1
  49. package/dist/chunks/createLiveScene-CWBunxPi.js +0 -367
  50. package/dist/chunks/createLiveScene-CWBunxPi.js.map +0 -1
  51. package/dist/chunks/createRaceScene-C7Rw89kj.js +0 -305
  52. package/dist/chunks/createRaceScene-C7Rw89kj.js.map +0 -1
  53. package/dist/chunks/decor-CyyCnmct.js +0 -418
  54. package/dist/chunks/decor-CyyCnmct.js.map +0 -1
  55. package/dist/chunks/fx-1ZwzmPWj.js +0 -458
  56. package/dist/chunks/fx-1ZwzmPWj.js.map +0 -1
  57. package/dist/chunks/fx-UZwhOmdl.js +0 -584
  58. package/dist/chunks/fx-UZwhOmdl.js.map +0 -1
  59. package/dist/chunks/games-BvYTWgaR.js.map +0 -1
  60. package/dist/chunks/rolldown-runtime-CGnMp29N.js +0 -10
  61. package/dist/chunks/tank-DjEQ4FXF.js +0 -553
  62. package/dist/chunks/tank-DjEQ4FXF.js.map +0 -1
  63. package/dist/chunks/track-BcnnpnAm.js +0 -259
  64. package/dist/chunks/track-BcnnpnAm.js.map +0 -1
  65. package/dist/chunks/util-DwI9bfS7.js +0 -57
  66. package/dist/chunks/util-DwI9bfS7.js.map +0 -1
@@ -0,0 +1,557 @@
1
+ // src/games/racing-live/logic/classes.js
2
+ var e = Object.freeze([
3
+ "50cc",
4
+ "100cc",
5
+ "200cc",
6
+ "400cc",
7
+ "500cc"
8
+ ]), t = "200cc", n = Object.freeze({
9
+ laps: 3,
10
+ trackLength: 600,
11
+ trackWidth: 10
12
+ }), r = {
13
+ reverseSpeed: 10,
14
+ grassDrag: 4,
15
+ barrierMargin: 3,
16
+ barrierBounce: .22,
17
+ steeringRate: 1.65
18
+ }, i = (e) => Math.round(e * 1e7) / 1e7;
19
+ function a({ id: e, label: t, topKmh: n, laps: a, trackLength: o, trackWidth: s, acceleration: c, braking: l, rollingDrag: u, lateralGrip: d, driftGrip: f, steerFalloffSpeed: p }) {
20
+ let m = n / 3.6, h = Object.freeze({
21
+ ...r,
22
+ maxSpeed: i(m * 1.05),
23
+ acceleration: c,
24
+ braking: l,
25
+ rollingDrag: u,
26
+ airDrag: i((c - u * m) / (m * m)),
27
+ lateralGrip: d,
28
+ driftGrip: f,
29
+ steerFalloffSpeed: p
30
+ });
31
+ return Object.freeze({
32
+ id: e,
33
+ label: t,
34
+ topKmh: n,
35
+ laps: a,
36
+ trackLength: o,
37
+ trackWidth: s,
38
+ rules: h
39
+ });
40
+ }
41
+ var o = Object.freeze({
42
+ "50cc": a({
43
+ id: "50cc",
44
+ label: "50cc",
45
+ topKmh: 80,
46
+ laps: 3,
47
+ trackLength: 600,
48
+ trackWidth: 10,
49
+ acceleration: 11,
50
+ braking: 20,
51
+ rollingDrag: .3,
52
+ lateralGrip: 10,
53
+ driftGrip: 2.5,
54
+ steerFalloffSpeed: 40
55
+ }),
56
+ "100cc": a({
57
+ id: "100cc",
58
+ label: "100cc",
59
+ topKmh: 130,
60
+ laps: 3,
61
+ trackLength: 600,
62
+ trackWidth: 10,
63
+ acceleration: 15,
64
+ braking: 26,
65
+ rollingDrag: .3,
66
+ lateralGrip: 11,
67
+ driftGrip: 2.7,
68
+ steerFalloffSpeed: 50
69
+ }),
70
+ "200cc": a({
71
+ id: "200cc",
72
+ label: "200cc",
73
+ topKmh: 200,
74
+ laps: 3,
75
+ trackLength: 1200,
76
+ trackWidth: 12,
77
+ acceleration: 21,
78
+ braking: 34,
79
+ rollingDrag: .3,
80
+ lateralGrip: 13,
81
+ driftGrip: 3,
82
+ steerFalloffSpeed: 65
83
+ }),
84
+ "400cc": a({
85
+ id: "400cc",
86
+ label: "400cc",
87
+ topKmh: 300,
88
+ laps: 3,
89
+ trackLength: 2e3,
90
+ trackWidth: 14,
91
+ acceleration: 29,
92
+ braking: 45,
93
+ rollingDrag: .3,
94
+ lateralGrip: 15,
95
+ driftGrip: 3.4,
96
+ steerFalloffSpeed: 90
97
+ }),
98
+ "500cc": a({
99
+ id: "500cc",
100
+ label: "500cc",
101
+ topKmh: 380,
102
+ laps: 4,
103
+ trackLength: 2e3,
104
+ trackWidth: 14,
105
+ acceleration: 35,
106
+ braking: 52,
107
+ rollingDrag: .3,
108
+ lateralGrip: 16,
109
+ driftGrip: 3.6,
110
+ steerFalloffSpeed: 105
111
+ })
112
+ }), s = (t) => typeof t == "string" && e.includes(t), c = (e) => s(e) ? o[e] : null, l = {
113
+ id: "city",
114
+ name: "Ciudad Neón",
115
+ emoji: "🏙️",
116
+ theme: "city",
117
+ baseLength: 1200,
118
+ width: 12,
119
+ startT: 0,
120
+ controlPoints: [
121
+ [-1, -.75],
122
+ [-.4, -.75],
123
+ [.35, -.75],
124
+ [.95, -.7],
125
+ [1.05, -.15],
126
+ [.9, .12],
127
+ [1, .55],
128
+ [.8, .95],
129
+ [.1, .95],
130
+ [-.65, .95],
131
+ [-1.05, .6],
132
+ [-1.05, 0]
133
+ ],
134
+ obstacles: [
135
+ {
136
+ kind: "cone",
137
+ t: .23,
138
+ offset: -.55,
139
+ radius: .7
140
+ },
141
+ {
142
+ kind: "barrier",
143
+ t: .52,
144
+ offset: .6,
145
+ radius: 1.2
146
+ },
147
+ {
148
+ kind: "cone",
149
+ t: .78,
150
+ offset: -.6,
151
+ radius: .7
152
+ }
153
+ ]
154
+ }, u = {
155
+ id: "canyon",
156
+ name: "Cañón Turbo",
157
+ emoji: "🏜️",
158
+ theme: "canyon",
159
+ baseLength: 1320,
160
+ width: 12,
161
+ startT: 0,
162
+ controlPoints: [
163
+ [-1, -.75],
164
+ [-.45, -.85],
165
+ [.15, -.55],
166
+ [.75, -.85],
167
+ [1.15, -.45],
168
+ [.85, .05],
169
+ [1.1, .6],
170
+ [.6, 1],
171
+ [.05, .7],
172
+ [-.5, 1.05],
173
+ [-1.1, .65],
174
+ [-.85, .1]
175
+ ],
176
+ obstacles: [
177
+ {
178
+ kind: "rock",
179
+ t: .18,
180
+ offset: .62,
181
+ radius: 1.2
182
+ },
183
+ {
184
+ kind: "rock",
185
+ t: .47,
186
+ offset: -.65,
187
+ radius: 1.1
188
+ },
189
+ {
190
+ kind: "rock",
191
+ t: .73,
192
+ offset: .6,
193
+ radius: 1.4
194
+ }
195
+ ]
196
+ }, d = {
197
+ id: "forest",
198
+ name: "Bosque de Juguete",
199
+ emoji: "🌲",
200
+ theme: "forest",
201
+ baseLength: 1260,
202
+ width: 12,
203
+ startT: 0,
204
+ controlPoints: [
205
+ [-1.1, -.65],
206
+ [-.55, -.8],
207
+ [.1, -.65],
208
+ [.7, -.95],
209
+ [1.15, -.55],
210
+ [.95, 0],
211
+ [.7, .2],
212
+ [.9, .75],
213
+ [.5, 1.1],
214
+ [-.2, .95],
215
+ [-.85, .65],
216
+ [-1.15, .1]
217
+ ],
218
+ obstacles: [
219
+ {
220
+ kind: "log",
221
+ t: .25,
222
+ offset: -.6,
223
+ radius: 1.2
224
+ },
225
+ {
226
+ kind: "log",
227
+ t: .56,
228
+ offset: .6,
229
+ radius: 1.1
230
+ },
231
+ {
232
+ kind: "rock",
233
+ t: .81,
234
+ offset: -.55,
235
+ radius: .9
236
+ }
237
+ ]
238
+ }, f = {
239
+ id: "snow",
240
+ name: "Cumbre Nevada",
241
+ emoji: "❄️",
242
+ theme: "snow",
243
+ baseLength: 1380,
244
+ width: 13,
245
+ startT: 0,
246
+ controlPoints: [
247
+ [-1, -.9],
248
+ [-.35, -1],
249
+ [.4, -.9],
250
+ [1.05, -.55],
251
+ [.95, 0],
252
+ [.7, .2],
253
+ [.85, .75],
254
+ [.45, 1.1],
255
+ [-.25, 1],
256
+ [-.95, .7],
257
+ [-.9, .1],
258
+ [-1.1, -.3]
259
+ ],
260
+ obstacles: [
261
+ {
262
+ kind: "ice",
263
+ t: .21,
264
+ offset: .65,
265
+ radius: 1.1
266
+ },
267
+ {
268
+ kind: "snowman",
269
+ t: .49,
270
+ offset: -.6,
271
+ radius: 1
272
+ },
273
+ {
274
+ kind: "ice",
275
+ t: .77,
276
+ offset: .6,
277
+ radius: 1.3
278
+ }
279
+ ]
280
+ }, p = {
281
+ id: "coast",
282
+ name: "Costa Nocturna",
283
+ emoji: "🌴",
284
+ theme: "coast",
285
+ baseLength: 1440,
286
+ width: 13,
287
+ startT: 0,
288
+ controlPoints: [
289
+ [-1.2, -.6],
290
+ [-.55, -.9],
291
+ [.2, -.95],
292
+ [.95, -.65],
293
+ [1.25, -.15],
294
+ [1.05, .45],
295
+ [.5, .85],
296
+ [-.2, 1.05],
297
+ [-.85, .75],
298
+ [-.95, .2],
299
+ [-1.15, 0]
300
+ ],
301
+ obstacles: [
302
+ {
303
+ kind: "buoy",
304
+ t: .28,
305
+ offset: -.62,
306
+ radius: .9
307
+ },
308
+ {
309
+ kind: "rock",
310
+ t: .58,
311
+ offset: .65,
312
+ radius: 1.3
313
+ },
314
+ {
315
+ kind: "buoy",
316
+ t: .82,
317
+ offset: -.6,
318
+ radius: .9
319
+ }
320
+ ]
321
+ }, m = "oval", h = "random", g = Object.freeze(Object.fromEntries([
322
+ l,
323
+ u,
324
+ d,
325
+ f,
326
+ p
327
+ ].filter((e) => e && typeof e.id == "string").map((e) => [e.id, Object.freeze(e)]))), _ = Object.freeze(Object.values(g).map(({ id: e, name: t, emoji: n }) => Object.freeze({
328
+ id: e,
329
+ name: t,
330
+ emoji: n
331
+ }))), v = Object.freeze([m, ...Object.keys(g)]);
332
+ Object.freeze([...Object.keys(g), h]);
333
+ var y = Object.freeze({
334
+ [m]: "Óvalo clásico",
335
+ ...Object.fromEntries(_.map((e) => [e.id, e.name]))
336
+ }), b = Object.freeze({
337
+ [m]: "🏁",
338
+ ...Object.fromEntries(_.map((e) => [e.id, e.emoji]))
339
+ }), x = (e) => typeof e == "string" && v.includes(e), S = (e) => e && Object.prototype.hasOwnProperty.call(g, e) ? g[e] : null;
340
+ function C(e, t = 0) {
341
+ if (e == null) return m;
342
+ if (e === "random") {
343
+ let e = Object.keys(g);
344
+ if (!e.length) return m;
345
+ let n = Number(t) >>> 0 ^ 2654435769;
346
+ return n = Math.imul(n ^ n >>> 16, 2246822507), n = Math.imul(n ^ n >>> 13, 3266489909), n ^= n >>> 16, e[(n >>> 0) % e.length];
347
+ }
348
+ if (!x(e)) throw RangeError(`Unsupported race track: ${e}`);
349
+ return e;
350
+ }
351
+ var w = Object.freeze(["neon_city"]), T = 128, E = 256, D = 1200, O = 12, k = 1.5, A = 3, j = (e) => Math.round(e * 1e6) / 1e6, M = (e, t) => Math.hypot(t.x - e.x, t.z - e.z);
352
+ function N(e) {
353
+ let t = 2166136261;
354
+ for (let n = 0; n < e.length; n += 1) t ^= e.charCodeAt(n), t = Math.imul(t, 16777619);
355
+ return (t >>> 0).toString(16).padStart(8, "0");
356
+ }
357
+ function P(e) {
358
+ if (typeof e == "string") return parseInt(N(e), 16);
359
+ if (typeof e != "number" || !Number.isFinite(e)) throw TypeError("Race seed must be a finite number or string");
360
+ return Math.trunc(e) >>> 0;
361
+ }
362
+ function F(e, t) {
363
+ let n = e.length - 1, r = e[(t + n - 1) % n], i = e[(t + 1) % n], a = M(r, i);
364
+ return {
365
+ x: (i.x - r.x) / a,
366
+ z: (i.z - r.z) / a
367
+ };
368
+ }
369
+ function I(e, t) {
370
+ if (!Number.isFinite(t)) throw TypeError("Track distance must be finite");
371
+ let n = (t % e.length + e.length) % e.length, r = e.points.length - 2;
372
+ for (let t = 0; t < e.points.length - 1; t += 1) if (n < e.points[t + 1].s) {
373
+ r = t;
374
+ break;
375
+ }
376
+ let i = e.points[r], a = e.points[r + 1], o = a.s - i.s, s = (n - i.s) / o;
377
+ return {
378
+ x: i.x + (a.x - i.x) * s,
379
+ z: i.z + (a.z - i.z) * s,
380
+ s: n,
381
+ segment: r,
382
+ tangent: {
383
+ x: (a.x - i.x) / o,
384
+ z: (a.z - i.z) / o
385
+ }
386
+ };
387
+ }
388
+ function L(e, t) {
389
+ if (!Number.isFinite(t?.x) || !Number.isFinite(t?.z)) throw TypeError("Position must contain finite x and z");
390
+ let n;
391
+ for (let r = 0; r < e.points.length - 1; r += 1) {
392
+ let i = e.points[r], a = e.points[r + 1], o = a.x - i.x, s = a.z - i.z, c = o * o + s * s, l = Math.min(1, Math.max(0, ((t.x - i.x) * o + (t.z - i.z) * s) / c)), u = i.x + o * l, d = i.z + s * l, f = Math.hypot(t.x - u, t.z - d);
393
+ if (!n || f < n.distance) {
394
+ let a = Math.sqrt(c), p = {
395
+ x: o / a,
396
+ z: s / a
397
+ }, m = (t.x - u) * -p.z + (t.z - d) * p.x;
398
+ n = {
399
+ x: u,
400
+ z: d,
401
+ point: {
402
+ x: u,
403
+ z: d
404
+ },
405
+ distance: f,
406
+ s: (i.s + l * a) % e.length,
407
+ tangent: p,
408
+ lateral: m,
409
+ signedDistance: m,
410
+ segment: r
411
+ };
412
+ }
413
+ }
414
+ return n;
415
+ }
416
+ function R(e, t = E) {
417
+ let n = e.map(([e, t]) => ({
418
+ x: e,
419
+ z: t
420
+ })), r = n.length;
421
+ if (r < 4 || !n.every((e) => Number.isFinite(e.x) && Number.isFinite(e.z))) throw RangeError("A circuit needs at least 4 finite control points");
422
+ let i = [];
423
+ for (let e = 0; e < r; e += 1) {
424
+ let t = n[(e - 1 + r) % r], a = n[e], o = n[(e + 1) % r], s = n[(e + 2) % r], c = (e, t) => Math.max(1e-6, Math.sqrt(Math.hypot(t.x - e.x, t.z - e.z))), l = c(t, a), u = l + c(a, o), d = u + c(o, s);
425
+ for (let e = 0; e < 24; e += 1) {
426
+ let n = l + (u - l) * (e / 24), r = (e, t, r, i) => ({
427
+ x: ((i - n) * e.x + (n - r) * t.x) / (i - r),
428
+ z: ((i - n) * e.z + (n - r) * t.z) / (i - r)
429
+ }), c = r(t, a, 0, l), f = r(a, o, l, u), p = r(o, s, u, d), m = r(c, f, 0, u), h = r(f, p, l, d);
430
+ i.push(r(m, h, l, u));
431
+ }
432
+ }
433
+ i.push({ ...i[0] });
434
+ let a = [0];
435
+ for (let e = 1; e < i.length; e += 1) a.push(a[e - 1] + M(i[e - 1], i[e]));
436
+ let o = a.at(-1), s = [], c = 0;
437
+ for (let e = 0; e < t; e += 1) {
438
+ let n = o * e / t;
439
+ for (; a[c + 1] < n;) c += 1;
440
+ let r = a[c + 1] - a[c] || 1, l = (n - a[c]) / r;
441
+ s.push({
442
+ x: i[c].x + (i[c + 1].x - i[c].x) * l,
443
+ z: i[c].z + (i[c + 1].z - i[c].z) * l
444
+ });
445
+ }
446
+ return s;
447
+ }
448
+ function z(e, t) {
449
+ let r = t ? t.trackLength : n.trackLength, i = t ? t.trackWidth : n.trackWidth, a = Number.isFinite(e.baseLength) && e.baseLength > 0 ? e.baseLength : D, o = Number.isFinite(e.width) && e.width > 0 ? e.width : O;
450
+ return {
451
+ length: a * r / D,
452
+ width: j(o * i / O)
453
+ };
454
+ }
455
+ function B(e, t) {
456
+ return (Array.isArray(e.obstacles) ? e.obstacles : []).filter((e) => e && Number.isFinite(e.t) && Number.isFinite(e.offset) && Number.isFinite(e.radius)).map((e, n) => {
457
+ let r = Math.min(.94, Math.max(.06, e.t)), i = Math.min(.75, Math.max(-.75, e.offset)), a = Math.min(k, Math.max(.3, e.radius)), o = I(t, r * t.length), s = i * t.width / 2;
458
+ return {
459
+ id: n,
460
+ kind: typeof e.kind == "string" ? e.kind : "block",
461
+ radius: j(a),
462
+ s: j(o.s),
463
+ lateral: j(s),
464
+ x: j(o.x - o.tangent.z * s),
465
+ z: j(o.z + o.tangent.x * s)
466
+ };
467
+ });
468
+ }
469
+ function V(e = "neon_city", t = 0, { speedClass: r, trackId: i } = {}) {
470
+ let a = e === "random" ? "neon_city" : e;
471
+ if (!w.includes(a)) throw RangeError(`Unsupported race map: ${e}`);
472
+ if (r != null && !c(r)) throw RangeError(`Unsupported speed class: ${r}`);
473
+ if (i != null && !x(i)) throw RangeError(`Unsupported race track: ${i}`);
474
+ let o = P(t), s = c(r), l = i && i !== "oval" ? S(i) : null, u, d, f;
475
+ l ? ({length: d, width: f} = z(l, s), u = R(l.controlPoints, E)) : (d = s ? s.trackLength : n.trackLength, f = s ? s.trackWidth : n.trackWidth, u = Array.from({ length: T }, (e, t) => {
476
+ let n = t / T * Math.PI * 2;
477
+ return {
478
+ x: 110 * Math.cos(n),
479
+ z: 75 * Math.sin(n)
480
+ };
481
+ }));
482
+ let p = u.length, m = u.reduce((e, t, n) => e + M(t, u[(n + 1) % p]), 0), h = d / m, g = u.map((e) => ({
483
+ x: j(e.x * h),
484
+ z: j(e.z * h)
485
+ }));
486
+ g.push({ ...g[0] });
487
+ let _ = 0;
488
+ g.forEach((e, t) => {
489
+ t && (_ += M(g[t - 1], e)), e.s = _;
490
+ });
491
+ let v = [
492
+ 0,
493
+ 1,
494
+ 2,
495
+ 3
496
+ ].map((e) => {
497
+ let t = e * p / 4, n = g[t], r = F(g, t), i = {
498
+ x: -r.z,
499
+ z: r.x
500
+ };
501
+ return {
502
+ id: e,
503
+ index: e,
504
+ s: n.s,
505
+ center: {
506
+ x: n.x,
507
+ z: n.z
508
+ },
509
+ normal: r,
510
+ halfWidth: f / 2,
511
+ a: {
512
+ x: n.x + i.x * f / 2,
513
+ z: n.z + i.z * f / 2
514
+ },
515
+ b: {
516
+ x: n.x - i.x * f / 2,
517
+ z: n.z - i.z * f / 2
518
+ }
519
+ };
520
+ }), y = [-1, 1].map((e) => ({
521
+ id: e < 0 ? "right_edge" : "left_edge",
522
+ type: "track_boundary",
523
+ points: g.map((t, n) => {
524
+ let r = F(g, n % p), i = f / 2 + A;
525
+ return {
526
+ x: j(t.x - r.z * e * i),
527
+ z: j(t.z + r.x * e * i)
528
+ };
529
+ })
530
+ })), b = {
531
+ mapId: a,
532
+ ...l ? { trackId: l.id } : {},
533
+ seed: o,
534
+ ...s ? { speedClass: s.id } : {},
535
+ rulesVersion: 1,
536
+ width: f,
537
+ barrierMargin: A,
538
+ length: _,
539
+ points: g,
540
+ checkpoints: v,
541
+ colliders: y
542
+ };
543
+ l && (b.obstacles = B(l, b));
544
+ let C = I(b, _ - 8), D = Math.atan2(C.tangent.x, C.tangent.z);
545
+ return b.grid = [-f / 4, f / 4].map((e, t) => ({
546
+ playerIndex: t,
547
+ x: C.x - C.tangent.z * e,
548
+ z: C.z + C.tangent.x * e,
549
+ s: C.s,
550
+ lateral: e,
551
+ yaw: D,
552
+ heading: D
553
+ })), b.startFinish = v[0], b.trackHash = `racing-v1-${N(JSON.stringify(b))}`, b;
554
+ }
555
+ export { b as a, C as c, o as d, c as f, _ as i, t as l, L as n, y as o, m as r, x as s, V as t, n as u };
556
+
557
+ //# sourceMappingURL=track-C1TWWT19.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-C1TWWT19.js","names":["city","canyon","forest","snow","coast","RACE_CLASS_IDS","DEFAULT_RACE_CLASS","LEGACY_RACE","BASE","round","n","defineClass","top","topKmh","rules","acceleration","rollingDrag","RACE_CLASSES","isRaceClass","value","getRaceClass","city_default","canyon_default","forest_default","snow_default","coast_default","LEGACY_TRACK_ID","RANDOM_TRACK","DEFINITIONS","def","RACING_TRACKS","RACE_TRACK_IDS","TRACK_NAMES","t","TRACK_EMOJIS","isRaceTrackId","getTrackDefinition","id","resolveTrackId","choice","ids","h","seed","RACE_TRACK_MAP_IDS","SEGMENTS","CIRCUIT_SEGMENTS","REFERENCE_CLASS_LENGTH","REFERENCE_CLASS_WIDTH","MAX_OBSTACLE_RADIUS","BARRIER_MARGIN","rounded","distanceBetween","b","a","hashText","hash","i","text","normalizeSeed","tangentAt","points","previous","index","next","magnitude","sampleTrack","distance","s","track","segment","length","projectToTrack","position","best","dx","dz","lengthSquared","x","z","tangent","lateral","smoothClosedSpline","cp","controlPoints","p","dense","p0","p1","p2","p3","knot","t1","t2","t3","k","lerp","tb","ta","a1","a2","a3","b1","b2","cumulative","total","out","j","count","target","span","f","circuitDimensions","classLength","raceClass","classWidth","baseLength","definition","baseWidth","placeObstacles","o","offset","radius","at","generateTrack","selectedMap","mapId","speedClass","trackId","normalizedSeed","raw","targetLength","roadWidth","angle","rawLength","sum","point","scale","checkpoints","pointIndex","normal","side","colliders","start","yaw"],"sources":["../../src/games/racing-live/logic/classes.js","../../src/games/racing-live/logic/tracks/city.js","../../src/games/racing-live/logic/tracks/canyon.js","../../src/games/racing-live/logic/tracks/forest.js","../../src/games/racing-live/logic/tracks/snow.js","../../src/games/racing-live/logic/tracks/coast.js","../../src/games/racing-live/logic/tracks/index.js","../../src/games/racing-live/logic/track.js"],"sourcesContent":["// Mario-Kart-style speed classes. Pure data: no imports so track.js and car.js can share it.\n// Top speed is the REAL equilibrium of stepCar at full throttle on tarmac:\n// acceleration = rollingDrag·v + airDrag·v² → airDrag = (acceleration − rollingDrag·v) / v²\n// maxSpeed is only a safety ceiling 5 % above that equilibrium.\nexport const RACE_CLASS_IDS = Object.freeze(['50cc', '100cc', '200cc', '400cc', '500cc']);\nexport const DEFAULT_RACE_CLASS = '200cc';\n// Invitations without speed_class keep the original rules, laps and 600 m circuit.\nexport const LEGACY_RACE = Object.freeze({ laps: 3, trackLength: 600, trackWidth: 10 });\n\nconst BASE = { reverseSpeed: 10, grassDrag: 4, barrierMargin: 3, barrierBounce: 0.22, steeringRate: 1.65 };\nconst round = (n) => Math.round(n * 1e7) / 1e7;\n\nfunction defineClass({ id, label, topKmh, laps, trackLength, trackWidth, acceleration, braking, rollingDrag, lateralGrip, driftGrip, steerFalloffSpeed }) {\n const top = topKmh / 3.6;\n const rules = Object.freeze({ ...BASE, maxSpeed: round(top * 1.05), acceleration, braking, rollingDrag,\n airDrag: round((acceleration - rollingDrag * top) / (top * top)), lateralGrip, driftGrip, steerFalloffSpeed });\n return Object.freeze({ id, label, topKmh, laps, trackLength, trackWidth, rules });\n}\n\nexport const RACE_CLASSES = Object.freeze({\n '50cc': defineClass({ id: '50cc', label: '50cc', topKmh: 80, laps: 3, trackLength: 600, trackWidth: 10,\n acceleration: 11, braking: 20, rollingDrag: 0.3, lateralGrip: 10, driftGrip: 2.5, steerFalloffSpeed: 40 }),\n '100cc': defineClass({ id: '100cc', label: '100cc', topKmh: 130, laps: 3, trackLength: 600, trackWidth: 10,\n acceleration: 15, braking: 26, rollingDrag: 0.3, lateralGrip: 11, driftGrip: 2.7, steerFalloffSpeed: 50 }),\n '200cc': defineClass({ id: '200cc', label: '200cc', topKmh: 200, laps: 3, trackLength: 1200, trackWidth: 12,\n acceleration: 21, braking: 34, rollingDrag: 0.3, lateralGrip: 13, driftGrip: 3, steerFalloffSpeed: 65 }),\n '400cc': defineClass({ id: '400cc', label: '400cc', topKmh: 300, laps: 3, trackLength: 2000, trackWidth: 14,\n acceleration: 29, braking: 45, rollingDrag: 0.3, lateralGrip: 15, driftGrip: 3.4, steerFalloffSpeed: 90 }),\n '500cc': defineClass({ id: '500cc', label: '500cc', topKmh: 380, laps: 4, trackLength: 2000, trackWidth: 14,\n acceleration: 35, braking: 52, rollingDrag: 0.3, lateralGrip: 16, driftGrip: 3.6, steerFalloffSpeed: 105 }),\n});\n\nexport const isRaceClass = (value) => typeof value === 'string' && RACE_CLASS_IDS.includes(value);\n/** Class definition or null for legacy invitations (no speed_class). */\nexport const getRaceClass = (value) => (isRaceClass(value) ? RACE_CLASSES[value] : null);\n","export default {\n id: 'city', name: 'Ciudad Neón', emoji: '🏙️', theme: 'city', baseLength: 1200, width: 12, startT: 0,\n controlPoints: [[-1, -0.75], [-0.4, -0.75], [0.35, -0.75], [0.95, -0.7], [1.05, -0.15], [0.9, 0.12], [1, 0.55], [0.8, 0.95], [0.1, 0.95], [-0.65, 0.95], [-1.05, 0.6], [-1.05, 0]],\n obstacles: [{ kind: 'cone', t: 0.23, offset: -0.55, radius: 0.7 }, { kind: 'barrier', t: 0.52, offset: 0.6, radius: 1.2 }, { kind: 'cone', t: 0.78, offset: -0.6, radius: 0.7 }],\n};\n","export default {\n id: 'canyon', name: 'Cañón Turbo', emoji: '🏜️', theme: 'canyon', baseLength: 1320, width: 12, startT: 0,\n controlPoints: [[-1, -0.75], [-0.45, -0.85], [0.15, -0.55], [0.75, -0.85], [1.15, -0.45], [0.85, 0.05], [1.1, 0.6], [0.6, 1], [0.05, 0.7], [-0.5, 1.05], [-1.1, 0.65], [-0.85, 0.1]],\n obstacles: [{ kind: 'rock', t: 0.18, offset: 0.62, radius: 1.2 }, { kind: 'rock', t: 0.47, offset: -0.65, radius: 1.1 }, { kind: 'rock', t: 0.73, offset: 0.6, radius: 1.4 }],\n};\n","export default {\n id: 'forest', name: 'Bosque de Juguete', emoji: '🌲', theme: 'forest', baseLength: 1260, width: 12, startT: 0,\n controlPoints: [[-1.1, -0.65], [-0.55, -0.8], [0.1, -0.65], [0.7, -0.95], [1.15, -0.55], [0.95, 0], [0.7, 0.2], [0.9, 0.75], [0.5, 1.1], [-0.2, 0.95], [-0.85, 0.65], [-1.15, 0.1]],\n obstacles: [{ kind: 'log', t: 0.25, offset: -0.6, radius: 1.2 }, { kind: 'log', t: 0.56, offset: 0.6, radius: 1.1 }, { kind: 'rock', t: 0.81, offset: -0.55, radius: 0.9 }],\n};\n","// Folded S loop rather than a planar figure-eight: no ambiguous progress crossing.\nexport default {\n id: 'snow', name: 'Cumbre Nevada', emoji: '❄️', theme: 'snow', baseLength: 1380, width: 13, startT: 0,\n controlPoints: [[-1, -0.9], [-0.35, -1], [0.4, -0.9], [1.05, -0.55], [0.95, 0], [0.7, 0.2], [0.85, 0.75], [0.45, 1.1], [-0.25, 1], [-0.95, 0.7], [-0.9, 0.1], [-1.1, -0.3]],\n obstacles: [{ kind: 'ice', t: 0.21, offset: 0.65, radius: 1.1 }, { kind: 'snowman', t: 0.49, offset: -0.6, radius: 1 }, { kind: 'ice', t: 0.77, offset: 0.6, radius: 1.3 }],\n};\n","export default {\n id: 'coast', name: 'Costa Nocturna', emoji: '🌴', theme: 'coast', baseLength: 1440, width: 13, startT: 0,\n controlPoints: [[-1.2, -0.6], [-0.55, -0.9], [0.2, -0.95], [0.95, -0.65], [1.25, -0.15], [1.05, 0.45], [0.5, 0.85], [-0.2, 1.05], [-0.85, 0.75], [-0.95, 0.2], [-1.15, 0]],\n obstacles: [{ kind: 'buoy', t: 0.28, offset: -0.62, radius: 0.9 }, { kind: 'rock', t: 0.58, offset: 0.65, radius: 1.3 }, { kind: 'buoy', t: 0.82, offset: -0.6, radius: 0.9 }],\n};\n","// Carreras LIVE circuit registry. Pure data, loaded synchronously: both clients must\n// rebuild identical geometry from { track_id, seed, speed_class } to agree on the hash.\n// The legacy oval (`oval`, map neon_city) is generated by logic/track.js and is the\n// implicit circuit of invitations without track_id.\nimport city from './city.js';\nimport canyon from './canyon.js';\nimport forest from './forest.js';\nimport snow from './snow.js';\nimport coast from './coast.js';\n\nexport const LEGACY_TRACK_ID = 'oval';\nexport const RANDOM_TRACK = 'random';\n\nconst DEFINITIONS = Object.freeze(Object.fromEntries([city, canyon, forest, snow, coast]\n .filter((def) => def && typeof def.id === 'string').map((def) => [def.id, Object.freeze(def)])));\n\n/** The five selectable circuits (UI order). The oval is kept only for compatibility. */\nexport const RACING_TRACKS = Object.freeze(Object.values(DEFINITIONS)\n .map(({ id, name, emoji }) => Object.freeze({ id, name, emoji })));\nexport const RACE_TRACK_IDS = Object.freeze([LEGACY_TRACK_ID, ...Object.keys(DEFINITIONS)]);\nexport const RACING_TRACK_IDS = RACE_TRACK_IDS;\nexport const RACE_TRACK_CHOICES = Object.freeze([...Object.keys(DEFINITIONS), RANDOM_TRACK]);\nexport const TRACK_NAMES = Object.freeze({ [LEGACY_TRACK_ID]: 'Óvalo clásico', ...Object.fromEntries(RACING_TRACKS.map((t) => [t.id, t.name])) });\nexport const TRACK_EMOJIS = Object.freeze({ [LEGACY_TRACK_ID]: '🏁', ...Object.fromEntries(RACING_TRACKS.map((t) => [t.id, t.emoji])) });\n\nexport const isRaceTrackId = (value) => typeof value === 'string' && RACE_TRACK_IDS.includes(value);\nexport const getTrackDefinition = (id) => (id && Object.prototype.hasOwnProperty.call(DEFINITIONS, id) ? DEFINITIONS[id] : null);\n\n/** 'random' picks one of the five circuits deterministically from the invitation seed (host side). */\nexport function resolveTrackId(choice, seed = 0) {\n if (choice === undefined || choice === null) return LEGACY_TRACK_ID;\n if (choice === RANDOM_TRACK) {\n const ids = Object.keys(DEFINITIONS);\n if (!ids.length) return LEGACY_TRACK_ID;\n // Mix the seed so consecutive game ids do not walk the list in order.\n let h = (Number(seed) >>> 0) ^ 0x9e3779b9;\n h = Math.imul(h ^ (h >>> 16), 0x85ebca6b); h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35); h ^= h >>> 16;\n return ids[(h >>> 0) % ids.length];\n }\n if (!isRaceTrackId(choice)) throw new RangeError(`Unsupported race track: ${choice}`);\n return choice;\n}\n","import { getRaceClass, LEGACY_RACE } from './classes.js';\nimport { LEGACY_TRACK_ID, getTrackDefinition, isRaceTrackId } from './tracks/index.js';\n\n// MVP geometry in metres. The seed varies future scenery, never player advantages.\nexport const RACE_TRACK_RULES_VERSION = 1;\nexport const RACE_TRACK_MAP_IDS = Object.freeze(['neon_city']);\nconst SEGMENTS = 128;\n// Spline circuits use a denser polyline (curves, chicanes) and a reference class.\nconst CIRCUIT_SEGMENTS = 256;\nconst REFERENCE_CLASS_LENGTH = 1200; // 200cc\nconst REFERENCE_CLASS_WIDTH = 12;\nconst MAX_OBSTACLE_RADIUS = 1.5;\nconst BARRIER_MARGIN = 3;\nconst rounded = (n) => Math.round(n * 1e6) / 1e6;\nconst distanceBetween = (a, b) => Math.hypot(b.x - a.x, b.z - a.z);\n\nfunction hashText(text) {\n let hash = 2166136261;\n for (let i = 0; i < text.length; i += 1) {\n hash ^= text.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction normalizeSeed(seed) {\n if (typeof seed === 'string') return parseInt(hashText(seed), 16);\n if (typeof seed !== 'number' || !Number.isFinite(seed)) throw new TypeError('Race seed must be a finite number or string');\n return Math.trunc(seed) >>> 0;\n}\n\nfunction tangentAt(points, index) {\n const n = points.length - 1;\n const previous = points[(index + n - 1) % n];\n const next = points[(index + 1) % n];\n const magnitude = distanceBetween(previous, next);\n return { x: (next.x - previous.x) / magnitude, z: (next.z - previous.z) / magnitude };\n}\n\n/** Sample the closed polyline by travelled centre-line distance. */\nexport function sampleTrack(track, distance) {\n if (!Number.isFinite(distance)) throw new TypeError('Track distance must be finite');\n const s = ((distance % track.length) + track.length) % track.length;\n let segment = track.points.length - 2;\n for (let i = 0; i < track.points.length - 1; i += 1) {\n if (s < track.points[i + 1].s) { segment = i; break; }\n }\n const a = track.points[segment];\n const b = track.points[segment + 1];\n const length = b.s - a.s;\n const t = (s - a.s) / length;\n return { x: a.x + (b.x - a.x) * t, z: a.z + (b.z - a.z) * t, s, segment,\n tangent: { x: (b.x - a.x) / length, z: (b.z - a.z) / length } };\n}\n\n/** Nearest centre-line point; positive lateral distance is to the driver's left. */\nexport function projectToTrack(track, position) {\n if (!Number.isFinite(position?.x) || !Number.isFinite(position?.z)) throw new TypeError('Position must contain finite x and z');\n let best;\n for (let segment = 0; segment < track.points.length - 1; segment += 1) {\n const a = track.points[segment];\n const b = track.points[segment + 1];\n const dx = b.x - a.x;\n const dz = b.z - a.z;\n const lengthSquared = dx * dx + dz * dz;\n const t = Math.min(1, Math.max(0, ((position.x - a.x) * dx + (position.z - a.z) * dz) / lengthSquared));\n const x = a.x + dx * t;\n const z = a.z + dz * t;\n const distance = Math.hypot(position.x - x, position.z - z);\n if (!best || distance < best.distance) {\n const length = Math.sqrt(lengthSquared);\n const tangent = { x: dx / length, z: dz / length };\n const lateral = (position.x - x) * -tangent.z + (position.z - z) * tangent.x;\n best = { x, z, point: { x, z }, distance, s: (a.s + t * length) % track.length,\n tangent, lateral, signedDistance: lateral, segment };\n }\n }\n return best;\n}\n\nexport const projectOnTrack = projectToTrack;\n\n/** Closed centripetal Catmull-Rom through control points, resampled to `count` points evenly spaced. */\nexport function smoothClosedSpline(controlPoints, count = CIRCUIT_SEGMENTS) {\n const cp = controlPoints.map(([x, z]) => ({ x, z }));\n const n = cp.length;\n if (n < 4 || !cp.every((p) => Number.isFinite(p.x) && Number.isFinite(p.z))) throw new RangeError('A circuit needs at least 4 finite control points');\n const dense = [];\n const STEPS = 24;\n for (let i = 0; i < n; i += 1) {\n const p0 = cp[(i - 1 + n) % n]; const p1 = cp[i]; const p2 = cp[(i + 1) % n]; const p3 = cp[(i + 2) % n];\n const knot = (a, b) => Math.max(1e-6, Math.sqrt(Math.hypot(b.x - a.x, b.z - a.z)));\n const t1 = knot(p0, p1); const t2 = t1 + knot(p1, p2); const t3 = t2 + knot(p2, p3);\n for (let k = 0; k < STEPS; k += 1) {\n const t = t1 + (t2 - t1) * (k / STEPS);\n const lerp = (a, b, ta, tb) => ({ x: ((tb - t) * a.x + (t - ta) * b.x) / (tb - ta), z: ((tb - t) * a.z + (t - ta) * b.z) / (tb - ta) });\n const a1 = lerp(p0, p1, 0, t1); const a2 = lerp(p1, p2, t1, t2); const a3 = lerp(p2, p3, t2, t3);\n const b1 = lerp(a1, a2, 0, t2); const b2 = lerp(a2, a3, t1, t3);\n dense.push(lerp(b1, b2, t1, t2));\n }\n }\n dense.push({ ...dense[0] });\n const cumulative = [0];\n for (let i = 1; i < dense.length; i += 1) cumulative.push(cumulative[i - 1] + distanceBetween(dense[i - 1], dense[i]));\n const total = cumulative.at(-1);\n const out = [];\n let j = 0;\n for (let i = 0; i < count; i += 1) {\n const target = total * i / count;\n while (cumulative[j + 1] < target) j += 1;\n const span = cumulative[j + 1] - cumulative[j] || 1;\n const f = (target - cumulative[j]) / span;\n out.push({ x: dense[j].x + (dense[j + 1].x - dense[j].x) * f, z: dense[j].z + (dense[j + 1].z - dense[j].z) * f });\n }\n return out;\n}\n\n/** Scaled per class: 50/100cc short, 200cc reference, 400/500cc long. Legacy (no class) = 600 m reference. */\nexport function circuitDimensions(definition, raceClass) {\n const classLength = raceClass ? raceClass.trackLength : LEGACY_RACE.trackLength;\n const classWidth = raceClass ? raceClass.trackWidth : LEGACY_RACE.trackWidth;\n const baseLength = Number.isFinite(definition.baseLength) && definition.baseLength > 0 ? definition.baseLength : REFERENCE_CLASS_LENGTH;\n const baseWidth = Number.isFinite(definition.width) && definition.width > 0 ? definition.width : REFERENCE_CLASS_WIDTH;\n return { length: baseLength * classLength / REFERENCE_CLASS_LENGTH, width: rounded(baseWidth * classWidth / REFERENCE_CLASS_WIDTH) };\n}\n\nfunction placeObstacles(definition, track) {\n const list = Array.isArray(definition.obstacles) ? definition.obstacles : [];\n return list.filter((o) => o && Number.isFinite(o.t) && Number.isFinite(o.offset) && Number.isFinite(o.radius)).map((o, index) => {\n const t = Math.min(0.94, Math.max(0.06, o.t));\n const offset = Math.min(0.75, Math.max(-0.75, o.offset));\n const radius = Math.min(MAX_OBSTACLE_RADIUS, Math.max(0.3, o.radius));\n const at = sampleTrack(track, t * track.length);\n const lateral = offset * track.width / 2;\n return { id: index, kind: typeof o.kind === 'string' ? o.kind : 'block', radius: rounded(radius), s: rounded(at.s), lateral: rounded(lateral),\n x: rounded(at.x - at.tangent.z * lateral), z: rounded(at.z + at.tangent.x * lateral) };\n });\n}\n\n/**\n * `mapId` stays 'neon_city' on the wire. `trackId` selects the circuit: absent/'oval' keeps the\n * legacy 128-point oval with the exact same hash as before; the five spline circuits add\n * `trackId` and `obstacles` to the hashed geometry. `speedClass` scales length and width and\n * enters the hash, so both clients must agree on it.\n */\nexport function generateTrack(mapId = 'neon_city', seed = 0, { speedClass, trackId } = {}) {\n const selectedMap = mapId === 'random' ? 'neon_city' : mapId;\n if (!RACE_TRACK_MAP_IDS.includes(selectedMap)) throw new RangeError(`Unsupported race map: ${mapId}`);\n if (speedClass != null && !getRaceClass(speedClass)) throw new RangeError(`Unsupported speed class: ${speedClass}`);\n if (trackId != null && !isRaceTrackId(trackId)) throw new RangeError(`Unsupported race track: ${trackId}`);\n const normalizedSeed = normalizeSeed(seed);\n const raceClass = getRaceClass(speedClass);\n const definition = trackId && trackId !== LEGACY_TRACK_ID ? getTrackDefinition(trackId) : null;\n let raw; let targetLength; let roadWidth;\n if (definition) {\n ({ length: targetLength, width: roadWidth } = circuitDimensions(definition, raceClass));\n raw = smoothClosedSpline(definition.controlPoints, CIRCUIT_SEGMENTS);\n } else {\n targetLength = raceClass ? raceClass.trackLength : LEGACY_RACE.trackLength;\n roadWidth = raceClass ? raceClass.trackWidth : LEGACY_RACE.trackWidth;\n raw = Array.from({ length: SEGMENTS }, (_, i) => {\n const angle = i / SEGMENTS * Math.PI * 2;\n return { x: 110 * Math.cos(angle), z: 75 * Math.sin(angle) };\n });\n }\n const count = raw.length;\n const rawLength = raw.reduce((sum, point, i) => sum + distanceBetween(point, raw[(i + 1) % count]), 0);\n const scale = targetLength / rawLength;\n const points = raw.map((point) => ({ x: rounded(point.x * scale), z: rounded(point.z * scale) }));\n points.push({ ...points[0] });\n let length = 0;\n points.forEach((point, i) => {\n if (i) length += distanceBetween(points[i - 1], point);\n point.s = length;\n });\n // Checkpoints cover only the road. The traversable shoulder does not grant\n // progress: a driver must pass the gate on the road rather than cut around it.\n const checkpoints = [0, 1, 2, 3].map((index) => {\n const pointIndex = index * count / 4;\n const point = points[pointIndex];\n const normal = tangentAt(points, pointIndex);\n const side = { x: -normal.z, z: normal.x };\n return { id: index, index, s: point.s, center: { x: point.x, z: point.z }, normal, halfWidth: roadWidth / 2,\n a: { x: point.x + side.x * roadWidth / 2, z: point.z + side.z * roadWidth / 2 },\n b: { x: point.x - side.x * roadWidth / 2, z: point.z - side.z * roadWidth / 2 } };\n });\n // Physical barriers leave a three-metre shoulder beyond each road edge. Scenery is\n // decoration only; on-road obstacles (spline circuits) are listed in `obstacles`.\n const colliders = [-1, 1].map((side) => ({\n id: side < 0 ? 'right_edge' : 'left_edge', type: 'track_boundary',\n points: points.map((point, i) => {\n const tangent = tangentAt(points, i % count);\n const offset = roadWidth / 2 + BARRIER_MARGIN;\n return { x: rounded(point.x - tangent.z * side * offset), z: rounded(point.z + tangent.x * side * offset) };\n }),\n }));\n const track = { mapId: selectedMap, ...(definition ? { trackId: definition.id } : {}), seed: normalizedSeed, ...(raceClass ? { speedClass: raceClass.id } : {}), rulesVersion: RACE_TRACK_RULES_VERSION, width: roadWidth, barrierMargin: BARRIER_MARGIN, length, points, checkpoints, colliders };\n if (definition) track.obstacles = placeObstacles(definition, track);\n const start = sampleTrack(track, length - 8);\n const yaw = Math.atan2(start.tangent.x, start.tangent.z);\n track.grid = [-roadWidth / 4, roadWidth / 4].map((lateral, playerIndex) => ({\n playerIndex, x: start.x - start.tangent.z * lateral, z: start.z + start.tangent.x * lateral,\n s: start.s, lateral, yaw, heading: yaw,\n }));\n track.startFinish = checkpoints[0];\n // Include all competitive geometry, grid and normalized seed in the versioned hash.\n track.trackHash = `racing-v${RACE_TRACK_RULES_VERSION}-${hashText(JSON.stringify(track))}`;\n return track;\n}\n"],"mappings":"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"}