maidraw 0.9.5 → 0.10.1

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 (167) hide show
  1. package/assets/themes/chunithm/best/luminousLandscape/new/manifest.json +58 -32
  2. package/assets/themes/chunithm/best/luminousLandscape/recents/manifest.json +57 -31
  3. package/assets/themes/chunithm/best/luminousPlusLandscape/new/manifest.json +57 -31
  4. package/assets/themes/chunithm/best/luminousPlusLandscape/recents/manifest.json +57 -31
  5. package/assets/themes/chunithm/best/verseLandscape/new/manifest.json +57 -31
  6. package/assets/themes/chunithm/best/verseLandscape/recents/manifest.json +57 -31
  7. package/assets/themes/chunithm/chart/jp/verse/manifest.json +73 -71
  8. package/assets/themes/maimai/best50/cn/2024Landscape/manifest.json +90 -54
  9. package/assets/themes/maimai/best50/cn/2024Portrait/manifest.json +89 -53
  10. package/assets/themes/maimai/best50/cn/2025Landscape/manifest.json +90 -54
  11. package/assets/themes/maimai/best50/cn/2025Portrait/manifest.json +89 -53
  12. package/assets/themes/maimai/best50/common/prism/plus/background.png +0 -0
  13. package/assets/themes/maimai/best50/jp/buddiesLandscape/manifest.json +89 -53
  14. package/assets/themes/maimai/best50/jp/buddiesPlusLandscape/manifest.json +89 -53
  15. package/assets/themes/maimai/best50/jp/buddiesPlusPortrait/manifest.json +89 -53
  16. package/assets/themes/maimai/best50/jp/buddiesPortrait/manifest.json +89 -53
  17. package/assets/themes/maimai/best50/jp/finaleLandscape/manifest.json +89 -53
  18. package/assets/themes/maimai/best50/jp/finalePortrait/manifest.json +89 -53
  19. package/assets/themes/maimai/best50/jp/prismLandscape/manifest.json +90 -54
  20. package/assets/themes/maimai/best50/jp/prismPlusLandscape/manifest.json +90 -54
  21. package/assets/themes/maimai/best50/jp/prismPlusPortrait/manifest.json +92 -55
  22. package/assets/themes/maimai/best50/jp/prismPortrait/manifest.json +89 -53
  23. package/assets/themes/maimai/best50/salt/2026landscape/manifest.json +89 -53
  24. package/assets/themes/maimai/chart/jp/prism/manifest.json +100 -96
  25. package/assets/themes/ongeki/jp/brightMemoryLandscape/classic/manifest.json +101 -30
  26. package/assets/themes/ongeki/jp/brightMemoryLandscape/refresh/manifest.json +78 -30
  27. package/assets/themes/ongeki/jp/refreshLandscape/classic/manifest.json +101 -2
  28. package/assets/themes/ongeki/jp/refreshLandscape/refresh/manifest.json +78 -30
  29. package/dist/chu/index.d.ts +14 -4
  30. package/dist/chu/index.js +16 -4
  31. package/dist/chu/index.js.map +1 -1
  32. package/dist/chu/lib/{index.d.ts → adapter/index.d.ts} +1 -1
  33. package/dist/chu/lib/{index.js → adapter/index.js} +1 -1
  34. package/dist/chu/lib/adapter/index.js.map +1 -0
  35. package/dist/chu/lib/{kamaiTachi → adapter/kamaiTachi}/index.d.ts +1 -1
  36. package/dist/chu/lib/{kamaiTachi → adapter/kamaiTachi}/index.js +5 -5
  37. package/dist/chu/lib/adapter/kamaiTachi/index.js.map +1 -0
  38. package/dist/chu/lib/{lxns → adapter/lxns}/index.d.ts +1 -1
  39. package/dist/chu/lib/{lxns → adapter/lxns}/index.js +4 -4
  40. package/dist/chu/lib/adapter/lxns/index.js.map +1 -0
  41. package/dist/chu/{chart → lib}/database.d.ts +3 -3
  42. package/dist/chu/{chart → lib}/database.js +2 -2
  43. package/dist/chu/lib/database.js.map +1 -0
  44. package/dist/chu/lib/util.d.ts +149 -0
  45. package/dist/chu/lib/util.js +270 -0
  46. package/dist/chu/lib/util.js.map +1 -0
  47. package/dist/chu/painter/best50/index.d.ts +120 -0
  48. package/dist/chu/painter/best50/index.js +158 -0
  49. package/dist/chu/painter/best50/index.js.map +1 -0
  50. package/dist/chu/painter/chart/index.d.ts +170 -0
  51. package/dist/chu/painter/chart/index.js +116 -0
  52. package/dist/chu/painter/chart/index.js.map +1 -0
  53. package/dist/chu/painter/index.d.ts +194 -0
  54. package/dist/chu/painter/index.js +1105 -0
  55. package/dist/chu/painter/index.js.map +1 -0
  56. package/dist/geki/index.d.ts +10 -4
  57. package/dist/geki/index.js +12 -4
  58. package/dist/geki/index.js.map +1 -1
  59. package/dist/geki/lib/adapter/index.js.map +1 -0
  60. package/dist/geki/lib/adapter/kamaiTachi/index.js.map +1 -0
  61. package/dist/geki/{chart → lib}/database.d.ts +1 -1
  62. package/dist/geki/{chart → lib}/database.js +2 -2
  63. package/dist/geki/lib/database.js.map +1 -0
  64. package/dist/geki/painter/best50/index.d.ts +122 -0
  65. package/dist/geki/painter/best50/index.js +197 -0
  66. package/dist/geki/painter/best50/index.js.map +1 -0
  67. package/dist/geki/painter/index.d.ts +88 -0
  68. package/dist/geki/painter/index.js +448 -0
  69. package/dist/geki/painter/index.js.map +1 -0
  70. package/dist/lib/cache.d.ts +1 -0
  71. package/dist/lib/cache.js +6 -1
  72. package/dist/lib/cache.js.map +1 -1
  73. package/dist/lib/painter.d.ts +100 -0
  74. package/dist/lib/painter.js +216 -0
  75. package/dist/lib/painter.js.map +1 -0
  76. package/dist/lib/util.d.ts +6 -282
  77. package/dist/lib/util.js +50 -540
  78. package/dist/lib/util.js.map +1 -1
  79. package/dist/mai/index.d.ts +22 -6
  80. package/dist/mai/index.js +24 -6
  81. package/dist/mai/index.js.map +1 -1
  82. package/dist/mai/lib/{divingFish → adapter/divingFish}/index.d.ts +6 -6
  83. package/dist/mai/lib/{divingFish → adapter/divingFish}/index.js +29 -30
  84. package/dist/mai/lib/adapter/divingFish/index.js.map +1 -0
  85. package/dist/mai/lib/{index.d.ts → adapter/index.d.ts} +11 -11
  86. package/dist/mai/lib/{index.js → adapter/index.js} +2 -2
  87. package/dist/{geki/bests/lib → mai/lib/adapter}/index.js.map +1 -1
  88. package/dist/mai/lib/{kamaiTachi → adapter/kamaiTachi}/index.d.ts +84 -42
  89. package/dist/mai/lib/{kamaiTachi → adapter/kamaiTachi}/index.js +36 -29
  90. package/dist/mai/lib/adapter/kamaiTachi/index.js.map +1 -0
  91. package/dist/mai/lib/{lxns → adapter/lxns}/index.d.ts +12 -12
  92. package/dist/mai/lib/{lxns → adapter/lxns}/index.js +29 -30
  93. package/dist/mai/lib/adapter/lxns/index.js.map +1 -0
  94. package/dist/mai/lib/{maishift → adapter/maishift}/index.d.ts +4 -4
  95. package/dist/mai/lib/{maishift → adapter/maishift}/index.js +20 -20
  96. package/dist/mai/lib/adapter/maishift/index.js.map +1 -0
  97. package/dist/mai/{chart → lib}/database.d.ts +4 -5
  98. package/dist/mai/{chart → lib}/database.js +12 -6
  99. package/dist/mai/lib/database.js.map +1 -0
  100. package/dist/mai/lib/util.d.ts +134 -0
  101. package/dist/mai/lib/util.js +264 -0
  102. package/dist/mai/lib/util.js.map +1 -0
  103. package/dist/mai/painter/best50/index.d.ts +140 -0
  104. package/dist/mai/painter/best50/index.js +176 -0
  105. package/dist/mai/painter/best50/index.js.map +1 -0
  106. package/dist/mai/painter/chart/index.d.ts +195 -0
  107. package/dist/mai/painter/chart/index.js +115 -0
  108. package/dist/mai/painter/chart/index.js.map +1 -0
  109. package/dist/mai/painter/index.d.ts +237 -0
  110. package/dist/mai/painter/index.js +1431 -0
  111. package/dist/mai/painter/index.js.map +1 -0
  112. package/dist/mai/painter/level50/index.d.ts +28 -0
  113. package/dist/mai/painter/level50/index.js +129 -0
  114. package/dist/mai/painter/level50/index.js.map +1 -0
  115. package/dist/mai/type.d.ts +110 -0
  116. package/dist/mai/type.js +73 -1
  117. package/dist/mai/type.js.map +1 -1
  118. package/package.json +56 -55
  119. package/dist/chu/bests/best50.d.ts +0 -37
  120. package/dist/chu/bests/best50.js +0 -742
  121. package/dist/chu/bests/best50.js.map +0 -1
  122. package/dist/chu/bests/index.d.ts +0 -1
  123. package/dist/chu/bests/index.js +0 -6
  124. package/dist/chu/bests/index.js.map +0 -1
  125. package/dist/chu/bests/type.d.ts +0 -122
  126. package/dist/chu/bests/type.js +0 -3
  127. package/dist/chu/bests/type.js.map +0 -1
  128. package/dist/chu/chart/database.js.map +0 -1
  129. package/dist/chu/chart/index.d.ts +0 -212
  130. package/dist/chu/chart/index.js +0 -1064
  131. package/dist/chu/chart/index.js.map +0 -1
  132. package/dist/chu/lib/index.js.map +0 -1
  133. package/dist/chu/lib/kamaiTachi/index.js.map +0 -1
  134. package/dist/chu/lib/lxns/index.js.map +0 -1
  135. package/dist/geki/bests/best50.d.ts +0 -35
  136. package/dist/geki/bests/best50.js +0 -821
  137. package/dist/geki/bests/best50.js.map +0 -1
  138. package/dist/geki/bests/index.d.ts +0 -1
  139. package/dist/geki/bests/index.js +0 -6
  140. package/dist/geki/bests/index.js.map +0 -1
  141. package/dist/geki/bests/lib/kamaiTachi/index.js.map +0 -1
  142. package/dist/geki/bests/type.d.ts +0 -122
  143. package/dist/geki/bests/type.js +0 -3
  144. package/dist/geki/bests/type.js.map +0 -1
  145. package/dist/geki/chart/database.js.map +0 -1
  146. package/dist/geki/chart/index.d.ts +0 -4
  147. package/dist/geki/chart/index.js +0 -32
  148. package/dist/geki/chart/index.js.map +0 -1
  149. package/dist/mai/best50/index.d.ts +0 -271
  150. package/dist/mai/best50/index.js +0 -915
  151. package/dist/mai/best50/index.js.map +0 -1
  152. package/dist/mai/chart/database.js.map +0 -1
  153. package/dist/mai/chart/index.d.ts +0 -238
  154. package/dist/mai/chart/index.js +0 -1281
  155. package/dist/mai/chart/index.js.map +0 -1
  156. package/dist/mai/level50/index.d.ts +0 -28
  157. package/dist/mai/level50/index.js +0 -774
  158. package/dist/mai/level50/index.js.map +0 -1
  159. package/dist/mai/lib/divingFish/index.js.map +0 -1
  160. package/dist/mai/lib/index.js.map +0 -1
  161. package/dist/mai/lib/kamaiTachi/index.js.map +0 -1
  162. package/dist/mai/lib/lxns/index.js.map +0 -1
  163. package/dist/mai/lib/maishift/index.js.map +0 -1
  164. /package/dist/geki/{bests/lib → lib/adapter}/index.d.ts +0 -0
  165. /package/dist/geki/{bests/lib → lib/adapter}/index.js +0 -0
  166. /package/dist/geki/{bests/lib → lib/adapter}/kamaiTachi/index.d.ts +0 -0
  167. /package/dist/geki/{bests/lib → lib/adapter}/kamaiTachi/index.js +0 -0
@@ -1,915 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.Best50 = void 0;
30
- const fs_1 = __importDefault(require("fs"));
31
- const upath_1 = __importDefault(require("upath"));
32
- const canvas_1 = require("canvas");
33
- const color_1 = __importDefault(require("color"));
34
- const sharp_1 = __importDefault(require("sharp"));
35
- const glob_1 = require("glob");
36
- const chart_1 = require("../chart");
37
- const string_template_1 = __importDefault(require("string-template"));
38
- const lxns = __importStar(require("../lib/lxns"));
39
- const kamaiTachi = __importStar(require("../lib/kamaiTachi"));
40
- const divingFish = __importStar(require("../lib/divingFish"));
41
- const maishift = __importStar(require("../lib/maishift"));
42
- const util_1 = require("../../lib/util");
43
- const type_1 = require("../type");
44
- class Best50 {
45
- static DEFAULT_THEME = "jp-prism-landscape";
46
- static get assetsPath() {
47
- return upath_1.default.join(__dirname, "..", "..", "..", "assets");
48
- }
49
- static themes = {};
50
- static hasTheme(name) {
51
- return !!this.themes[name];
52
- }
53
- static {
54
- const manifests = (0, glob_1.globSync)(upath_1.default.join(this.assetsPath, "themes", "maimai", "best50", "**", "manifest.json"));
55
- for (const manifestPath of manifests) {
56
- const manifest = JSON.parse(fs_1.default.readFileSync(manifestPath, "utf-8"));
57
- if (this.validateManifest(manifest, upath_1.default.dirname(manifestPath))) {
58
- this.themes[manifest.name] = upath_1.default.dirname(manifestPath);
59
- }
60
- }
61
- const loadThemeResult = this.loadTheme(this.DEFAULT_THEME);
62
- if (!loadThemeResult) {
63
- console.error("Failed to load default theme.");
64
- }
65
- (0, canvas_1.registerFont)(upath_1.default.join(this.assetsPath, "fonts", "gen-jyuu-gothic", "GenJyuuGothic-Bold.ttf"), {
66
- family: "standard-font-title-jp",
67
- });
68
- (0, canvas_1.registerFont)(upath_1.default.join(this.assetsPath, "fonts", "comfortaa", "Comfortaa-Bold.ttf"), {
69
- family: "standard-font-title-latin",
70
- weight: "regular",
71
- });
72
- (0, canvas_1.registerFont)(upath_1.default.join(this.assetsPath, "fonts", "seurat-db", "FOT-Seurat Pro DB.otf"), {
73
- family: "standard-font-username",
74
- weight: "regular",
75
- });
76
- }
77
- static validateManifest(payload, path) {
78
- function isFileExist(p) {
79
- if (isString(p))
80
- return fs_1.default.existsSync(upath_1.default.join(path, p));
81
- else
82
- return false;
83
- }
84
- function isOneOf(p, ...args) {
85
- return args.includes(p);
86
- }
87
- function isString(p) {
88
- return typeof p == "string";
89
- }
90
- function isNumber(p) {
91
- return typeof p == "number";
92
- }
93
- function isArray(p) {
94
- return Array.isArray(p);
95
- }
96
- function isObject(p) {
97
- return typeof p == "object";
98
- }
99
- function isHexColor(p) {
100
- if (isString(p))
101
- return /^(?:#[0-9A-F]{6}|#[0-9A-F]{8})$/i.test(p);
102
- else
103
- return false;
104
- }
105
- function isUndefined(p) {
106
- return typeof p == "undefined";
107
- }
108
- function isBoolean(p) {
109
- return typeof p == "boolean";
110
- }
111
- if (isString(payload.displayName) &&
112
- isString(payload.name) &&
113
- isNumber(payload.width) &&
114
- isNumber(payload.height) &&
115
- isObject(payload.sprites) &&
116
- isObject(payload.sprites.achievement) &&
117
- isFileExist(payload.sprites.achievement.d) &&
118
- isFileExist(payload.sprites.achievement.c) &&
119
- isFileExist(payload.sprites.achievement.b) &&
120
- isFileExist(payload.sprites.achievement.bb) &&
121
- isFileExist(payload.sprites.achievement.bbb) &&
122
- isFileExist(payload.sprites.achievement.a) &&
123
- isFileExist(payload.sprites.achievement.aa) &&
124
- isFileExist(payload.sprites.achievement.aaa) &&
125
- isFileExist(payload.sprites.achievement.s) &&
126
- isFileExist(payload.sprites.achievement.sp) &&
127
- isFileExist(payload.sprites.achievement.ss) &&
128
- isFileExist(payload.sprites.achievement.ssp) &&
129
- isFileExist(payload.sprites.achievement.sss) &&
130
- isFileExist(payload.sprites.achievement.sssp) &&
131
- isObject(payload.sprites.mode) &&
132
- isFileExist(payload.sprites.mode.standard) &&
133
- isFileExist(payload.sprites.mode.dx) &&
134
- isObject(payload.sprites.milestone) &&
135
- isFileExist(payload.sprites.milestone.ap) &&
136
- isFileExist(payload.sprites.milestone.app) &&
137
- isFileExist(payload.sprites.milestone.fc) &&
138
- isFileExist(payload.sprites.milestone.fcp) &&
139
- isFileExist(payload.sprites.milestone.fdx) &&
140
- isFileExist(payload.sprites.milestone.fdxp) &&
141
- isFileExist(payload.sprites.milestone.fs) &&
142
- isFileExist(payload.sprites.milestone.fsp) &&
143
- isFileExist(payload.sprites.milestone.sync) &&
144
- isFileExist(payload.sprites.milestone.none) &&
145
- isObject(payload.sprites.dxRating) &&
146
- isFileExist(payload.sprites.dxRating.white) &&
147
- isFileExist(payload.sprites.dxRating.blue) &&
148
- isFileExist(payload.sprites.dxRating.green) &&
149
- isFileExist(payload.sprites.dxRating.yellow) &&
150
- isFileExist(payload.sprites.dxRating.red) &&
151
- isFileExist(payload.sprites.dxRating.purple) &&
152
- isFileExist(payload.sprites.dxRating.bronze) &&
153
- isFileExist(payload.sprites.dxRating.silver) &&
154
- isFileExist(payload.sprites.dxRating.gold) &&
155
- isFileExist(payload.sprites.dxRating.platinum) &&
156
- isFileExist(payload.sprites.dxRating.rainbow) &&
157
- isObject(payload.sprites.profile) &&
158
- isFileExist(payload.sprites.profile.icon) &&
159
- isFileExist(payload.sprites.profile.nameplate) &&
160
- isFileExist(payload.sprites.dxRatingNumberMap) &&
161
- isArray(payload.elements)) {
162
- for (const element of payload.elements) {
163
- if (isNumber(element.x) && isNumber(element.y)) {
164
- switch (element.type) {
165
- case "image": {
166
- if (isNumber(element.width) &&
167
- isNumber(element.height) &&
168
- isFileExist(element.path)) {
169
- continue;
170
- }
171
- else
172
- return false;
173
- }
174
- case "score-grid": {
175
- if (isOneOf(element.region, "old", "new") &&
176
- isNumber(element.horizontalSize) &&
177
- isNumber(element.verticalSize) &&
178
- isNumber(element.index) &&
179
- isObject(element.scoreBubble) &&
180
- isNumber(element.scoreBubble.width) &&
181
- isNumber(element.scoreBubble.height) &&
182
- isNumber(element.scoreBubble.margin) &&
183
- isNumber(element.scoreBubble.gap) &&
184
- isObject(element.scoreBubble.color) &&
185
- isHexColor(element.scoreBubble.color.basic) &&
186
- isHexColor(element.scoreBubble.color.advanced) &&
187
- isHexColor(element.scoreBubble.color.expert) &&
188
- isHexColor(element.scoreBubble.color.master) &&
189
- isHexColor(element.scoreBubble.color.remaster) &&
190
- isHexColor(element.scoreBubble.color.utage)) {
191
- continue;
192
- }
193
- else
194
- return false;
195
- }
196
- case "profile": {
197
- if (isNumber(element.height)) {
198
- continue;
199
- }
200
- else
201
- return false;
202
- }
203
- case "text": {
204
- if (isNumber(element.size) &&
205
- isString(element.content) &&
206
- (isUndefined(element.width) ||
207
- isNumber(element.width)) &&
208
- (isUndefined(element.height) ||
209
- isNumber(element.height)) &&
210
- (isUndefined(element.linebreak) ||
211
- isBoolean(element.linebreak)) &&
212
- (isUndefined(element.align) ||
213
- isOneOf(element.align, "left", "center", "right")) &&
214
- (isUndefined(element.color) ||
215
- isString(element.color)) &&
216
- (isUndefined(element.borderColor) ||
217
- isString(element.borderColor)) &&
218
- (isUndefined(element.font) ||
219
- isString(element.font))) {
220
- continue;
221
- }
222
- else
223
- return false;
224
- }
225
- default:
226
- return false;
227
- }
228
- }
229
- }
230
- return true;
231
- }
232
- else
233
- return false;
234
- }
235
- static primaryTheme = null;
236
- static loadTheme(path) {
237
- const theme = this.getTheme(path);
238
- if (theme) {
239
- this.primaryTheme = theme;
240
- return true;
241
- }
242
- else
243
- return false;
244
- }
245
- static getTheme(path) {
246
- if (!fs_1.default.existsSync(upath_1.default.join(path, "manifest.json"))) {
247
- path = this.themes[path] ?? "";
248
- }
249
- else
250
- path = upath_1.default.join(this.assetsPath, path);
251
- if (fs_1.default.existsSync(upath_1.default.join(path, "manifest.json"))) {
252
- const manifest = JSON.parse(fs_1.default.readFileSync(upath_1.default.join(path, "manifest.json"), "utf-8"));
253
- if (this.validateManifest(manifest, path)) {
254
- return { manifest, path };
255
- }
256
- }
257
- return null;
258
- }
259
- static getThemeFile(path, themePath) {
260
- if (typeof path == "string" &&
261
- fs_1.default.existsSync(upath_1.default.join(themePath ?? this.primaryTheme?.path, path)))
262
- return fs_1.default.readFileSync(upath_1.default.join(themePath ?? this.primaryTheme?.path, path));
263
- else
264
- return Buffer.from([]);
265
- }
266
- /* Begin Draw Tools*/
267
- static async drawImageModule(ctx, theme, element) {
268
- const img = new canvas_1.Image();
269
- img.src = this.getThemeFile(element.path, theme.path);
270
- ctx.drawImage(img, element.x, element.y, element.width, element.height);
271
- }
272
- static async drawScoreGridModule(ctx, theme, element, score, index, x, y) {
273
- let curColor = "#FFFFFF";
274
- switch (score.chart.difficulty) {
275
- case type_1.EDifficulty.BASIC:
276
- curColor = element.scoreBubble.color.basic;
277
- break;
278
- case type_1.EDifficulty.ADVANCED:
279
- curColor = element.scoreBubble.color.advanced;
280
- break;
281
- case type_1.EDifficulty.EXPERT:
282
- curColor = element.scoreBubble.color.expert;
283
- break;
284
- case type_1.EDifficulty.MASTER:
285
- curColor = element.scoreBubble.color.master;
286
- break;
287
- case type_1.EDifficulty.REMASTER:
288
- curColor = element.scoreBubble.color.remaster;
289
- break;
290
- case type_1.EDifficulty.UTAGE:
291
- curColor = element.scoreBubble.color.utage;
292
- break;
293
- }
294
- /** Begin Card Draw */
295
- ctx.save();
296
- ctx.fillStyle = new color_1.default(curColor).lighten(0.4).hexa();
297
- ctx.beginPath();
298
- ctx.roundRect(x, y, element.scoreBubble.width, element.scoreBubble.height, (element.scoreBubble.height * 0.806) / 7);
299
- ctx.strokeStyle = new color_1.default(curColor).darken(0.3).hexa();
300
- ctx.lineWidth = element.scoreBubble.margin / 4;
301
- ctx.stroke();
302
- ctx.fill();
303
- ctx.beginPath();
304
- ctx.roundRect(x, y, element.scoreBubble.width, element.scoreBubble.height, (element.scoreBubble.height * 0.806) / 7);
305
- ctx.clip();
306
- /** Begin Main Content Draw */
307
- {
308
- ctx.save();
309
- ctx.beginPath();
310
- ctx.roundRect(x, y, element.scoreBubble.width, element.scoreBubble.height * 0.742, (element.scoreBubble.height * 0.806) / 7);
311
- ctx.clip();
312
- ctx.fillStyle = curColor;
313
- ctx.fill();
314
- const jacketSize = Math.min(element.scoreBubble.width, element.scoreBubble.height * 0.742);
315
- const jacketMaskGrad = ctx.createLinearGradient(x + jacketSize / 2, y + jacketSize / 2, x + jacketSize, y + jacketSize / 2);
316
- jacketMaskGrad.addColorStop(0, new color_1.default(curColor).alpha(0).hexa());
317
- jacketMaskGrad.addColorStop(0.25, new color_1.default(curColor).alpha(0.2).hexa());
318
- jacketMaskGrad.addColorStop(1, new color_1.default(curColor).alpha(1).hexa());
319
- const jacketMaskGradDark = ctx.createLinearGradient(x + jacketSize / 2, y + jacketSize / 2, x + jacketSize, y + jacketSize / 2);
320
- jacketMaskGradDark.addColorStop(0, new color_1.default(curColor).darken(0.3).alpha(0).hexa());
321
- jacketMaskGradDark.addColorStop(0.25, new color_1.default(curColor).darken(0.3).alpha(0.2).hexa());
322
- jacketMaskGradDark.addColorStop(1, new color_1.default(curColor).darken(0.3).alpha(1).hexa());
323
- /** Begin Jacket Draw*/
324
- let jacket = await chart_1.Chart.Database.fecthJacket(score.chart.id);
325
- if (!jacket)
326
- jacket = await chart_1.Chart.Database.fecthJacket(0);
327
- if (jacket) {
328
- const img = new canvas_1.Image();
329
- img.src = jacket;
330
- ctx.drawImage(img, x, y, jacketSize, jacketSize);
331
- }
332
- else {
333
- ctx.fillStyle = "#b6ffab";
334
- ctx.fillRect(x, y, jacketSize, jacketSize);
335
- }
336
- /** End Jacket Draw*/
337
- /** Begin Jacket Gradient Mask Draw*/ {
338
- ctx.fillStyle = jacketMaskGrad;
339
- ctx.fillRect(x + jacketSize / 2, y, (jacketSize * 3) / 4, jacketSize);
340
- } /** End Jacket Gradient Mask Draw*/
341
- ctx.beginPath();
342
- ctx.roundRect(x + element.scoreBubble.margin, y + element.scoreBubble.margin, element.scoreBubble.width - element.scoreBubble.margin * 2, element.scoreBubble.height * 0.806 -
343
- element.scoreBubble.margin * 2, (element.scoreBubble.height * 0.806 -
344
- element.scoreBubble.margin * 2) /
345
- 7);
346
- /** Begin Title Draw */ {
347
- util_1.Util.drawText(ctx, score.chart.name, x + (jacketSize * 7) / 8, y +
348
- element.scoreBubble.margin +
349
- element.scoreBubble.height * 0.806 * 0.144, element.scoreBubble.height * 0.806 * 0.144, element.scoreBubble.height * 0.806 * 0.04, element.scoreBubble.width -
350
- (jacketSize * 7) / 8 -
351
- element.scoreBubble.margin, "left", "white", jacketMaskGradDark);
352
- } /** End Title Draw */
353
- /** Begin Separation Line Draw */ {
354
- ctx.beginPath();
355
- ctx.roundRect(x + (jacketSize * 13) / 16, y +
356
- element.scoreBubble.margin +
357
- element.scoreBubble.height * 0.806 * (0.144 + 0.072), element.scoreBubble.width -
358
- (jacketSize * 13) / 16 -
359
- element.scoreBubble.margin * 2, element.scoreBubble.height * 0.806 * 0.02, element.scoreBubble.height * 0.806 * 0.16);
360
- ctx.fillStyle = jacketMaskGradDark;
361
- ctx.fill();
362
- } /** End Separation Line Draw */
363
- /** Begin Achievement Rate Draw */
364
- util_1.Util.drawText(ctx, `${util_1.Util.truncate(score.achievement, 4)}%`, x -
365
- element.scoreBubble.margin -
366
- element.scoreBubble.height * 0.806 * 0.02 +
367
- element.scoreBubble.width, y +
368
- element.scoreBubble.margin +
369
- element.scoreBubble.height *
370
- 0.806 *
371
- (0.144 + 0.144 + 0.208 - 0.04), element.scoreBubble.height * 0.806 * 0.208, element.scoreBubble.height * 0.806 * 0.04, Infinity, "right", "white", new color_1.default(curColor).darken(0.3).hexa());
372
- /** End Achievement Rate Draw */
373
- /** Begin Achievement Rank Draw */
374
- {
375
- let rankImg;
376
- switch (score.achievementRank) {
377
- case Best50.EAchievementTypes.D:
378
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.d, theme.path);
379
- break;
380
- case Best50.EAchievementTypes.C:
381
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.c, theme.path);
382
- break;
383
- case Best50.EAchievementTypes.B:
384
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.b, theme.path);
385
- break;
386
- case Best50.EAchievementTypes.BB:
387
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.bb, theme.path);
388
- break;
389
- case Best50.EAchievementTypes.BBB:
390
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.bbb, theme.path);
391
- break;
392
- case Best50.EAchievementTypes.A:
393
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.a, theme.path);
394
- break;
395
- case Best50.EAchievementTypes.AA:
396
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.aa, theme.path);
397
- break;
398
- case Best50.EAchievementTypes.AAA:
399
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.aaa, theme.path);
400
- break;
401
- case Best50.EAchievementTypes.S:
402
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.s, theme.path);
403
- break;
404
- case Best50.EAchievementTypes.SP:
405
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.sp, theme.path);
406
- break;
407
- case Best50.EAchievementTypes.SS:
408
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.ss, theme.path);
409
- break;
410
- case Best50.EAchievementTypes.SSP:
411
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.ssp, theme.path);
412
- break;
413
- case Best50.EAchievementTypes.SSS:
414
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.sss, theme.path);
415
- break;
416
- default:
417
- rankImg = this.getThemeFile(theme.manifest.sprites.achievement.sssp, theme.path);
418
- }
419
- const img = new canvas_1.Image();
420
- img.src = rankImg;
421
- ctx.drawImage(img, x + jacketSize, y +
422
- element.scoreBubble.margin +
423
- element.scoreBubble.height *
424
- 0.806 *
425
- (0.144 + 0.144 + 0.208 + 0.02), element.scoreBubble.height * 0.806 * 0.3 * 2.133, element.scoreBubble.height * 0.806 * 0.3);
426
- }
427
- /** End Achievement Rank Draw */
428
- /** Begin Milestone Draw */
429
- {
430
- let comboImg, syncImg;
431
- switch (score.combo) {
432
- case Best50.EComboTypes.NONE:
433
- comboImg = this.getThemeFile(theme.manifest.sprites.milestone.none, theme.path);
434
- break;
435
- case Best50.EComboTypes.FULL_COMBO:
436
- comboImg = this.getThemeFile(theme.manifest.sprites.milestone.fc, theme.path);
437
- break;
438
- case Best50.EComboTypes.FULL_COMBO_PLUS:
439
- comboImg = this.getThemeFile(theme.manifest.sprites.milestone.fcp, theme.path);
440
- break;
441
- case Best50.EComboTypes.ALL_PERFECT:
442
- comboImg = this.getThemeFile(theme.manifest.sprites.milestone.ap, theme.path);
443
- break;
444
- case Best50.EComboTypes.ALL_PERFECT_PLUS:
445
- comboImg = this.getThemeFile(theme.manifest.sprites.milestone.app, theme.path);
446
- break;
447
- }
448
- switch (score.sync) {
449
- case Best50.ESyncTypes.NONE:
450
- syncImg = this.getThemeFile(theme.manifest.sprites.milestone.none, theme.path);
451
- break;
452
- case Best50.ESyncTypes.SYNC_PLAY:
453
- syncImg = this.getThemeFile(theme.manifest.sprites.milestone.sync, theme.path);
454
- break;
455
- case Best50.ESyncTypes.FULL_SYNC:
456
- syncImg = this.getThemeFile(theme.manifest.sprites.milestone.fs, theme.path);
457
- break;
458
- case Best50.ESyncTypes.FULL_SYNC_PLUS:
459
- syncImg = this.getThemeFile(theme.manifest.sprites.milestone.fsp, theme.path);
460
- break;
461
- case Best50.ESyncTypes.FULL_SYNC_DX:
462
- syncImg = this.getThemeFile(theme.manifest.sprites.milestone.fdx, theme.path);
463
- break;
464
- case Best50.ESyncTypes.FULL_SYNC_DX_PLUS:
465
- syncImg = this.getThemeFile(theme.manifest.sprites.milestone.fdxp, theme.path);
466
- break;
467
- }
468
- const combo = new canvas_1.Image();
469
- combo.src = comboImg;
470
- ctx.drawImage(combo, x +
471
- (jacketSize * 7) / 8 +
472
- element.scoreBubble.height *
473
- 0.806 *
474
- (0.32 * 2.133 + 0.06), y +
475
- element.scoreBubble.margin +
476
- element.scoreBubble.height *
477
- 0.806 *
478
- (0.144 + 0.144 + 0.208 + 0.01), element.scoreBubble.height * 0.806 * 0.32, element.scoreBubble.height * 0.806 * 0.32);
479
- const sync = new canvas_1.Image();
480
- sync.src = syncImg;
481
- ctx.drawImage(sync, x +
482
- (jacketSize * 7) / 8 +
483
- element.scoreBubble.height *
484
- 0.806 *
485
- (0.32 * 2.133 + 0.04 + 0.32), y +
486
- element.scoreBubble.margin +
487
- element.scoreBubble.height *
488
- 0.806 *
489
- (0.144 + 0.144 + 0.208 + 0.01), element.scoreBubble.height * 0.806 * 0.32, element.scoreBubble.height * 0.806 * 0.32);
490
- }
491
- /** End Milestone Draw */
492
- /** Begin Chart Mode Draw */
493
- {
494
- const mode = new canvas_1.Image();
495
- const chartModeBadgeImg = this.getThemeFile(score.chart.id > 10000
496
- ? theme.manifest.sprites.mode.dx
497
- : theme.manifest.sprites.mode.standard, theme.path);
498
- const { width, height } = await (0, sharp_1.default)(chartModeBadgeImg).metadata();
499
- const aspectRatio = (width ?? 0) / (height ?? 1) || 3;
500
- mode.src = chartModeBadgeImg;
501
- const drawHeight = (jacketSize * 6) / 8;
502
- ctx.drawImage(mode, x + ((jacketSize * 7) / 8 - drawHeight) / 2, y +
503
- element.scoreBubble.margin +
504
- element.scoreBubble.height * 0.806 * 0.02, drawHeight, drawHeight / aspectRatio);
505
- }
506
- /** End Chart Mode Draw */
507
- /** Begin Bests Index Draw */
508
- {
509
- util_1.Util.drawText(ctx, `#${index + 1}`, x + element.scoreBubble.margin * 2, y + jacketSize - element.scoreBubble.margin * 2, element.scoreBubble.height * 0.806 * 0.128, element.scoreBubble.height * 0.806 * 0.04, Infinity, "left", "white", new color_1.default(curColor).darken(0.3).hexa());
510
- }
511
- /** End Bests Index Draw */
512
- ctx.restore();
513
- }
514
- /** End Main Content Draw */
515
- /** Begin Difficulty & DX Rating Draw */
516
- {
517
- util_1.Util.drawText(ctx, `${util_1.Util.truncate(score.chart.level, 1)} ↑${util_1.Util.truncate(score.dxRating, 0)}`, x + element.scoreBubble.margin * 2, y + element.scoreBubble.height * (0.806 + (1 - 0.806) / 2), element.scoreBubble.height * 0.806 * 0.128, element.scoreBubble.height * 0.806 * 0.04, Infinity, "left", "white", new color_1.default(curColor).darken(0.3).hexa());
518
- if (score.dxScore >= 0 && score.chart.maxDxScore > 0) {
519
- util_1.Util.drawText(ctx, `${score.dxScore}/${score.chart.maxDxScore}`, x +
520
- element.scoreBubble.width -
521
- element.scoreBubble.margin * 2, y + element.scoreBubble.height * (0.806 + (1 - 0.806) / 2), element.scoreBubble.height * 0.806 * 0.128, element.scoreBubble.height * 0.806 * 0.04, Infinity, "right", "white", new color_1.default(curColor).darken(0.3).hexa());
522
- }
523
- }
524
- /** End Difficulty & DX Rating Draw */
525
- ctx.restore();
526
- /** End Card Draw */
527
- }
528
- static async drawProfileModule(ctx, theme, element, username, rating, profilePicture) {
529
- const nameplate = new canvas_1.Image();
530
- nameplate.src = this.getThemeFile(theme.manifest.sprites.profile.nameplate, theme.path);
531
- ctx.drawImage(nameplate, element.x, element.y, element.height * 6.207, element.height);
532
- /* Begin Profile Picture Draw */
533
- {
534
- ctx.save();
535
- ctx.beginPath();
536
- ctx.roundRect(element.x + element.height * 0.064, element.y + element.height * 0.064, element.height * 0.872, element.height * 0.872, (element.height * 0.872) / 16);
537
- ctx.clip();
538
- ctx.fillStyle = "white";
539
- ctx.fill();
540
- const icon = new canvas_1.Image();
541
- try {
542
- (0, sharp_1.default)(profilePicture);
543
- }
544
- catch {
545
- // Unknown profile picture binary
546
- profilePicture = undefined;
547
- }
548
- const pfp = profilePicture ||
549
- this.getThemeFile(theme.manifest.sprites.profile.icon, theme.path);
550
- const { dominant } = await (0, sharp_1.default)(pfp).stats();
551
- icon.src = await (0, sharp_1.default)(pfp).png().toBuffer();
552
- const cropSize = Math.min(icon.width, icon.height);
553
- ctx.drawImage(icon, (icon.width - cropSize) / 2, (icon.height - cropSize) / 2, cropSize, cropSize, element.x + element.height * 0.064, element.y + element.height * 0.064, element.height * 0.872, element.height * 0.872);
554
- if (profilePicture) {
555
- ctx.beginPath();
556
- ctx.roundRect(element.x + element.height * 0.064, element.y + element.height * 0.064, element.height * 0.872, element.height * 0.872, (element.height * 0.872) / 16);
557
- ctx.strokeStyle = color_1.default.rgb(dominant).darken(0.3).hex();
558
- ctx.lineWidth = element.height / 30;
559
- ctx.stroke();
560
- }
561
- ctx.restore();
562
- }
563
- /* End Profile Picture Draw */
564
- /* Begin DX Rating Draw */
565
- {
566
- const dxRating = new canvas_1.Image();
567
- let dxRatingImg;
568
- switch (true) {
569
- case rating >= 15000: {
570
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.rainbow, theme.path);
571
- break;
572
- }
573
- case rating >= 14500: {
574
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.platinum, theme.path);
575
- break;
576
- }
577
- case rating >= 14000: {
578
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.gold, theme.path);
579
- break;
580
- }
581
- case rating >= 13000: {
582
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.silver, theme.path);
583
- break;
584
- }
585
- case rating >= 12000: {
586
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.bronze, theme.path);
587
- break;
588
- }
589
- case rating >= 10000: {
590
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.purple, theme.path);
591
- break;
592
- }
593
- case rating >= 8000: {
594
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.red, theme.path);
595
- break;
596
- }
597
- case rating >= 6000: {
598
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.yellow, theme.path);
599
- break;
600
- }
601
- case rating >= 4000: {
602
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.green, theme.path);
603
- break;
604
- }
605
- case rating >= 2000: {
606
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.blue, theme.path);
607
- break;
608
- }
609
- default: {
610
- dxRatingImg = this.getThemeFile(theme.manifest.sprites.dxRating.white, theme.path);
611
- break;
612
- }
613
- }
614
- dxRating.src = dxRatingImg;
615
- ctx.drawImage(dxRating, element.x + element.height, element.y + element.height * 0.064, (element.height / 3) * 5.108, element.height / 3);
616
- }
617
- /* End DX Rating Draw */
618
- /* Begin Username Draw */
619
- {
620
- ctx.beginPath();
621
- ctx.roundRect(element.x + element.height * (1 + 1 / 32), element.y + element.height * (0.064 + 0.333 + 1 / 32), ((element.height / 3) * 5.108 * 6) / 5, (element.height * 7) / 24, element.height / 20);
622
- ctx.fillStyle = "white";
623
- ctx.strokeStyle = color_1.default.rgb(180, 180, 180).hex();
624
- ctx.lineWidth = element.height / 32;
625
- ctx.stroke();
626
- ctx.fill();
627
- const ratingImgBuffer = await this.getRatingNumber(rating, theme);
628
- if (ratingImgBuffer) {
629
- const { width, height } = await (0, sharp_1.default)(ratingImgBuffer).metadata();
630
- if (width && height) {
631
- const aspectRatio = width / height;
632
- const image = new canvas_1.Image();
633
- image.src = ratingImgBuffer;
634
- const drawHeight = (element.height * 7) / 32;
635
- ctx.drawImage(image, element.x + element.height * 1.785, element.y + element.height * 0.12, drawHeight * aspectRatio * 0.8, drawHeight);
636
- }
637
- }
638
- util_1.Util.drawText(ctx, util_1.Util.HalfFullWidthConvert.toFullWidth(username), element.x + element.height * (1 + 1 / 16), element.y + element.height * (0.064 + 0.333 + 1 / 4), (element.height * 1) / 6, 0, ((element.height / 3) * 5.108 * 6) / 5, "left", "black", "black", "standard-font-username");
639
- }
640
- /* End Username Draw*/
641
- }
642
- static async drawTextModule(ctx, theme, element, variables = {}) {
643
- let naiveLines = (0, string_template_1.default)(element.content, variables).split("\n");
644
- let lines = [];
645
- if (element.linebreak) {
646
- for (let originalContent of naiveLines) {
647
- while (originalContent.length) {
648
- const line = util_1.Util.findMaxFitString(ctx, originalContent, element.width || Infinity, "");
649
- originalContent = originalContent.replace(line, "").trim();
650
- lines.push(line.trim());
651
- }
652
- }
653
- }
654
- else {
655
- for (const originalContent of naiveLines) {
656
- lines.push(util_1.Util.findMaxFitString(ctx, originalContent, element.width || Infinity));
657
- }
658
- }
659
- for (let i = 0; i < lines.length; ++i) {
660
- const line = lines[i];
661
- util_1.Util.drawText(ctx, line, element.x, element.y + i * element.size * 1.3, element.size, element.size / 3.5, element.width || Infinity, element.align, element.color || "#FFFFFF", element.borderColor
662
- ? element.borderColor
663
- : color_1.default.rgb(element.color || "#FFFFFF")
664
- .darken(0.3)
665
- .hex(), element.font, element.linebreak ? "" : "...");
666
- }
667
- }
668
- /* End Draw Tools*/
669
- static async draw(name, rating, newScores, oldScores, options) {
670
- let currentTheme = this.primaryTheme;
671
- if (options?.theme) {
672
- const theme = this.getTheme(options.theme);
673
- if (theme) {
674
- currentTheme = theme;
675
- }
676
- }
677
- if (currentTheme) {
678
- await chart_1.Chart.Database.cacheJackets([
679
- ...newScores.map((v) => v.chart.id),
680
- ...oldScores.map((v) => v.chart.id),
681
- ]);
682
- const canvas = new canvas_1.Canvas(currentTheme.manifest.width * (options?.scale ?? 1), currentTheme.manifest.height * (options?.scale ?? 1));
683
- const ctx = canvas.getContext("2d");
684
- if (options?.scale)
685
- ctx.scale(options.scale, options.scale);
686
- ctx.imageSmoothingEnabled = true;
687
- for (const element of currentTheme.manifest.elements) {
688
- switch (element.type) {
689
- case "image": {
690
- await this.drawImageModule(ctx, currentTheme, element);
691
- break;
692
- }
693
- case "score-grid": {
694
- for (let y = element.y, index = element.index, i = 0; i < element.verticalSize; ++i,
695
- y +=
696
- element.scoreBubble.height +
697
- element.scoreBubble.gap) {
698
- for (let x = element.x, j = 0; j < element.horizontalSize; ++j,
699
- ++index,
700
- x +=
701
- element.scoreBubble.width +
702
- element.scoreBubble.gap) {
703
- let curScore;
704
- if (element.region == "new")
705
- curScore = newScores[index];
706
- else
707
- curScore = oldScores[index];
708
- if (curScore) {
709
- await this.drawScoreGridModule(ctx, currentTheme, element, curScore, index, x, y);
710
- }
711
- }
712
- }
713
- break;
714
- }
715
- case "profile": {
716
- await this.drawProfileModule(ctx, currentTheme, element, name, rating, options?.profilePicture);
717
- break;
718
- }
719
- case "text": {
720
- const getRatingBase = (scores, length) => {
721
- if (scores.length < length)
722
- return 0;
723
- return (scores
724
- .slice(0, length)
725
- .map((v) => util_1.Util.Maimai.calculateRating(v.chart.level, v.achievement))
726
- .sort((a, b) => a - b)[0] || 0);
727
- };
728
- function getRatingAvg(scores, length) {
729
- if (scores.length <= 0)
730
- return 0;
731
- return (scores
732
- .map((v) => v.dxRating)
733
- .reduce((sum, v) => sum + v, 0) / length);
734
- }
735
- const getRatingTargetLevel = (rating, target) => {
736
- if (target == Best50.EAchievementTypes.D) {
737
- return 0;
738
- }
739
- const naiveLevel = rating /
740
- (this.RATING_CONSTANTS[target] *
741
- this.RANK_BORDERS[target]);
742
- return Math.ceil(naiveLevel * 10) / 10;
743
- };
744
- function getMilestone(scores, length) {
745
- const base = getRatingBase(scores, length);
746
- let sssTarget, ssspTarget;
747
- const sssLevel = getRatingTargetLevel(base, Best50.EAchievementTypes.SSS);
748
- const ssspLevel = getRatingTargetLevel(base, Best50.EAchievementTypes.SSSP);
749
- if (sssLevel > 0 && sssLevel < 15) {
750
- sssTarget = sssLevel;
751
- }
752
- if (ssspLevel > 0 && ssspLevel < 15) {
753
- ssspTarget = ssspLevel;
754
- }
755
- if (sssTarget && ssspTarget)
756
- return `Next rating boost: lv. ${util_1.Util.ceilWithPercision(ssspTarget, 1)} SSS+/${util_1.Util.ceilWithPercision(sssTarget, 1)} SSS`;
757
- else if (sssTarget)
758
- return `Next rating boost: lv. ${util_1.Util.ceilWithPercision(sssTarget, 1)} SSS`;
759
- else if (ssspTarget)
760
- return `Next rating boost: lv. ${util_1.Util.ceilWithPercision(ssspTarget, 1)} SSS+`;
761
- else
762
- return "Good job!";
763
- }
764
- await this.drawTextModule(ctx, currentTheme, element, {
765
- username: util_1.Util.HalfFullWidthConvert.toFullWidth(name),
766
- rating: util_1.Util.truncate(rating, 0),
767
- newScoreRatingAvgString: `NEW scores average: ${util_1.Util.ceilWithPercision(getRatingAvg(newScores, 15), 0)}`,
768
- oldScoreRatingAvgString: `OLD scores average: ${util_1.Util.ceilWithPercision(getRatingAvg(oldScores, 35), 0)}`,
769
- newScoreMilestone: getMilestone(newScores, 15),
770
- oldScoreMilestone: getMilestone(oldScores, 35),
771
- });
772
- break;
773
- }
774
- }
775
- }
776
- return canvas.toBuffer();
777
- }
778
- else
779
- return null;
780
- }
781
- static async drawWithScoreSource(source, username, options) {
782
- const profile = await source.getPlayerInfo(username);
783
- const score = await source.getPlayerBest50(username);
784
- if (!profile || !score)
785
- return null;
786
- return this.draw(profile.name, profile.rating, score.new, score.old, {
787
- ...options,
788
- profilePicture: options?.profilePicture === null
789
- ? undefined
790
- : options?.profilePicture ||
791
- (await source.getPlayerProfilePicture(username)) ||
792
- undefined,
793
- });
794
- }
795
- static async getRatingNumber(num, theme) {
796
- async function getRaingDigit(map, digit, unitWidth, unitHeight) {
797
- digit = Math.trunc(digit % 10);
798
- return await (0, sharp_1.default)(map)
799
- .extract({
800
- left: (digit % 4) * unitWidth,
801
- top: Math.trunc(digit / 4) * unitHeight,
802
- width: unitWidth,
803
- height: unitHeight,
804
- })
805
- .toBuffer();
806
- }
807
- if (theme.manifest) {
808
- const map = this.getThemeFile(theme.manifest.sprites.dxRatingNumberMap, theme.path);
809
- const { width, height } = await (0, sharp_1.default)(map).metadata();
810
- if (!(width && height))
811
- return null;
812
- const unitWidth = width / 4, unitHeight = height / 4;
813
- let digits = [];
814
- while (num > 0) {
815
- digits.push(await getRaingDigit(map, num % 10, unitWidth, unitHeight));
816
- num = Math.trunc(num / 10);
817
- }
818
- while (digits.length < 5)
819
- digits.push(null);
820
- digits = digits.reverse();
821
- const canvas = new canvas_1.Canvas(unitWidth * digits.length, unitHeight);
822
- const ctx = canvas.getContext("2d");
823
- for (let i = 0; i < digits.length; ++i) {
824
- const curDigit = digits[i];
825
- if (!curDigit)
826
- continue;
827
- const img = new canvas_1.Image();
828
- img.src = curDigit;
829
- ctx.drawImage(img, unitWidth * i * 0.88, 0);
830
- }
831
- return canvas.toBuffer();
832
- }
833
- return null;
834
- }
835
- }
836
- exports.Best50 = Best50;
837
- (function (Best50) {
838
- Best50.LXNS = lxns.LXNS;
839
- Best50.KamaiTachi = kamaiTachi.KamaiTachi;
840
- Best50.DivingFish = divingFish.DivingFish;
841
- Best50.Maishift = maishift.Maishift;
842
- let EComboTypes;
843
- (function (EComboTypes) {
844
- EComboTypes[EComboTypes["NONE"] = 0] = "NONE";
845
- EComboTypes[EComboTypes["FULL_COMBO"] = 1] = "FULL_COMBO";
846
- EComboTypes[EComboTypes["FULL_COMBO_PLUS"] = 2] = "FULL_COMBO_PLUS";
847
- EComboTypes[EComboTypes["ALL_PERFECT"] = 3] = "ALL_PERFECT";
848
- EComboTypes[EComboTypes["ALL_PERFECT_PLUS"] = 4] = "ALL_PERFECT_PLUS";
849
- })(EComboTypes = Best50.EComboTypes || (Best50.EComboTypes = {}));
850
- let ESyncTypes;
851
- (function (ESyncTypes) {
852
- ESyncTypes[ESyncTypes["NONE"] = 0] = "NONE";
853
- ESyncTypes[ESyncTypes["SYNC_PLAY"] = 1] = "SYNC_PLAY";
854
- ESyncTypes[ESyncTypes["FULL_SYNC"] = 2] = "FULL_SYNC";
855
- ESyncTypes[ESyncTypes["FULL_SYNC_PLUS"] = 3] = "FULL_SYNC_PLUS";
856
- ESyncTypes[ESyncTypes["FULL_SYNC_DX"] = 4] = "FULL_SYNC_DX";
857
- ESyncTypes[ESyncTypes["FULL_SYNC_DX_PLUS"] = 5] = "FULL_SYNC_DX_PLUS";
858
- })(ESyncTypes = Best50.ESyncTypes || (Best50.ESyncTypes = {}));
859
- let EAchievementTypes;
860
- (function (EAchievementTypes) {
861
- EAchievementTypes[EAchievementTypes["D"] = 0] = "D";
862
- EAchievementTypes[EAchievementTypes["C"] = 1] = "C";
863
- EAchievementTypes[EAchievementTypes["B"] = 2] = "B";
864
- EAchievementTypes[EAchievementTypes["BB"] = 3] = "BB";
865
- EAchievementTypes[EAchievementTypes["BBB"] = 4] = "BBB";
866
- EAchievementTypes[EAchievementTypes["A"] = 5] = "A";
867
- EAchievementTypes[EAchievementTypes["AA"] = 6] = "AA";
868
- EAchievementTypes[EAchievementTypes["AAA"] = 7] = "AAA";
869
- EAchievementTypes[EAchievementTypes["S"] = 8] = "S";
870
- EAchievementTypes[EAchievementTypes["SP"] = 9] = "SP";
871
- EAchievementTypes[EAchievementTypes["SS"] = 10] = "SS";
872
- EAchievementTypes[EAchievementTypes["SSP"] = 11] = "SSP";
873
- EAchievementTypes[EAchievementTypes["SSS"] = 12] = "SSS";
874
- EAchievementTypes[EAchievementTypes["SSSP"] = 13] = "SSSP";
875
- })(EAchievementTypes = Best50.EAchievementTypes || (Best50.EAchievementTypes = {}));
876
- Best50.RATING_CONSTANTS = {
877
- [Best50.EAchievementTypes.D]: {
878
- [0.4]: 6.4,
879
- [0.3]: 4.8,
880
- [0.2]: 3.2,
881
- [0.1]: 1.6,
882
- [0]: 0,
883
- },
884
- [EAchievementTypes.C]: 13.6,
885
- [EAchievementTypes.B]: 13.6,
886
- [EAchievementTypes.BB]: 13.6,
887
- [EAchievementTypes.BBB]: 13.6,
888
- [EAchievementTypes.A]: 13.6,
889
- [EAchievementTypes.AA]: 15.2,
890
- [EAchievementTypes.AAA]: 16.8,
891
- [EAchievementTypes.S]: 20.0,
892
- [EAchievementTypes.SP]: 20.3,
893
- [EAchievementTypes.SS]: 20.8,
894
- [EAchievementTypes.SSP]: 21.1,
895
- [EAchievementTypes.SSS]: 21.6,
896
- [EAchievementTypes.SSSP]: 22.4,
897
- };
898
- Best50.RANK_BORDERS = {
899
- [EAchievementTypes.D]: [0.0, 0.1, 0.2, 0.3, 0.4],
900
- [EAchievementTypes.C]: 0.5,
901
- [EAchievementTypes.B]: 0.6,
902
- [EAchievementTypes.BB]: 0.7,
903
- [EAchievementTypes.BBB]: 0.75,
904
- [EAchievementTypes.A]: 0.8,
905
- [EAchievementTypes.AA]: 0.9,
906
- [EAchievementTypes.AAA]: 0.94,
907
- [EAchievementTypes.S]: 0.97,
908
- [EAchievementTypes.SP]: 0.98,
909
- [EAchievementTypes.SS]: 0.99,
910
- [EAchievementTypes.SSP]: 0.995,
911
- [EAchievementTypes.SSS]: 1.0,
912
- [EAchievementTypes.SSSP]: 1.005,
913
- };
914
- })(Best50 || (exports.Best50 = Best50 = {}));
915
- //# sourceMappingURL=index.js.map