@voltro/plugin-leaderboards 0.0.0-stage → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +24329 -0
  2. package/LICENSE +61 -0
  3. package/README.md +1087 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +5007 -0
  6. package/dist/administration.js +5 -0
  7. package/dist/bracketAdmission.js +294 -0
  8. package/dist/bracketAdmissionPolicy.js +22 -0
  9. package/dist/bracketInstallation.js +133 -0
  10. package/dist/bracketMatchPorts.js +5 -0
  11. package/dist/bracketMatches.js +546 -0
  12. package/dist/brackets.d.ts +149 -0
  13. package/dist/brackets.js +379 -0
  14. package/dist/bucketStore.js +93 -0
  15. package/dist/buckets.js +9 -0
  16. package/dist/errors.d.ts +13 -0
  17. package/dist/errors.js +17 -0
  18. package/dist/glicko2.js +72 -0
  19. package/dist/index.d.ts +1208 -0
  20. package/dist/index.js +15 -0
  21. package/dist/inspect.js +84 -0
  22. package/dist/json.js +39 -0
  23. package/dist/leaderboard.d.ts +49 -0
  24. package/dist/leaderboard.js +57 -0
  25. package/dist/leagueSchedule.js +40 -0
  26. package/dist/leagues.js +31 -0
  27. package/dist/openskill.js +74 -0
  28. package/dist/plugin.js +338 -0
  29. package/dist/portLifetime.js +67 -0
  30. package/dist/ports.d.ts +294 -0
  31. package/dist/ports.js +7 -0
  32. package/dist/rankQuery.js +24 -0
  33. package/dist/ranking.d.ts +42 -0
  34. package/dist/ranking.js +71 -0
  35. package/dist/rating.d.ts +103 -0
  36. package/dist/rating.js +50 -0
  37. package/dist/ratingPools.js +134 -0
  38. package/dist/ratingStore.js +334 -0
  39. package/dist/ratingStrategies.js +108 -0
  40. package/dist/records.d.ts +116 -0
  41. package/dist/records.js +88 -0
  42. package/dist/rpc.d.ts +321 -0
  43. package/dist/rpc.js +306 -0
  44. package/dist/score.d.ts +13 -0
  45. package/dist/score.js +27 -0
  46. package/dist/server.d.ts +1477 -0
  47. package/dist/server.js +17 -0
  48. package/dist/service.js +949 -0
  49. package/dist/subjectFences.js +44 -0
  50. package/dist/tables.entity.js +188 -0
  51. package/dist/testing.d.ts +872 -0
  52. package/dist/testing.js +368 -0
  53. package/dist/tournament-app/tournament.advance.workflow.server.tsx +3 -0
  54. package/dist/tournament-app/tournament.advance.workflow.tsx +12 -0
  55. package/dist/tournament-app/tournament.stage.workflow.server.tsx +3 -0
  56. package/dist/tournament-app/tournament.stage.workflow.tsx +10 -0
  57. package/dist/tournamentInstallation.js +168 -0
  58. package/dist/tournamentPrizes.js +34 -0
  59. package/dist/tournamentStage.js +151 -0
  60. package/dist/tournamentStagePorts.js +5 -0
  61. package/dist/tournamentWorkflow.js +101 -0
  62. package/dist/tournamentWorkflowSchemas.js +54 -0
  63. package/dist/tournaments.d.ts +32 -0
  64. package/dist/tournaments.js +21 -0
  65. package/dist/web.d.ts +175 -0
  66. package/dist/web.js +17 -0
  67. package/package.json +113 -4
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ import { LeaderboardError as e } from "./errors.js";
2
+ import { defineLeaderboard as t } from "./leaderboard.js";
3
+ import { defineLeague as n, leagueMovements as r } from "./leagues.js";
4
+ import { applyScore as i, scoreString as a, scoreValue as o } from "./score.js";
5
+ import { glicko2 as s } from "./glicko2.js";
6
+ import { openskill as c } from "./openskill.js";
7
+ import { elo as l } from "./rating.js";
8
+ import { defineTournament as u } from "./tournaments.js";
9
+ import { defaultRatingDecay as d, defaultRatingPlacement as f, defaultRatingRate as p } from "./ratingStrategies.js";
10
+ import { defaultLeaderboardTiebreak as m, defaultPeriodSummary as h, hashBucket as g, leaderboardAround as _, rankLeaderboardRecords as v } from "./ranking.js";
11
+ import { defaultLeaderboardBucketAssign as y } from "./buckets.js";
12
+ import { defaultLeaderboardRankQuery as b } from "./rankQuery.js";
13
+ import { BracketAdmissionPort as x } from "./ports.js";
14
+ import { leaderboardsPlugin as S, leaderboardsSystemContract as C } from "./plugin.js";
15
+ export { x as BracketAdmissionPort, e as LeaderboardError, i as applyScore, y as defaultLeaderboardBucketAssign, b as defaultLeaderboardRankQuery, m as defaultLeaderboardTiebreak, h as defaultPeriodSummary, d as defaultRatingDecay, f as defaultRatingPlacement, p as defaultRatingRate, t as defineLeaderboard, n as defineLeague, u as defineTournament, l as elo, s as glicko2, g as hashBucket, _ as leaderboardAround, S as leaderboardsPlugin, C as leaderboardsSystemContract, r as leagueMovements, c as openskill, v as rankLeaderboardRecords, a as scoreString, o as scoreValue };
@@ -0,0 +1,84 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ import { defaultRatingDecay as t, defaultRatingPlacement as n, defaultRatingRate as r, resolveRatingStrategies as i } from "./ratingStrategies.js";
3
+ import { defaultLeaderboardTiebreak as a, defaultPeriodSummary as o } from "./ranking.js";
4
+ import { defaultLeaderboardBucketAssign as s } from "./buckets.js";
5
+ import { defaultLeaderboardRankQuery as c } from "./rankQuery.js";
6
+ import { acceptLeaderboardSubmission as l } from "./service.js";
7
+ //#region src/inspect.ts
8
+ var u = (u, d, f = Date.now(), p = null, m = null) => {
9
+ if (!Number.isSafeInteger(f) || f < 0 || f > 864e13) throw e("unavailable");
10
+ let h = i(u.ratingStrategies);
11
+ return {
12
+ observedAt: f,
13
+ bound: d,
14
+ brackets: p === null ? null : {
15
+ ...p,
16
+ workflowInstalled: !1
17
+ },
18
+ coordination: m === null ? null : {
19
+ ...m,
20
+ workflowRuntimeObserved: !1
21
+ },
22
+ resetSchedulerInstalled: !1,
23
+ hotIndexInstalled: !1,
24
+ maxMetadataBytes: u.maxMetadataBytes ?? 16384,
25
+ maxExportRows: u.maxExportRows ?? 1e4,
26
+ maxSubmissionsPerOwner: u.maxSubmissionsPerOwner ?? 1e4,
27
+ maxPeriodRows: u.maxPeriodRows ?? 1e4,
28
+ maxSummaryBytes: u.maxSummaryBytes ?? 16384,
29
+ slots: {
30
+ validate: u.validate === void 0 || u.validate === l ? "default" : "custom",
31
+ tiebreak: u.tiebreak === void 0 || u.tiebreak === a ? "default" : "custom",
32
+ bucketAssign: u.bucketAssign === void 0 || u.bucketAssign === s ? "default" : "custom",
33
+ rankQuery: u.rankQuery === void 0 || u.rankQuery === c ? "default" : "custom",
34
+ rate: h.rate === r ? "default" : "custom",
35
+ placementPolicy: h.placementPolicy === n ? "default" : "custom",
36
+ decay: h.decay === t ? "default" : "custom",
37
+ periodSummary: u.periodSummary === void 0 || u.periodSummary === o ? "default" : "custom"
38
+ },
39
+ boards: u.boards.map((e) => ({
40
+ name: e.name,
41
+ sort: e.sort,
42
+ operator: e.operator,
43
+ submitVia: e.submit.via,
44
+ maxRankRecords: e.maxRankRecords,
45
+ maxPageSize: e.maxPageSize,
46
+ reset: e.reset === void 0 ? null : { ...e.reset },
47
+ buckets: e.buckets === void 0 ? null : { ...e.buckets }
48
+ })),
49
+ tournaments: (u.tournaments ?? []).map((e) => ({
50
+ name: e.name,
51
+ board: e.board,
52
+ startsAt: e.startsAt,
53
+ endsAt: e.endsAt,
54
+ maxEntries: e.maxEntries,
55
+ attemptsPerEntry: e.attemptsPerEntry,
56
+ joinRequired: e.joinRequired,
57
+ format: e.format
58
+ })),
59
+ ratingPools: (u.ratingPools ?? []).map((e) => ({
60
+ name: e.name,
61
+ algorithm: e.algorithm
62
+ })),
63
+ tables: [
64
+ "_voltro_lb_boards",
65
+ "_voltro_lb_records",
66
+ "_voltro_lb_periods",
67
+ "_voltro_lb_submissions",
68
+ "_voltro_lb_subject_admission",
69
+ "_voltro_lb_tournaments",
70
+ "_voltro_lb_tournament_entries",
71
+ "_voltro_lb_rating_pools",
72
+ "_voltro_lb_ratings",
73
+ "_voltro_lb_rating_matches",
74
+ "_voltro_lb_rating_results",
75
+ "_voltro_lb_bucket_assignments",
76
+ "_voltro_lb_league_members",
77
+ "_voltro_lb_league_rolls",
78
+ ...p?.backend === "sql" ? ["_voltro_tournament_admissions"] : [],
79
+ ...m?.backend === "sql" ? ["_voltro_brackets"] : []
80
+ ]
81
+ };
82
+ };
83
+ //#endregion
84
+ export { u as leaderboardsStatus };
package/dist/json.js ADDED
@@ -0,0 +1,39 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ //#region src/json.ts
3
+ var t = (n, r, i, a, o) => {
4
+ if (i > 32) throw e("invalid_input");
5
+ if (o !== void 0 && (o.remaining -= typeof n == "string" ? n.length + 2 : typeof n == "object" && n ? 2 : 1, o.remaining < 0)) throw e("limit_exceeded");
6
+ if (n === null || typeof n == "string" || typeof n == "boolean" || typeof n == "number" && Number.isFinite(n) && !Object.is(n, -0)) return;
7
+ if (typeof n != "object" || r.has(n)) throw e("invalid_input");
8
+ let s = Array.isArray(n);
9
+ if (!s && Object.getPrototypeOf(n) !== Object.prototype && Object.getPrototypeOf(n) !== null || Object.getOwnPropertySymbols(n).length > 0) throw e("invalid_input");
10
+ let c = Object.keys(n);
11
+ if (o !== void 0 && c.length > o.remaining) throw e("limit_exceeded");
12
+ if (s ? c.length !== n.length : Object.getOwnPropertyNames(n).length !== c.length) throw e("invalid_input");
13
+ if (s) {
14
+ for (let t = 0; t < n.length; t++) if (!Object.hasOwn(n, t)) throw e("invalid_input");
15
+ }
16
+ r.add(n);
17
+ for (let l = 0; l < c.length; l++) {
18
+ let u = c[l];
19
+ if (o !== void 0 && (o.remaining -= (l === 0 ? 0 : 1) + (s ? 0 : u.length + 3), o.remaining < 0)) throw e("limit_exceeded");
20
+ let d = Object.getOwnPropertyDescriptor(n, u);
21
+ if (!d || !("value" in d)) throw e("invalid_input");
22
+ t(d.value, r, i + 1, a, o);
23
+ }
24
+ r.delete(n), a && Object.freeze(n);
25
+ }, n = (n) => {
26
+ t(n, /* @__PURE__ */ new Set(), 0, !1);
27
+ let r = JSON.stringify(n, (e, t) => typeof t == "object" && t && !Array.isArray(t) ? Object.fromEntries(Object.entries(t).sort(([e], [t]) => e < t ? -1 : +(e > t))) : t);
28
+ if (r === void 0) throw e("invalid_input");
29
+ return r;
30
+ }, r = (r, i) => {
31
+ if (!Number.isSafeInteger(i) || i < 1 || i > 65536) throw e("invalid_input");
32
+ t(r, /* @__PURE__ */ new Set(), 0, !1, { remaining: i });
33
+ let a = n(r);
34
+ if (new TextEncoder().encode(a).byteLength > i) throw e("limit_exceeded");
35
+ let o = structuredClone(r);
36
+ return t(o, /* @__PURE__ */ new Set(), 0, !0), o;
37
+ };
38
+ //#endregion
39
+ export { n as canonicalLeaderboardJson, r as captureLeaderboardJson };
@@ -0,0 +1,49 @@
1
+ import { Schema } from 'effect';
2
+
3
+ export declare const defineLeaderboard: <S extends Schema.Codec<unknown, unknown>>(input: LeaderboardDefinition<S>) => LeaderboardDescriptor<S>;
4
+
5
+ export declare interface LeaderboardDefinition<S extends Schema.Codec<unknown, unknown>> {
6
+ readonly name: string;
7
+ readonly sort?: LeaderboardSort;
8
+ readonly operator?: ScoreOperator;
9
+ readonly metadata: S;
10
+ /** Only service-owned writes exist in this foundation; no client score route. */
11
+ readonly submit?: {
12
+ readonly via: 'service-only';
13
+ };
14
+ readonly reset?: {
15
+ readonly cron: string;
16
+ readonly timezone: string;
17
+ readonly keepHistory: number;
18
+ } | undefined;
19
+ readonly maxRankRecords?: number;
20
+ readonly maxPageSize?: number;
21
+ readonly buckets?: {
22
+ readonly size: number;
23
+ readonly assign: 'hash' | 'skill' | 'cohort';
24
+ readonly skillWidth?: number;
25
+ } | undefined;
26
+ }
27
+
28
+ export declare interface LeaderboardDescriptor<S extends Schema.Codec<unknown, unknown>> {
29
+ readonly kind: 'leaderboard';
30
+ readonly name: string;
31
+ readonly sort: LeaderboardSort;
32
+ readonly operator: ScoreOperator;
33
+ readonly metadata: S;
34
+ readonly submit: {
35
+ readonly via: 'service-only';
36
+ };
37
+ readonly reset: LeaderboardDefinition<S>['reset'];
38
+ readonly maxRankRecords: number;
39
+ readonly maxPageSize: number;
40
+ readonly buckets: LeaderboardDefinition<S>['buckets'];
41
+ }
42
+
43
+ export declare const leaderboardIdentifier: (value: unknown) => value is string;
44
+
45
+ declare type LeaderboardSort = 'asc' | 'desc';
46
+
47
+ declare type ScoreOperator = 'best' | 'set' | 'increment' | 'decrement';
48
+
49
+ export { }
@@ -0,0 +1,57 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ import { Cron as t, Result as n, Schema as r } from "effect";
3
+ //#region src/leaderboard.ts
4
+ var i = (e) => typeof e == "string" && e.trim().length > 0 && e.length <= 256 && !e.includes("\0"), a = (e, t) => Number.isSafeInteger(e) && e >= 1 && e <= t, o = (o) => {
5
+ if (!o || !i(o.name)) throw e("invalid_board");
6
+ let s = o.sort ?? "desc", c = o.operator ?? "best", l = o.maxRankRecords ?? 1e4, u = o.maxPageSize ?? 100;
7
+ if (!["asc", "desc"].includes(s) || ![
8
+ "best",
9
+ "set",
10
+ "increment",
11
+ "decrement"
12
+ ].includes(c) || o.submit !== void 0 && o.submit.via !== "service-only" || !a(l, 1e5) || !a(u, 1e3) || u > l) throw e("invalid_board");
13
+ try {
14
+ r.decodeUnknownSync(o.metadata);
15
+ } catch {
16
+ throw e("invalid_board");
17
+ }
18
+ let d, f;
19
+ if (o.buckets !== void 0) {
20
+ let t = o.buckets;
21
+ if (!t || !a(t.size, 1e4) || t.size > l || ![
22
+ "hash",
23
+ "skill",
24
+ "cohort"
25
+ ].includes(t.assign) || t.assign !== "skill" && t.skillWidth !== void 0) throw e("invalid_board");
26
+ let n = t.skillWidth ?? 100;
27
+ if (!Number.isFinite(n) || n < 1e-6 || n > 1e9) throw e("invalid_board");
28
+ f = Object.freeze({
29
+ size: t.size,
30
+ assign: t.assign,
31
+ ...t.assign === "skill" ? { skillWidth: n } : {}
32
+ });
33
+ }
34
+ if (o.reset !== void 0) {
35
+ if (!o.reset || typeof o.reset.cron != "string" || o.reset.cron.length > 256 || !a(o.reset.keepHistory, 1e4) || !i(o.reset.timezone)) throw e("invalid_board");
36
+ try {
37
+ if (new Intl.DateTimeFormat("en", { timeZone: o.reset.timezone }).format(0), n.isFailure(t.parse(o.reset.cron, o.reset.timezone))) throw e("invalid_board");
38
+ } catch {
39
+ throw e("invalid_board");
40
+ }
41
+ d = Object.freeze({ ...o.reset });
42
+ }
43
+ return Object.freeze({
44
+ kind: "leaderboard",
45
+ name: o.name,
46
+ sort: s,
47
+ operator: c,
48
+ metadata: o.metadata,
49
+ submit: Object.freeze({ via: "service-only" }),
50
+ reset: d,
51
+ buckets: f,
52
+ maxRankRecords: l,
53
+ maxPageSize: u
54
+ });
55
+ };
56
+ //#endregion
57
+ export { o as defineLeaderboard, i as leaderboardIdentifier };
@@ -0,0 +1,40 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ import { leaderboardIdentifier as t } from "./leaderboard.js";
3
+ import { LeaderboardAdministration as n } from "./administration.js";
4
+ import { Effect as r, Result as i } from "effect";
5
+ import { systemSubject as a } from "@voltro/protocol";
6
+ import { defineSchedule as o } from "@voltro/runtime";
7
+ //#region src/leagueSchedule.ts
8
+ var s = (s) => {
9
+ let c = s?.pageSize ?? 100, l = s?.maxPages ?? 100, u = s?.timezone ?? "UTC";
10
+ if (!s || !t(s.league) || s.league.length > 120 || typeof s.cron != "string" || s.cron.length > 128 || typeof u != "string" || u.length > 128 || ![c, l].every((e) => Number.isSafeInteger(e) && e >= 1 && e <= 1e3)) throw e("invalid_input");
11
+ let d = s.league, f = a("leaderboards.leagueRoll");
12
+ return o({
13
+ name: "leaderboards.leagueRoll." + d,
14
+ cron: s.cron,
15
+ timezone: u,
16
+ onOverlap: "skip",
17
+ backfill: "latest",
18
+ handler: (t) => r.gen(function* () {
19
+ let a = yield* n, o = "schedule:" + d + ":" + t.scheduledAt.toISOString(), s = t.scheduledAt.getTime(), u = null, p = !1;
20
+ for (let t = 0; t < l; t++) {
21
+ let t = yield* a.leagueTenants(f, {
22
+ league: d,
23
+ after: u,
24
+ limit: c
25
+ });
26
+ for (let e of t.tenants) i.isFailure(yield* r.result(a.rollLeague(f, {
27
+ tenantId: e,
28
+ league: d,
29
+ requestId: o,
30
+ closedAt: s
31
+ }))) && (p = !0);
32
+ if (t.next === null) return p ? yield* r.fail(e("unavailable")) : void 0;
33
+ u = t.next;
34
+ }
35
+ return yield* r.fail(e("limit_exceeded"));
36
+ })
37
+ });
38
+ };
39
+ //#endregion
40
+ export { s as defineLeagueRollSchedule };
@@ -0,0 +1,31 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ import { leaderboardIdentifier as t } from "./leaderboard.js";
3
+ //#region src/leagues.ts
4
+ var n = (n) => {
5
+ if (!n || typeof n != "object" || !t(n.name) || !Array.isArray(n.divisions) || n.divisions.length < 2 || n.divisions.length > 16 || n.divisions.some((e) => !t(e)) || new Set(n.divisions).size !== n.divisions.length || ![n.promote, n.relegate].every((e) => Number.isSafeInteger(e) && e >= 0 && e <= 1e3) || n.promote + n.relegate < 1) throw e("invalid_input");
6
+ return Object.freeze({
7
+ name: n.name,
8
+ divisions: Object.freeze([...n.divisions]),
9
+ promote: n.promote,
10
+ relegate: n.relegate
11
+ });
12
+ }, r = (t, n) => {
13
+ let r = new Map(t.divisions.map((e, t) => [e, t]));
14
+ if (n.length !== t.divisions.length || n.some((e, t) => r.get(e.division) !== t)) throw e("invalid_input");
15
+ let i = [];
16
+ return n.forEach((e, n) => {
17
+ let r = n > 0 ? e.owners.slice(0, t.promote) : [], a = e.owners.slice(r.length), o = n < t.divisions.length - 1 && t.relegate > 0 ? a.slice(-t.relegate) : [];
18
+ for (let a of r) i.push(Object.freeze({
19
+ ownerId: a,
20
+ from: e.division,
21
+ to: t.divisions[n - 1]
22
+ }));
23
+ for (let r of o) i.push(Object.freeze({
24
+ ownerId: r,
25
+ from: e.division,
26
+ to: t.divisions[n + 1]
27
+ }));
28
+ }), Object.freeze(i);
29
+ };
30
+ //#endregion
31
+ export { n as defineLeague, r as leagueMovements };
@@ -0,0 +1,74 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ import { leaderboardIdentifier as t } from "./leaderboard.js";
3
+ //#region src/openskill.ts
4
+ var n = (e, t, n) => Number.isFinite(e) && e >= t && e <= n, r = (r = {}) => {
5
+ let i = r.beta ?? 25 / 6, a = r.tau ?? 25 / 300, o = r.kappa ?? 1e-4, s = r.ordinalZ ?? 3;
6
+ if (!n(i, 1e-6, 1e6) || !n(a, 0, 1e6) || !n(o, 1e-12, 1) || !n(s, 0, 100)) throw e("invalid_input");
7
+ return (r) => {
8
+ if (!r || !Array.isArray(r.teams) || r.teams.length < 2 || r.teams.length > 64 || !Array.isArray(r.ranks) || r.ranks.length !== r.teams.length) throw e("invalid_input");
9
+ let c = /* @__PURE__ */ new Set(), l = r.teams.map((i, o) => {
10
+ let s = r.ranks[o];
11
+ if (!Array.isArray(i) || i.length < 1 || i.length > 256 || !Object.hasOwn(r.ranks, o) || !Number.isSafeInteger(s) || s < 1 || s > r.teams.length) throw e("invalid_input");
12
+ let l = i.map((r) => {
13
+ let i = r?.weight ?? 1;
14
+ if (!r || !t(r.id) || c.has(r.id) || !n(r.mu, -1e9, 1e9) || !n(r.sigma, 1e-6, 1e6) || !n(i, 0, 1)) throw e("invalid_input");
15
+ c.add(r.id);
16
+ let o = i === 0 ? r.sigma ** 2 : r.sigma ** 2 + a ** 2;
17
+ return {
18
+ id: r.id,
19
+ mu: r.mu,
20
+ sigma: r.sigma,
21
+ weight: i,
22
+ variance: o
23
+ };
24
+ });
25
+ for (let t = 0; t < i.length; t++) if (!Object.hasOwn(i, t)) throw e("invalid_input");
26
+ let u = l.reduce((e, t) => e + t.weight * t.mu, 0), d = l.reduce((e, t) => e + t.weight ** 2 * t.variance, 0);
27
+ if (d <= 0) throw e("invalid_input");
28
+ return {
29
+ members: l,
30
+ rank: s,
31
+ mu: u,
32
+ variance: d
33
+ };
34
+ });
35
+ for (let t = 0; t < r.teams.length; t++) if (!Object.hasOwn(r.teams, t)) throw e("invalid_input");
36
+ if (c.size > 4096) throw e("limit_exceeded");
37
+ let u = Math.sqrt(l.reduce((e, t) => e + t.variance + i ** 2, 0)), d = l.map((e) => {
38
+ let t = l.map((e, t) => ({
39
+ other: e,
40
+ index: t
41
+ })).filter(({ other: t }) => t.rank >= e.rank), n = Math.max(...t.map(({ other: e }) => e.mu / u));
42
+ return {
43
+ max: n,
44
+ denominator: t.reduce((e, { other: t }) => e + Math.exp(t.mu / u - n), 0),
45
+ tied: l.filter((t) => t.rank === e.rank).length
46
+ };
47
+ });
48
+ return Object.freeze(l.map((t, r) => {
49
+ let i = 0, a = 0;
50
+ l.forEach((e, n) => {
51
+ if (e.rank > t.rank) return;
52
+ let o = d[n], s = Math.exp(t.mu / u - o.max) / o.denominator;
53
+ i += (+(n === r) - s) / o.tied, a += s * (1 - s) / o.tied;
54
+ });
55
+ let c = t.variance / u * i, f = t.variance / u ** 2 * a * Math.sqrt(t.variance) / u;
56
+ return Object.freeze(t.members.map((r) => {
57
+ let i = Object.freeze({
58
+ mu: r.mu,
59
+ sigma: r.sigma
60
+ }), a = r.weight === 0 ? r.mu : r.mu + r.weight * r.variance / t.variance * c, l = r.weight === 0 ? r.sigma : Math.sqrt(r.variance * Math.max(1 - r.weight ** 2 * r.variance / t.variance * f, o)), u = a - s * l;
61
+ if (!n(a, -1e9, 1e9) || !n(l, 1e-12, 1e9) || !Number.isFinite(u)) throw e("overflow");
62
+ return Object.freeze({
63
+ id: r.id,
64
+ previous: i,
65
+ mu: a,
66
+ sigma: l,
67
+ ordinal: u
68
+ });
69
+ }));
70
+ }));
71
+ };
72
+ };
73
+ //#endregion
74
+ export { r as openskill };