@rian8337/osu-droid-utilities 4.0.0-beta.9 → 4.0.0-beta.91

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/dist/index.js CHANGED
@@ -1,224 +1,137 @@
1
1
  'use strict';
2
2
 
3
3
  var osuBase = require('@rian8337/osu-base');
4
- var osuDroidReplayAnalyzer = require('@rian8337/osu-droid-replay-analyzer');
4
+
5
+ /******************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
20
+
21
+
22
+ function __awaiter(thisArg, _arguments, P, generator) {
23
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
24
+ return new (P || (P = Promise))(function (resolve, reject) {
25
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
26
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
27
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
28
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
29
+ });
30
+ }
31
+
32
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
33
+ var e = new Error(message);
34
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
35
+ };
5
36
 
6
37
  /**
7
38
  * Represents an osu!droid score.
8
39
  */
9
40
  class Score {
10
41
  /**
11
- * The uid of the player.
12
- */
13
- uid;
14
- /**
15
- * The ID of the score.
16
- */
17
- scoreID;
18
- /**
19
- * The player's name.
20
- */
21
- username;
22
- /**
23
- * The title of the beatmap.
24
- */
25
- title;
26
- /**
27
- * The maximum combo achieved in the play.
28
- */
29
- combo;
30
- /**
31
- * The score achieved in the play.
32
- */
33
- score;
34
- /**
35
- * The rank achieved in the play.
36
- */
37
- rank;
38
- /**
39
- * The date of which the play was set.
40
- */
41
- date;
42
- /**
43
- * The accuracy achieved in the play.
44
- */
45
- accuracy;
46
- /**
47
- * Enabled modifications in the score.
48
- */
49
- mods;
50
- /**
51
- * MD5 hash of the play.
42
+ * The amount of 300s in the play.
52
43
  */
53
- hash;
54
- /**
55
- * The speed multiplier of the play.
56
- */
57
- speedMultiplier = 1;
44
+ get perfect() {
45
+ return this.accuracy.n300;
46
+ }
58
47
  /**
59
- * Whether to use old statistics for this score when calculating with `MapStats`.
60
- *
61
- * Otherwise, this denotes whether the score was set in version 1.6.7 or lower.
48
+ * The amount of 100s in the play.
62
49
  */
63
- oldStatistics;
50
+ get good() {
51
+ return this.accuracy.n100;
52
+ }
64
53
  /**
65
- * The forced AR of the play.
54
+ * The amount of 50s in the play.
66
55
  */
67
- forcedAR;
56
+ get bad() {
57
+ return this.accuracy.n50;
58
+ }
68
59
  /**
69
- * The replay of the score.
60
+ * The amount of misses in the play.
70
61
  */
71
- replay;
62
+ get miss() {
63
+ return this.accuracy.nmiss;
64
+ }
72
65
  /**
73
- * The complete mod string of this score (mods, speed multiplier, and force AR combined).
66
+ * The complete mod string of this score.
74
67
  */
75
68
  get completeModString() {
76
- let finalString = `+${this.mods.length > 0 ? this.mods.map((v) => v.acronym) : "No Mod"}`;
77
- if (this.forcedAR !== undefined || this.speedMultiplier !== 1) {
78
- finalString += " (";
79
- if (this.forcedAR !== undefined) {
80
- finalString += `AR${this.forcedAR}`;
81
- }
82
- if (this.speedMultiplier !== 1) {
83
- if (this.forcedAR !== undefined) {
84
- finalString += ", ";
85
- }
86
- finalString += `${this.speedMultiplier}x`;
87
- }
88
- finalString += ")";
69
+ if (this.mods.isEmpty) {
70
+ return `+No Mod`;
89
71
  }
90
- return finalString;
72
+ return `+${osuBase.ModUtil.modsToOrderedString(this.mods)}`;
91
73
  }
92
- constructor(values) {
93
- this.uid = values?.uid ?? 0;
94
- this.scoreID = values?.scoreID ?? 0;
95
- this.username = values?.username ?? "";
96
- this.title = values?.title ?? "";
97
- this.combo = values?.combo ?? 0;
98
- this.score = values?.score ?? 0;
99
- this.rank = values?.rank ?? "";
100
- this.date = new Date(values?.date ?? 0);
101
- this.accuracy = values?.accuracy ?? new osuBase.Accuracy({});
102
- this.hash = values?.hash ?? "";
103
- const modstrings = (values?.mods ?? "").split("|");
104
- let actualMods = "";
105
- for (const str of modstrings) {
106
- if (!str) {
107
- continue;
108
- }
109
- if (str.startsWith("AR")) {
110
- this.forcedAR = parseFloat(str.replace("AR", ""));
111
- }
112
- else if (str.startsWith("x")) {
113
- this.speedMultiplier = parseFloat(str.replace("x", ""));
114
- }
115
- else {
116
- actualMods += str;
117
- }
118
- }
119
- this.mods = osuBase.ModUtil.droidStringToMods(actualMods);
120
- // The pipe was added in 1.6.8 first pre-release (https://github.com/osudroid/osu-droid/commit/c08c406f4b2e535ed1ec43607a72fd8f70f8e316),
121
- // so we can use that information to infer whether the score was set on version 1.6.7 or lower.
122
- this.oldStatistics = !(values?.mods ?? "").includes("|");
74
+ constructor(apiScore) {
75
+ this.id = apiScore.id;
76
+ this.uid = apiScore.uid;
77
+ this.username = apiScore.username;
78
+ this.title = apiScore.filename;
79
+ this.combo = apiScore.combo;
80
+ this.score = apiScore.score;
81
+ this.rank = apiScore.mark;
82
+ this.date = new Date(apiScore.date * 1000);
83
+ this.mods = osuBase.ModUtil.deserializeMods(apiScore.mods);
84
+ this.accuracy = new osuBase.Accuracy({
85
+ n300: apiScore.perfect,
86
+ n100: apiScore.good,
87
+ n50: apiScore.bad,
88
+ nmiss: apiScore.miss,
89
+ });
90
+ this.sliderTickHits = apiScore.sliderTickHit;
91
+ this.sliderEndHits = apiScore.sliderEndHit;
92
+ this.hash = apiScore.hash;
93
+ this.pp = apiScore.pp;
94
+ this.ppMultiplier = apiScore.ppMultiplier;
123
95
  }
124
96
  /**
125
97
  * Retrieves score information on a beatmap from a player.
126
98
  *
127
99
  * @param uid The uid of the player.
128
100
  * @param hash The MD5 hash of the beatmap.
101
+ * @param fetchBestPP Whether to retrieve the score in terms of the best performance points rather than best score. Defaults to `false`.
129
102
  * @returns The score, `null` if the score is not found.
130
103
  */
131
- static async getFromHash(uid, hash) {
132
- const score = new Score();
133
- const apiRequestBuilder = new osuBase.DroidAPIRequestBuilder()
134
- .setEndpoint("scoresearchv2.php")
135
- .addParameter("uid", uid)
136
- .addParameter("hash", hash);
137
- const result = await apiRequestBuilder.sendRequest();
138
- if (result.statusCode !== 200) {
139
- throw new Error("Error retrieving score data");
140
- }
141
- const entry = result.data.toString("utf-8").split("<br>");
142
- entry.shift();
143
- if (entry.length === 0) {
144
- return null;
145
- }
146
- score.fillInformation(entry[0]);
147
- return score;
148
- }
149
- /**
150
- * Fills this instance with score information.
151
- *
152
- * @param info The score information from API response to fill with.
153
- */
154
- fillInformation(info) {
155
- const play = info.split(" ");
156
- this.scoreID = parseInt(play[0]);
157
- this.uid = parseInt(play[1]);
158
- this.username = play[2];
159
- this.score = parseInt(play[3]);
160
- this.combo = parseInt(play[4]);
161
- this.rank = play[5];
162
- const modstrings = play[6].split("|");
163
- let actualMods = "";
164
- for (const str of modstrings) {
165
- if (!str) {
166
- continue;
104
+ static getFromHash(uid_1, hash_1) {
105
+ return __awaiter(this, arguments, void 0, function* (uid, hash, fetchBestPP = false) {
106
+ const apiRequestBuilder = new osuBase.DroidAPIRequestBuilder()
107
+ .setEndpoint("scoresearchv2.php")
108
+ .addParameter("uid", uid)
109
+ .addParameter("hash", hash);
110
+ if (fetchBestPP) {
111
+ apiRequestBuilder.addParameter("order", "pp");
167
112
  }
168
- if (str.startsWith("AR")) {
169
- this.forcedAR = parseFloat(str.replace("AR", ""));
113
+ const result = yield apiRequestBuilder.sendRequest();
114
+ if (result.statusCode !== 200) {
115
+ throw new Error("Error retrieving score data");
170
116
  }
171
- else if (str.startsWith("x")) {
172
- this.speedMultiplier = parseFloat(str.replace("x", ""));
117
+ let response;
118
+ try {
119
+ response = JSON.parse(result.data.toString("utf-8"));
173
120
  }
174
- else {
175
- actualMods += str;
121
+ catch (_a) {
122
+ return null;
176
123
  }
177
- }
178
- this.mods = osuBase.ModUtil.droidStringToMods(actualMods);
179
- this.oldStatistics = !play[6].includes("|");
180
- this.accuracy = new osuBase.Accuracy({
181
- n300: parseInt(play[8]),
182
- n100: parseInt(play[9]),
183
- n50: parseInt(play[10]),
184
- nmiss: parseInt(play[11]),
124
+ if (response.length === 0) {
125
+ return null;
126
+ }
127
+ return new Score(response[0]);
185
128
  });
186
- const date = new Date(parseInt(play[12]) * 1000);
187
- date.setUTCHours(date.getUTCHours() + 8);
188
- // https://stackoverflow.com/a/63199512
189
- const tz = date
190
- .toLocaleString("en", {
191
- timeZone: "Europe/Berlin",
192
- timeStyle: "long",
193
- })
194
- .split(" ")
195
- .slice(-1)[0];
196
- const dateString = date.toString();
197
- const msOffset = Date.parse(`${dateString} UTC`) - Date.parse(`${dateString} ${tz}`);
198
- date.setUTCMilliseconds(date.getUTCMilliseconds() - msOffset);
199
- this.date = date;
200
- this.title = play[13]
201
- .substring(0, play[13].length - 4)
202
- .replace(/_/g, " ");
203
- this.hash = play[14];
204
- return this;
205
- }
206
- /**
207
- * Downloads the replay of this score.
208
- */
209
- async downloadReplay() {
210
- if (!this.scoreID || this.replay) {
211
- return;
212
- }
213
- this.replay = await new osuDroidReplayAnalyzer.ReplayAnalyzer({
214
- scoreID: this.scoreID,
215
- }).analyze();
216
129
  }
217
130
  /**
218
131
  * Returns a string representative of the class.
219
132
  */
220
133
  toString() {
221
- return `Player: ${this.username}, uid: ${this.uid}, title: ${this.title}, score: ${this.score}, combo: ${this.combo}, rank: ${this.rank}, acc: ${this.accuracy}%, date: ${this.date}, mods: ${this.mods}, hash: ${this.hash}`;
134
+ return `Player: ${this.username}, uid: ${this.uid.toString()}, title: ${this.title}, score: ${this.score.toString()}, combo: ${this.combo.toString()}, rank: ${this.rank}, acc: ${(this.accuracy.value() * 100).toFixed(2)}%, date: ${this.date.toString()}, mods: ${osuBase.ModUtil.modsToOrderedString(this.mods)}, hash: ${this.hash}`;
222
135
  }
223
136
  }
224
137
 
@@ -226,131 +139,94 @@ class Score {
226
139
  * Represents an osu!droid player.
227
140
  */
228
141
  class Player {
229
- /**
230
- * The uid of the player.
231
- */
232
- uid = 0;
233
- /**
234
- * The username of the player.
235
- */
236
- username = "";
237
142
  /**
238
143
  * The avatar URL of the player.
239
144
  */
240
- avatarURL = "";
241
- /**
242
- * The location of the player based on ISO 3166-1 country codes. See {@link https://en.wikipedia.org/wiki/ISO_3166-1 this} Wikipedia page for more information.
243
- */
244
- location = "";
245
- /**
246
- * The email that is attached to the player's account.
247
- */
248
- email = "";
249
- /**
250
- * The overall rank of the player.
251
- */
252
- rank = 0;
253
- /**
254
- * The total score of the player.
255
- */
256
- score = 0;
257
- /**
258
- * The overall accuracy of the player.
259
- */
260
- accuracy = 0;
261
- /**
262
- * The amount of times the player has played.
263
- */
264
- playCount = 0;
265
- /**
266
- * Recent plays of the player.
267
- */
268
- recentPlays = [];
145
+ get avatarUrl() {
146
+ return `https://osudroid.moe/user/avatar?id=${this.id.toString()}`;
147
+ }
148
+ constructor(apiPlayer) {
149
+ /**
150
+ * The user ID of the player.
151
+ */
152
+ this.id = 0;
153
+ /**
154
+ * The username of the player.
155
+ */
156
+ this.username = "";
157
+ /**
158
+ * The location of the player based on ISO 3166-1 country codes. See {@link https://en.wikipedia.org/wiki/ISO_3166-1 this} Wikipedia page for more information.
159
+ */
160
+ this.location = "";
161
+ /**
162
+ * The overall rank of the player.
163
+ */
164
+ this.rank = 0;
165
+ /**
166
+ * The total score of the player.
167
+ */
168
+ this.score = 0;
169
+ /**
170
+ * The total performance points of the player.
171
+ */
172
+ this.pp = 0;
173
+ /**
174
+ * The overall accuracy of the player.
175
+ */
176
+ this.accuracy = 0;
177
+ /**
178
+ * The amount of times the player has played.
179
+ */
180
+ this.playCount = 0;
181
+ /**
182
+ * Recent plays of the player.
183
+ */
184
+ this.recentPlays = [];
185
+ this.id = apiPlayer.id;
186
+ this.username = apiPlayer.username;
187
+ this.score = apiPlayer.score;
188
+ this.playCount = apiPlayer.playcount;
189
+ this.accuracy = apiPlayer.accuracy * 100;
190
+ this.location = apiPlayer.region;
191
+ this.rank = apiPlayer.rank;
192
+ this.pp = apiPlayer.pp;
193
+ for (const score of apiPlayer.recent) {
194
+ this.recentPlays.push(new Score(Object.assign(Object.assign({}, score), { uid: this.id, username: this.username })));
195
+ }
196
+ }
269
197
  /**
270
198
  * Retrieves a player's info based on their username.
271
199
  *
272
200
  * @param uidOrUsername The uid or username of the player.
273
201
  * @returns The player, `null` if the player is not found.
274
202
  */
275
- static async getInformation(uidOrUsername) {
276
- const player = new Player();
277
- const apiRequestBuilder = new osuBase.DroidAPIRequestBuilder()
278
- .setEndpoint("getuserinfo.php")
279
- .addParameter(typeof uidOrUsername === "number" ? "uid" : "username", uidOrUsername);
280
- const result = await apiRequestBuilder.sendRequest();
281
- if (result.statusCode !== 200) {
282
- throw new Error("Error retrieving player data");
283
- }
284
- const data = result.data.toString("utf-8");
285
- const resArr = data.split("<br>");
286
- const headerRes = resArr[0].split(" ");
287
- if (headerRes[0] === "FAILED") {
288
- return null;
289
- }
290
- player.fillInformation(data);
291
- return player;
292
- }
293
- /**
294
- * Fills this instance with player information.
295
- *
296
- * @param info The player information from API response to fill with.
297
- */
298
- fillInformation(info) {
299
- const resArr = info.split("<br>");
300
- const headerRes = resArr[0].split(" ");
301
- if (headerRes[0] === "FAILED") {
302
- return this;
303
- }
304
- const obj = JSON.parse(resArr[1]);
305
- this.uid = parseInt(headerRes[1]);
306
- this.username = headerRes[2];
307
- this.score = parseInt(headerRes[3]);
308
- this.playCount = parseInt(headerRes[4]);
309
- this.accuracy = parseFloat((parseFloat(headerRes[5]) * 100).toFixed(2));
310
- this.email = headerRes[6];
311
- this.location = headerRes[7];
312
- this.avatarURL = `https://osudroid.moe/user/avatar?id=${this.uid}&s=200`;
313
- this.rank = obj.rank;
314
- const recent = obj.recent;
315
- for (const play of recent) {
316
- // https://stackoverflow.com/a/63199512
317
- const date = new Date((play.date + 3600 * 8) * 1000);
318
- const tz = date
319
- .toLocaleString("en", {
320
- timeZone: "Europe/Berlin",
321
- timeStyle: "long",
322
- })
323
- .split(" ")
324
- .slice(-1)[0];
325
- const dateString = date.toString();
326
- const msOffset = Date.parse(`${dateString} UTC`) -
327
- Date.parse(`${dateString} ${tz}`);
328
- this.recentPlays.push(new Score({
329
- uid: this.uid,
330
- username: this.username,
331
- scoreID: play.scoreid,
332
- score: play.score,
333
- accuracy: new osuBase.Accuracy({
334
- n300: play.perfect,
335
- n100: play.good,
336
- n50: play.bad,
337
- nmiss: play.miss,
338
- }),
339
- rank: play.mark,
340
- combo: play.combo,
341
- title: play.filename,
342
- date: date.getTime() - msOffset,
343
- mods: play.mode,
344
- hash: play.hash,
345
- }));
346
- }
347
- return this;
203
+ static getInformation(uidOrUsername) {
204
+ return __awaiter(this, void 0, void 0, function* () {
205
+ const apiRequestBuilder = new osuBase.DroidAPIRequestBuilder()
206
+ .setEndpoint("getuserinfo.php")
207
+ .addParameter(typeof uidOrUsername === "number" ? "uid" : "username", uidOrUsername);
208
+ const result = yield apiRequestBuilder.sendRequest();
209
+ if (result.statusCode !== 200) {
210
+ throw new Error("Error retrieving player data");
211
+ }
212
+ let response;
213
+ try {
214
+ response = JSON.parse(result.data.toString("utf-8"));
215
+ }
216
+ catch (_a) {
217
+ return null;
218
+ }
219
+ if (!response.id) {
220
+ return null;
221
+ }
222
+ return new Player(response);
223
+ });
348
224
  }
349
225
  /**
350
226
  * Returns a string representative of the class.
351
227
  */
352
228
  toString() {
353
- return `Username: ${this.username}\nUID: ${this.uid}\nRank: ${this.rank}\nScore: ${this.score}\nPlay count: ${this.playCount}`;
229
+ return `Username: ${this.username}\nUID: ${this.id.toString()}\nRank: ${this.rank.toString()}\nScore: ${this.score.toString()}\nPlay count: ${this.playCount.toString()}`;
354
230
  }
355
231
  }
356
232
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rian8337/osu-droid-utilities",
3
- "version": "4.0.0-beta.9",
3
+ "version": "4.0.0-beta.91",
4
4
  "description": "A module containing utilities for osu!droid.",
5
5
  "keywords": [
6
6
  "osu",
@@ -12,9 +12,12 @@
12
12
  "main": "dist/index.js",
13
13
  "typings": "typings/index.d.ts",
14
14
  "typedocMain": "src/index.ts",
15
+ "engines": {
16
+ "node": ">=18"
17
+ },
15
18
  "files": [
16
- "dist/**",
17
- "typings/**"
19
+ "dist/index.js",
20
+ "typings/index.d.ts"
18
21
  ],
19
22
  "repository": {
20
23
  "type": "git",
@@ -22,19 +25,18 @@
22
25
  },
23
26
  "scripts": {
24
27
  "build": "rollup -c ../../rollup.config.mjs",
25
- "lint": "eslint --ext ts",
26
- "prepare": "npm run build",
27
- "test": "jest"
28
+ "lint": "eslint 'src/**/*.ts'",
29
+ "prepublishOnly": "pnpm build",
30
+ "test": "jest --silent"
28
31
  },
29
32
  "bugs": {
30
33
  "url": "https://github.com/Rian8337/osu-droid-module/issues"
31
34
  },
32
35
  "dependencies": {
33
- "@rian8337/osu-base": "^4.0.0-beta.9",
34
- "@rian8337/osu-droid-replay-analyzer": "^4.0.0-beta.9"
36
+ "@rian8337/osu-base": "4.0.0-beta.91"
35
37
  },
36
38
  "publishConfig": {
37
39
  "access": "public"
38
40
  },
39
- "gitHead": "35702aa327055e3d8edb13c038b9d9ae00eadf48"
41
+ "gitHead": "21fc1a8f1ddf89952521bf670a84dcfdd0495ed7"
40
42
  }
@@ -1,15 +1,51 @@
1
- import { Accuracy, Mod, IModApplicableToDroid } from '@rian8337/osu-base';
2
- import { ReplayAnalyzer } from '@rian8337/osu-droid-replay-analyzer';
1
+ import { ScoreRank, SerializedMod, Accuracy, ModMap } from '@rian8337/osu-base';
3
2
 
4
- interface ScoreInformation {
3
+ interface APIScore {
4
+ readonly id: number;
5
+ readonly uid: number;
6
+ readonly username: string;
7
+ readonly filename: string;
8
+ readonly score: number;
9
+ readonly combo: number;
10
+ readonly mark: ScoreRank;
11
+ readonly mods: SerializedMod[];
12
+ readonly accuracy: number;
13
+ readonly perfect: number;
14
+ readonly good: number;
15
+ readonly bad: number;
16
+ readonly miss: number;
17
+ readonly sliderTickHit: number | null;
18
+ readonly sliderEndHit: number | null;
19
+ readonly date: number;
20
+ readonly hash: string;
21
+ readonly pp: number | null;
22
+ readonly ppMultiplier: number | null;
23
+ }
24
+
25
+ interface APIPlayer {
26
+ readonly id: number;
27
+ readonly username: string;
28
+ readonly score: number;
29
+ readonly playcount: number;
30
+ readonly accuracy: number;
31
+ readonly region: string;
32
+ readonly rank: number;
33
+ readonly pp: number;
34
+ readonly recent: Omit<APIScore, "uid" | "username">[];
35
+ }
36
+
37
+ /**
38
+ * Represents an osu!droid score.
39
+ */
40
+ declare class Score {
5
41
  /**
6
- * The uid of the player.
42
+ * The ID of the score.
7
43
  */
8
- uid?: number;
44
+ id: number;
9
45
  /**
10
- * The ID of the score.
46
+ * The uid of the player.
11
47
  */
12
- scoreID?: number;
48
+ uid: number;
13
49
  /**
14
50
  * The player's name.
15
51
  */
@@ -29,113 +65,73 @@ interface ScoreInformation {
29
65
  /**
30
66
  * The rank achieved in the play.
31
67
  */
32
- rank: string;
68
+ rank: ScoreRank;
33
69
  /**
34
70
  * The date of which the play was set.
35
71
  */
36
- date: Date | number;
72
+ date: Date;
37
73
  /**
38
74
  * The accuracy achieved in the play.
39
75
  */
40
76
  accuracy: Accuracy;
41
77
  /**
42
- * Enabled modifications in the score, including force AR and custom speed multiplier.
43
- */
44
- mods: string;
45
- /**
46
- * MD5 hash of the play.
47
- */
48
- hash: string;
49
- }
50
- /**
51
- * Represents an osu!droid score.
52
- */
53
- declare class Score {
54
- /**
55
- * The uid of the player.
56
- */
57
- uid: number;
58
- /**
59
- * The ID of the score.
60
- */
61
- scoreID: number;
62
- /**
63
- * The player's name.
64
- */
65
- username: string;
66
- /**
67
- * The title of the beatmap.
78
+ * The amount of 300s in the play.
68
79
  */
69
- title: string;
80
+ get perfect(): number;
70
81
  /**
71
- * The maximum combo achieved in the play.
82
+ * The amount of 100s in the play.
72
83
  */
73
- combo: number;
84
+ get good(): number;
74
85
  /**
75
- * The score achieved in the play.
86
+ * The amount of 50s in the play.
76
87
  */
77
- score: number;
88
+ get bad(): number;
78
89
  /**
79
- * The rank achieved in the play.
90
+ * The amount of misses in the play.
80
91
  */
81
- rank: string;
82
- /**
83
- * The date of which the play was set.
84
- */
85
- date: Date;
86
- /**
87
- * The accuracy achieved in the play.
88
- */
89
- accuracy: Accuracy;
92
+ get miss(): number;
90
93
  /**
91
94
  * Enabled modifications in the score.
92
95
  */
93
- mods: (Mod & IModApplicableToDroid)[];
96
+ mods: ModMap;
94
97
  /**
95
98
  * MD5 hash of the play.
96
99
  */
97
100
  hash: string;
98
101
  /**
99
- * The speed multiplier of the play.
102
+ * The amount of slider ticks hit in the play.
100
103
  */
101
- speedMultiplier: number;
104
+ sliderTickHits: number | null;
102
105
  /**
103
- * Whether to use old statistics for this score when calculating with `MapStats`.
104
- *
105
- * Otherwise, this denotes whether the score was set in version 1.6.7 or lower.
106
+ * The amount of slider ends hit in the play.
106
107
  */
107
- oldStatistics: boolean;
108
+ sliderEndHits: number | null;
108
109
  /**
109
- * The forced AR of the play.
110
+ * The performance points value of the play.
111
+ *
112
+ * This is the final value, affected by {@link ppMultiplier}. To get the raw pp value, divide by said multiplier.
110
113
  */
111
- forcedAR?: number;
114
+ pp: number | null;
112
115
  /**
113
- * The replay of the score.
116
+ * The pp multiplier of the play.
117
+ *
118
+ * This is applied directly to {@link pp} during calculation.
114
119
  */
115
- replay?: ReplayAnalyzer;
120
+ ppMultiplier: number | null;
116
121
  /**
117
- * The complete mod string of this score (mods, speed multiplier, and force AR combined).
122
+ * The complete mod string of this score.
118
123
  */
119
124
  get completeModString(): string;
120
- constructor(values?: ScoreInformation);
125
+ constructor(apiScore: APIScore);
121
126
  /**
122
127
  * Retrieves score information on a beatmap from a player.
123
128
  *
124
129
  * @param uid The uid of the player.
125
130
  * @param hash The MD5 hash of the beatmap.
131
+ * @param fetchBestPP Whether to retrieve the score in terms of the best performance points rather than best score. Defaults to `false`.
126
132
  * @returns The score, `null` if the score is not found.
127
133
  */
128
- static getFromHash(uid: number, hash: string): Promise<Score | null>;
129
- /**
130
- * Fills this instance with score information.
131
- *
132
- * @param info The score information from API response to fill with.
133
- */
134
- fillInformation(info: string): Score;
135
- /**
136
- * Downloads the replay of this score.
137
- */
138
- downloadReplay(): Promise<void>;
134
+ static getFromHash(uid: number, hash: string, fetchBestPP?: boolean): Promise<Score | null>;
139
135
  /**
140
136
  * Returns a string representative of the class.
141
137
  */
@@ -147,9 +143,9 @@ declare class Score {
147
143
  */
148
144
  declare class Player {
149
145
  /**
150
- * The uid of the player.
146
+ * The user ID of the player.
151
147
  */
152
- uid: number;
148
+ id: number;
153
149
  /**
154
150
  * The username of the player.
155
151
  */
@@ -157,15 +153,11 @@ declare class Player {
157
153
  /**
158
154
  * The avatar URL of the player.
159
155
  */
160
- avatarURL: string;
156
+ get avatarUrl(): string;
161
157
  /**
162
158
  * The location of the player based on ISO 3166-1 country codes. See {@link https://en.wikipedia.org/wiki/ISO_3166-1 this} Wikipedia page for more information.
163
159
  */
164
160
  location: string;
165
- /**
166
- * The email that is attached to the player's account.
167
- */
168
- email: string;
169
161
  /**
170
162
  * The overall rank of the player.
171
163
  */
@@ -174,6 +166,10 @@ declare class Player {
174
166
  * The total score of the player.
175
167
  */
176
168
  score: number;
169
+ /**
170
+ * The total performance points of the player.
171
+ */
172
+ pp: number;
177
173
  /**
178
174
  * The overall accuracy of the player.
179
175
  */
@@ -186,6 +182,7 @@ declare class Player {
186
182
  * Recent plays of the player.
187
183
  */
188
184
  readonly recentPlays: Score[];
185
+ constructor(apiPlayer: APIPlayer);
189
186
  /**
190
187
  * Retrieves a player's info based on their username.
191
188
  *
@@ -193,12 +190,6 @@ declare class Player {
193
190
  * @returns The player, `null` if the player is not found.
194
191
  */
195
192
  static getInformation(uidOrUsername: string | number): Promise<Player | null>;
196
- /**
197
- * Fills this instance with player information.
198
- *
199
- * @param info The player information from API response to fill with.
200
- */
201
- fillInformation(info: string): Player;
202
193
  /**
203
194
  * Returns a string representative of the class.
204
195
  */
@@ -206,3 +197,4 @@ declare class Player {
206
197
  }
207
198
 
208
199
  export { Player, Score };
200
+ export type { APIPlayer, APIScore };
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../src/Score.ts","../src/Player.ts"],"sourcesContent":[null,null],"names":["Accuracy","ModUtil","DroidAPIRequestBuilder","ReplayAnalyzer"],"mappings":";;;;;AAmEA;;AAEG;MACU,KAAK,CAAA;AACd;;AAEG;AACH,IAAA,GAAG,CAAS;AAEZ;;AAEG;AACH,IAAA,OAAO,CAAS;AAEhB;;AAEG;AACH,IAAA,QAAQ,CAAS;AAEjB;;AAEG;AACH,IAAA,KAAK,CAAS;AAEd;;AAEG;AACH,IAAA,KAAK,CAAS;AAEd;;AAEG;AACH,IAAA,KAAK,CAAS;AAEd;;AAEG;AACH,IAAA,IAAI,CAAS;AAEb;;AAEG;AACH,IAAA,IAAI,CAAO;AAEX;;AAEG;AACH,IAAA,QAAQ,CAAW;AAEnB;;AAEG;AACH,IAAA,IAAI,CAAkC;AAEtC;;AAEG;AACH,IAAA,IAAI,CAAS;AAEb;;AAEG;IACH,eAAe,GAAW,CAAC,CAAC;AAE5B;;;;AAIG;AACH,IAAA,aAAa,CAAU;AAEvB;;AAEG;AACH,IAAA,QAAQ,CAAU;AAElB;;AAEG;AACH,IAAA,MAAM,CAAkB;AAExB;;AAEG;AACH,IAAA,IAAI,iBAAiB,GAAA;AACjB,QAAA,IAAI,WAAW,GAAW,CACtB,CAAA,EAAA,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,QAC7D,EAAE,CAAC;QAEH,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE;YAC3D,WAAW,IAAI,IAAI,CAAC;AACpB,YAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC7B,gBAAA,WAAW,IAAI,CAAK,EAAA,EAAA,IAAI,CAAC,QAAQ,EAAE,CAAC;AACvC,aAAA;AACD,YAAA,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE;AAC5B,gBAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;oBAC7B,WAAW,IAAI,IAAI,CAAC;AACvB,iBAAA;AACD,gBAAA,WAAW,IAAI,CAAG,EAAA,IAAI,CAAC,eAAe,GAAG,CAAC;AAC7C,aAAA;YACD,WAAW,IAAI,GAAG,CAAC;AACtB,SAAA;AAED,QAAA,OAAO,WAAW,CAAC;KACtB;AAED,IAAA,WAAA,CAAY,MAAyB,EAAA;QACjC,IAAI,CAAC,GAAG,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;AAC/B,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;AACxC,QAAA,IAAI,CAAC,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,IAAIA,gBAAQ,CAAC,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;AAE/B,QAAA,MAAM,UAAU,GAAa,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,UAAU,GAAW,EAAE,CAAC;AAC5B,QAAA,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;YAC1B,IAAI,CAAC,GAAG,EAAE;gBACN,SAAS;AACZ,aAAA;AAED,YAAA,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;AACtB,gBAAA,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACrD,aAAA;AAAM,iBAAA,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC5B,gBAAA,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,aAAA;AAAM,iBAAA;gBACH,UAAU,IAAI,GAAG,CAAC;AACrB,aAAA;AACJ,SAAA;QAED,IAAI,CAAC,IAAI,GAAGC,eAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;;;AAGlD,QAAA,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;KAC5D;AAED;;;;;;AAMG;AACH,IAAA,aAAa,WAAW,CAAC,GAAW,EAAE,IAAY,EAAA;AAC9C,QAAA,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;AAE1B,QAAA,MAAM,iBAAiB,GACnB,IAAIC,8BAAsB,EAAE;aACvB,WAAW,CAAC,mBAAmB,CAAC;AAChC,aAAA,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC;AACxB,aAAA,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEpC,QAAA,MAAM,MAAM,GAAoB,MAAM,iBAAiB,CAAC,WAAW,EAAE,CAAC;AAEtE,QAAA,IAAI,MAAM,CAAC,UAAU,KAAK,GAAG,EAAE;AAC3B,YAAA,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAClD,SAAA;AAED,QAAA,MAAM,KAAK,GAAa,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEpE,KAAK,CAAC,KAAK,EAAE,CAAC;AAEd,QAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AACpB,YAAA,OAAO,IAAI,CAAC;AACf,SAAA;QAED,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhC,QAAA,OAAO,KAAK,CAAC;KAChB;AAED;;;;AAIG;AACH,IAAA,eAAe,CAAC,IAAY,EAAA;QACxB,MAAM,IAAI,GAAa,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvC,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,MAAM,UAAU,GAAa,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,UAAU,GAAW,EAAE,CAAC;AAC5B,QAAA,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;YAC1B,IAAI,CAAC,GAAG,EAAE;gBACN,SAAS;AACZ,aAAA;AAED,YAAA,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;AACtB,gBAAA,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACrD,aAAA;AAAM,iBAAA,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC5B,gBAAA,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,aAAA;AAAM,iBAAA;gBACH,UAAU,IAAI,GAAG,CAAC;AACrB,aAAA;AACJ,SAAA;QAED,IAAI,CAAC,IAAI,GAAGD,eAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;AAClD,QAAA,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAE5C,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAID,gBAAQ,CAAC;AACzB,YAAA,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvB,YAAA,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvB,YAAA,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvB,YAAA,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5B,SAAA,CAAC,CAAC;AAEH,QAAA,MAAM,IAAI,GAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;;QAGzC,MAAM,EAAE,GAAW,IAAI;aAClB,cAAc,CAAC,IAAI,EAAE;AAClB,YAAA,QAAQ,EAAE,eAAe;AACzB,YAAA,SAAS,EAAE,MAAM;SACpB,CAAC;aACD,KAAK,CAAC,GAAG,CAAC;AACV,aAAA,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClB,QAAA,MAAM,UAAU,GAAW,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,QAAQ,GACV,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,UAAU,CAAM,IAAA,CAAA,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,UAAU,CAAI,CAAA,EAAA,EAAE,CAAE,CAAA,CAAC,CAAC;QACxE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,QAAQ,CAAC,CAAC;AAE9D,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;AACjB,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;aAChB,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AACjC,aAAA,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACxB,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AACrB,QAAA,OAAO,IAAI,CAAC;KACf;AAED;;AAEG;AACH,IAAA,MAAM,cAAc,GAAA;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE;YAC9B,OAAO;AACV,SAAA;AAED,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAIG,qCAAc,CAAC;YACnC,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC,CAAC,OAAO,EAAE,CAAC;KAChB;AAED;;AAEG;IACH,QAAQ,GAAA;AACJ,QAAA,OAAO,WAAW,IAAI,CAAC,QAAQ,CAAU,OAAA,EAAA,IAAI,CAAC,GAAG,CAAA,SAAA,EAAY,IAAI,CAAC,KAAK,CAAY,SAAA,EAAA,IAAI,CAAC,KAAK,CAAA,SAAA,EAAY,IAAI,CAAC,KAAK,CAAW,QAAA,EAAA,IAAI,CAAC,IAAI,CAAA,OAAA,EAAU,IAAI,CAAC,QAAQ,YAAY,IAAI,CAAC,IAAI,CAAW,QAAA,EAAA,IAAI,CAAC,IAAI,CAAA,QAAA,EAAW,IAAI,CAAC,IAAI,EAAE,CAAC;KACjO;AACJ;;AC5SD;;AAEG;MACU,MAAM,CAAA;AACf;;AAEG;IACH,GAAG,GAAW,CAAC,CAAC;AAEhB;;AAEG;IACH,QAAQ,GAAW,EAAE,CAAC;AAEtB;;AAEG;IACH,SAAS,GAAW,EAAE,CAAC;AAEvB;;AAEG;IACH,QAAQ,GAAW,EAAE,CAAC;AAEtB;;AAEG;IACH,KAAK,GAAW,EAAE,CAAC;AAEnB;;AAEG;IACH,IAAI,GAAW,CAAC,CAAC;AAEjB;;AAEG;IACH,KAAK,GAAW,CAAC,CAAC;AAElB;;AAEG;IACH,QAAQ,GAAW,CAAC,CAAC;AAErB;;AAEG;IACH,SAAS,GAAW,CAAC,CAAC;AAEtB;;AAEG;IACM,WAAW,GAAY,EAAE,CAAC;AAEnC;;;;;AAKG;AACH,IAAA,aAAa,cAAc,CACvB,aAA8B,EAAA;AAE9B,QAAA,MAAM,MAAM,GAAW,IAAI,MAAM,EAAE,CAAC;AAEpC,QAAA,MAAM,iBAAiB,GACnB,IAAID,8BAAsB,EAAE;aACvB,WAAW,CAAC,iBAAiB,CAAC;AAC9B,aAAA,YAAY,CACT,OAAO,aAAa,KAAK,QAAQ,GAAG,KAAK,GAAG,UAAU,EACtD,aAAa,CAChB,CAAC;AAEV,QAAA,MAAM,MAAM,GAAoB,MAAM,iBAAiB,CAAC,WAAW,EAAE,CAAC;AACtE,QAAA,IAAI,MAAM,CAAC,UAAU,KAAK,GAAG,EAAE;AAC3B,YAAA,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;AACnD,SAAA;QAED,MAAM,IAAI,GAAW,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAa,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAa,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEjD,QAAA,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;AAC3B,YAAA,OAAO,IAAI,CAAC;AACf,SAAA;AAED,QAAA,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAE7B,QAAA,OAAO,MAAM,CAAC;KACjB;AAED;;;;AAIG;AACH,IAAA,eAAe,CAAC,IAAY,EAAA;QACxB,MAAM,MAAM,GAAa,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAa,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEjD,QAAA,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;AAC3B,YAAA,OAAO,IAAI,CAAC;AACf,SAAA;QAED,MAAM,GAAG,GAAqB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpD,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,QAAA,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACxE,QAAA,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,CAAA,oCAAA,EAAuC,IAAI,CAAC,GAAG,QAAQ,CAAC;AACzE,QAAA,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;AAErB,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,MAAM,CAAC;AACtD,QAAA,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE;;AAEvB,YAAA,MAAM,IAAI,GAAS,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;YAC3D,MAAM,EAAE,GAAW,IAAI;iBAClB,cAAc,CAAC,IAAI,EAAE;AAClB,gBAAA,QAAQ,EAAE,eAAe;AACzB,gBAAA,SAAS,EAAE,MAAM;aACpB,CAAC;iBACD,KAAK,CAAC,GAAG,CAAC;AACV,iBAAA,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClB,YAAA,MAAM,UAAU,GAAW,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,QAAQ,GACV,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,UAAU,CAAA,IAAA,CAAM,CAAC;gBAC/B,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,UAAU,CAAI,CAAA,EAAA,EAAE,CAAE,CAAA,CAAC,CAAC;AAEtC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CACjB,IAAI,KAAK,CAAC;gBACN,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAIF,gBAAQ,CAAC;oBACnB,IAAI,EAAE,IAAI,CAAC,OAAO;oBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,GAAG,EAAE,IAAI,CAAC,GAAG;oBACb,KAAK,EAAE,IAAI,CAAC,IAAI;iBACnB,CAAC;gBACF,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,QAAQ;AACpB,gBAAA,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ;gBAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;AAClB,aAAA,CAAC,CACL,CAAC;AACL,SAAA;AAED,QAAA,OAAO,IAAI,CAAC;KACf;AAED;;AAEG;IACH,QAAQ,GAAA;QACJ,OAAO,CAAA,UAAA,EAAa,IAAI,CAAC,QAAQ,UAAU,IAAI,CAAC,GAAG,CAAW,QAAA,EAAA,IAAI,CAAC,IAAI,CAAA,SAAA,EAAY,IAAI,CAAC,KAAK,iBAAiB,IAAI,CAAC,SAAS,CAAA,CAAE,CAAC;KAClI;AACJ;;;;;"}