@fboes/aerofly-custom-missions 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +46 -1
- package/dist/index.js +117 -24
- package/dist/index.test.js +33 -10
- package/package.json +1 -1
- package/src/index.test.ts +33 -7
- package/src/index.ts +197 -20
- package/types/index.d.ts +109 -6
- package/types/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
- Added new mission properties `tags`, `isFeatured`, `difficulty`, `distance`, `duration` and translations
|
|
6
|
+
- Added new flight settings `"winch_launch`, `aerotow`
|
|
7
|
+
- Improved temperature property
|
|
8
|
+
|
|
9
|
+
## 1.0.4
|
|
10
|
+
|
|
3
11
|
- Added documentation for known issues
|
|
4
12
|
- Added property `AeroflyMissionConditions.temperature`
|
|
5
13
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Builder for Aerofly FS4 Custom Missions Files
|
|
4
4
|
|
|
5
|
-
[Aerofly Flight Simulator 4](https://www.aerofly.com/) has a custom missions file `custom_missions_user.tmc` with a very unique format. To help you build this custom missions file, this JavaScript / TypeScript library offers Data Objects to create this file
|
|
5
|
+
[Aerofly Flight Simulator 4](https://www.aerofly.com/) has a custom missions file `custom_missions_user.tmc` with a very unique format. To help you build this custom missions file, this JavaScript / TypeScript library offers Data Objects to create this file programmatically.
|
|
6
6
|
|
|
7
7
|
This library is intended to work in modern browsers as well as [Node.js](https://nodejs.org/en).
|
|
8
8
|
|
|
@@ -119,6 +119,44 @@ console.log(missionList.toString());
|
|
|
119
119
|
|
|
120
120
|
As there are lots of properties for the mission object, check the type hinting on the various objects to find out which properties you are able to set.
|
|
121
121
|
|
|
122
|
+
### Values for tags
|
|
123
|
+
|
|
124
|
+
The `tags` property of a single mission can contain multiple values. The following values have been used officially by Aerofly FS4.
|
|
125
|
+
|
|
126
|
+
- aerobatics
|
|
127
|
+
- aerotow
|
|
128
|
+
- airline
|
|
129
|
+
- airshow
|
|
130
|
+
- circling_approach
|
|
131
|
+
- crosswind
|
|
132
|
+
- dropoff
|
|
133
|
+
- full_flight
|
|
134
|
+
- gliding
|
|
135
|
+
- instruments
|
|
136
|
+
- landing
|
|
137
|
+
- law_enforcement
|
|
138
|
+
- low_level_flight
|
|
139
|
+
- low_visibility
|
|
140
|
+
- medical
|
|
141
|
+
- military
|
|
142
|
+
- night
|
|
143
|
+
- pattern
|
|
144
|
+
- practice
|
|
145
|
+
- race
|
|
146
|
+
- short_runway
|
|
147
|
+
- sidestep_approach
|
|
148
|
+
- sight_seeing
|
|
149
|
+
- sloped_runway
|
|
150
|
+
- steep_approach
|
|
151
|
+
- straight_in_approach
|
|
152
|
+
- supersonic
|
|
153
|
+
- surveillance
|
|
154
|
+
- takeoff
|
|
155
|
+
- terrain_avoidance
|
|
156
|
+
- vip
|
|
157
|
+
- winch_launch
|
|
158
|
+
- windy
|
|
159
|
+
|
|
122
160
|
### Important notices
|
|
123
161
|
|
|
124
162
|
- Be aware that `mission.origin` and `mission.destination` do not need to match the flight plan. In case of `origin` you may want to set the position to the actual parking position of your aircraft, which may not be the first way point in your flight plan.
|
|
@@ -129,6 +167,13 @@ As there are lots of properties for the mission object, check the type hinting o
|
|
|
129
167
|
- `destination`
|
|
130
168
|
- Be aware that all units for altitude, elevation or distance are measured in meters! In most cases there will be helper functions for defining these values in feet (for length, altitude, elevation) or statute miles (for visibility).
|
|
131
169
|
|
|
170
|
+
There are also some unsupported properties, which are present in Aerofly FS4, but as of yet will not be generated by this library:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
<[string8][tutorial_name][c172]> // Opens https://www.aerofly.com/aircraft-tutorials/${tutorial_name}
|
|
174
|
+
<[bool][is_scheduled][true]>
|
|
175
|
+
```
|
|
176
|
+
|
|
132
177
|
### Known issues
|
|
133
178
|
|
|
134
179
|
- `AeroflyMissionConditions.time`: Even though a date property is available in Aerofly FS 4 (which is not accessible to the user), [the custom missions cannot change the date in Aerofly FS 4](https://www.aerofly.com/community/forum/index.php?thread/22487-more-settings-for-environment-conditions/&pageNo=1).
|
package/dist/index.js
CHANGED
|
@@ -40,15 +40,21 @@ export class AeroflyMission {
|
|
|
40
40
|
* @param {string} title of this flight plan
|
|
41
41
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
42
42
|
* @param {string} [additionalAttributes.description] text, mission briefing, etc
|
|
43
|
-
* @param {
|
|
43
|
+
* @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
|
|
44
|
+
* @param {string[]} [additionalAttributes.tags]
|
|
45
|
+
* @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
|
|
46
|
+
* @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
|
|
47
|
+
* @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
|
|
44
48
|
* @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
|
|
45
49
|
* @param {string} [additionalAttributes.callsign] of aircraft, uppercased
|
|
46
50
|
* @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
47
51
|
* @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
52
|
+
* @param {number} [additionalAttributes.distance] in meters
|
|
53
|
+
* @param {number} [additionalAttributes.duration] in seconds
|
|
48
54
|
* @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
|
|
49
55
|
* @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
|
|
50
56
|
*/
|
|
51
|
-
constructor(title, { description = "", flightSetting = "taxi", aircraft = {
|
|
57
|
+
constructor(title, { description = "", localizedTexts = [], tags = [], isFeatured = false, difficulty = undefined, flightSetting = "taxi", aircraft = {
|
|
52
58
|
name: "c172",
|
|
53
59
|
icao: "",
|
|
54
60
|
livery: "",
|
|
@@ -64,15 +70,21 @@ export class AeroflyMission {
|
|
|
64
70
|
latitude: 0,
|
|
65
71
|
dir: 0,
|
|
66
72
|
alt: 0,
|
|
67
|
-
}, conditions = new AeroflyMissionConditions(), checkpoints = [], } = {}) {
|
|
73
|
+
}, distance = 0, duration = 0, conditions = new AeroflyMissionConditions(), checkpoints = [], } = {}) {
|
|
68
74
|
this.title = title;
|
|
69
75
|
this.checkpoints = checkpoints;
|
|
70
76
|
this.description = description;
|
|
77
|
+
this.localizedTexts = localizedTexts;
|
|
78
|
+
this.tags = tags;
|
|
79
|
+
this.isFeatured = isFeatured;
|
|
80
|
+
this.difficulty = difficulty;
|
|
71
81
|
this.flightSetting = flightSetting;
|
|
72
82
|
this.aircraft = aircraft;
|
|
73
83
|
this.callsign = callsign;
|
|
74
84
|
this.origin = origin;
|
|
75
85
|
this.destination = destination;
|
|
86
|
+
this.distance = distance;
|
|
87
|
+
this.duration = duration;
|
|
76
88
|
this.conditions = conditions;
|
|
77
89
|
}
|
|
78
90
|
/**
|
|
@@ -85,6 +97,16 @@ export class AeroflyMission {
|
|
|
85
97
|
})
|
|
86
98
|
.join("\n");
|
|
87
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* @returns {string} indexed checkpoints
|
|
102
|
+
*/
|
|
103
|
+
getLocalizedTextsString() {
|
|
104
|
+
return this.localizedTexts
|
|
105
|
+
.map((c, index) => {
|
|
106
|
+
return c.toString(index);
|
|
107
|
+
})
|
|
108
|
+
.join("\n");
|
|
109
|
+
}
|
|
88
110
|
/**
|
|
89
111
|
* @throws {Error} on missing waypoints
|
|
90
112
|
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
@@ -113,9 +135,32 @@ export class AeroflyMission {
|
|
|
113
135
|
alt: lastCheckpoint.altitude,
|
|
114
136
|
};
|
|
115
137
|
}
|
|
138
|
+
const optionalProperties = [];
|
|
139
|
+
if (this.localizedTexts.length > 0) {
|
|
140
|
+
optionalProperties.push(` <[list_tmmission_definition_localized][localized_text][]
|
|
141
|
+
${this.getLocalizedTextsString()}
|
|
142
|
+
>`);
|
|
143
|
+
}
|
|
144
|
+
if (this.tags.length > 0) {
|
|
145
|
+
optionalProperties.push(` <[string8u][tags][ ${this.tags.join(" ")} ]>`);
|
|
146
|
+
}
|
|
147
|
+
if (this.difficulty !== undefined) {
|
|
148
|
+
optionalProperties.push(` <[float64] [difficulty] [${this.difficulty}]>`);
|
|
149
|
+
}
|
|
150
|
+
if (this.isFeatured) {
|
|
151
|
+
optionalProperties.push(` <[bool][is_featured][[${this.isFeatured ? "true" : "false"}]>`);
|
|
152
|
+
}
|
|
153
|
+
const moreOptionalProperties = [];
|
|
154
|
+
if (this.distance) {
|
|
155
|
+
moreOptionalProperties.push(` <[float64] [distance] [${this.distance}]> // ${Math.ceil(this.distance / 1000)} km`);
|
|
156
|
+
}
|
|
157
|
+
if (this.duration) {
|
|
158
|
+
moreOptionalProperties.push(` <[float64] [duration] [${this.duration}]> // ${Math.ceil(this.duration / 60)} min`);
|
|
159
|
+
}
|
|
116
160
|
return ` <[tmmission_definition][mission][]
|
|
117
161
|
<[string8][title][${this.title}]>
|
|
118
162
|
<[string8][description][${this.description}]>
|
|
163
|
+
${optionalProperties.join("\n")}
|
|
119
164
|
<[string8] [flight_setting] [${this.flightSetting}]>
|
|
120
165
|
<[string8u] [aircraft_name] [${this.aircraft.name}]>
|
|
121
166
|
//<[string8u][aircraft_livery] [${this.aircraft.livery}]>
|
|
@@ -123,11 +168,13 @@ export class AeroflyMission {
|
|
|
123
168
|
<[stringt8c] [callsign] [${this.callsign}]>
|
|
124
169
|
<[stringt8c] [origin_icao] [${this.origin.icao}]>
|
|
125
170
|
<[tmvector2d][origin_lon_lat] [${this.origin.longitude} ${this.origin.latitude}]>
|
|
126
|
-
<[float64] [origin_dir] [${this.origin.dir}]>
|
|
127
171
|
<[float64] [origin_alt] [${this.origin.alt}]> // ${this.origin.alt * feetPerMeter} ft MSL
|
|
172
|
+
<[float64] [origin_dir] [${this.origin.dir}]>
|
|
128
173
|
<[stringt8c] [destination_icao] [${this.destination.icao}]>
|
|
129
174
|
<[tmvector2d][destination_lon_lat][${this.destination.longitude} ${this.destination.latitude}]>
|
|
175
|
+
<[float64] [destination_alt] [${this.destination.alt}]> // ${this.destination.alt * feetPerMeter} ft MSL
|
|
130
176
|
<[float64] [destination_dir] [${this.destination.dir}]>
|
|
177
|
+
${moreOptionalProperties.join("\n")}
|
|
131
178
|
${this.conditions}
|
|
132
179
|
<[list_tmmission_checkpoint][checkpoints][]
|
|
133
180
|
${this.getCheckpointsString()}
|
|
@@ -152,27 +199,31 @@ export class AeroflyMissionConditions {
|
|
|
152
199
|
* @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
|
|
153
200
|
* @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
|
|
154
201
|
* @param {number} [additionalAttributes.visibility] in meters
|
|
155
|
-
* @param {number?} [additionalAttributes.visibility_sm] in statute miles
|
|
202
|
+
* @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
|
|
203
|
+
* @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
|
|
156
204
|
* @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
|
|
157
205
|
*/
|
|
158
206
|
constructor({ time = new Date(), wind = {
|
|
159
207
|
direction: 0,
|
|
160
208
|
speed: 0,
|
|
161
209
|
gusts: 0,
|
|
162
|
-
}, turbulenceStrength = 0, thermalStrength = 0, visibility =
|
|
210
|
+
}, turbulenceStrength = 0, thermalStrength = 0, visibility = 25000, visibility_sm = null, temperature = null, clouds = [], } = {}) {
|
|
163
211
|
/**
|
|
164
212
|
* @property {AeroflyMissionConditionsCloud[]} clouds for the whole flight
|
|
165
213
|
*/
|
|
166
214
|
this.clouds = [];
|
|
167
|
-
if (visibility_sm) {
|
|
168
|
-
visibility = visibility_sm * meterPerStatuteMile;
|
|
169
|
-
}
|
|
170
215
|
this.time = time;
|
|
171
216
|
this.wind = wind;
|
|
172
217
|
this.turbulenceStrength = turbulenceStrength;
|
|
173
218
|
this.thermalStrength = thermalStrength;
|
|
174
219
|
this.visibility = visibility;
|
|
175
220
|
this.clouds = clouds;
|
|
221
|
+
if (visibility_sm) {
|
|
222
|
+
this.visibility_sm = visibility_sm;
|
|
223
|
+
}
|
|
224
|
+
if (temperature) {
|
|
225
|
+
this.temperature = temperature;
|
|
226
|
+
}
|
|
176
227
|
}
|
|
177
228
|
/**
|
|
178
229
|
* @returns {number} the Aerofly value for UTC hours + minutes/60 + seconds/3600. Ignores milliseconds ;)
|
|
@@ -207,8 +258,14 @@ export class AeroflyMissionConditions {
|
|
|
207
258
|
* @param {number} temperature in °C
|
|
208
259
|
*/
|
|
209
260
|
set temperature(temperature) {
|
|
210
|
-
// Range from
|
|
211
|
-
this.thermalStrength = Math.max(0, (temperature
|
|
261
|
+
// Range from -15°C to 35°C
|
|
262
|
+
this.thermalStrength = Math.max(0, (temperature + 15) / 50) ** 2;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* @returns {number} in °C
|
|
266
|
+
*/
|
|
267
|
+
get temperature() {
|
|
268
|
+
return Math.sqrt(this.thermalStrength) * 50 - 15;
|
|
212
269
|
}
|
|
213
270
|
/**
|
|
214
271
|
* @returns {string}
|
|
@@ -238,7 +295,7 @@ export class AeroflyMissionConditions {
|
|
|
238
295
|
<[float64][wind_speed][${this.wind.speed}]> // kts
|
|
239
296
|
<[float64][wind_gusts][${this.wind.gusts}]> // kts
|
|
240
297
|
<[float64][turbulence_strength][${this.turbulenceStrength}]>
|
|
241
|
-
<[float64][thermal_strength][${this.thermalStrength}]>
|
|
298
|
+
<[float64][thermal_strength][${this.thermalStrength}]> // ${this.temperature} °C
|
|
242
299
|
<[float64][visibility][${this.visibility}]> // ${this.visibility_sm} SM
|
|
243
300
|
${this.getCloudsString()}
|
|
244
301
|
>`;
|
|
@@ -333,20 +390,14 @@ export class AeroflyMissionCheckpoint {
|
|
|
333
390
|
* @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
|
|
334
391
|
* 84 reference ellipsoid
|
|
335
392
|
* @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
|
|
336
|
-
* 84 reference ellipsoid
|
|
393
|
+
* 84 reference ellipsoid. Will overwrite altitude
|
|
337
394
|
* @param {number} [additionalAttributes.direction] of runway, in degree
|
|
338
395
|
* @param {number?} [additionalAttributes.slope] of runway
|
|
339
396
|
* @param {number?} [additionalAttributes.length] of runway, in meters
|
|
340
|
-
* @param {number?} [additionalAttributes.length_feet] of runway, in feet
|
|
397
|
+
* @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
|
|
341
398
|
* @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
342
399
|
*/
|
|
343
400
|
constructor(name, type, longitude, latitude, { altitude = 0, altitude_feet = null, direction = null, slope = null, length = null, length_feet = null, frequency = null, } = {}) {
|
|
344
|
-
if (altitude_feet) {
|
|
345
|
-
altitude = altitude_feet / feetPerMeter;
|
|
346
|
-
}
|
|
347
|
-
if (length_feet) {
|
|
348
|
-
length = length_feet / feetPerMeter;
|
|
349
|
-
}
|
|
350
401
|
this.type = type;
|
|
351
402
|
this.name = name;
|
|
352
403
|
this.longitude = longitude;
|
|
@@ -356,6 +407,12 @@ export class AeroflyMissionCheckpoint {
|
|
|
356
407
|
this.slope = slope;
|
|
357
408
|
this.length = length;
|
|
358
409
|
this.frequency = frequency;
|
|
410
|
+
if (altitude_feet) {
|
|
411
|
+
this.altitude_feet = altitude_feet;
|
|
412
|
+
}
|
|
413
|
+
if (length_feet) {
|
|
414
|
+
this.length_feet = length_feet;
|
|
415
|
+
}
|
|
359
416
|
}
|
|
360
417
|
/**
|
|
361
418
|
* @param {number} altitude_feet
|
|
@@ -388,11 +445,11 @@ export class AeroflyMissionCheckpoint {
|
|
|
388
445
|
if (!this.frequency) {
|
|
389
446
|
return "None";
|
|
390
447
|
}
|
|
391
|
-
if (this.frequency >
|
|
392
|
-
return String(this.frequency /
|
|
448
|
+
if (this.frequency > 1000000) {
|
|
449
|
+
return String(this.frequency / 1000000) + " MHz";
|
|
393
450
|
}
|
|
394
|
-
if (this.frequency >
|
|
395
|
-
return String(this.frequency /
|
|
451
|
+
if (this.frequency > 1000) {
|
|
452
|
+
return String(this.frequency / 1000) + " kHz";
|
|
396
453
|
}
|
|
397
454
|
return String(this.frequency) + " Hz";
|
|
398
455
|
}
|
|
@@ -413,10 +470,46 @@ export class AeroflyMissionCheckpoint {
|
|
|
413
470
|
>`;
|
|
414
471
|
}
|
|
415
472
|
}
|
|
473
|
+
export class AeroflyLocalizedText {
|
|
474
|
+
/**
|
|
475
|
+
* @param {string} language like
|
|
476
|
+
* - br
|
|
477
|
+
* - cn
|
|
478
|
+
* - de
|
|
479
|
+
* - es
|
|
480
|
+
* - fr
|
|
481
|
+
* - id
|
|
482
|
+
* - it
|
|
483
|
+
* - jp
|
|
484
|
+
* - kr
|
|
485
|
+
* - pl
|
|
486
|
+
* - sv
|
|
487
|
+
* - tr
|
|
488
|
+
* @param {string} title of this flight plan
|
|
489
|
+
* @param {string} description text, mission briefing, etc
|
|
490
|
+
*/
|
|
491
|
+
constructor(language, title, description) {
|
|
492
|
+
this.language = language;
|
|
493
|
+
this.title = title;
|
|
494
|
+
this.description = description;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* @param {number} index if used in an array will se the array index
|
|
498
|
+
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
499
|
+
*/
|
|
500
|
+
toString(index) {
|
|
501
|
+
return ` <[tmmission_definition_localized][element][${index}]
|
|
502
|
+
<[string8u][language][${this.language}]>
|
|
503
|
+
<[string8][title][${this.title}]>
|
|
504
|
+
<[string8][description][${this.description}]>
|
|
505
|
+
>`;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
416
508
|
export default {
|
|
417
509
|
AeroflyMissionsList,
|
|
418
510
|
AeroflyMission,
|
|
419
511
|
AeroflyMissionConditions,
|
|
420
512
|
AeroflyMissionConditionsCloud,
|
|
421
513
|
AeroflyMissionCheckpoint,
|
|
514
|
+
AeroflyLocalizedText,
|
|
422
515
|
};
|
package/dist/index.test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AeroflyMissionsList, AeroflyMission, AeroflyMissionConditions, AeroflyMissionConditionsCloud, AeroflyMissionCheckpoint, } from "./index.js";
|
|
1
|
+
import { AeroflyMissionsList, AeroflyMission, AeroflyMissionConditions, AeroflyMissionConditionsCloud, AeroflyMissionCheckpoint, AeroflyLocalizedText, } from "./index.js";
|
|
2
2
|
import { strict as assert } from "node:assert";
|
|
3
3
|
{
|
|
4
4
|
const mission = new AeroflyMission("Title");
|
|
@@ -7,8 +7,8 @@ import { strict as assert } from "node:assert";
|
|
|
7
7
|
}
|
|
8
8
|
{
|
|
9
9
|
const conditions = new AeroflyMissionConditions();
|
|
10
|
-
conditions.visibility =
|
|
11
|
-
assert.deepStrictEqual(conditions.visibility,
|
|
10
|
+
conditions.visibility = 15000;
|
|
11
|
+
assert.deepStrictEqual(conditions.visibility, 15000);
|
|
12
12
|
conditions.visibility_sm = 10;
|
|
13
13
|
assert.notDeepStrictEqual(conditions.visibility, 10);
|
|
14
14
|
assert.deepStrictEqual(Math.round(conditions.visibility_sm), 10);
|
|
@@ -16,9 +16,9 @@ import { strict as assert } from "node:assert";
|
|
|
16
16
|
}
|
|
17
17
|
{
|
|
18
18
|
const conditions = new AeroflyMissionConditions({
|
|
19
|
-
visibility:
|
|
19
|
+
visibility: 15000,
|
|
20
20
|
});
|
|
21
|
-
assert.deepStrictEqual(conditions.visibility,
|
|
21
|
+
assert.deepStrictEqual(conditions.visibility, 15000);
|
|
22
22
|
console.log("✅ AeroflyMissionConditions test successful");
|
|
23
23
|
}
|
|
24
24
|
{
|
|
@@ -53,7 +53,7 @@ import { strict as assert } from "node:assert";
|
|
|
53
53
|
gusts: 22,
|
|
54
54
|
},
|
|
55
55
|
turbulenceStrength: 1,
|
|
56
|
-
|
|
56
|
+
temperature: 21,
|
|
57
57
|
visibility: 14484.096000000001,
|
|
58
58
|
clouds: [
|
|
59
59
|
AeroflyMissionConditionsCloud.createInFeet(0.1, 5000),
|
|
@@ -64,7 +64,7 @@ import { strict as assert } from "node:assert";
|
|
|
64
64
|
assert.strictEqual(conditions.wind.speed, 11);
|
|
65
65
|
assert.strictEqual(conditions.wind.gusts, 22);
|
|
66
66
|
assert.strictEqual(conditions.turbulenceStrength, 1);
|
|
67
|
-
assert.strictEqual(conditions.
|
|
67
|
+
assert.strictEqual(conditions.temperature, 21);
|
|
68
68
|
assert.strictEqual(conditions.visibility, 14484.096000000001);
|
|
69
69
|
const checkpoints = [
|
|
70
70
|
new AeroflyMissionCheckpoint("KCCR", "origin", -122.057, 37.9897, {
|
|
@@ -115,9 +115,7 @@ import { strict as assert } from "node:assert";
|
|
|
115
115
|
assert.strictEqual(missionList.missions.length, 1);
|
|
116
116
|
assert.strictEqual(missionList.missions[0].aircraft.name, "c172");
|
|
117
117
|
assert.strictEqual(missionList.missions[0].aircraft.icao, "C172");
|
|
118
|
-
|
|
119
|
-
const missionListString = missionList.toString();
|
|
120
|
-
//console.log(missionListString);
|
|
118
|
+
let missionListString = missionList.toString();
|
|
121
119
|
assert.ok(missionListString.includes("[origin]"));
|
|
122
120
|
assert.ok(missionListString.includes("[tmmission_definition]"));
|
|
123
121
|
assert.ok(missionListString.includes("[list_tmmission_checkpoint]"));
|
|
@@ -130,5 +128,30 @@ import { strict as assert } from "node:assert";
|
|
|
130
128
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][2]"));
|
|
131
129
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][3]"));
|
|
132
130
|
assert.ok(missionListString.includes("<[float64][length][844.2959729825288]>"));
|
|
131
|
+
assert.ok(!missionListString.includes("[tags]"));
|
|
132
|
+
assert.ok(!missionListString.includes("[difficulty]"));
|
|
133
|
+
assert.ok(!missionListString.includes("[is_featured]"));
|
|
134
|
+
assert.ok(!missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
135
|
+
assert.ok(!missionListString.includes("[distance]"));
|
|
136
|
+
assert.ok(!missionListString.includes("[duration]"));
|
|
137
|
+
//console.log(missionListString);
|
|
138
|
+
mission.difficulty = 1.0;
|
|
139
|
+
mission.isFeatured = true;
|
|
140
|
+
mission.localizedTexts.push(new AeroflyLocalizedText("de", "Landeübung #1", "Probier die Landung"));
|
|
141
|
+
mission.distance = 1400;
|
|
142
|
+
mission.duration = 2 * 60 * 60;
|
|
143
|
+
mission.tags.push("approach");
|
|
144
|
+
mission.tags.push("pattern");
|
|
145
|
+
missionListString = missionList.toString();
|
|
146
|
+
assert.ok(missionListString.includes("[tags]"));
|
|
147
|
+
assert.ok(missionListString.includes("[difficulty]"));
|
|
148
|
+
assert.ok(missionListString.includes("[is_featured]"));
|
|
149
|
+
assert.ok(missionListString.includes("true"));
|
|
150
|
+
assert.ok(missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
151
|
+
assert.ok(missionListString.includes("Landeübung"));
|
|
152
|
+
assert.ok(missionListString.includes("[distance]"));
|
|
153
|
+
assert.ok(missionListString.includes("[duration]"));
|
|
154
|
+
//console.dir(missionList.missions[0], { depth: null });
|
|
155
|
+
//console.log(missionListString);
|
|
133
156
|
console.log("✅ AeroflyMissionsList test successful");
|
|
134
157
|
}
|
package/package.json
CHANGED
package/src/index.test.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
AeroflyMissionConditions,
|
|
5
5
|
AeroflyMissionConditionsCloud,
|
|
6
6
|
AeroflyMissionCheckpoint,
|
|
7
|
+
AeroflyLocalizedText,
|
|
7
8
|
} from "./index.js";
|
|
8
9
|
import { strict as assert } from "node:assert";
|
|
9
10
|
|
|
@@ -69,7 +70,7 @@ import { strict as assert } from "node:assert";
|
|
|
69
70
|
gusts: 22,
|
|
70
71
|
},
|
|
71
72
|
turbulenceStrength: 1,
|
|
72
|
-
|
|
73
|
+
temperature: 21,
|
|
73
74
|
visibility: 14484.096000000001,
|
|
74
75
|
clouds: [
|
|
75
76
|
AeroflyMissionConditionsCloud.createInFeet(0.1, 5000),
|
|
@@ -81,7 +82,7 @@ import { strict as assert } from "node:assert";
|
|
|
81
82
|
assert.strictEqual(conditions.wind.speed, 11);
|
|
82
83
|
assert.strictEqual(conditions.wind.gusts, 22);
|
|
83
84
|
assert.strictEqual(conditions.turbulenceStrength, 1);
|
|
84
|
-
assert.strictEqual(conditions.
|
|
85
|
+
assert.strictEqual(conditions.temperature, 21);
|
|
85
86
|
assert.strictEqual(conditions.visibility, 14484.096000000001);
|
|
86
87
|
|
|
87
88
|
const checkpoints = [
|
|
@@ -137,11 +138,7 @@ import { strict as assert } from "node:assert";
|
|
|
137
138
|
assert.strictEqual(missionList.missions[0].aircraft.name, "c172");
|
|
138
139
|
assert.strictEqual(missionList.missions[0].aircraft.icao, "C172");
|
|
139
140
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const missionListString = missionList.toString();
|
|
143
|
-
|
|
144
|
-
//console.log(missionListString);
|
|
141
|
+
let missionListString = missionList.toString();
|
|
145
142
|
|
|
146
143
|
assert.ok(missionListString.includes("[origin]"));
|
|
147
144
|
assert.ok(missionListString.includes("[tmmission_definition]"));
|
|
@@ -155,6 +152,35 @@ import { strict as assert } from "node:assert";
|
|
|
155
152
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][2]"));
|
|
156
153
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][3]"));
|
|
157
154
|
assert.ok(missionListString.includes("<[float64][length][844.2959729825288]>"));
|
|
155
|
+
assert.ok(!missionListString.includes("[tags]"));
|
|
156
|
+
assert.ok(!missionListString.includes("[difficulty]"));
|
|
157
|
+
assert.ok(!missionListString.includes("[is_featured]"));
|
|
158
|
+
assert.ok(!missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
159
|
+
assert.ok(!missionListString.includes("[distance]"));
|
|
160
|
+
assert.ok(!missionListString.includes("[duration]"));
|
|
161
|
+
|
|
162
|
+
//console.log(missionListString);
|
|
163
|
+
|
|
164
|
+
mission.difficulty = 1.0;
|
|
165
|
+
mission.isFeatured = true;
|
|
166
|
+
mission.localizedTexts.push(new AeroflyLocalizedText("de", "Landeübung #1", "Probier die Landung"));
|
|
167
|
+
mission.distance = 1400;
|
|
168
|
+
mission.duration = 2 * 60 * 60;
|
|
169
|
+
mission.tags.push("approach");
|
|
170
|
+
mission.tags.push("pattern");
|
|
171
|
+
missionListString = missionList.toString();
|
|
172
|
+
|
|
173
|
+
assert.ok(missionListString.includes("[tags]"));
|
|
174
|
+
assert.ok(missionListString.includes("[difficulty]"));
|
|
175
|
+
assert.ok(missionListString.includes("[is_featured]"));
|
|
176
|
+
assert.ok(missionListString.includes("true"));
|
|
177
|
+
assert.ok(missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
178
|
+
assert.ok(missionListString.includes("Landeübung"));
|
|
179
|
+
assert.ok(missionListString.includes("[distance]"));
|
|
180
|
+
assert.ok(missionListString.includes("[duration]"));
|
|
181
|
+
|
|
182
|
+
//console.dir(missionList.missions[0], { depth: null });
|
|
183
|
+
//console.log(missionListString);
|
|
158
184
|
|
|
159
185
|
console.log("✅ AeroflyMissionsList test successful");
|
|
160
186
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type AeroflyMissionPosition = {
|
|
|
25
25
|
/**
|
|
26
26
|
* State of aircraft systems. Configures power settings, flap positions etc
|
|
27
27
|
*/
|
|
28
|
-
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing";
|
|
28
|
+
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing" | "winch_launch" | "aerotow";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Types of checkpoints. Required are usually "origin", "departure_runway" at the start and "destination_runway", "destination" at the end.
|
|
@@ -112,6 +112,8 @@ export class AeroflyMissionsList {
|
|
|
112
112
|
* for this file via the `toString()` method.
|
|
113
113
|
*/
|
|
114
114
|
export class AeroflyMission {
|
|
115
|
+
// tutorial_name
|
|
116
|
+
|
|
115
117
|
/**
|
|
116
118
|
* @property {string} title of this flight plan
|
|
117
119
|
*/
|
|
@@ -123,7 +125,27 @@ export class AeroflyMission {
|
|
|
123
125
|
description: string;
|
|
124
126
|
|
|
125
127
|
/**
|
|
126
|
-
* @property {
|
|
128
|
+
* @property {AeroflyLocalizedText[]} localizedTexts for title and description
|
|
129
|
+
*/
|
|
130
|
+
localizedTexts: AeroflyLocalizedText[];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @property {string[]} tags
|
|
134
|
+
*/
|
|
135
|
+
tags: string[];
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @property {boolean} isFeatured makes this mission pop up in "Challenges"
|
|
139
|
+
*/
|
|
140
|
+
isFeatured: boolean;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @property {number|undefined} difficulty in 0..1, percentage
|
|
144
|
+
*/
|
|
145
|
+
difficulty: number | undefined;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} flightSetting of aircraft, like "taxi", "cruise"
|
|
127
149
|
*/
|
|
128
150
|
flightSetting: AeroflyMissionSetting;
|
|
129
151
|
|
|
@@ -147,6 +169,16 @@ export class AeroflyMission {
|
|
|
147
169
|
*/
|
|
148
170
|
destination: AeroflyMissionPosition;
|
|
149
171
|
|
|
172
|
+
/**
|
|
173
|
+
* @property {number} in meters
|
|
174
|
+
*/
|
|
175
|
+
distance: number;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @property {number} in seconds
|
|
179
|
+
*/
|
|
180
|
+
duration: number;
|
|
181
|
+
|
|
150
182
|
/**
|
|
151
183
|
* @property {AeroflyMissionConditions} conditions like time and weather for mission
|
|
152
184
|
*/
|
|
@@ -161,11 +193,17 @@ export class AeroflyMission {
|
|
|
161
193
|
* @param {string} title of this flight plan
|
|
162
194
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
163
195
|
* @param {string} [additionalAttributes.description] text, mission briefing, etc
|
|
164
|
-
* @param {
|
|
196
|
+
* @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
|
|
197
|
+
* @param {string[]} [additionalAttributes.tags]
|
|
198
|
+
* @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
|
|
199
|
+
* @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
|
|
200
|
+
* @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
|
|
165
201
|
* @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
|
|
166
202
|
* @param {string} [additionalAttributes.callsign] of aircraft, uppercased
|
|
167
203
|
* @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
168
204
|
* @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
205
|
+
* @param {number} [additionalAttributes.distance] in meters
|
|
206
|
+
* @param {number} [additionalAttributes.duration] in seconds
|
|
169
207
|
* @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
|
|
170
208
|
* @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
|
|
171
209
|
*/
|
|
@@ -173,6 +211,10 @@ export class AeroflyMission {
|
|
|
173
211
|
title: string,
|
|
174
212
|
{
|
|
175
213
|
description = "",
|
|
214
|
+
localizedTexts = [],
|
|
215
|
+
tags = [],
|
|
216
|
+
isFeatured = false,
|
|
217
|
+
difficulty = undefined,
|
|
176
218
|
flightSetting = "taxi",
|
|
177
219
|
aircraft = {
|
|
178
220
|
name: "c172",
|
|
@@ -194,15 +236,23 @@ export class AeroflyMission {
|
|
|
194
236
|
dir: 0,
|
|
195
237
|
alt: 0,
|
|
196
238
|
},
|
|
239
|
+
distance = 0,
|
|
240
|
+
duration = 0,
|
|
197
241
|
conditions = new AeroflyMissionConditions(),
|
|
198
242
|
checkpoints = [],
|
|
199
243
|
}: {
|
|
200
244
|
description?: string;
|
|
245
|
+
localizedTexts?: AeroflyLocalizedText[];
|
|
246
|
+
tags?: string[];
|
|
247
|
+
isFeatured?: boolean;
|
|
248
|
+
difficulty?: number | undefined;
|
|
201
249
|
flightSetting?: AeroflyMissionSetting;
|
|
202
250
|
aircraft?: AeroflyMissionAircraft;
|
|
203
251
|
callsign?: string;
|
|
204
252
|
origin?: AeroflyMissionPosition;
|
|
205
253
|
destination?: AeroflyMissionPosition;
|
|
254
|
+
distance?: number;
|
|
255
|
+
duration?: number;
|
|
206
256
|
conditions?: AeroflyMissionConditions;
|
|
207
257
|
checkpoints?: AeroflyMissionCheckpoint[];
|
|
208
258
|
} = {},
|
|
@@ -210,11 +260,17 @@ export class AeroflyMission {
|
|
|
210
260
|
this.title = title;
|
|
211
261
|
this.checkpoints = checkpoints;
|
|
212
262
|
this.description = description;
|
|
263
|
+
this.localizedTexts = localizedTexts;
|
|
264
|
+
this.tags = tags;
|
|
265
|
+
this.isFeatured = isFeatured;
|
|
266
|
+
this.difficulty = difficulty;
|
|
213
267
|
this.flightSetting = flightSetting;
|
|
214
268
|
this.aircraft = aircraft;
|
|
215
269
|
this.callsign = callsign;
|
|
216
270
|
this.origin = origin;
|
|
217
271
|
this.destination = destination;
|
|
272
|
+
this.distance = distance;
|
|
273
|
+
this.duration = duration;
|
|
218
274
|
this.conditions = conditions;
|
|
219
275
|
}
|
|
220
276
|
|
|
@@ -229,6 +285,17 @@ export class AeroflyMission {
|
|
|
229
285
|
.join("\n");
|
|
230
286
|
}
|
|
231
287
|
|
|
288
|
+
/**
|
|
289
|
+
* @returns {string} indexed checkpoints
|
|
290
|
+
*/
|
|
291
|
+
getLocalizedTextsString(): string {
|
|
292
|
+
return this.localizedTexts
|
|
293
|
+
.map((c: AeroflyLocalizedText, index: number): string => {
|
|
294
|
+
return c.toString(index);
|
|
295
|
+
})
|
|
296
|
+
.join("\n");
|
|
297
|
+
}
|
|
298
|
+
|
|
232
299
|
/**
|
|
233
300
|
* @throws {Error} on missing waypoints
|
|
234
301
|
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
@@ -260,9 +327,38 @@ export class AeroflyMission {
|
|
|
260
327
|
};
|
|
261
328
|
}
|
|
262
329
|
|
|
330
|
+
const optionalProperties = [];
|
|
331
|
+
if (this.localizedTexts.length > 0) {
|
|
332
|
+
optionalProperties.push(` <[list_tmmission_definition_localized][localized_text][]
|
|
333
|
+
${this.getLocalizedTextsString()}
|
|
334
|
+
>`);
|
|
335
|
+
}
|
|
336
|
+
if (this.tags.length > 0) {
|
|
337
|
+
optionalProperties.push(` <[string8u][tags][ ${this.tags.join(" ")} ]>`);
|
|
338
|
+
}
|
|
339
|
+
if (this.difficulty !== undefined) {
|
|
340
|
+
optionalProperties.push(` <[float64] [difficulty] [${this.difficulty}]>`);
|
|
341
|
+
}
|
|
342
|
+
if (this.isFeatured) {
|
|
343
|
+
optionalProperties.push(` <[bool][is_featured][[${this.isFeatured ? "true" : "false"}]>`);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const moreOptionalProperties = [];
|
|
347
|
+
if (this.distance) {
|
|
348
|
+
moreOptionalProperties.push(
|
|
349
|
+
` <[float64] [distance] [${this.distance}]> // ${Math.ceil(this.distance / 1000)} km`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
if (this.duration) {
|
|
353
|
+
moreOptionalProperties.push(
|
|
354
|
+
` <[float64] [duration] [${this.duration}]> // ${Math.ceil(this.duration / 60)} min`,
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
|
|
263
358
|
return ` <[tmmission_definition][mission][]
|
|
264
359
|
<[string8][title][${this.title}]>
|
|
265
360
|
<[string8][description][${this.description}]>
|
|
361
|
+
${optionalProperties.join("\n")}
|
|
266
362
|
<[string8] [flight_setting] [${this.flightSetting}]>
|
|
267
363
|
<[string8u] [aircraft_name] [${this.aircraft.name}]>
|
|
268
364
|
//<[string8u][aircraft_livery] [${this.aircraft.livery}]>
|
|
@@ -270,11 +366,13 @@ export class AeroflyMission {
|
|
|
270
366
|
<[stringt8c] [callsign] [${this.callsign}]>
|
|
271
367
|
<[stringt8c] [origin_icao] [${this.origin.icao}]>
|
|
272
368
|
<[tmvector2d][origin_lon_lat] [${this.origin.longitude} ${this.origin.latitude}]>
|
|
273
|
-
<[float64] [origin_dir] [${this.origin.dir}]>
|
|
274
369
|
<[float64] [origin_alt] [${this.origin.alt}]> // ${this.origin.alt * feetPerMeter} ft MSL
|
|
370
|
+
<[float64] [origin_dir] [${this.origin.dir}]>
|
|
275
371
|
<[stringt8c] [destination_icao] [${this.destination.icao}]>
|
|
276
372
|
<[tmvector2d][destination_lon_lat][${this.destination.longitude} ${this.destination.latitude}]>
|
|
373
|
+
<[float64] [destination_alt] [${this.destination.alt}]> // ${this.destination.alt * feetPerMeter} ft MSL
|
|
277
374
|
<[float64] [destination_dir] [${this.destination.dir}]>
|
|
375
|
+
${moreOptionalProperties.join("\n")}
|
|
278
376
|
${this.conditions}
|
|
279
377
|
<[list_tmmission_checkpoint][checkpoints][]
|
|
280
378
|
${this.getCheckpointsString()}
|
|
@@ -331,7 +429,8 @@ export class AeroflyMissionConditions {
|
|
|
331
429
|
* @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
|
|
332
430
|
* @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
|
|
333
431
|
* @param {number} [additionalAttributes.visibility] in meters
|
|
334
|
-
* @param {number?} [additionalAttributes.visibility_sm] in statute miles
|
|
432
|
+
* @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
|
|
433
|
+
* @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
|
|
335
434
|
* @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
|
|
336
435
|
*/
|
|
337
436
|
constructor({
|
|
@@ -345,6 +444,7 @@ export class AeroflyMissionConditions {
|
|
|
345
444
|
thermalStrength = 0,
|
|
346
445
|
visibility = 25_000,
|
|
347
446
|
visibility_sm = null,
|
|
447
|
+
temperature = null,
|
|
348
448
|
clouds = [],
|
|
349
449
|
}: {
|
|
350
450
|
time?: Date;
|
|
@@ -357,17 +457,22 @@ export class AeroflyMissionConditions {
|
|
|
357
457
|
thermalStrength?: number;
|
|
358
458
|
visibility?: number;
|
|
359
459
|
visibility_sm?: number | null;
|
|
460
|
+
temperature?: number | null;
|
|
360
461
|
clouds?: AeroflyMissionConditionsCloud[];
|
|
361
462
|
} = {}) {
|
|
362
|
-
if (visibility_sm) {
|
|
363
|
-
visibility = visibility_sm * meterPerStatuteMile;
|
|
364
|
-
}
|
|
365
463
|
this.time = time;
|
|
366
464
|
this.wind = wind;
|
|
367
465
|
this.turbulenceStrength = turbulenceStrength;
|
|
368
466
|
this.thermalStrength = thermalStrength;
|
|
369
467
|
this.visibility = visibility;
|
|
370
468
|
this.clouds = clouds;
|
|
469
|
+
|
|
470
|
+
if (visibility_sm) {
|
|
471
|
+
this.visibility_sm = visibility_sm;
|
|
472
|
+
}
|
|
473
|
+
if (temperature) {
|
|
474
|
+
this.temperature = temperature;
|
|
475
|
+
}
|
|
371
476
|
}
|
|
372
477
|
|
|
373
478
|
/**
|
|
@@ -407,8 +512,15 @@ export class AeroflyMissionConditions {
|
|
|
407
512
|
* @param {number} temperature in °C
|
|
408
513
|
*/
|
|
409
514
|
set temperature(temperature: number) {
|
|
410
|
-
// Range from
|
|
411
|
-
this.thermalStrength = Math.max(0, (temperature
|
|
515
|
+
// Range from -15°C to 35°C
|
|
516
|
+
this.thermalStrength = Math.max(0, (temperature + 15) / 50) ** 2;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* @returns {number} in °C
|
|
521
|
+
*/
|
|
522
|
+
get temperature(): number {
|
|
523
|
+
return Math.sqrt(this.thermalStrength) * 50 - 15;
|
|
412
524
|
}
|
|
413
525
|
|
|
414
526
|
/**
|
|
@@ -441,7 +553,7 @@ export class AeroflyMissionConditions {
|
|
|
441
553
|
<[float64][wind_speed][${this.wind.speed}]> // kts
|
|
442
554
|
<[float64][wind_gusts][${this.wind.gusts}]> // kts
|
|
443
555
|
<[float64][turbulence_strength][${this.turbulenceStrength}]>
|
|
444
|
-
<[float64][thermal_strength][${this.thermalStrength}]>
|
|
556
|
+
<[float64][thermal_strength][${this.thermalStrength}]> // ${this.temperature} °C
|
|
445
557
|
<[float64][visibility][${this.visibility}]> // ${this.visibility_sm} SM
|
|
446
558
|
${this.getCloudsString()}
|
|
447
559
|
>`;
|
|
@@ -602,11 +714,11 @@ export class AeroflyMissionCheckpoint {
|
|
|
602
714
|
* @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
|
|
603
715
|
* 84 reference ellipsoid
|
|
604
716
|
* @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
|
|
605
|
-
* 84 reference ellipsoid
|
|
717
|
+
* 84 reference ellipsoid. Will overwrite altitude
|
|
606
718
|
* @param {number} [additionalAttributes.direction] of runway, in degree
|
|
607
719
|
* @param {number?} [additionalAttributes.slope] of runway
|
|
608
720
|
* @param {number?} [additionalAttributes.length] of runway, in meters
|
|
609
|
-
* @param {number?} [additionalAttributes.length_feet] of runway, in feet
|
|
721
|
+
* @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
|
|
610
722
|
* @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
611
723
|
*/
|
|
612
724
|
constructor(
|
|
@@ -632,13 +744,6 @@ export class AeroflyMissionCheckpoint {
|
|
|
632
744
|
frequency?: number | null;
|
|
633
745
|
} = {},
|
|
634
746
|
) {
|
|
635
|
-
if (altitude_feet) {
|
|
636
|
-
altitude = altitude_feet / feetPerMeter;
|
|
637
|
-
}
|
|
638
|
-
if (length_feet) {
|
|
639
|
-
length = length_feet / feetPerMeter;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
747
|
this.type = type;
|
|
643
748
|
this.name = name;
|
|
644
749
|
this.longitude = longitude;
|
|
@@ -648,6 +753,13 @@ export class AeroflyMissionCheckpoint {
|
|
|
648
753
|
this.slope = slope;
|
|
649
754
|
this.length = length;
|
|
650
755
|
this.frequency = frequency;
|
|
756
|
+
|
|
757
|
+
if (altitude_feet) {
|
|
758
|
+
this.altitude_feet = altitude_feet;
|
|
759
|
+
}
|
|
760
|
+
if (length_feet) {
|
|
761
|
+
this.length_feet = length_feet;
|
|
762
|
+
}
|
|
651
763
|
}
|
|
652
764
|
|
|
653
765
|
/**
|
|
@@ -713,10 +825,75 @@ export class AeroflyMissionCheckpoint {
|
|
|
713
825
|
}
|
|
714
826
|
}
|
|
715
827
|
|
|
828
|
+
export class AeroflyLocalizedText {
|
|
829
|
+
/**
|
|
830
|
+
* @property {string} language like
|
|
831
|
+
* - br
|
|
832
|
+
* - cn
|
|
833
|
+
* - de
|
|
834
|
+
* - es
|
|
835
|
+
* - fr
|
|
836
|
+
* - id
|
|
837
|
+
* - it
|
|
838
|
+
* - jp
|
|
839
|
+
* - kr
|
|
840
|
+
* - pl
|
|
841
|
+
* - sv
|
|
842
|
+
* - tr
|
|
843
|
+
*/
|
|
844
|
+
language: string;
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* @property {string} title of this flight plan
|
|
848
|
+
*/
|
|
849
|
+
title: string;
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* @property {string} description text, mission briefing, etc
|
|
853
|
+
*/
|
|
854
|
+
description: string;
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* @param {string} language like
|
|
858
|
+
* - br
|
|
859
|
+
* - cn
|
|
860
|
+
* - de
|
|
861
|
+
* - es
|
|
862
|
+
* - fr
|
|
863
|
+
* - id
|
|
864
|
+
* - it
|
|
865
|
+
* - jp
|
|
866
|
+
* - kr
|
|
867
|
+
* - pl
|
|
868
|
+
* - sv
|
|
869
|
+
* - tr
|
|
870
|
+
* @param {string} title of this flight plan
|
|
871
|
+
* @param {string} description text, mission briefing, etc
|
|
872
|
+
*/
|
|
873
|
+
constructor(language: string, title: string, description: string) {
|
|
874
|
+
this.language = language;
|
|
875
|
+
this.title = title;
|
|
876
|
+
this.description = description;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* @param {number} index if used in an array will se the array index
|
|
881
|
+
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
882
|
+
*/
|
|
883
|
+
toString(index: number): string {
|
|
884
|
+
return ` <[tmmission_definition_localized][element][${index}]
|
|
885
|
+
<[string8u][language][${this.language}]>
|
|
886
|
+
<[string8][title][${this.title}]>
|
|
887
|
+
<[string8][description][${this.description}]>
|
|
888
|
+
>`;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
716
892
|
export default {
|
|
717
893
|
AeroflyMissionsList,
|
|
718
894
|
AeroflyMission,
|
|
719
895
|
AeroflyMissionConditions,
|
|
720
896
|
AeroflyMissionConditionsCloud,
|
|
721
897
|
AeroflyMissionCheckpoint,
|
|
898
|
+
AeroflyLocalizedText,
|
|
722
899
|
};
|
package/types/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type AeroflyMissionPosition = {
|
|
|
21
21
|
/**
|
|
22
22
|
* State of aircraft systems. Configures power settings, flap positions etc
|
|
23
23
|
*/
|
|
24
|
-
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing";
|
|
24
|
+
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing" | "winch_launch" | "aerotow";
|
|
25
25
|
/**
|
|
26
26
|
* Types of checkpoints. Required are usually "origin", "departure_runway" at the start and "destination_runway", "destination" at the end.
|
|
27
27
|
*/
|
|
@@ -100,7 +100,23 @@ export declare class AeroflyMission {
|
|
|
100
100
|
*/
|
|
101
101
|
description: string;
|
|
102
102
|
/**
|
|
103
|
-
* @property {
|
|
103
|
+
* @property {AeroflyLocalizedText[]} localizedTexts for title and description
|
|
104
|
+
*/
|
|
105
|
+
localizedTexts: AeroflyLocalizedText[];
|
|
106
|
+
/**
|
|
107
|
+
* @property {string[]} tags
|
|
108
|
+
*/
|
|
109
|
+
tags: string[];
|
|
110
|
+
/**
|
|
111
|
+
* @property {boolean} isFeatured makes this mission pop up in "Challenges"
|
|
112
|
+
*/
|
|
113
|
+
isFeatured: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* @property {number|undefined} difficulty in 0..1, percentage
|
|
116
|
+
*/
|
|
117
|
+
difficulty: number | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} flightSetting of aircraft, like "taxi", "cruise"
|
|
104
120
|
*/
|
|
105
121
|
flightSetting: AeroflyMissionSetting;
|
|
106
122
|
/**
|
|
@@ -119,6 +135,14 @@ export declare class AeroflyMission {
|
|
|
119
135
|
* @property {object} destination position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
120
136
|
*/
|
|
121
137
|
destination: AeroflyMissionPosition;
|
|
138
|
+
/**
|
|
139
|
+
* @property {number} in meters
|
|
140
|
+
*/
|
|
141
|
+
distance: number;
|
|
142
|
+
/**
|
|
143
|
+
* @property {number} in seconds
|
|
144
|
+
*/
|
|
145
|
+
duration: number;
|
|
122
146
|
/**
|
|
123
147
|
* @property {AeroflyMissionConditions} conditions like time and weather for mission
|
|
124
148
|
*/
|
|
@@ -131,11 +155,17 @@ export declare class AeroflyMission {
|
|
|
131
155
|
* @param {string} title of this flight plan
|
|
132
156
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
133
157
|
* @param {string} [additionalAttributes.description] text, mission briefing, etc
|
|
134
|
-
* @param {
|
|
158
|
+
* @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
|
|
159
|
+
* @param {string[]} [additionalAttributes.tags]
|
|
160
|
+
* @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
|
|
161
|
+
* @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
|
|
162
|
+
* @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
|
|
135
163
|
* @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
|
|
136
164
|
* @param {string} [additionalAttributes.callsign] of aircraft, uppercased
|
|
137
165
|
* @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
138
166
|
* @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
167
|
+
* @param {number} [additionalAttributes.distance] in meters
|
|
168
|
+
* @param {number} [additionalAttributes.duration] in seconds
|
|
139
169
|
* @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
|
|
140
170
|
* @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
|
|
141
171
|
*/
|
|
@@ -143,20 +173,32 @@ export declare class AeroflyMission {
|
|
|
143
173
|
title: string,
|
|
144
174
|
{
|
|
145
175
|
description,
|
|
176
|
+
localizedTexts,
|
|
177
|
+
tags,
|
|
178
|
+
isFeatured,
|
|
179
|
+
difficulty,
|
|
146
180
|
flightSetting,
|
|
147
181
|
aircraft,
|
|
148
182
|
callsign,
|
|
149
183
|
origin,
|
|
150
184
|
destination,
|
|
185
|
+
distance,
|
|
186
|
+
duration,
|
|
151
187
|
conditions,
|
|
152
188
|
checkpoints,
|
|
153
189
|
}?: {
|
|
154
190
|
description?: string;
|
|
191
|
+
localizedTexts?: AeroflyLocalizedText[];
|
|
192
|
+
tags?: string[];
|
|
193
|
+
isFeatured?: boolean;
|
|
194
|
+
difficulty?: number | undefined;
|
|
155
195
|
flightSetting?: AeroflyMissionSetting;
|
|
156
196
|
aircraft?: AeroflyMissionAircraft;
|
|
157
197
|
callsign?: string;
|
|
158
198
|
origin?: AeroflyMissionPosition;
|
|
159
199
|
destination?: AeroflyMissionPosition;
|
|
200
|
+
distance?: number;
|
|
201
|
+
duration?: number;
|
|
160
202
|
conditions?: AeroflyMissionConditions;
|
|
161
203
|
checkpoints?: AeroflyMissionCheckpoint[];
|
|
162
204
|
},
|
|
@@ -165,6 +207,10 @@ export declare class AeroflyMission {
|
|
|
165
207
|
* @returns {string} indexed checkpoints
|
|
166
208
|
*/
|
|
167
209
|
getCheckpointsString(): string;
|
|
210
|
+
/**
|
|
211
|
+
* @returns {string} indexed checkpoints
|
|
212
|
+
*/
|
|
213
|
+
getLocalizedTextsString(): string;
|
|
168
214
|
/**
|
|
169
215
|
* @throws {Error} on missing waypoints
|
|
170
216
|
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
@@ -213,7 +259,8 @@ export declare class AeroflyMissionConditions {
|
|
|
213
259
|
* @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
|
|
214
260
|
* @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
|
|
215
261
|
* @param {number} [additionalAttributes.visibility] in meters
|
|
216
|
-
* @param {number?} [additionalAttributes.visibility_sm] in statute miles
|
|
262
|
+
* @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
|
|
263
|
+
* @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
|
|
217
264
|
* @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
|
|
218
265
|
*/
|
|
219
266
|
constructor({
|
|
@@ -223,6 +270,7 @@ export declare class AeroflyMissionConditions {
|
|
|
223
270
|
thermalStrength,
|
|
224
271
|
visibility,
|
|
225
272
|
visibility_sm,
|
|
273
|
+
temperature,
|
|
226
274
|
clouds,
|
|
227
275
|
}?: {
|
|
228
276
|
time?: Date;
|
|
@@ -235,6 +283,7 @@ export declare class AeroflyMissionConditions {
|
|
|
235
283
|
thermalStrength?: number;
|
|
236
284
|
visibility?: number;
|
|
237
285
|
visibility_sm?: number | null;
|
|
286
|
+
temperature?: number | null;
|
|
238
287
|
clouds?: AeroflyMissionConditionsCloud[];
|
|
239
288
|
});
|
|
240
289
|
/**
|
|
@@ -258,6 +307,10 @@ export declare class AeroflyMissionConditions {
|
|
|
258
307
|
* @param {number} temperature in °C
|
|
259
308
|
*/
|
|
260
309
|
set temperature(temperature: number);
|
|
310
|
+
/**
|
|
311
|
+
* @returns {number} in °C
|
|
312
|
+
*/
|
|
313
|
+
get temperature(): number;
|
|
261
314
|
/**
|
|
262
315
|
* @returns {string}
|
|
263
316
|
*/
|
|
@@ -378,11 +431,11 @@ export declare class AeroflyMissionCheckpoint {
|
|
|
378
431
|
* @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
|
|
379
432
|
* 84 reference ellipsoid
|
|
380
433
|
* @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
|
|
381
|
-
* 84 reference ellipsoid
|
|
434
|
+
* 84 reference ellipsoid. Will overwrite altitude
|
|
382
435
|
* @param {number} [additionalAttributes.direction] of runway, in degree
|
|
383
436
|
* @param {number?} [additionalAttributes.slope] of runway
|
|
384
437
|
* @param {number?} [additionalAttributes.length] of runway, in meters
|
|
385
|
-
* @param {number?} [additionalAttributes.length_feet] of runway, in feet
|
|
438
|
+
* @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
|
|
386
439
|
* @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
387
440
|
*/
|
|
388
441
|
constructor(
|
|
@@ -434,12 +487,62 @@ export declare class AeroflyMissionCheckpoint {
|
|
|
434
487
|
*/
|
|
435
488
|
toString(index?: number): string;
|
|
436
489
|
}
|
|
490
|
+
export declare class AeroflyLocalizedText {
|
|
491
|
+
/**
|
|
492
|
+
* @property {string} language like
|
|
493
|
+
* - br
|
|
494
|
+
* - cn
|
|
495
|
+
* - de
|
|
496
|
+
* - es
|
|
497
|
+
* - fr
|
|
498
|
+
* - id
|
|
499
|
+
* - it
|
|
500
|
+
* - jp
|
|
501
|
+
* - kr
|
|
502
|
+
* - pl
|
|
503
|
+
* - sv
|
|
504
|
+
* - tr
|
|
505
|
+
*/
|
|
506
|
+
language: string;
|
|
507
|
+
/**
|
|
508
|
+
* @property {string} title of this flight plan
|
|
509
|
+
*/
|
|
510
|
+
title: string;
|
|
511
|
+
/**
|
|
512
|
+
* @property {string} description text, mission briefing, etc
|
|
513
|
+
*/
|
|
514
|
+
description: string;
|
|
515
|
+
/**
|
|
516
|
+
* @param {string} language like
|
|
517
|
+
* - br
|
|
518
|
+
* - cn
|
|
519
|
+
* - de
|
|
520
|
+
* - es
|
|
521
|
+
* - fr
|
|
522
|
+
* - id
|
|
523
|
+
* - it
|
|
524
|
+
* - jp
|
|
525
|
+
* - kr
|
|
526
|
+
* - pl
|
|
527
|
+
* - sv
|
|
528
|
+
* - tr
|
|
529
|
+
* @param {string} title of this flight plan
|
|
530
|
+
* @param {string} description text, mission briefing, etc
|
|
531
|
+
*/
|
|
532
|
+
constructor(language: string, title: string, description: string);
|
|
533
|
+
/**
|
|
534
|
+
* @param {number} index if used in an array will se the array index
|
|
535
|
+
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
536
|
+
*/
|
|
537
|
+
toString(index: number): string;
|
|
538
|
+
}
|
|
437
539
|
declare const _default: {
|
|
438
540
|
AeroflyMissionsList: typeof AeroflyMissionsList;
|
|
439
541
|
AeroflyMission: typeof AeroflyMission;
|
|
440
542
|
AeroflyMissionConditions: typeof AeroflyMissionConditions;
|
|
441
543
|
AeroflyMissionConditionsCloud: typeof AeroflyMissionConditionsCloud;
|
|
442
544
|
AeroflyMissionCheckpoint: typeof AeroflyMissionCheckpoint;
|
|
545
|
+
AeroflyLocalizedText: typeof AeroflyLocalizedText;
|
|
443
546
|
};
|
|
444
547
|
export default _default;
|
|
445
548
|
//# sourceMappingURL=index.d.ts.map
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;AAExH;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAClC,QAAQ,GACR,kBAAkB,GAClB,WAAW,GACX,UAAU,GACV,SAAS,GACT,UAAU,GACV,oBAAoB,GACpB,aAAa,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sCAAsC,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAE3F;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAC5B;;OAEG;IACH,QAAQ,EAAE,cAAc,EAAE,CAAC;IAE3B;;OAEG;gBACS,QAAQ,GAAE,cAAc,EAAO;IAI3C;;OAEG;IACH,QAAQ,IAAI,MAAM;CAQrB;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;IAGvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,oBAAoB,EAAE,CAAC;IAEvC;;OAEG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/B;;OAEG;IACH,aAAa,EAAE,qBAAqB,CAAC;IAErC;;OAEG;IACH,QAAQ,EAAE,sBAAsB,CAAC;IAEjC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,sBAAsB,CAAC;IAE/B;;OAEG;IACH,WAAW,EAAE,sBAAsB,CAAC;IAEpC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,EAAE,wBAAwB,CAAC;IAErC;;OAEG;IACH,WAAW,EAAE,wBAAwB,EAAE,CAAC;IAExC;;;;;;;;;;;;;;;;;OAiBG;gBAEC,KAAK,EAAE,MAAM,EACb,EACI,WAAgB,EAChB,cAAmB,EACnB,IAAS,EACT,UAAkB,EAClB,UAAsB,EACtB,aAAsB,EACtB,QAIC,EACD,QAAa,EACb,MAMC,EACD,WAMC,EACD,QAAY,EACZ,QAAY,EACZ,UAA2C,EAC3C,WAAgB,GACnB,GAAE;QACC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;QACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAChC,aAAa,CAAC,EAAE,qBAAqB,CAAC;QACtC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;QAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,sBAAsB,CAAC;QAChC,WAAW,CAAC,EAAE,sBAAsB,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,wBAAwB,CAAC;QACtC,WAAW,CAAC,EAAE,wBAAwB,EAAE,CAAC;KACvC;IAmBV;;OAEG;IACH,oBAAoB,IAAI,MAAM;IAQ9B;;OAEG;IACH,uBAAuB,IAAI,MAAM;IAQjC;;;OAGG;IACH,QAAQ,IAAI,MAAM;CA+ErB;AAED;;;;;;;GAOG;AACH,qBAAa,wBAAwB;IACjC;;;OAGG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,4BAA4B,CAAC;IAEnC;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,6BAA6B,EAAE,CAAM;IAE7C;;;;;;;;;;;OAWG;gBACS,EACR,IAAiB,EACjB,IAIC,EACD,kBAAsB,EACtB,eAAmB,EACnB,UAAmB,EACnB,aAAoB,EACpB,WAAkB,EAClB,MAAW,GACd,GAAE;QACC,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,IAAI,CAAC,EAAE;YACH,SAAS,EAAE,MAAM,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,MAAM,CAAC,EAAE,6BAA6B,EAAE,CAAC;KACvC;IAgBN;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,IAAI,mBAAmB,IAAI,MAAM,CAMhC;IAED;;OAEG;IACH,IAAI,aAAa,CAAC,aAAa,EAAE,MAAM,EAEtC;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;;OAGG;IACH,IAAI,WAAW,CAAC,WAAW,EAAE,MAAM,EAGlC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,eAAe,IAAI,MAAM;IAQzB;;OAEG;IACH,QAAQ,IAAI,MAAM;CAqBrB;AAED;;;;;;;GAOG;AACH,qBAAa,6BAA6B;IACtC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;gBACS,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKvC;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,6BAA6B;IAIpF;;OAEG;IACH,IAAI,SAAS,CAAC,SAAS,EAAE,MAAM,EAE9B;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,sCAAsC,CAWvD;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM;CAOtC;AAED;;;;;;;GAOG;AACH,qBAAa,wBAAwB;IACjC;;OAEG;IACH,IAAI,EAAE,4BAA4B,CAAC;IAEnC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB;;;;;;;;;;;;;;;;;;;;OAoBG;gBAEC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,4BAA4B,EAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,EACI,QAAY,EACZ,aAAoB,EACpB,SAAgB,EAChB,KAAY,EACZ,MAAa,EACb,WAAkB,EAClB,SAAgB,GACnB,GAAE;QACC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB;IAoBV;;OAEG;IACH,IAAI,aAAa,CAAC,aAAa,EAAE,MAAM,EAEtC;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,IAAI,WAAW,CAAC,WAAW,EAAE,MAAM,EAElC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAY7B;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM;CAYtC;AAED,qBAAa,oBAAoB;IAC7B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;;;OAgBG;gBACS,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMhE;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAOlC;;;;;;;;;AAED,wBAOE"}
|