@wise-old-man/utils 2.0.0-beta.1 → 2.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +470 -128
  2. package/dist/index.js +864 -521
  3. package/package.json +4 -1
package/dist/index.js CHANGED
@@ -97,6 +97,32 @@ function sendPostRequest(path, body) {
97
97
  });
98
98
  });
99
99
  }
100
+ function sendPutRequest(path, body) {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ const requestURL = `${config.apiBaseUrl}${path}`;
103
+ return axios__default["default"]
104
+ .put(requestURL, body || {})
105
+ .then(response => transformDates(response.data))
106
+ .catch(e => {
107
+ if (axios__default["default"].isAxiosError(e))
108
+ handleError(requestURL, e);
109
+ throw e;
110
+ });
111
+ });
112
+ }
113
+ function sendDeleteRequest(path, body) {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ const requestURL = `${config.apiBaseUrl}${path}`;
116
+ return axios__default["default"]
117
+ .delete(requestURL, { data: body })
118
+ .then(response => transformDates(response.data))
119
+ .catch(e => {
120
+ if (axios__default["default"].isAxiosError(e))
121
+ handleError(requestURL, e);
122
+ throw e;
123
+ });
124
+ });
125
+ }
100
126
  function sendGetRequest(path, params) {
101
127
  return __awaiter(this, void 0, void 0, function* () {
102
128
  const requestURL = `${config.apiBaseUrl}${path}`;
@@ -152,72 +178,262 @@ class InternalServerError extends Error {
152
178
  }
153
179
  }
154
180
 
155
- function getPlayerURL(player) {
156
- if (typeof player === 'string') {
157
- return `/players/${player}`;
181
+ class DeltasClient {
182
+ /**
183
+ * Fetches the current top leaderboard for a specific metric, period, playerType, playerBuild and country.
184
+ * @returns A list of deltas, with their respective players, values and dates included.
185
+ */
186
+ getDeltaLeaderboard(filter) {
187
+ return sendGetRequest('/deltas/leaderboard', filter);
158
188
  }
159
- if (player.id) {
160
- return `/players/id/${player.id}`;
189
+ }
190
+
191
+ class GroupsClient {
192
+ /**
193
+ * Searches for groups that match a partial name.
194
+ * @returns A list of groups.
195
+ */
196
+ searchGroups(name, pagination) {
197
+ return sendGetRequest('/groups', Object.assign({ name }, pagination));
198
+ }
199
+ /**
200
+ * Fetches a group's details.
201
+ * @returns A group details object.
202
+ */
203
+ getGroupDetails(id) {
204
+ return sendGetRequest(`/groups/${id}`);
205
+ }
206
+ /**
207
+ * Fetches a group's entire members list.
208
+ * @returns A list of memberships, with players included.
209
+ */
210
+ getGroupMembers(id) {
211
+ return sendGetRequest(`/groups/${id}/members`);
212
+ }
213
+ /**
214
+ * Creates a new group.
215
+ * @returns The newly created group, and the verification code that authorizes future changes to it.
216
+ */
217
+ createGroup(payload) {
218
+ return sendPostRequest('/groups', payload);
219
+ }
220
+ /**
221
+ * Edits an existing group.
222
+ * @returns The updated group.
223
+ */
224
+ editGroup(id, payload, verificationCode) {
225
+ return sendPutRequest(`/groups/${id}`, Object.assign(Object.assign({}, payload), { verificationCode }));
226
+ }
227
+ /**
228
+ * Deletes an existing group.
229
+ * @returns A confirmation message.
230
+ */
231
+ deleteGroup(id, verificationCode) {
232
+ return sendDeleteRequest(`/groups/${id}`, { verificationCode });
233
+ }
234
+ /**
235
+ * Adds all (valid) given usernames (and roles) to a group, ignoring duplicates.
236
+ * @returns The number of members added and a confirmation message.
237
+ */
238
+ addMembers(id, members, verificationCode) {
239
+ return sendPostRequest(`/groups/${id}/members`, {
240
+ verificationCode,
241
+ members
242
+ });
243
+ }
244
+ /**
245
+ * Remove all given usernames from a group, ignoring usernames that aren't members.
246
+ * @returns The number of members removed and a confirmation message.
247
+ */
248
+ removeMembers(id, usernames, verificationCode) {
249
+ return sendDeleteRequest(`/groups/${id}/members`, {
250
+ verificationCode,
251
+ members: usernames
252
+ });
253
+ }
254
+ /**
255
+ * Changes a player's role in a given group.
256
+ * @returns The updated membership, with player included.
257
+ */
258
+ changeRole(id, payload, verificationCode) {
259
+ return sendPutRequest(`/groups/${id}/role`, Object.assign(Object.assign({}, payload), { verificationCode }));
260
+ }
261
+ /**
262
+ * Adds an "update" request to the queue, for each outdated group member.
263
+ * @returns The number of players to be updated and a confirmation message.
264
+ */
265
+ updateAll(id, verificationCode) {
266
+ return sendPostRequest(`/groups/${id}/update-all`, {
267
+ verificationCode
268
+ });
269
+ }
270
+ /**
271
+ * Fetches all of the groups's competitions
272
+ * @returns A list of competitions.
273
+ */
274
+ getGroupCompetitions(id, pagination) {
275
+ return sendGetRequest(`/groups/${id}/competitions`, Object.assign({}, pagination));
276
+ }
277
+ getGroupGains(id, filter, pagination) {
278
+ return sendGetRequest(`/groups/${id}/gained`, Object.assign(Object.assign({}, pagination), filter));
279
+ }
280
+ /**
281
+ * Fetches a group members' latest achievements.
282
+ * @returns A list of achievements.
283
+ */
284
+ getGroupAchievements(id, pagination) {
285
+ return sendGetRequest(`/groups/${id}/achievements`, Object.assign({}, pagination));
286
+ }
287
+ /**
288
+ * Fetches a group's record leaderboard for a specific metric and period.
289
+ * @returns A list of records, including their respective players.
290
+ */
291
+ getGroupRecords(id, filter, pagination) {
292
+ return sendGetRequest(`/groups/${id}/records`, Object.assign(Object.assign({}, pagination), filter));
293
+ }
294
+ /**
295
+ * Fetches a group's hiscores for a specific metric.
296
+ * @returns A list of hiscores entries (value, rank), including their respective players.
297
+ */
298
+ getGroupHiscores(id, metric, pagination) {
299
+ return sendGetRequest(`/groups/${id}/hiscores`, Object.assign(Object.assign({}, pagination), { metric }));
300
+ }
301
+ /**
302
+ * Fetches a group members' latest name changes.
303
+ * @returns A list of name change (approved) requests.
304
+ */
305
+ getGroupNameChanges(id, pagination) {
306
+ return sendGetRequest(`/groups/${id}/name-changes`, Object.assign({}, pagination));
307
+ }
308
+ /**
309
+ * Fetches a group's general statistics.
310
+ * @returns An object with a few statistic values and an average stats snapshot.
311
+ */
312
+ getGroupStatistics(id) {
313
+ return sendGetRequest(`/groups/${id}/statistics`);
161
314
  }
162
- return `/players/${player.username}`;
163
315
  }
316
+
164
317
  class PlayersClient {
318
+ /**
319
+ * Searches players by partial username.
320
+ * @returns A list of players.
321
+ */
165
322
  searchPlayers(partialUsername, pagination) {
166
323
  return sendGetRequest('/players/search', Object.assign({ username: partialUsername }, pagination));
167
324
  }
325
+ /**
326
+ * Updates/tracks a player.
327
+ * @returns The player's new details, including the latest snapshot.
328
+ */
168
329
  updatePlayer(player) {
169
330
  return sendPostRequest(getPlayerURL(player));
170
331
  }
332
+ /**
333
+ * Asserts (and attempts to fix, if necessary) a player's game-mode type.
334
+ * @returns The updated player, and an indication of whether the type was changed.
335
+ */
171
336
  assertPlayerType(player) {
172
337
  return sendPostRequest(`${getPlayerURL(player)}/assert-type`);
173
338
  }
339
+ /**
340
+ * Attempts to import a player's snapshot history from CrystalMathLabs.
341
+ * @returns The number of snapshots that were imported.
342
+ */
174
343
  importPlayer(player) {
175
344
  return sendPostRequest(`${getPlayerURL(player)}/import-history`);
176
345
  }
346
+ /**
347
+ * Fetches a player's details.
348
+ * @returns The player's details, including the latest snapshot.
349
+ */
177
350
  getPlayerDetails(player) {
178
351
  return sendGetRequest(getPlayerURL(player));
179
352
  }
353
+ /**
354
+ * Fetches a player's current achievements.
355
+ * @returns A list of achievements.
356
+ */
180
357
  getPlayerAchievements(player) {
181
358
  return sendGetRequest(`${getPlayerURL(player)}/achievements`);
182
359
  }
360
+ /**
361
+ * Fetches a player's current achievement progress.
362
+ * @returns A list of achievements (completed or otherwise), with their respective relative/absolute progress percentage.
363
+ */
183
364
  getPlayerAchievementProgress(player) {
184
365
  return sendGetRequest(`${getPlayerURL(player)}/achievements/progress`);
185
366
  }
367
+ /**
368
+ * Fetches all of the player's competition participations.
369
+ * @returns A list of participations, with the respective competition included.
370
+ */
186
371
  getPlayerCompetitions(player, pagination) {
187
372
  return sendGetRequest(`${getPlayerURL(player)}/competitions`, pagination);
188
373
  }
374
+ /**
375
+ * Fetches all of the player's group memberships.
376
+ * @returns A list of memberships, with the respective group included.
377
+ */
189
378
  getPlayerGroups(player, pagination) {
190
379
  return sendGetRequest(`${getPlayerURL(player)}/groups`, pagination);
191
380
  }
381
+ /**
382
+ * Fetches a player's gains, for a specific period or time range, as a [metric: data] map.
383
+ * @returns A map of each metric's gained data.
384
+ */
192
385
  getPlayerGains(player, options) {
193
386
  return sendGetRequest(`${getPlayerURL(player)}/gained`, options);
194
387
  }
388
+ /**
389
+ * Fetches a player's gains, for a specific period or time range, as an array.
390
+ * @returns An array of each metric's gained data.
391
+ */
195
392
  getPlayerGainsAsArray(player, options) {
196
393
  return sendGetRequest(`${getPlayerURL(player)}/gained`, Object.assign(Object.assign({}, options), { formatting: 'array' }));
197
394
  }
395
+ /**
396
+ * Fetches all of the player's records.
397
+ * @returns A list of records.
398
+ */
198
399
  getPlayerRecords(player, options) {
199
400
  return sendGetRequest(`${getPlayerURL(player)}/records`, options);
200
401
  }
402
+ /**
403
+ * Fetches all of the player's past snapshots.
404
+ * @returns A list of snapshots.
405
+ */
201
406
  getPlayerSnapshots(player, options) {
202
407
  return sendGetRequest(`${getPlayerURL(player)}/snapshots`, options);
203
408
  }
409
+ /**
410
+ * Fetches all of the player's approved name changes.
411
+ * @returns A list of name changes.
412
+ */
204
413
  getPlayerNames(player) {
205
414
  return sendGetRequest(`${getPlayerURL(player)}/names`);
206
415
  }
207
416
  }
417
+ function getPlayerURL(player) {
418
+ if (typeof player === 'string') {
419
+ return `/players/${player}`;
420
+ }
421
+ if (player.id) {
422
+ return `/players/id/${player.id}`;
423
+ }
424
+ return `/players/${player.username}`;
425
+ }
208
426
 
209
427
  class RecordsClient {
428
+ /**
429
+ * Fetches the current records leaderboard for a specific metric, period, playerType, playerBuild and country.
430
+ * @returns A list of records, with their respective players, dates and values included.
431
+ */
210
432
  getRecordLeaderboard(filter) {
211
433
  return sendGetRequest('/records/leaderboard', filter);
212
434
  }
213
435
  }
214
436
 
215
- class DeltasClient {
216
- getDeltaLeaderboard(filter) {
217
- return sendGetRequest('/deltas/leaderboard', filter);
218
- }
219
- }
220
-
221
437
  /**
222
438
  * Prisma currently seems to ignore the @map() in enum declarations.
223
439
  *
@@ -342,6 +558,8 @@ const Boss = {
342
558
  THEATRE_OF_BLOOD: 'theatre_of_blood',
343
559
  THEATRE_OF_BLOOD_HARD_MODE: 'theatre_of_blood_hard_mode',
344
560
  THERMONUCLEAR_SMOKE_DEVIL: 'thermonuclear_smoke_devil',
561
+ TOMBS_OF_AMASCUT: 'tombs_of_amascut',
562
+ TOMBS_OF_AMASCUT_EXPERT: 'tombs_of_amascut_expert',
345
563
  TZKAL_ZUK: 'tzkal_zuk',
346
564
  TZTOK_JAD: 'tztok_jad',
347
565
  VENENATIS: 'venenatis',
@@ -351,11 +569,11 @@ const Boss = {
351
569
  ZALCANO: 'zalcano',
352
570
  ZULRAH: 'zulrah'
353
571
  };
354
- const Virtual = {
572
+ const ComputedMetric = {
355
573
  EHP: 'ehp',
356
574
  EHB: 'ehb'
357
575
  };
358
- const Metric = Object.assign(Object.assign(Object.assign(Object.assign({}, Skill), Activity), Boss), Virtual);
576
+ const Metric = Object.assign(Object.assign(Object.assign(Object.assign({}, Skill), Activity), Boss), ComputedMetric);
359
577
  const NameChangeStatus = {
360
578
  PENDING: 'pending',
361
579
  DENIED: 'denied',
@@ -927,19 +1145,11 @@ const CompetitionStatusProps = {
927
1145
  };
928
1146
  const COMPETITION_TYPES = Object.values(CompetitionType);
929
1147
  const COMPETITION_STATUSES = Object.values(exports.CompetitionStatus);
930
- function findCompetitionType(typeName) {
931
- for (const [key, value] of Object.entries(CompetitionTypeProps)) {
932
- if (value.name === typeName)
933
- return key;
934
- }
935
- return null;
1148
+ function isCompetitionType(typeString) {
1149
+ return typeString in CompetitionTypeProps;
936
1150
  }
937
- function findCompetitionStatus(statusName) {
938
- for (const [key, value] of Object.entries(CompetitionStatusProps)) {
939
- if (value.name === statusName)
940
- return key;
941
- }
942
- return null;
1151
+ function isCompetitionStatus(statusString) {
1152
+ return statusString in CompetitionStatusProps;
943
1153
  }
944
1154
 
945
1155
  const CountryProps = {
@@ -1198,6 +1408,9 @@ const COMMON_ALIASES = [
1198
1408
  { commonIdentifier: 'UK', trueIdentifier: 'GB' },
1199
1409
  { commonIdentifier: 'USA', trueIdentifier: 'US' }
1200
1410
  ];
1411
+ function isCountry(countryCodeString) {
1412
+ return countryCodeString in CountryProps;
1413
+ }
1201
1414
  function findCountry(countryIdentifier) {
1202
1415
  return findCountryByCode(countryIdentifier) || findCountryByName(countryIdentifier);
1203
1416
  }
@@ -1214,485 +1427,61 @@ function replaceCommonAliases(countryCode) {
1214
1427
  return ((_a = COMMON_ALIASES.find(ca => ca.commonIdentifier === countryCode)) === null || _a === void 0 ? void 0 : _a.trueIdentifier) || countryCode;
1215
1428
  }
1216
1429
 
1217
- exports.MetricType = void 0;
1218
- (function (MetricType) {
1219
- MetricType["SKILL"] = "skill";
1220
- MetricType["BOSS"] = "boss";
1221
- MetricType["ACTIVITY"] = "activity";
1222
- MetricType["VIRTUAL"] = "virtual";
1223
- })(exports.MetricType || (exports.MetricType = {}));
1224
- exports.MetricMeasure = void 0;
1225
- (function (MetricMeasure) {
1226
- MetricMeasure["EXPERIENCE"] = "experience";
1227
- MetricMeasure["KILLS"] = "kills";
1228
- MetricMeasure["SCORE"] = "score";
1229
- MetricMeasure["VALUE"] = "value";
1230
- })(exports.MetricMeasure || (exports.MetricMeasure = {}));
1231
- const SkillProps = lodash.mapValues({
1232
- [Skill.OVERALL]: { name: 'Overall', isCombat: false, isMembers: false },
1233
- [Skill.ATTACK]: { name: 'Attack', isCombat: true, isMembers: false },
1234
- [Skill.DEFENCE]: { name: 'Defence', isCombat: true, isMembers: false },
1235
- [Skill.STRENGTH]: { name: 'Strength', isCombat: true, isMembers: false },
1236
- [Skill.HITPOINTS]: { name: 'Hitpoints', isCombat: true, isMembers: false },
1237
- [Skill.RANGED]: { name: 'Ranged', isCombat: true, isMembers: false },
1238
- [Skill.PRAYER]: { name: 'Prayer', isCombat: true, isMembers: false },
1239
- [Skill.MAGIC]: { name: 'Magic', isCombat: true, isMembers: false },
1240
- [Skill.COOKING]: { name: 'Cooking', isCombat: false, isMembers: false },
1241
- [Skill.WOODCUTTING]: { name: 'Woodcutting', isCombat: false, isMembers: false },
1242
- [Skill.FLETCHING]: { name: 'Fletching', isCombat: false, isMembers: true },
1243
- [Skill.FISHING]: { name: 'Fishing', isCombat: false, isMembers: false },
1244
- [Skill.FIREMAKING]: { name: 'Firemaking', isCombat: false, isMembers: false },
1245
- [Skill.CRAFTING]: { name: 'Crafting', isCombat: false, isMembers: false },
1246
- [Skill.SMITHING]: { name: 'Smithing', isCombat: false, isMembers: false },
1247
- [Skill.MINING]: { name: 'Mining', isCombat: false, isMembers: false },
1248
- [Skill.HERBLORE]: { name: 'Herblore', isCombat: false, isMembers: true },
1249
- [Skill.AGILITY]: { name: 'Agility', isCombat: false, isMembers: true },
1250
- [Skill.THIEVING]: { name: 'Thieving', isCombat: false, isMembers: true },
1251
- [Skill.SLAYER]: { name: 'Slayer', isCombat: false, isMembers: true },
1252
- [Skill.FARMING]: { name: 'Farming', isCombat: false, isMembers: true },
1253
- [Skill.RUNECRAFTING]: { name: 'Runecrafting', isCombat: false, isMembers: false },
1254
- [Skill.HUNTER]: { name: 'Hunter', isCombat: false, isMembers: true },
1255
- [Skill.CONSTRUCTION]: { name: 'Construction', isCombat: false, isMembers: false }
1256
- }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.SKILL, measure: exports.MetricMeasure.EXPERIENCE })));
1257
- const BossProps = lodash.mapValues({
1258
- [Boss.ABYSSAL_SIRE]: { name: 'Abyssal Sire', minimumKc: 50, isMembers: true },
1259
- [Boss.ALCHEMICAL_HYDRA]: { name: 'Alchemical Hydra', minimumKc: 50, isMembers: true },
1260
- [Boss.BARROWS_CHESTS]: { name: 'Barrows Chests', minimumKc: 50, isMembers: true },
1261
- [Boss.BRYOPHYTA]: { name: 'Bryophyta', minimumKc: 5, isMembers: false },
1262
- [Boss.CALLISTO]: { name: 'Callisto', minimumKc: 50, isMembers: true },
1263
- [Boss.CERBERUS]: { name: 'Cerberus', minimumKc: 50, isMembers: true },
1264
- [Boss.CHAMBERS_OF_XERIC]: { name: 'Chambers Of Xeric', minimumKc: 50, isMembers: true },
1265
- [Boss.CHAMBERS_OF_XERIC_CM]: { name: 'Chambers Of Xeric (CM)', minimumKc: 5, isMembers: true },
1266
- [Boss.CHAOS_ELEMENTAL]: { name: 'Chaos Elemental', minimumKc: 50, isMembers: true },
1267
- [Boss.CHAOS_FANATIC]: { name: 'Chaos Fanatic', minimumKc: 50, isMembers: true },
1268
- [Boss.COMMANDER_ZILYANA]: { name: 'Commander Zilyana', minimumKc: 50, isMembers: true },
1269
- [Boss.CORPOREAL_BEAST]: { name: 'Corporeal Beast', minimumKc: 50, isMembers: true },
1270
- [Boss.CRAZY_ARCHAEOLOGIST]: { name: 'Crazy Archaeologist', minimumKc: 50, isMembers: true },
1271
- [Boss.DAGANNOTH_PRIME]: { name: 'Dagannoth Prime', minimumKc: 50, isMembers: true },
1272
- [Boss.DAGANNOTH_REX]: { name: 'Dagannoth Rex', minimumKc: 50, isMembers: true },
1273
- [Boss.DAGANNOTH_SUPREME]: { name: 'Dagannoth Supreme', minimumKc: 50, isMembers: true },
1274
- [Boss.DERANGED_ARCHAEOLOGIST]: { name: 'Deranged Archaeologist', minimumKc: 50, isMembers: true },
1275
- [Boss.GENERAL_GRAARDOR]: { name: 'General Graardor', minimumKc: 50, isMembers: true },
1276
- [Boss.GIANT_MOLE]: { name: 'Giant Mole', minimumKc: 50, isMembers: true },
1277
- [Boss.GROTESQUE_GUARDIANS]: { name: 'Grotesque Guardians', minimumKc: 50, isMembers: true },
1278
- [Boss.HESPORI]: { name: 'Hespori', minimumKc: 5, isMembers: true },
1279
- [Boss.KALPHITE_QUEEN]: { name: 'Kalphite Queen', minimumKc: 50, isMembers: true },
1280
- [Boss.KING_BLACK_DRAGON]: { name: 'King Black Dragon', minimumKc: 50, isMembers: true },
1281
- [Boss.KRAKEN]: { name: 'Kraken', minimumKc: 50, isMembers: true },
1282
- [Boss.KREEARRA]: { name: "Kree'Arra", minimumKc: 50, isMembers: true },
1283
- [Boss.KRIL_TSUTSAROTH]: { name: "K'ril Tsutsaroth", minimumKc: 50, isMembers: true },
1284
- [Boss.MIMIC]: { name: 'Mimic', minimumKc: 1, isMembers: true },
1285
- [Boss.NEX]: { name: 'Nex', minimumKc: 50, isMembers: true },
1286
- [Boss.NIGHTMARE]: { name: 'Nightmare', minimumKc: 50, isMembers: true },
1287
- [Boss.PHOSANIS_NIGHTMARE]: { name: "Phosani's Nightmare", minimumKc: 50, isMembers: true },
1288
- [Boss.OBOR]: { name: 'Obor', minimumKc: 5, isMembers: false },
1289
- [Boss.SARACHNIS]: { name: 'Sarachnis', minimumKc: 50, isMembers: true },
1290
- [Boss.SKOTIZO]: { name: 'Skotizo', minimumKc: 5, isMembers: true },
1291
- [Boss.SCORPIA]: { name: 'Scorpia', minimumKc: 50, isMembers: true },
1292
- [Boss.TEMPOROSS]: { name: 'Tempoross', minimumKc: 50, isMembers: true },
1293
- [Boss.THE_GAUNTLET]: { name: 'The Gauntlet', minimumKc: 50, isMembers: true },
1294
- [Boss.THE_CORRUPTED_GAUNTLET]: { name: 'The Corrupted Gauntlet', minimumKc: 5, isMembers: true },
1295
- [Boss.THEATRE_OF_BLOOD]: { name: 'Theatre Of Blood', minimumKc: 50, isMembers: true },
1296
- [Boss.THEATRE_OF_BLOOD_HARD_MODE]: { name: 'Theatre Of Blood (HM)', minimumKc: 50, isMembers: true },
1297
- [Boss.THERMONUCLEAR_SMOKE_DEVIL]: { name: 'Thermonuclear Smoke Devil', minimumKc: 50, isMembers: true },
1298
- [Boss.TZKAL_ZUK]: { name: 'TzKal-Zuk', minimumKc: 1, isMembers: true },
1299
- [Boss.TZTOK_JAD]: { name: 'TzTok-Jad', minimumKc: 5, isMembers: true },
1300
- [Boss.VENENATIS]: { name: 'Venenatis', minimumKc: 50, isMembers: true },
1301
- [Boss.VETION]: { name: "Vet'ion", minimumKc: 50, isMembers: true },
1302
- [Boss.VORKATH]: { name: 'Vorkath', minimumKc: 50, isMembers: true },
1303
- [Boss.WINTERTODT]: { name: 'Wintertodt', minimumKc: 50, isMembers: true },
1304
- [Boss.ZALCANO]: { name: 'Zalcano', minimumKc: 50, isMembers: true },
1305
- [Boss.ZULRAH]: { name: 'Zulrah', minimumKc: 50, isMembers: true }
1306
- }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.BOSS, measure: exports.MetricMeasure.KILLS })));
1307
- const ActivityProps = lodash.mapValues({
1308
- [Activity.LEAGUE_POINTS]: { name: 'League Points' },
1309
- [Activity.BOUNTY_HUNTER_HUNTER]: { name: 'Bounty Hunter (Hunter)' },
1310
- [Activity.BOUNTY_HUNTER_ROGUE]: { name: 'Bounty Hunter (Rogue)' },
1311
- [Activity.CLUE_SCROLLS_ALL]: { name: 'Clue Scrolls (All)' },
1312
- [Activity.CLUE_SCROLLS_BEGINNER]: { name: 'Clue Scrolls (Beginner)' },
1313
- [Activity.CLUE_SCROLLS_EASY]: { name: 'Clue Scrolls (Easy)' },
1314
- [Activity.CLUE_SCROLLS_MEDIUM]: { name: 'Clue Scrolls (Medium)' },
1315
- [Activity.CLUE_SCROLLS_HARD]: { name: 'Clue Scrolls (Hard)' },
1316
- [Activity.CLUE_SCROLLS_ELITE]: { name: 'Clue Scrolls (Elite)' },
1317
- [Activity.CLUE_SCROLLS_MASTER]: { name: 'Clue Scrolls (Master)' },
1318
- [Activity.LAST_MAN_STANDING]: { name: 'Last Man Standing' },
1319
- [Activity.PVP_ARENA]: { name: 'PvP Arena' },
1320
- [Activity.SOUL_WARS_ZEAL]: { name: 'Soul Wars Zeal' },
1321
- [Activity.GUARDIANS_OF_THE_RIFT]: { name: 'Guardians of the Rift' }
1322
- }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.ACTIVITY, measure: exports.MetricMeasure.SCORE })));
1323
- const VirtualProps = lodash.mapValues({
1324
- [Virtual.EHP]: { name: 'EHP' },
1325
- [Virtual.EHB]: { name: 'EHB' }
1326
- }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.VIRTUAL, measure: exports.MetricMeasure.VALUE })));
1327
- const MetricProps = Object.assign(Object.assign(Object.assign(Object.assign({}, SkillProps), BossProps), ActivityProps), VirtualProps);
1328
- const METRICS = Object.values(Metric);
1329
- const SKILLS = Object.values(Skill);
1330
- const BOSSES = Object.values(Boss);
1331
- const ACTIVITIES = Object.values(Activity);
1332
- const VIRTUALS = Object.values(Virtual);
1333
- const REAL_SKILLS = SKILLS.filter(s => s !== Skill.OVERALL);
1334
- const F2P_BOSSES = BOSSES.filter(b => !MetricProps[b].isMembers);
1335
- const MEMBER_SKILLS = SKILLS.filter(s => MetricProps[s].isMembers);
1336
- const COMBAT_SKILLS = SKILLS.filter(s => MetricProps[s].isCombat);
1337
- function findMetric(metricName) {
1338
- for (const [key, value] of Object.entries(MetricProps)) {
1339
- if (value.name.toUpperCase() === metricName.toUpperCase())
1340
- return key;
1430
+ // Maximum effective skill level at 13,034,431 experience.
1431
+ const MAX_LEVEL = 99;
1432
+ // The maximum virtual skill level for any skill (200M experience).
1433
+ const MAX_VIRTUAL_LEVEL = 126;
1434
+ // The maximum skill experience (200M experience).
1435
+ const MAX_SKILL_EXP = 200000000;
1436
+ // The minimum skill exp for level 99
1437
+ const SKILL_EXP_AT_99 = 13034431;
1438
+ // The maximum skill at exactly 99 on all skills
1439
+ const CAPPED_MAX_TOTAL_XP = 23 * SKILL_EXP_AT_99;
1440
+ // Builds a lookup table for each level's required experience
1441
+ // exp = XP_FOR_LEVEL[level - 1] || 13m = XP_FOR_LEVEL[98]
1442
+ const XP_FOR_LEVEL = (function () {
1443
+ let xp = 0;
1444
+ const array = [];
1445
+ for (let level = 1; level <= MAX_VIRTUAL_LEVEL; ++level) {
1446
+ array[level - 1] = Math.floor(xp / 4);
1447
+ xp += Math.floor(level + 300 * Math.pow(2, level / 7));
1341
1448
  }
1342
- return null;
1343
- }
1344
- function isSkill(metric) {
1345
- return metric in SkillProps;
1346
- }
1347
- function isActivity(metric) {
1348
- return metric in ActivityProps;
1349
- }
1350
- function isBoss(metric) {
1351
- return metric in BossProps;
1449
+ return array;
1450
+ })();
1451
+ function getExpForLevel(level) {
1452
+ if (level < 1 || level > MAX_VIRTUAL_LEVEL)
1453
+ return 0;
1454
+ return XP_FOR_LEVEL[level - 1];
1352
1455
  }
1353
- function isVirtualMetric(metric) {
1354
- return metric in VirtualProps;
1456
+ function getLevel(exp, virtual = false) {
1457
+ if (!exp || exp < 0) {
1458
+ return 1;
1459
+ }
1460
+ let low = 0;
1461
+ let high = virtual ? XP_FOR_LEVEL.length - 1 : 98;
1462
+ while (low <= high) {
1463
+ const mid = Math.floor(low + (high - low) / 2);
1464
+ const xpForLevel = XP_FOR_LEVEL[mid];
1465
+ if (exp < xpForLevel) {
1466
+ high = mid - 1;
1467
+ }
1468
+ else if (exp > xpForLevel) {
1469
+ low = mid + 1;
1470
+ }
1471
+ else {
1472
+ return mid + 1;
1473
+ }
1474
+ }
1475
+ return high + 1;
1355
1476
  }
1356
- function getMetricRankKey(metric) {
1357
- return `${metric}Rank`;
1358
- }
1359
- function getMetricValueKey(metric) {
1360
- return `${metric}${lodash.capitalize(MetricProps[metric].measure)}`;
1361
- }
1362
- function getMetricMeasure(metric) {
1363
- return MetricProps[metric].measure;
1364
- }
1365
- function getMetricName(metric) {
1366
- return MetricProps[metric].name;
1367
- }
1368
- function getMinimumBossKc(metric) {
1369
- return isBoss(metric) ? MetricProps[metric].minimumKc : 0;
1370
- }
1371
- function getParentVirtualMetric(metric) {
1372
- if (isBoss(metric))
1373
- return Metric.EHB;
1374
- if (isSkill(metric))
1375
- return Metric.EHP;
1376
- return null;
1377
- }
1378
- function parseMetricAbbreviation(abbreviation) {
1379
- if (!abbreviation || abbreviation.length === 0) {
1380
- return null;
1381
- }
1382
- switch (abbreviation.toLowerCase()) {
1383
- // Bosses
1384
- case 'sire':
1385
- return Metric.ABYSSAL_SIRE;
1386
- case 'hydra':
1387
- return Metric.ALCHEMICAL_HYDRA;
1388
- case 'barrows':
1389
- return Metric.BARROWS_CHESTS;
1390
- case 'bryo':
1391
- return Metric.BRYOPHYTA;
1392
- case 'cerb':
1393
- return Metric.CERBERUS;
1394
- case 'cox':
1395
- case 'xeric':
1396
- case 'chambers':
1397
- case 'olm':
1398
- case 'raids':
1399
- return Metric.CHAMBERS_OF_XERIC;
1400
- case 'cox-cm':
1401
- case 'xeric-cm':
1402
- case 'chambers-cm':
1403
- case 'olm-cm':
1404
- case 'raids-cm':
1405
- return Metric.CHAMBERS_OF_XERIC_CM;
1406
- case 'chaos-ele':
1407
- return Metric.CHAOS_ELEMENTAL;
1408
- case 'fanatic':
1409
- return Metric.CHAOS_FANATIC;
1410
- case 'sara':
1411
- case 'saradomin':
1412
- case 'zilyana':
1413
- case 'zily':
1414
- return Metric.COMMANDER_ZILYANA;
1415
- case 'corp':
1416
- return Metric.CORPOREAL_BEAST;
1417
- case 'crazy-arch':
1418
- return Metric.CRAZY_ARCHAEOLOGIST;
1419
- case 'prime':
1420
- return Metric.DAGANNOTH_PRIME;
1421
- case 'rex':
1422
- return Metric.DAGANNOTH_REX;
1423
- case 'supreme':
1424
- return Metric.DAGANNOTH_SUPREME;
1425
- case 'deranged-arch':
1426
- return Metric.DERANGED_ARCHAEOLOGIST;
1427
- case 'bandos':
1428
- case 'graardor':
1429
- return Metric.GENERAL_GRAARDOR;
1430
- case 'mole':
1431
- return Metric.GIANT_MOLE;
1432
- case 'dusk':
1433
- case 'dawn':
1434
- case 'gargs':
1435
- case 'guardians':
1436
- case 'ggs':
1437
- return Metric.GROTESQUE_GUARDIANS;
1438
- case 'kq':
1439
- return Metric.KALPHITE_QUEEN;
1440
- case 'kbd':
1441
- return Metric.KING_BLACK_DRAGON;
1442
- case 'kree':
1443
- case 'kreearra':
1444
- case 'armadyl':
1445
- case 'arma':
1446
- return Metric.KREEARRA;
1447
- case 'zammy':
1448
- case 'zamorak':
1449
- case 'kril':
1450
- case 'kril-tsutsaroth':
1451
- return Metric.KRIL_TSUTSAROTH;
1452
- case 'gaunt':
1453
- case 'gauntlet':
1454
- case 'the-gauntlet':
1455
- return Metric.THE_GAUNTLET;
1456
- case 'cgaunt':
1457
- case 'cgauntlet':
1458
- case 'corrupted':
1459
- case 'corrupted-gauntlet':
1460
- case 'the-corrupted-gauntlet':
1461
- return Metric.THE_CORRUPTED_GAUNTLET;
1462
- case 'tob':
1463
- case 'theatre':
1464
- case 'verzik':
1465
- case 'tob-normal':
1466
- return Metric.THEATRE_OF_BLOOD;
1467
- case 'tob-hm':
1468
- case 'tob-cm':
1469
- case 'tob-hard-mode':
1470
- case 'tob-hard':
1471
- return Metric.THEATRE_OF_BLOOD_HARD_MODE;
1472
- case 'nm':
1473
- case 'tnm':
1474
- case 'nmare':
1475
- case 'the-nightmare':
1476
- return Metric.NIGHTMARE;
1477
- case 'pnm':
1478
- case 'phosani':
1479
- case 'phosanis':
1480
- case 'phosani-nm':
1481
- case 'phosani-nightmare':
1482
- case 'phosanis nightmare':
1483
- return Metric.PHOSANIS_NIGHTMARE;
1484
- case 'thermy':
1485
- case 'smoke-devil':
1486
- return Metric.THERMONUCLEAR_SMOKE_DEVIL;
1487
- case 'zuk':
1488
- case 'inferno':
1489
- return Metric.TZKAL_ZUK;
1490
- case 'jad':
1491
- case 'fight-caves':
1492
- case 'fc':
1493
- return Metric.TZTOK_JAD;
1494
- case 'vork':
1495
- case 'vorky':
1496
- return Metric.VORKATH;
1497
- case 'wt':
1498
- return Metric.WINTERTODT;
1499
- case 'snek':
1500
- case 'zul':
1501
- return Metric.ZULRAH;
1502
- // Minigames and others
1503
- case 'all-clues':
1504
- case 'clues':
1505
- return Metric.CLUE_SCROLLS_ALL;
1506
- case 'beginner':
1507
- case 'beginner-clues':
1508
- case 'beg-clues':
1509
- case 'beginners':
1510
- return Metric.CLUE_SCROLLS_BEGINNER;
1511
- case 'easy':
1512
- case 'easy-clues':
1513
- case 'easies':
1514
- return Metric.CLUE_SCROLLS_EASY;
1515
- case 'medium':
1516
- case 'med':
1517
- case 'meds':
1518
- case 'medium-clues':
1519
- case 'med-clues':
1520
- case 'mediums':
1521
- return Metric.CLUE_SCROLLS_MEDIUM;
1522
- case 'hard':
1523
- case 'hard-clues':
1524
- case 'hards':
1525
- return Metric.CLUE_SCROLLS_HARD;
1526
- case 'elite':
1527
- case 'elite-clues':
1528
- case 'elites':
1529
- return Metric.CLUE_SCROLLS_ELITE;
1530
- case 'master':
1531
- case 'master-clues':
1532
- case 'masters':
1533
- return Metric.CLUE_SCROLLS_MASTER;
1534
- case 'lms':
1535
- return Metric.LAST_MAN_STANDING;
1536
- case 'league':
1537
- case 'lp':
1538
- case 'lps':
1539
- return Metric.LEAGUE_POINTS;
1540
- case 'sw':
1541
- case 'zeal':
1542
- case 'soul-wars':
1543
- return Metric.SOUL_WARS_ZEAL;
1544
- // Skills
1545
- case 'runecraft':
1546
- case 'rc':
1547
- return Metric.RUNECRAFTING;
1548
- case 'att':
1549
- case 'atk':
1550
- case 'attk':
1551
- return Metric.ATTACK;
1552
- case 'def':
1553
- case 'defense':
1554
- return Metric.DEFENCE;
1555
- case 'str':
1556
- return Metric.STRENGTH;
1557
- case 'hp':
1558
- return Metric.HITPOINTS;
1559
- case 'range':
1560
- return Metric.RANGED;
1561
- case 'pray':
1562
- return Metric.PRAYER;
1563
- case 'mage':
1564
- return Metric.MAGIC;
1565
- case 'cook':
1566
- return Metric.COOKING;
1567
- case 'wc':
1568
- return Metric.WOODCUTTING;
1569
- case 'fletch':
1570
- return Metric.FLETCHING;
1571
- case 'fish':
1572
- return Metric.FISHING;
1573
- case 'fm':
1574
- case 'burning':
1575
- return Metric.FIREMAKING;
1576
- case 'craft':
1577
- return Metric.CRAFTING;
1578
- case 'sm':
1579
- case 'smith':
1580
- return Metric.SMITHING;
1581
- case 'mine':
1582
- case 'smash':
1583
- return Metric.MINING;
1584
- case 'herb':
1585
- return Metric.HERBLORE;
1586
- case 'agi':
1587
- case 'agil':
1588
- return Metric.AGILITY;
1589
- case 'thief':
1590
- return Metric.THIEVING;
1591
- case 'slay':
1592
- return Metric.SLAYER;
1593
- case 'farm':
1594
- return Metric.FARMING;
1595
- case 'hunt':
1596
- case 'hunting':
1597
- return Metric.HUNTER;
1598
- case 'con':
1599
- case 'cons':
1600
- case 'const':
1601
- return Metric.CONSTRUCTION;
1602
- default:
1603
- return abbreviation;
1604
- }
1605
- }
1606
-
1607
- // Maximum effective skill level at 13,034,431 experience.
1608
- const MAX_LEVEL = 99;
1609
- // The maximum virtual skill level for any skill (200M experience).
1610
- const MAX_VIRTUAL_LEVEL = 126;
1611
- // The maximum skill experience (200M experience).
1612
- const MAX_SKILL_EXP = 200000000;
1613
- // The minimum skill exp for level 99
1614
- const SKILL_EXP_AT_99 = 13034431;
1615
- // The maximum skill at exactly 99 on all skills
1616
- const CAPPED_MAX_TOTAL_XP = 23 * SKILL_EXP_AT_99;
1617
- // Builds a lookup table for each level's required experience
1618
- // exp = XP_FOR_LEVEL[level - 1] || 13m = XP_FOR_LEVEL[98]
1619
- const XP_FOR_LEVEL = (function () {
1620
- let xp = 0;
1621
- const array = [];
1622
- for (let level = 1; level <= MAX_VIRTUAL_LEVEL; ++level) {
1623
- array[level - 1] = Math.floor(xp / 4);
1624
- xp += Math.floor(level + 300 * Math.pow(2, level / 7));
1625
- }
1626
- return array;
1627
- })();
1628
- function getExpForLevel(level) {
1629
- if (level < 1 || level > MAX_VIRTUAL_LEVEL)
1630
- return 0;
1631
- return XP_FOR_LEVEL[level - 1];
1632
- }
1633
- function getLevel(exp, virtual = false) {
1634
- if (!exp || exp < 0) {
1635
- return 1;
1636
- }
1637
- let low = 0;
1638
- let high = virtual ? XP_FOR_LEVEL.length - 1 : 98;
1639
- while (low <= high) {
1640
- const mid = Math.floor(low + (high - low) / 2);
1641
- const xpForLevel = XP_FOR_LEVEL[mid];
1642
- if (exp < xpForLevel) {
1643
- high = mid - 1;
1644
- }
1645
- else if (exp > xpForLevel) {
1646
- low = mid + 1;
1647
- }
1648
- else {
1649
- return mid + 1;
1650
- }
1651
- }
1652
- return high + 1;
1653
- }
1654
- function getCombatLevelFromExp(attack, strength, defence, ranged, magic, hitpoints, prayer) {
1655
- if ([attack, strength, defence, ranged, magic, hitpoints, prayer].some(l => l === 0))
1656
- return 0;
1657
- const baseCombat = 0.25 * (defence + Math.max(hitpoints, 10) + Math.floor(prayer / 2));
1658
- const meleeCombat = 0.325 * (attack + strength);
1659
- const rangeCombat = 0.325 * Math.floor((3 * ranged) / 2);
1660
- const mageCombat = 0.325 * Math.floor((3 * magic) / 2);
1661
- return Math.floor(baseCombat + Math.max(meleeCombat, rangeCombat, mageCombat));
1662
- }
1663
- function getCombatLevel(snapshot) {
1664
- if (!snapshot)
1665
- return 3;
1666
- return getCombatLevelFromExp(getLevel(snapshot.attackExperience), getLevel(snapshot.strengthExperience), getLevel(snapshot.defenceExperience), getLevel(snapshot.rangedExperience), getLevel(snapshot.magicExperience), getLevel(snapshot.hitpointsExperience), getLevel(snapshot.prayerExperience));
1667
- }
1668
- function get200msCount(snapshot) {
1669
- return REAL_SKILLS.filter(s => snapshot[getMetricValueKey(s)] === MAX_SKILL_EXP).length;
1670
- }
1671
- function getMinimumExp(snapshot) {
1672
- return REAL_SKILLS.map(s => Math.max(0, snapshot[getMetricValueKey(s)] || 0)).sort((a, b) => a - b)[0];
1673
- }
1674
- function getCappedExp(snapshot, max) {
1675
- return REAL_SKILLS.map(s => Math.min(snapshot[getMetricValueKey(s)], max)).reduce((acc, cur) => acc + cur);
1676
- }
1677
- function getTotalLevel(snapshot) {
1678
- return REAL_SKILLS.map(s => getLevel(snapshot[getMetricValueKey(s)])).reduce((acc, cur) => acc + cur);
1679
- }
1680
- function isF2p(snapshot) {
1681
- const hasMemberStats = MEMBER_SKILLS.some(s => getLevel(snapshot[getMetricValueKey(s)]) > 1);
1682
- const hasBossKc = BOSSES.filter(b => !F2P_BOSSES.includes(b)).some(b => snapshot[getMetricValueKey(b)] > 0);
1683
- return !hasMemberStats && !hasBossKc;
1684
- }
1685
- function isLvl3(snapshot) {
1686
- return getCombatLevel(snapshot) <= 3;
1687
- }
1688
- function is1Def(snapshot) {
1689
- return getLevel(snapshot.defenceExperience) === 1;
1690
- }
1691
- function is10HP(snapshot) {
1692
- return getCombatLevel(snapshot) > 3 && getLevel(snapshot.hitpointsExperience) === 10;
1693
- }
1694
- function isZerker(snapshot) {
1695
- return getLevel(snapshot.defenceExperience) === 45;
1477
+ function getCombatLevel(attack, strength, defence, ranged, magic, hitpoints, prayer) {
1478
+ if ([attack, strength, defence, ranged, magic, hitpoints, prayer].some(l => l === 0))
1479
+ return 0;
1480
+ const baseCombat = 0.25 * (defence + Math.max(hitpoints, 10) + Math.floor(prayer / 2));
1481
+ const meleeCombat = 0.325 * (attack + strength);
1482
+ const rangeCombat = 0.325 * Math.floor((3 * ranged) / 2);
1483
+ const mageCombat = 0.325 * Math.floor((3 * magic) / 2);
1484
+ return Math.floor(baseCombat + Math.max(meleeCombat, rangeCombat, mageCombat));
1696
1485
  }
1697
1486
 
1698
1487
  const GROUP_ROLES = Object.values(GroupRole);
@@ -1980,7 +1769,420 @@ function findGroupRole(roleName) {
1980
1769
  return key;
1981
1770
  }
1982
1771
  }
1983
- return null;
1772
+ return null;
1773
+ }
1774
+ function isGroupRole(roleString) {
1775
+ return roleString in GroupRoleProps;
1776
+ }
1777
+
1778
+ exports.MetricType = void 0;
1779
+ (function (MetricType) {
1780
+ MetricType["SKILL"] = "skill";
1781
+ MetricType["BOSS"] = "boss";
1782
+ MetricType["ACTIVITY"] = "activity";
1783
+ MetricType["COMPUTED"] = "computed";
1784
+ })(exports.MetricType || (exports.MetricType = {}));
1785
+ exports.MetricMeasure = void 0;
1786
+ (function (MetricMeasure) {
1787
+ MetricMeasure["EXPERIENCE"] = "experience";
1788
+ MetricMeasure["KILLS"] = "kills";
1789
+ MetricMeasure["SCORE"] = "score";
1790
+ MetricMeasure["VALUE"] = "value";
1791
+ })(exports.MetricMeasure || (exports.MetricMeasure = {}));
1792
+ const SkillProps = lodash.mapValues({
1793
+ [Skill.OVERALL]: { name: 'Overall', isCombat: false, isMembers: false },
1794
+ [Skill.ATTACK]: { name: 'Attack', isCombat: true, isMembers: false },
1795
+ [Skill.DEFENCE]: { name: 'Defence', isCombat: true, isMembers: false },
1796
+ [Skill.STRENGTH]: { name: 'Strength', isCombat: true, isMembers: false },
1797
+ [Skill.HITPOINTS]: { name: 'Hitpoints', isCombat: true, isMembers: false },
1798
+ [Skill.RANGED]: { name: 'Ranged', isCombat: true, isMembers: false },
1799
+ [Skill.PRAYER]: { name: 'Prayer', isCombat: true, isMembers: false },
1800
+ [Skill.MAGIC]: { name: 'Magic', isCombat: true, isMembers: false },
1801
+ [Skill.COOKING]: { name: 'Cooking', isCombat: false, isMembers: false },
1802
+ [Skill.WOODCUTTING]: { name: 'Woodcutting', isCombat: false, isMembers: false },
1803
+ [Skill.FLETCHING]: { name: 'Fletching', isCombat: false, isMembers: true },
1804
+ [Skill.FISHING]: { name: 'Fishing', isCombat: false, isMembers: false },
1805
+ [Skill.FIREMAKING]: { name: 'Firemaking', isCombat: false, isMembers: false },
1806
+ [Skill.CRAFTING]: { name: 'Crafting', isCombat: false, isMembers: false },
1807
+ [Skill.SMITHING]: { name: 'Smithing', isCombat: false, isMembers: false },
1808
+ [Skill.MINING]: { name: 'Mining', isCombat: false, isMembers: false },
1809
+ [Skill.HERBLORE]: { name: 'Herblore', isCombat: false, isMembers: true },
1810
+ [Skill.AGILITY]: { name: 'Agility', isCombat: false, isMembers: true },
1811
+ [Skill.THIEVING]: { name: 'Thieving', isCombat: false, isMembers: true },
1812
+ [Skill.SLAYER]: { name: 'Slayer', isCombat: false, isMembers: true },
1813
+ [Skill.FARMING]: { name: 'Farming', isCombat: false, isMembers: true },
1814
+ [Skill.RUNECRAFTING]: { name: 'Runecrafting', isCombat: false, isMembers: false },
1815
+ [Skill.HUNTER]: { name: 'Hunter', isCombat: false, isMembers: true },
1816
+ [Skill.CONSTRUCTION]: { name: 'Construction', isCombat: false, isMembers: false }
1817
+ }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.SKILL, measure: exports.MetricMeasure.EXPERIENCE })));
1818
+ const BossProps = lodash.mapValues({
1819
+ [Boss.ABYSSAL_SIRE]: { name: 'Abyssal Sire', minimumKc: 50, isMembers: true },
1820
+ [Boss.ALCHEMICAL_HYDRA]: { name: 'Alchemical Hydra', minimumKc: 50, isMembers: true },
1821
+ [Boss.BARROWS_CHESTS]: { name: 'Barrows Chests', minimumKc: 50, isMembers: true },
1822
+ [Boss.BRYOPHYTA]: { name: 'Bryophyta', minimumKc: 5, isMembers: false },
1823
+ [Boss.CALLISTO]: { name: 'Callisto', minimumKc: 50, isMembers: true },
1824
+ [Boss.CERBERUS]: { name: 'Cerberus', minimumKc: 50, isMembers: true },
1825
+ [Boss.CHAMBERS_OF_XERIC]: { name: 'Chambers Of Xeric', minimumKc: 50, isMembers: true },
1826
+ [Boss.CHAMBERS_OF_XERIC_CM]: { name: 'Chambers Of Xeric (CM)', minimumKc: 5, isMembers: true },
1827
+ [Boss.CHAOS_ELEMENTAL]: { name: 'Chaos Elemental', minimumKc: 50, isMembers: true },
1828
+ [Boss.CHAOS_FANATIC]: { name: 'Chaos Fanatic', minimumKc: 50, isMembers: true },
1829
+ [Boss.COMMANDER_ZILYANA]: { name: 'Commander Zilyana', minimumKc: 50, isMembers: true },
1830
+ [Boss.CORPOREAL_BEAST]: { name: 'Corporeal Beast', minimumKc: 50, isMembers: true },
1831
+ [Boss.CRAZY_ARCHAEOLOGIST]: { name: 'Crazy Archaeologist', minimumKc: 50, isMembers: true },
1832
+ [Boss.DAGANNOTH_PRIME]: { name: 'Dagannoth Prime', minimumKc: 50, isMembers: true },
1833
+ [Boss.DAGANNOTH_REX]: { name: 'Dagannoth Rex', minimumKc: 50, isMembers: true },
1834
+ [Boss.DAGANNOTH_SUPREME]: { name: 'Dagannoth Supreme', minimumKc: 50, isMembers: true },
1835
+ [Boss.DERANGED_ARCHAEOLOGIST]: { name: 'Deranged Archaeologist', minimumKc: 50, isMembers: true },
1836
+ [Boss.GENERAL_GRAARDOR]: { name: 'General Graardor', minimumKc: 50, isMembers: true },
1837
+ [Boss.GIANT_MOLE]: { name: 'Giant Mole', minimumKc: 50, isMembers: true },
1838
+ [Boss.GROTESQUE_GUARDIANS]: { name: 'Grotesque Guardians', minimumKc: 50, isMembers: true },
1839
+ [Boss.HESPORI]: { name: 'Hespori', minimumKc: 5, isMembers: true },
1840
+ [Boss.KALPHITE_QUEEN]: { name: 'Kalphite Queen', minimumKc: 50, isMembers: true },
1841
+ [Boss.KING_BLACK_DRAGON]: { name: 'King Black Dragon', minimumKc: 50, isMembers: true },
1842
+ [Boss.KRAKEN]: { name: 'Kraken', minimumKc: 50, isMembers: true },
1843
+ [Boss.KREEARRA]: { name: "Kree'Arra", minimumKc: 50, isMembers: true },
1844
+ [Boss.KRIL_TSUTSAROTH]: { name: "K'ril Tsutsaroth", minimumKc: 50, isMembers: true },
1845
+ [Boss.MIMIC]: { name: 'Mimic', minimumKc: 1, isMembers: true },
1846
+ [Boss.NEX]: { name: 'Nex', minimumKc: 50, isMembers: true },
1847
+ [Boss.NIGHTMARE]: { name: 'Nightmare', minimumKc: 50, isMembers: true },
1848
+ [Boss.PHOSANIS_NIGHTMARE]: { name: "Phosani's Nightmare", minimumKc: 50, isMembers: true },
1849
+ [Boss.OBOR]: { name: 'Obor', minimumKc: 5, isMembers: false },
1850
+ [Boss.SARACHNIS]: { name: 'Sarachnis', minimumKc: 50, isMembers: true },
1851
+ [Boss.SKOTIZO]: { name: 'Skotizo', minimumKc: 5, isMembers: true },
1852
+ [Boss.SCORPIA]: { name: 'Scorpia', minimumKc: 50, isMembers: true },
1853
+ [Boss.TEMPOROSS]: { name: 'Tempoross', minimumKc: 50, isMembers: true },
1854
+ [Boss.THE_GAUNTLET]: { name: 'The Gauntlet', minimumKc: 50, isMembers: true },
1855
+ [Boss.THE_CORRUPTED_GAUNTLET]: { name: 'The Corrupted Gauntlet', minimumKc: 5, isMembers: true },
1856
+ [Boss.THEATRE_OF_BLOOD]: { name: 'Theatre Of Blood', minimumKc: 50, isMembers: true },
1857
+ [Boss.THEATRE_OF_BLOOD_HARD_MODE]: { name: 'Theatre Of Blood (HM)', minimumKc: 50, isMembers: true },
1858
+ [Boss.THERMONUCLEAR_SMOKE_DEVIL]: { name: 'Thermonuclear Smoke Devil', minimumKc: 50, isMembers: true },
1859
+ [Boss.TOMBS_OF_AMASCUT]: { name: 'Tombs of Amascut', minimumKc: 50, isMembers: true },
1860
+ [Boss.TOMBS_OF_AMASCUT_EXPERT]: {
1861
+ name: 'Tombs of Amascut (Expert Mode)',
1862
+ minimumKc: 50,
1863
+ isMembers: true
1864
+ },
1865
+ [Boss.TZKAL_ZUK]: { name: 'TzKal-Zuk', minimumKc: 1, isMembers: true },
1866
+ [Boss.TZTOK_JAD]: { name: 'TzTok-Jad', minimumKc: 5, isMembers: true },
1867
+ [Boss.VENENATIS]: { name: 'Venenatis', minimumKc: 50, isMembers: true },
1868
+ [Boss.VETION]: { name: "Vet'ion", minimumKc: 50, isMembers: true },
1869
+ [Boss.VORKATH]: { name: 'Vorkath', minimumKc: 50, isMembers: true },
1870
+ [Boss.WINTERTODT]: { name: 'Wintertodt', minimumKc: 50, isMembers: true },
1871
+ [Boss.ZALCANO]: { name: 'Zalcano', minimumKc: 50, isMembers: true },
1872
+ [Boss.ZULRAH]: { name: 'Zulrah', minimumKc: 50, isMembers: true }
1873
+ }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.BOSS, measure: exports.MetricMeasure.KILLS })));
1874
+ const ActivityProps = lodash.mapValues({
1875
+ [Activity.LEAGUE_POINTS]: { name: 'League Points' },
1876
+ [Activity.BOUNTY_HUNTER_HUNTER]: { name: 'Bounty Hunter (Hunter)' },
1877
+ [Activity.BOUNTY_HUNTER_ROGUE]: { name: 'Bounty Hunter (Rogue)' },
1878
+ [Activity.CLUE_SCROLLS_ALL]: { name: 'Clue Scrolls (All)' },
1879
+ [Activity.CLUE_SCROLLS_BEGINNER]: { name: 'Clue Scrolls (Beginner)' },
1880
+ [Activity.CLUE_SCROLLS_EASY]: { name: 'Clue Scrolls (Easy)' },
1881
+ [Activity.CLUE_SCROLLS_MEDIUM]: { name: 'Clue Scrolls (Medium)' },
1882
+ [Activity.CLUE_SCROLLS_HARD]: { name: 'Clue Scrolls (Hard)' },
1883
+ [Activity.CLUE_SCROLLS_ELITE]: { name: 'Clue Scrolls (Elite)' },
1884
+ [Activity.CLUE_SCROLLS_MASTER]: { name: 'Clue Scrolls (Master)' },
1885
+ [Activity.LAST_MAN_STANDING]: { name: 'Last Man Standing' },
1886
+ [Activity.PVP_ARENA]: { name: 'PvP Arena' },
1887
+ [Activity.SOUL_WARS_ZEAL]: { name: 'Soul Wars Zeal' },
1888
+ [Activity.GUARDIANS_OF_THE_RIFT]: { name: 'Guardians of the Rift' }
1889
+ }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.ACTIVITY, measure: exports.MetricMeasure.SCORE })));
1890
+ const ComputedMetricProps = lodash.mapValues({
1891
+ [ComputedMetric.EHP]: { name: 'EHP' },
1892
+ [ComputedMetric.EHB]: { name: 'EHB' }
1893
+ }, props => (Object.assign(Object.assign({}, props), { type: exports.MetricType.COMPUTED, measure: exports.MetricMeasure.VALUE })));
1894
+ const MetricProps = Object.assign(Object.assign(Object.assign(Object.assign({}, SkillProps), BossProps), ActivityProps), ComputedMetricProps);
1895
+ const METRICS = Object.values(Metric);
1896
+ const SKILLS = Object.values(Skill);
1897
+ const BOSSES = Object.values(Boss);
1898
+ const ACTIVITIES = Object.values(Activity);
1899
+ const COMPUTED_METRICS = Object.values(ComputedMetric);
1900
+ const REAL_SKILLS = SKILLS.filter(s => s !== Skill.OVERALL);
1901
+ const F2P_BOSSES = BOSSES.filter(b => !MetricProps[b].isMembers);
1902
+ const MEMBER_SKILLS = SKILLS.filter(s => MetricProps[s].isMembers);
1903
+ const COMBAT_SKILLS = SKILLS.filter(s => MetricProps[s].isCombat);
1904
+ function findMetric(metricName) {
1905
+ for (const [key, value] of Object.entries(MetricProps)) {
1906
+ if (value.name.toUpperCase() === metricName.toUpperCase())
1907
+ return key;
1908
+ }
1909
+ return null;
1910
+ }
1911
+ function isMetric(metricString) {
1912
+ return metricString in MetricProps;
1913
+ }
1914
+ function isSkill(metric) {
1915
+ return metric in SkillProps;
1916
+ }
1917
+ function isActivity(metric) {
1918
+ return metric in ActivityProps;
1919
+ }
1920
+ function isBoss(metric) {
1921
+ return metric in BossProps;
1922
+ }
1923
+ function isComputedMetric(metric) {
1924
+ return metric in ComputedMetricProps;
1925
+ }
1926
+ function getMetricRankKey(metric) {
1927
+ return `${metric}Rank`;
1928
+ }
1929
+ function getMetricValueKey(metric) {
1930
+ return `${metric}${lodash.capitalize(MetricProps[metric].measure)}`;
1931
+ }
1932
+ function getMetricMeasure(metric) {
1933
+ return MetricProps[metric].measure;
1934
+ }
1935
+ function getMetricName(metric) {
1936
+ return MetricProps[metric].name;
1937
+ }
1938
+ function getMinimumBossKc(metric) {
1939
+ return isBoss(metric) ? MetricProps[metric].minimumKc : 0;
1940
+ }
1941
+ function getParentEfficiencyMetric(metric) {
1942
+ if (isBoss(metric))
1943
+ return Metric.EHB;
1944
+ if (isSkill(metric))
1945
+ return Metric.EHP;
1946
+ return null;
1947
+ }
1948
+ function parseMetricAbbreviation(abbreviation) {
1949
+ if (!abbreviation || abbreviation.length === 0) {
1950
+ return null;
1951
+ }
1952
+ switch (abbreviation.toLowerCase()) {
1953
+ // Bosses
1954
+ case 'sire':
1955
+ return Metric.ABYSSAL_SIRE;
1956
+ case 'hydra':
1957
+ return Metric.ALCHEMICAL_HYDRA;
1958
+ case 'barrows':
1959
+ return Metric.BARROWS_CHESTS;
1960
+ case 'bryo':
1961
+ return Metric.BRYOPHYTA;
1962
+ case 'cerb':
1963
+ return Metric.CERBERUS;
1964
+ case 'cox':
1965
+ case 'xeric':
1966
+ case 'chambers':
1967
+ case 'olm':
1968
+ case 'raids':
1969
+ return Metric.CHAMBERS_OF_XERIC;
1970
+ case 'cox-cm':
1971
+ case 'xeric-cm':
1972
+ case 'chambers-cm':
1973
+ case 'olm-cm':
1974
+ case 'raids-cm':
1975
+ return Metric.CHAMBERS_OF_XERIC_CM;
1976
+ case 'chaos-ele':
1977
+ return Metric.CHAOS_ELEMENTAL;
1978
+ case 'fanatic':
1979
+ return Metric.CHAOS_FANATIC;
1980
+ case 'sara':
1981
+ case 'saradomin':
1982
+ case 'zilyana':
1983
+ case 'zily':
1984
+ return Metric.COMMANDER_ZILYANA;
1985
+ case 'corp':
1986
+ return Metric.CORPOREAL_BEAST;
1987
+ case 'crazy-arch':
1988
+ return Metric.CRAZY_ARCHAEOLOGIST;
1989
+ case 'prime':
1990
+ return Metric.DAGANNOTH_PRIME;
1991
+ case 'rex':
1992
+ return Metric.DAGANNOTH_REX;
1993
+ case 'supreme':
1994
+ return Metric.DAGANNOTH_SUPREME;
1995
+ case 'deranged-arch':
1996
+ return Metric.DERANGED_ARCHAEOLOGIST;
1997
+ case 'bandos':
1998
+ case 'graardor':
1999
+ return Metric.GENERAL_GRAARDOR;
2000
+ case 'mole':
2001
+ return Metric.GIANT_MOLE;
2002
+ case 'dusk':
2003
+ case 'dawn':
2004
+ case 'gargs':
2005
+ case 'guardians':
2006
+ case 'ggs':
2007
+ return Metric.GROTESQUE_GUARDIANS;
2008
+ case 'kq':
2009
+ return Metric.KALPHITE_QUEEN;
2010
+ case 'kbd':
2011
+ return Metric.KING_BLACK_DRAGON;
2012
+ case 'kree':
2013
+ case 'kreearra':
2014
+ case 'armadyl':
2015
+ case 'arma':
2016
+ return Metric.KREEARRA;
2017
+ case 'zammy':
2018
+ case 'zamorak':
2019
+ case 'kril':
2020
+ case 'kril-tsutsaroth':
2021
+ return Metric.KRIL_TSUTSAROTH;
2022
+ case 'gaunt':
2023
+ case 'gauntlet':
2024
+ case 'the-gauntlet':
2025
+ return Metric.THE_GAUNTLET;
2026
+ case 'cgaunt':
2027
+ case 'cgauntlet':
2028
+ case 'corrupted':
2029
+ case 'corrupted-gauntlet':
2030
+ case 'the-corrupted-gauntlet':
2031
+ return Metric.THE_CORRUPTED_GAUNTLET;
2032
+ case 'tob':
2033
+ case 'theatre':
2034
+ case 'verzik':
2035
+ case 'tob-normal':
2036
+ return Metric.THEATRE_OF_BLOOD;
2037
+ case 'tob-hm':
2038
+ case 'tob-cm':
2039
+ case 'tob-hard-mode':
2040
+ case 'tob-hard':
2041
+ return Metric.THEATRE_OF_BLOOD_HARD_MODE;
2042
+ case 'toa':
2043
+ case 'tombs':
2044
+ case 'amascut':
2045
+ return Metric.TOMBS_OF_AMASCUT;
2046
+ case 'toa-expert':
2047
+ case 'toa-hm':
2048
+ case 'tombs-expert':
2049
+ case 'tombs-hm':
2050
+ case 'amascut-expert':
2051
+ case 'amascut-hm':
2052
+ return Metric.TOMBS_OF_AMASCUT_EXPERT;
2053
+ case 'nm':
2054
+ case 'tnm':
2055
+ case 'nmare':
2056
+ case 'the-nightmare':
2057
+ return Metric.NIGHTMARE;
2058
+ case 'pnm':
2059
+ case 'phosani':
2060
+ case 'phosanis':
2061
+ case 'phosani-nm':
2062
+ case 'phosani-nightmare':
2063
+ case 'phosanis nightmare':
2064
+ return Metric.PHOSANIS_NIGHTMARE;
2065
+ case 'thermy':
2066
+ case 'smoke-devil':
2067
+ return Metric.THERMONUCLEAR_SMOKE_DEVIL;
2068
+ case 'zuk':
2069
+ case 'inferno':
2070
+ return Metric.TZKAL_ZUK;
2071
+ case 'jad':
2072
+ case 'fight-caves':
2073
+ case 'fc':
2074
+ return Metric.TZTOK_JAD;
2075
+ case 'vork':
2076
+ case 'vorky':
2077
+ return Metric.VORKATH;
2078
+ case 'wt':
2079
+ return Metric.WINTERTODT;
2080
+ case 'snek':
2081
+ case 'zul':
2082
+ return Metric.ZULRAH;
2083
+ // Minigames and others
2084
+ case 'all-clues':
2085
+ case 'clues':
2086
+ return Metric.CLUE_SCROLLS_ALL;
2087
+ case 'beginner':
2088
+ case 'beginner-clues':
2089
+ case 'beg-clues':
2090
+ case 'beginners':
2091
+ return Metric.CLUE_SCROLLS_BEGINNER;
2092
+ case 'easy':
2093
+ case 'easy-clues':
2094
+ case 'easies':
2095
+ return Metric.CLUE_SCROLLS_EASY;
2096
+ case 'medium':
2097
+ case 'med':
2098
+ case 'meds':
2099
+ case 'medium-clues':
2100
+ case 'med-clues':
2101
+ case 'mediums':
2102
+ return Metric.CLUE_SCROLLS_MEDIUM;
2103
+ case 'hard':
2104
+ case 'hard-clues':
2105
+ case 'hards':
2106
+ return Metric.CLUE_SCROLLS_HARD;
2107
+ case 'elite':
2108
+ case 'elite-clues':
2109
+ case 'elites':
2110
+ return Metric.CLUE_SCROLLS_ELITE;
2111
+ case 'master':
2112
+ case 'master-clues':
2113
+ case 'masters':
2114
+ return Metric.CLUE_SCROLLS_MASTER;
2115
+ case 'lms':
2116
+ return Metric.LAST_MAN_STANDING;
2117
+ case 'league':
2118
+ case 'lp':
2119
+ case 'lps':
2120
+ return Metric.LEAGUE_POINTS;
2121
+ case 'sw':
2122
+ case 'zeal':
2123
+ case 'soul-wars':
2124
+ return Metric.SOUL_WARS_ZEAL;
2125
+ // Skills
2126
+ case 'runecraft':
2127
+ case 'rc':
2128
+ return Metric.RUNECRAFTING;
2129
+ case 'att':
2130
+ case 'atk':
2131
+ case 'attk':
2132
+ return Metric.ATTACK;
2133
+ case 'def':
2134
+ case 'defense':
2135
+ return Metric.DEFENCE;
2136
+ case 'str':
2137
+ return Metric.STRENGTH;
2138
+ case 'hp':
2139
+ return Metric.HITPOINTS;
2140
+ case 'range':
2141
+ return Metric.RANGED;
2142
+ case 'pray':
2143
+ return Metric.PRAYER;
2144
+ case 'mage':
2145
+ return Metric.MAGIC;
2146
+ case 'cook':
2147
+ return Metric.COOKING;
2148
+ case 'wc':
2149
+ return Metric.WOODCUTTING;
2150
+ case 'fletch':
2151
+ return Metric.FLETCHING;
2152
+ case 'fish':
2153
+ return Metric.FISHING;
2154
+ case 'fm':
2155
+ case 'burning':
2156
+ return Metric.FIREMAKING;
2157
+ case 'craft':
2158
+ return Metric.CRAFTING;
2159
+ case 'sm':
2160
+ case 'smith':
2161
+ return Metric.SMITHING;
2162
+ case 'mine':
2163
+ case 'smash':
2164
+ return Metric.MINING;
2165
+ case 'herb':
2166
+ return Metric.HERBLORE;
2167
+ case 'agi':
2168
+ case 'agil':
2169
+ return Metric.AGILITY;
2170
+ case 'thief':
2171
+ return Metric.THIEVING;
2172
+ case 'slay':
2173
+ return Metric.SLAYER;
2174
+ case 'farm':
2175
+ return Metric.FARMING;
2176
+ case 'hunt':
2177
+ case 'hunting':
2178
+ return Metric.HUNTER;
2179
+ case 'con':
2180
+ case 'cons':
2181
+ case 'const':
2182
+ return Metric.CONSTRUCTION;
2183
+ default:
2184
+ return abbreviation;
2185
+ }
1984
2186
  }
1985
2187
 
1986
2188
  const CUSTOM_PERIOD_REGEX = /(\d+y)?(\d+m)?(\d+w)?(\d+d)?(\d+h)?/;
@@ -1999,9 +2201,12 @@ function findPeriod(periodName) {
1999
2201
  }
2000
2202
  return null;
2001
2203
  }
2204
+ function isPeriod(periodString) {
2205
+ return periodString in PeriodProps;
2206
+ }
2002
2207
  function parsePeriodExpression(periodExpression) {
2003
2208
  const fixed = periodExpression.toLowerCase();
2004
- if (PERIODS.includes(fixed)) {
2209
+ if (isPeriod(fixed)) {
2005
2210
  return {
2006
2211
  expression: fixed,
2007
2212
  durationMs: PeriodProps[fixed].milliseconds
@@ -2044,6 +2249,12 @@ const PlayerBuildProps = {
2044
2249
  };
2045
2250
  const PLAYER_TYPES = Object.values(PlayerType);
2046
2251
  const PLAYER_BUILDS = Object.values(PlayerBuild);
2252
+ function isPlayerType(typeString) {
2253
+ return typeString in PlayerTypeProps;
2254
+ }
2255
+ function isPlayerBuild(buildString) {
2256
+ return buildString in PlayerBuildProps;
2257
+ }
2047
2258
  function findPlayerType(typeName) {
2048
2259
  for (const [key, value] of Object.entries(PlayerTypeProps)) {
2049
2260
  if (value.name.toUpperCase() === typeName.toUpperCase())
@@ -2114,23 +2325,159 @@ exports.SnapshotDataSource = void 0;
2114
2325
  })(exports.SnapshotDataSource || (exports.SnapshotDataSource = {}));
2115
2326
 
2116
2327
  class EfficiencyClient {
2328
+ /**
2329
+ * Fetches the current efficiency leaderboard for a specific efficiency metric, playerType, playerBuild and country.
2330
+ * @returns A list of players.
2331
+ */
2117
2332
  getEfficiencyLeaderboards(filter, pagination) {
2118
2333
  return sendGetRequest('/efficiency/leaderboard', Object.assign(Object.assign({}, filter), pagination));
2119
2334
  }
2335
+ /**
2336
+ * Fetches the top EHP (Efficient Hours Played) rates.
2337
+ * @returns A list of skilling methods and their bonus exp ratios.
2338
+ */
2120
2339
  getEHPRates(algorithmType) {
2121
2340
  return sendGetRequest('/efficiency/rates', { metric: Metric.EHP, type: algorithmType });
2122
2341
  }
2342
+ /**
2343
+ * Fetches the top EHB (Efficient Hours Bossed) rates.
2344
+ * @returns A list of bosses and their respective "per-hour" kill rates.
2345
+ */
2123
2346
  getEHBRates(algorithmType) {
2124
2347
  return sendGetRequest('/efficiency/rates', { metric: Metric.EHB, type: algorithmType });
2125
2348
  }
2126
2349
  }
2127
2350
 
2351
+ class NameChangesClient {
2352
+ /**
2353
+ * Searches for name changes that match a name and/or status filter.
2354
+ * @returns A list of name changes.
2355
+ */
2356
+ searchNameChanges(filter, pagination) {
2357
+ return sendGetRequest('/names', Object.assign(Object.assign({}, filter), pagination));
2358
+ }
2359
+ /**
2360
+ * Submits a name change request between two usernames (old and new).
2361
+ * @returns A pending name change request, to be reviewed and resolved at a later date.
2362
+ */
2363
+ submitNameChange(oldName, newName) {
2364
+ return sendPostRequest('/names', { oldName, newName });
2365
+ }
2366
+ /**
2367
+ * Gets details on a specific name change request.
2368
+ * @returns The name change request's details, which includes all data required to review.
2369
+ */
2370
+ getNameChangeDetails(id) {
2371
+ return sendGetRequest(`/names/${id}`);
2372
+ }
2373
+ }
2374
+
2375
+ class CompetitionsClient {
2376
+ /**
2377
+ * Searches for competitions that match a title, type, metric and status filter.
2378
+ * @returns A list of competitions.
2379
+ */
2380
+ searchCompetitions(filter, pagination) {
2381
+ return sendGetRequest('/competitions', Object.assign(Object.assign({}, filter), pagination));
2382
+ }
2383
+ /**
2384
+ * Fetches the competition's full details, including all the participants and their progress.
2385
+ * @returns A competition with a list of participants.
2386
+ */
2387
+ getCompetitionDetails(id, previewMetric) {
2388
+ return sendGetRequest(`/competitions/${id}`, { metric: previewMetric });
2389
+ }
2390
+ /**
2391
+ * Fetches all the values (exp, kc, etc) in chronological order within the bounds
2392
+ * of the competition, for the top 5 participants.
2393
+ * @returns A list of competition progress objects, including the player and their value history over time.
2394
+ */
2395
+ getCompetitionTopHistory(id, previewMetric) {
2396
+ return sendGetRequest(`/competitions/${id}/top-history`, {
2397
+ metric: previewMetric
2398
+ });
2399
+ }
2400
+ /**
2401
+ * Creates a new competition.
2402
+ * @returns The newly created competition, and the verification code that authorizes future changes to it.
2403
+ */
2404
+ createCompetition(payload) {
2405
+ return sendPostRequest('/competitions', payload);
2406
+ }
2407
+ /**
2408
+ * Edits an existing competition.
2409
+ * @returns The updated competition.
2410
+ */
2411
+ editCompetition(id, payload, verificationCode) {
2412
+ return sendPutRequest(`/competitions/${id}`, Object.assign(Object.assign({}, payload), { verificationCode }));
2413
+ }
2414
+ /**
2415
+ * Deletes an existing competition.
2416
+ * @returns A confirmation message.
2417
+ */
2418
+ deleteCompetition(id, verificationCode) {
2419
+ return sendDeleteRequest(`/competitions/${id}`, { verificationCode });
2420
+ }
2421
+ /**
2422
+ * Adds all (valid) given participants to a competition, ignoring duplicates.
2423
+ * @returns The number of participants added and a confirmation message.
2424
+ */
2425
+ addParticipants(id, participants, verificationCode) {
2426
+ return sendPostRequest(`/competitions/${id}/participants`, {
2427
+ verificationCode,
2428
+ participants
2429
+ });
2430
+ }
2431
+ /**
2432
+ * Remove all given usernames from a competition, ignoring usernames that aren't competing.
2433
+ * @returns The number of participants removed and a confirmation message.
2434
+ */
2435
+ removeParticipants(id, participants, verificationCode) {
2436
+ return sendDeleteRequest(`/competitions/${id}/participants`, {
2437
+ verificationCode,
2438
+ participants
2439
+ });
2440
+ }
2441
+ /**
2442
+ * Adds all (valid) given teams to a team competition, ignoring duplicates.
2443
+ * @returns The number of participants added and a confirmation message.
2444
+ */
2445
+ addTeams(id, teams, verificationCode) {
2446
+ return sendPostRequest(`/competitions/${id}/teams`, {
2447
+ verificationCode,
2448
+ teams
2449
+ });
2450
+ }
2451
+ /**
2452
+ * Remove all given team names from a competition, ignoring names that don't exist.
2453
+ * @returns The number of participants removed and a confirmation message.
2454
+ */
2455
+ removeTeams(id, teamNames, verificationCode) {
2456
+ return sendDeleteRequest(`/competitions/${id}/teams`, {
2457
+ verificationCode,
2458
+ teamNames
2459
+ });
2460
+ }
2461
+ /**
2462
+ * Adds an "update" request to the queue, for each outdated competition participant.
2463
+ * @returns The number of players to be updated and a confirmation message.
2464
+ */
2465
+ updateAll(id, verificationCode) {
2466
+ return sendPostRequest(`/competitions/${id}/update-all`, {
2467
+ verificationCode
2468
+ });
2469
+ }
2470
+ }
2471
+
2128
2472
  class WOMClient {
2129
2473
  constructor() {
2474
+ this.deltas = new DeltasClient();
2475
+ this.groups = new GroupsClient();
2130
2476
  this.players = new PlayersClient();
2131
2477
  this.records = new RecordsClient();
2132
- this.deltas = new DeltasClient();
2133
2478
  this.efficiency = new EfficiencyClient();
2479
+ this.nameChanges = new NameChangesClient();
2480
+ this.competitions = new CompetitionsClient();
2134
2481
  }
2135
2482
  }
2136
2483
 
@@ -2142,10 +2489,12 @@ exports.CAPPED_MAX_TOTAL_XP = CAPPED_MAX_TOTAL_XP;
2142
2489
  exports.COMBAT_SKILLS = COMBAT_SKILLS;
2143
2490
  exports.COMPETITION_STATUSES = COMPETITION_STATUSES;
2144
2491
  exports.COMPETITION_TYPES = COMPETITION_TYPES;
2492
+ exports.COMPUTED_METRICS = COMPUTED_METRICS;
2145
2493
  exports.COUNTRY_CODES = COUNTRY_CODES;
2146
2494
  exports.CompetitionStatusProps = CompetitionStatusProps;
2147
2495
  exports.CompetitionType = CompetitionType;
2148
2496
  exports.CompetitionTypeProps = CompetitionTypeProps;
2497
+ exports.ComputedMetric = ComputedMetric;
2149
2498
  exports.Country = Country;
2150
2499
  exports.CountryProps = CountryProps;
2151
2500
  exports.F2P_BOSSES = F2P_BOSSES;
@@ -2174,11 +2523,7 @@ exports.REAL_SKILLS = REAL_SKILLS;
2174
2523
  exports.SKILLS = SKILLS;
2175
2524
  exports.SKILL_EXP_AT_99 = SKILL_EXP_AT_99;
2176
2525
  exports.Skill = Skill;
2177
- exports.VIRTUALS = VIRTUALS;
2178
- exports.Virtual = Virtual;
2179
2526
  exports.WOMClient = WOMClient;
2180
- exports.findCompetitionStatus = findCompetitionStatus;
2181
- exports.findCompetitionType = findCompetitionType;
2182
2527
  exports.findCountry = findCountry;
2183
2528
  exports.findCountryByCode = findCountryByCode;
2184
2529
  exports.findCountryByName = findCountryByName;
@@ -2188,10 +2533,7 @@ exports.findPeriod = findPeriod;
2188
2533
  exports.findPlayerBuild = findPlayerBuild;
2189
2534
  exports.findPlayerType = findPlayerType;
2190
2535
  exports.formatNumber = formatNumber;
2191
- exports.get200msCount = get200msCount;
2192
- exports.getCappedExp = getCappedExp;
2193
2536
  exports.getCombatLevel = getCombatLevel;
2194
- exports.getCombatLevelFromExp = getCombatLevelFromExp;
2195
2537
  exports.getExpForLevel = getExpForLevel;
2196
2538
  exports.getLevel = getLevel;
2197
2539
  exports.getMetricMeasure = getMetricMeasure;
@@ -2199,18 +2541,19 @@ exports.getMetricName = getMetricName;
2199
2541
  exports.getMetricRankKey = getMetricRankKey;
2200
2542
  exports.getMetricValueKey = getMetricValueKey;
2201
2543
  exports.getMinimumBossKc = getMinimumBossKc;
2202
- exports.getMinimumExp = getMinimumExp;
2203
- exports.getParentVirtualMetric = getParentVirtualMetric;
2204
- exports.getTotalLevel = getTotalLevel;
2205
- exports.is10HP = is10HP;
2206
- exports.is1Def = is1Def;
2544
+ exports.getParentEfficiencyMetric = getParentEfficiencyMetric;
2207
2545
  exports.isActivity = isActivity;
2208
2546
  exports.isBoss = isBoss;
2209
- exports.isF2p = isF2p;
2210
- exports.isLvl3 = isLvl3;
2547
+ exports.isCompetitionStatus = isCompetitionStatus;
2548
+ exports.isCompetitionType = isCompetitionType;
2549
+ exports.isComputedMetric = isComputedMetric;
2550
+ exports.isCountry = isCountry;
2551
+ exports.isGroupRole = isGroupRole;
2552
+ exports.isMetric = isMetric;
2553
+ exports.isPeriod = isPeriod;
2554
+ exports.isPlayerBuild = isPlayerBuild;
2555
+ exports.isPlayerType = isPlayerType;
2211
2556
  exports.isSkill = isSkill;
2212
- exports.isVirtualMetric = isVirtualMetric;
2213
- exports.isZerker = isZerker;
2214
2557
  exports.padNumber = padNumber;
2215
2558
  exports.parseMetricAbbreviation = parseMetricAbbreviation;
2216
2559
  exports.parsePeriodExpression = parsePeriodExpression;