1- function exponential_cdf ( x ) {
2- return 1 - 2 ** - x ;
3- }
1+ function score ( x , quantiles ) {
2+ const i = quantiles . findIndex ( ( q ) => x < q ) ;
3+
4+ if ( i == 0 ) {
5+ return 0.0 ;
6+ } else if ( i == - 1 ) {
7+ return 1.0 ;
8+ }
49
5- function log_normal_cdf ( x ) {
6- // approximation
7- return x / ( 1 + x ) ;
10+ const a = quantiles [ i - 1 ] ;
11+ const b = quantiles [ i ] ;
12+
13+ return ( ( x - a ) / ( b - a ) + i - 1 ) / ( quantiles . length - 1 ) ;
814}
915
16+ const QUANTILES = {
17+ commits : [
18+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 3 , 3 ,
19+ 4 , 4 , 5 , 6 , 7 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 15 , 16 , 17 , 19 , 20 , 22 , 23 , 25 , 27 ,
20+ 29 , 31 , 33 , 35 , 38 , 40 , 43 , 45 , 48 , 51 , 54 , 57 , 60 , 64 , 67 , 71 , 76 , 80 , 85 ,
21+ 89 , 94 , 99 , 105 , 111 , 118 , 125 , 132 , 140 , 147 , 155 , 164 , 173 , 184 , 195 , 207 ,
22+ 220 , 233 , 249 , 265 , 284 , 304 , 326 , 353 , 380 , 411 , 451 , 495 , 545 , 611 , 691 ,
23+ 794 , 933 , 1195 , 1704 , 9722 ,
24+ ] ,
25+ all_commits : [
26+ 0 , 0 , 0 , 0 , 2 , 4 , 8 , 11 , 15 , 19 , 23 , 27 , 32 , 36 , 41 , 45 , 50 , 55 , 60 , 65 , 71 ,
27+ 76 , 82 , 87 , 93 , 99 , 105 , 111 , 117 , 124 , 131 , 137 , 145 , 151 , 159 , 166 , 174 ,
28+ 182 , 190 , 198 , 207 , 215 , 225 , 234 , 244 , 253 , 264 , 274 , 285 , 296 , 306 , 318 ,
29+ 330 , 342 , 355 , 368 , 382 , 396 , 409 , 424 , 440 , 457 , 475 , 493 , 512 , 531 , 551 ,
30+ 570 , 593 , 618 , 643 , 667 , 695 , 723 , 752 , 784 , 815 , 857 , 893 , 934 , 984 , 1037 ,
31+ 1094 , 1152 , 1217 , 1289 , 1379 , 1475 , 1576 , 1696 , 1851 , 2023 , 2232 , 2480 ,
32+ 2835 , 3242 , 3885 , 4868 , 6614 , 11801 , 792319 ,
33+ ] ,
34+ prs : [
35+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 ,
36+ 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 ,
37+ 8 , 8 , 9 , 10 , 10 , 11 , 11 , 12 , 13 , 14 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 23 , 24 ,
38+ 25 , 27 , 28 , 30 , 32 , 34 , 36 , 38 , 40 , 43 , 46 , 50 , 53 , 57 , 61 , 65 , 70 , 76 , 83 ,
39+ 90 , 99 , 110 , 123 , 139 , 159 , 185 , 219 , 273 , 360 , 562 , 2291 ,
40+ ] ,
41+ issues : [
42+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
43+ 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 ,
44+ 4 , 4 , 4 , 5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 8 , 8 , 9 , 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 ,
45+ 16 , 17 , 19 , 20 , 21 , 23 , 24 , 26 , 28 , 30 , 32 , 35 , 38 , 41 , 45 , 49 , 54 , 59 , 66 ,
46+ 73 , 82 , 92 , 106 , 123 , 150 , 186 , 255 , 409 , 1590 ,
47+ ] ,
48+ reviews : [
49+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
50+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
51+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
52+ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 8 , 11 , 15 , 23 , 36 , 61 ,
53+ 129 , 764 ,
54+ ] ,
55+ repos : [
56+ 0 , 0 , 1 , 2 , 2 , 3 , 3 , 4 , 4 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 10 , 10 , 11 ,
57+ 11 , 12 , 12 , 12 , 13 , 13 , 14 , 14 , 15 , 15 , 16 , 16 , 17 , 17 , 18 , 18 , 19 , 19 , 20 ,
58+ 20 , 21 , 21 , 22 , 22 , 23 , 24 , 24 , 25 , 25 , 26 , 27 , 28 , 28 , 29 , 30 , 30 , 31 , 32 ,
59+ 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 45 , 46 , 47 , 49 , 50 , 52 , 54 , 56 ,
60+ 58 , 60 , 62 , 65 , 68 , 70 , 74 , 77 , 82 , 86 , 92 , 98 , 105 , 115 , 127 , 144 , 170 ,
61+ 211 , 316 , 2002 ,
62+ ] ,
63+ stars : [
64+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 ,
65+ 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 6 , 6 ,
66+ 7 , 7 , 8 , 8 , 9 , 9 , 10 , 11 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 21 , 22 , 24 ,
67+ 26 , 28 , 30 , 31 , 33 , 35 , 38 , 41 , 44 , 48 , 52 , 56 , 61 , 67 , 74 , 83 , 93 , 104 ,
68+ 117 , 134 , 154 , 181 , 215 , 257 , 321 , 417 , 565 , 818 , 1298 , 2599 , 18304 ,
69+ ] ,
70+ followers : [
71+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 ,
72+ 5 , 5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11 , 12 , 12 ,
73+ 13 , 13 , 14 , 14 , 15 , 15 , 16 , 16 , 17 , 18 , 18 , 19 , 20 , 20 , 21 , 22 , 23 , 24 , 25 ,
74+ 26 , 27 , 28 , 29 , 30 , 32 , 33 , 35 , 36 , 38 , 40 , 42 , 44 , 46 , 49 , 51 , 54 , 57 , 61 ,
75+ 65 , 70 , 75 , 81 , 88 , 97 , 108 , 121 , 139 , 161 , 193 , 240 , 334 , 569 , 3583 ,
76+ ] ,
77+ } ;
78+
79+ const WEIGHT = {
80+ commits : 2.0 ,
81+ prs : 3.0 ,
82+ issues : 1.0 ,
83+ reviews : 0.5 ,
84+ repos : 0.0 ,
85+ stars : 4.0 ,
86+ followers : 1.0 ,
87+ } ;
88+
1089/**
1190 * Calculates the users rank.
1291 *
@@ -27,48 +106,36 @@ function calculateRank({
27106 prs,
28107 issues,
29108 reviews,
30- // eslint-disable-next-line no-unused-vars
31- repos, // unused
109+ repos,
32110 stars,
33111 followers,
34112} ) {
35- const COMMITS_MEDIAN = all_commits ? 1000 : 250 ,
36- COMMITS_WEIGHT = 2 ;
37- const PRS_MEDIAN = 50 ,
38- PRS_WEIGHT = 3 ;
39- const ISSUES_MEDIAN = 25 ,
40- ISSUES_WEIGHT = 1 ;
41- const REVIEWS_MEDIAN = 2 ,
42- REVIEWS_WEIGHT = 1 ;
43- const STARS_MEDIAN = 50 ,
44- STARS_WEIGHT = 4 ;
45- const FOLLOWERS_MEDIAN = 10 ,
46- FOLLOWERS_WEIGHT = 1 ;
47-
48- const TOTAL_WEIGHT =
49- COMMITS_WEIGHT +
50- PRS_WEIGHT +
51- ISSUES_WEIGHT +
52- REVIEWS_WEIGHT +
53- STARS_WEIGHT +
54- FOLLOWERS_WEIGHT ;
55-
56113 const THRESHOLDS = [ 1 , 12.5 , 25 , 37.5 , 50 , 62.5 , 75 , 87.5 , 100 ] ;
57114 const LEVELS = [ "S" , "A+" , "A" , "A-" , "B+" , "B" , "B-" , "C+" , "C" ] ;
58115
59- const rank =
60- 1 -
61- ( COMMITS_WEIGHT * exponential_cdf ( commits / COMMITS_MEDIAN ) +
62- PRS_WEIGHT * exponential_cdf ( prs / PRS_MEDIAN ) +
63- ISSUES_WEIGHT * exponential_cdf ( issues / ISSUES_MEDIAN ) +
64- REVIEWS_WEIGHT * exponential_cdf ( reviews / REVIEWS_MEDIAN ) +
65- STARS_WEIGHT * log_normal_cdf ( stars / STARS_MEDIAN ) +
66- FOLLOWERS_WEIGHT * log_normal_cdf ( followers / FOLLOWERS_MEDIAN ) ) /
67- TOTAL_WEIGHT ;
116+ const total_weight =
117+ WEIGHT . commits +
118+ WEIGHT . prs +
119+ WEIGHT . issues +
120+ WEIGHT . reviews +
121+ WEIGHT . repos +
122+ WEIGHT . stars +
123+ WEIGHT . followers ;
124+
125+ const total_score =
126+ WEIGHT . commits *
127+ score ( commits , all_commits ? QUANTILES . all_commits : QUANTILES . commits ) +
128+ WEIGHT . prs * score ( prs , QUANTILES . prs ) +
129+ WEIGHT . issues * score ( issues , QUANTILES . issues ) +
130+ WEIGHT . reviews * score ( reviews , QUANTILES . reviews ) +
131+ WEIGHT . repos * score ( repos , QUANTILES . repos ) +
132+ WEIGHT . stars * score ( stars , QUANTILES . stars ) +
133+ WEIGHT . followers * score ( followers , QUANTILES . followers ) ;
68134
69- const level = LEVELS [ THRESHOLDS . findIndex ( ( t ) => rank * 100 <= t ) ] ;
135+ const percentile = 100 * ( 1 - total_score / total_weight ) ;
136+ const level = LEVELS [ THRESHOLDS . findIndex ( ( t ) => percentile <= t ) ] ;
70137
71- return { level, percentile : rank * 100 } ;
138+ return { level, percentile } ;
72139}
73140
74141export { calculateRank } ;
0 commit comments