ts-fsrs 5.2.2 → 5.3.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.
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +112 -192
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +112 -193
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +112 -192
- package/dist/index.umd.js.map +1 -1
- package/package.json +25 -36
- package/README.md +0 -174
package/dist/index.umd.js
CHANGED
|
@@ -76,8 +76,12 @@
|
|
|
76
76
|
throw new Error(`Invalid state:[${value}]`);
|
|
77
77
|
}
|
|
78
78
|
static time(value) {
|
|
79
|
-
if (
|
|
79
|
+
if (value instanceof Date) {
|
|
80
80
|
return value;
|
|
81
|
+
}
|
|
82
|
+
const date = new Date(value);
|
|
83
|
+
if (typeof value === "object" && value !== null && !Number.isNaN(Date.parse(value) || +date)) {
|
|
84
|
+
return date;
|
|
81
85
|
} else if (typeof value === "string") {
|
|
82
86
|
const timestamp = Date.parse(value);
|
|
83
87
|
if (!Number.isNaN(timestamp)) {
|
|
@@ -100,15 +104,19 @@
|
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
/* istanbul ignore next -- @preserve */
|
|
103
108
|
Date.prototype.scheduler = function(t, isDay) {
|
|
104
109
|
return date_scheduler(this, t, isDay);
|
|
105
110
|
};
|
|
111
|
+
/* istanbul ignore next -- @preserve */
|
|
106
112
|
Date.prototype.diff = function(pre, unit) {
|
|
107
113
|
return date_diff(this, pre, unit);
|
|
108
114
|
};
|
|
115
|
+
/* istanbul ignore next -- @preserve */
|
|
109
116
|
Date.prototype.format = function() {
|
|
110
117
|
return formatDate(this);
|
|
111
118
|
};
|
|
119
|
+
/* istanbul ignore next -- @preserve */
|
|
112
120
|
Date.prototype.dueFormat = function(last_review, unit, timeUnit) {
|
|
113
121
|
return show_diff_message(this, last_review, unit, timeUnit);
|
|
114
122
|
};
|
|
@@ -168,12 +176,15 @@
|
|
|
168
176
|
}
|
|
169
177
|
return `${Math.floor(diff)}${unit ? timeUnit[i] : ""}`;
|
|
170
178
|
}
|
|
179
|
+
/* istanbul ignore next -- @preserve */
|
|
171
180
|
function fixDate(value) {
|
|
172
181
|
return TypeConvert.time(value);
|
|
173
182
|
}
|
|
183
|
+
/* istanbul ignore next -- @preserve */
|
|
174
184
|
function fixState(value) {
|
|
175
185
|
return TypeConvert.state(value);
|
|
176
186
|
}
|
|
187
|
+
/* istanbul ignore next -- @preserve */
|
|
177
188
|
function fixRating(value) {
|
|
178
189
|
return TypeConvert.rating(value);
|
|
179
190
|
}
|
|
@@ -217,6 +228,10 @@
|
|
|
217
228
|
function clamp(value, min, max) {
|
|
218
229
|
return Math.min(Math.max(value, min), max);
|
|
219
230
|
}
|
|
231
|
+
function roundTo(num, decimals) {
|
|
232
|
+
const factor = 10 ** decimals;
|
|
233
|
+
return Math.round(num * factor) / factor;
|
|
234
|
+
}
|
|
220
235
|
function dateDiffInDays(last, cur) {
|
|
221
236
|
const utc1 = Date.UTC(
|
|
222
237
|
last.getUTCFullYear(),
|
|
@@ -496,7 +511,7 @@
|
|
|
496
511
|
return prng;
|
|
497
512
|
}
|
|
498
513
|
|
|
499
|
-
const version="5.
|
|
514
|
+
const version="5.3.0";
|
|
500
515
|
|
|
501
516
|
const default_request_retention = 0.9;
|
|
502
517
|
const default_maximum_interval = 36500;
|
|
@@ -674,11 +689,11 @@
|
|
|
674
689
|
const computeDecayFactor = (decayOrParams) => {
|
|
675
690
|
const decay = typeof decayOrParams === "number" ? -decayOrParams : -decayOrParams[20];
|
|
676
691
|
const factor = Math.exp(Math.pow(decay, -1) * Math.log(0.9)) - 1;
|
|
677
|
-
return { decay, factor:
|
|
692
|
+
return { decay, factor: roundTo(factor, 8) };
|
|
678
693
|
};
|
|
679
694
|
function forgetting_curve(decayOrParams, elapsed_days, stability) {
|
|
680
695
|
const { decay, factor } = computeDecayFactor(decayOrParams);
|
|
681
|
-
return
|
|
696
|
+
return roundTo(Math.pow(1 + factor * elapsed_days / stability, decay), 8);
|
|
682
697
|
}
|
|
683
698
|
class FSRSAlgorithm {
|
|
684
699
|
constructor(params) {
|
|
@@ -720,7 +735,7 @@
|
|
|
720
735
|
throw new Error("Requested retention rate should be in the range (0,1]");
|
|
721
736
|
}
|
|
722
737
|
const { decay, factor } = computeDecayFactor(this.param.w);
|
|
723
|
-
return
|
|
738
|
+
return roundTo((Math.pow(request_retention, 1 / decay) - 1) / factor, 8);
|
|
724
739
|
}
|
|
725
740
|
/**
|
|
726
741
|
* Get the parameters of the algorithm.
|
|
@@ -787,8 +802,9 @@
|
|
|
787
802
|
* @return {number} Difficulty $$D \in [1,10]$$
|
|
788
803
|
*/
|
|
789
804
|
init_difficulty(g) {
|
|
790
|
-
const
|
|
791
|
-
|
|
805
|
+
const w = this.param.w;
|
|
806
|
+
const d = w[4] - Math.exp((g - 1) * w[5]) + 1;
|
|
807
|
+
return roundTo(d, 8);
|
|
792
808
|
}
|
|
793
809
|
/**
|
|
794
810
|
* If fuzzing is disabled or ivl is less than 2.5, it returns the original interval.
|
|
@@ -823,7 +839,7 @@
|
|
|
823
839
|
* @see https://github.com/open-spaced-repetition/fsrs4anki/issues/697
|
|
824
840
|
*/
|
|
825
841
|
linear_damping(delta_d, old_d) {
|
|
826
|
-
return
|
|
842
|
+
return roundTo(delta_d * (10 - old_d) / 9, 8);
|
|
827
843
|
}
|
|
828
844
|
/**
|
|
829
845
|
* The formula used is :
|
|
@@ -851,9 +867,8 @@
|
|
|
851
867
|
* @return {number} difficulty
|
|
852
868
|
*/
|
|
853
869
|
mean_reversion(init, current) {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
);
|
|
870
|
+
const w = this.param.w;
|
|
871
|
+
return roundTo(w[7] * init + (1 - w[7]) * current, 8);
|
|
857
872
|
}
|
|
858
873
|
/**
|
|
859
874
|
* The formula used is :
|
|
@@ -865,13 +880,17 @@
|
|
|
865
880
|
* @return {number} S^\prime_r new stability after recall
|
|
866
881
|
*/
|
|
867
882
|
next_recall_stability(d, s, r, g) {
|
|
868
|
-
const
|
|
869
|
-
const
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
883
|
+
const w = this.param.w;
|
|
884
|
+
const hard_penalty = Rating.Hard === g ? w[15] : 1;
|
|
885
|
+
const easy_bound = Rating.Easy === g ? w[16] : 1;
|
|
886
|
+
return roundTo(
|
|
887
|
+
clamp(
|
|
888
|
+
s * (1 + Math.exp(w[8]) * (11 - d) * Math.pow(s, -w[9]) * (Math.exp((1 - r) * w[10]) - 1) * hard_penalty * easy_bound),
|
|
889
|
+
S_MIN,
|
|
890
|
+
36500
|
|
891
|
+
),
|
|
892
|
+
8
|
|
893
|
+
);
|
|
875
894
|
}
|
|
876
895
|
/**
|
|
877
896
|
* The formula used is :
|
|
@@ -884,11 +903,15 @@
|
|
|
884
903
|
* @return {number} S^\prime_f new stability after forgetting
|
|
885
904
|
*/
|
|
886
905
|
next_forget_stability(d, s, r) {
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
906
|
+
const w = this.param.w;
|
|
907
|
+
return roundTo(
|
|
908
|
+
clamp(
|
|
909
|
+
w[11] * Math.pow(d, -w[12]) * (Math.pow(s + 1, w[13]) - 1) * Math.exp((1 - r) * w[14]),
|
|
910
|
+
S_MIN,
|
|
911
|
+
36500
|
|
912
|
+
),
|
|
913
|
+
8
|
|
914
|
+
);
|
|
892
915
|
}
|
|
893
916
|
/**
|
|
894
917
|
* The formula used is :
|
|
@@ -897,9 +920,10 @@
|
|
|
897
920
|
* @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])
|
|
898
921
|
*/
|
|
899
922
|
next_short_term_stability(s, g) {
|
|
900
|
-
const
|
|
901
|
-
const
|
|
902
|
-
|
|
923
|
+
const w = this.param.w;
|
|
924
|
+
const sinc = Math.pow(s, -w[19]) * Math.exp(w[17] * (g - 3 + w[18]));
|
|
925
|
+
const maskedSinc = g >= Rating.Hard ? Math.max(sinc, 1) : sinc;
|
|
926
|
+
return roundTo(clamp(s * maskedSinc, S_MIN, 36500), 8);
|
|
903
927
|
}
|
|
904
928
|
/**
|
|
905
929
|
* Calculates the next state of memory based on the current state, time elapsed, and grade.
|
|
@@ -907,9 +931,10 @@
|
|
|
907
931
|
* @param memory_state - The current state of memory, which can be null.
|
|
908
932
|
* @param t - The time elapsed since the last review.
|
|
909
933
|
* @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])
|
|
934
|
+
* @param r - Optional retrievability value. If not provided, it will be calculated.
|
|
910
935
|
* @returns The next state of memory with updated difficulty and stability.
|
|
911
936
|
*/
|
|
912
|
-
next_state(memory_state, t, g) {
|
|
937
|
+
next_state(memory_state, t, g, r) {
|
|
913
938
|
const { difficulty: d, stability: s } = memory_state != null ? memory_state : {
|
|
914
939
|
difficulty: 0,
|
|
915
940
|
stability: 0
|
|
@@ -937,22 +962,22 @@
|
|
|
937
962
|
`Invalid memory state { difficulty: ${d}, stability: ${s} }`
|
|
938
963
|
);
|
|
939
964
|
}
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
if (g === 1) {
|
|
965
|
+
const w = this.param.w;
|
|
966
|
+
r = typeof r === "number" ? r : this.forgetting_curve(t, s);
|
|
967
|
+
let new_s;
|
|
968
|
+
if (t === 0 && this.param.enable_short_term) {
|
|
969
|
+
new_s = this.next_short_term_stability(s, g);
|
|
970
|
+
} else if (g === 1) {
|
|
971
|
+
const s_after_fail = this.next_forget_stability(d, s, r);
|
|
946
972
|
let [w_17, w_18] = [0, 0];
|
|
947
973
|
if (this.param.enable_short_term) {
|
|
948
|
-
w_17 =
|
|
949
|
-
w_18 =
|
|
974
|
+
w_17 = w[17];
|
|
975
|
+
w_18 = w[18];
|
|
950
976
|
}
|
|
951
977
|
const next_s_min = s / Math.exp(w_17 * w_18);
|
|
952
|
-
new_s = clamp(
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
new_s = s_after_short_term;
|
|
978
|
+
new_s = clamp(roundTo(next_s_min, 8), S_MIN, s_after_fail);
|
|
979
|
+
} else {
|
|
980
|
+
new_s = this.next_recall_stability(d, s, r, g);
|
|
956
981
|
}
|
|
957
982
|
const new_d = this.next_difficulty(d, g);
|
|
958
983
|
return { difficulty: new_d, stability: new_s };
|
|
@@ -1041,9 +1066,7 @@
|
|
|
1041
1066
|
if (exist) {
|
|
1042
1067
|
return exist;
|
|
1043
1068
|
}
|
|
1044
|
-
const next =
|
|
1045
|
-
next.difficulty = clamp(this.algorithm.init_difficulty(grade), 1, 10);
|
|
1046
|
-
next.stability = this.algorithm.init_stability(grade);
|
|
1069
|
+
const next = this.next_ds(this.elapsed_days, grade);
|
|
1047
1070
|
this.applyLearningSteps(next, grade, State.Learning);
|
|
1048
1071
|
const item = {
|
|
1049
1072
|
card: next,
|
|
@@ -1057,14 +1080,11 @@
|
|
|
1057
1080
|
if (exist) {
|
|
1058
1081
|
return exist;
|
|
1059
1082
|
}
|
|
1060
|
-
const
|
|
1061
|
-
const next = TypeConvert.card(this.current);
|
|
1062
|
-
next.difficulty = this.algorithm.next_difficulty(difficulty, grade);
|
|
1063
|
-
next.stability = this.algorithm.next_short_term_stability(stability, grade);
|
|
1083
|
+
const next = this.next_ds(this.elapsed_days, grade);
|
|
1064
1084
|
this.applyLearningSteps(
|
|
1065
1085
|
next,
|
|
1066
1086
|
grade,
|
|
1067
|
-
state
|
|
1087
|
+
this.last.state
|
|
1068
1088
|
/** Learning or Relearning */
|
|
1069
1089
|
);
|
|
1070
1090
|
const item = {
|
|
@@ -1080,21 +1100,14 @@
|
|
|
1080
1100
|
return exist;
|
|
1081
1101
|
}
|
|
1082
1102
|
const interval = this.elapsed_days;
|
|
1083
|
-
const
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
const next_hard = TypeConvert.card(this.current);
|
|
1087
|
-
const next_good = TypeConvert.card(this.current);
|
|
1088
|
-
const next_easy = TypeConvert.card(this.current);
|
|
1089
|
-
this.next_ds(
|
|
1090
|
-
next_again,
|
|
1091
|
-
next_hard,
|
|
1092
|
-
next_good,
|
|
1093
|
-
next_easy,
|
|
1094
|
-
difficulty,
|
|
1095
|
-
stability,
|
|
1096
|
-
retrievability
|
|
1103
|
+
const retrievability = this.algorithm.forgetting_curve(
|
|
1104
|
+
interval,
|
|
1105
|
+
this.current.stability
|
|
1097
1106
|
);
|
|
1107
|
+
const next_again = this.next_ds(interval, Rating.Again, retrievability);
|
|
1108
|
+
const next_hard = this.next_ds(interval, Rating.Hard, retrievability);
|
|
1109
|
+
const next_good = this.next_ds(interval, Rating.Good, retrievability);
|
|
1110
|
+
const next_easy = this.next_ds(interval, Rating.Easy, retrievability);
|
|
1098
1111
|
this.next_interval(next_hard, next_good, next_easy, interval);
|
|
1099
1112
|
this.next_state(next_hard, next_good, next_easy);
|
|
1100
1113
|
this.applyLearningSteps(next_again, Rating.Again, State.Relearning);
|
|
@@ -1124,50 +1137,20 @@
|
|
|
1124
1137
|
/**
|
|
1125
1138
|
* Review next_ds
|
|
1126
1139
|
*/
|
|
1127
|
-
next_ds(
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
difficulty,
|
|
1137
|
-
stability,
|
|
1138
|
-
retrievability
|
|
1139
|
-
);
|
|
1140
|
-
next_again.stability = clamp(+nextSMin.toFixed(8), S_MIN, s_after_fail);
|
|
1141
|
-
next_hard.difficulty = this.algorithm.next_difficulty(
|
|
1142
|
-
difficulty,
|
|
1143
|
-
Rating.Hard
|
|
1144
|
-
);
|
|
1145
|
-
next_hard.stability = this.algorithm.next_recall_stability(
|
|
1146
|
-
difficulty,
|
|
1147
|
-
stability,
|
|
1148
|
-
retrievability,
|
|
1149
|
-
Rating.Hard
|
|
1150
|
-
);
|
|
1151
|
-
next_good.difficulty = this.algorithm.next_difficulty(
|
|
1152
|
-
difficulty,
|
|
1153
|
-
Rating.Good
|
|
1154
|
-
);
|
|
1155
|
-
next_good.stability = this.algorithm.next_recall_stability(
|
|
1156
|
-
difficulty,
|
|
1157
|
-
stability,
|
|
1158
|
-
retrievability,
|
|
1159
|
-
Rating.Good
|
|
1160
|
-
);
|
|
1161
|
-
next_easy.difficulty = this.algorithm.next_difficulty(
|
|
1162
|
-
difficulty,
|
|
1163
|
-
Rating.Easy
|
|
1164
|
-
);
|
|
1165
|
-
next_easy.stability = this.algorithm.next_recall_stability(
|
|
1166
|
-
difficulty,
|
|
1167
|
-
stability,
|
|
1168
|
-
retrievability,
|
|
1169
|
-
Rating.Easy
|
|
1140
|
+
next_ds(t, g, r) {
|
|
1141
|
+
const next_state = this.algorithm.next_state(
|
|
1142
|
+
{
|
|
1143
|
+
difficulty: this.current.difficulty,
|
|
1144
|
+
stability: this.current.stability
|
|
1145
|
+
},
|
|
1146
|
+
t,
|
|
1147
|
+
g,
|
|
1148
|
+
r
|
|
1170
1149
|
);
|
|
1150
|
+
const card = TypeConvert.card(this.current);
|
|
1151
|
+
card.difficulty = next_state.difficulty;
|
|
1152
|
+
card.stability = next_state.stability;
|
|
1153
|
+
return card;
|
|
1171
1154
|
}
|
|
1172
1155
|
/**
|
|
1173
1156
|
* Review next_interval
|
|
@@ -1210,12 +1193,11 @@
|
|
|
1210
1193
|
}
|
|
1211
1194
|
this.current.scheduled_days = 0;
|
|
1212
1195
|
this.current.elapsed_days = 0;
|
|
1213
|
-
const next_again = TypeConvert.card(this.current);
|
|
1214
|
-
const next_hard = TypeConvert.card(this.current);
|
|
1215
|
-
const next_good = TypeConvert.card(this.current);
|
|
1216
|
-
const next_easy = TypeConvert.card(this.current);
|
|
1217
|
-
this.init_ds(next_again, next_hard, next_good, next_easy);
|
|
1218
1196
|
const first_interval = 0;
|
|
1197
|
+
const next_again = this.next_ds(first_interval, Rating.Again);
|
|
1198
|
+
const next_hard = this.next_ds(first_interval, Rating.Hard);
|
|
1199
|
+
const next_good = this.next_ds(first_interval, Rating.Good);
|
|
1200
|
+
const next_easy = this.next_ds(first_interval, Rating.Easy);
|
|
1219
1201
|
this.next_interval(
|
|
1220
1202
|
next_again,
|
|
1221
1203
|
next_hard,
|
|
@@ -1227,31 +1209,20 @@
|
|
|
1227
1209
|
this.update_next(next_again, next_hard, next_good, next_easy);
|
|
1228
1210
|
return this.next.get(grade);
|
|
1229
1211
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
1,
|
|
1240
|
-
10
|
|
1241
|
-
);
|
|
1242
|
-
next_hard.stability = this.algorithm.init_stability(Rating.Hard);
|
|
1243
|
-
next_good.difficulty = clamp(
|
|
1244
|
-
this.algorithm.init_difficulty(Rating.Good),
|
|
1245
|
-
1,
|
|
1246
|
-
10
|
|
1247
|
-
);
|
|
1248
|
-
next_good.stability = this.algorithm.init_stability(Rating.Good);
|
|
1249
|
-
next_easy.difficulty = clamp(
|
|
1250
|
-
this.algorithm.init_difficulty(Rating.Easy),
|
|
1251
|
-
1,
|
|
1252
|
-
10
|
|
1212
|
+
next_ds(t, g, r) {
|
|
1213
|
+
const next_state = this.algorithm.next_state(
|
|
1214
|
+
{
|
|
1215
|
+
difficulty: this.current.difficulty,
|
|
1216
|
+
stability: this.current.stability
|
|
1217
|
+
},
|
|
1218
|
+
t,
|
|
1219
|
+
g,
|
|
1220
|
+
r
|
|
1253
1221
|
);
|
|
1254
|
-
|
|
1222
|
+
const card = TypeConvert.card(this.current);
|
|
1223
|
+
card.difficulty = next_state.difficulty;
|
|
1224
|
+
card.stability = next_state.stability;
|
|
1225
|
+
return card;
|
|
1255
1226
|
}
|
|
1256
1227
|
/**
|
|
1257
1228
|
* @see https://github.com/open-spaced-repetition/ts-fsrs/issues/98#issuecomment-2241923194
|
|
@@ -1265,72 +1236,20 @@
|
|
|
1265
1236
|
return exist;
|
|
1266
1237
|
}
|
|
1267
1238
|
const interval = this.elapsed_days;
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
const next_hard = TypeConvert.card(this.current);
|
|
1272
|
-
const next_good = TypeConvert.card(this.current);
|
|
1273
|
-
const next_easy = TypeConvert.card(this.current);
|
|
1274
|
-
this.next_ds(
|
|
1275
|
-
next_again,
|
|
1276
|
-
next_hard,
|
|
1277
|
-
next_good,
|
|
1278
|
-
next_easy,
|
|
1279
|
-
difficulty,
|
|
1280
|
-
stability,
|
|
1281
|
-
retrievability
|
|
1239
|
+
const retrievability = this.algorithm.forgetting_curve(
|
|
1240
|
+
interval,
|
|
1241
|
+
this.current.stability
|
|
1282
1242
|
);
|
|
1243
|
+
const next_again = this.next_ds(interval, Rating.Again, retrievability);
|
|
1244
|
+
const next_hard = this.next_ds(interval, Rating.Hard, retrievability);
|
|
1245
|
+
const next_good = this.next_ds(interval, Rating.Good, retrievability);
|
|
1246
|
+
const next_easy = this.next_ds(interval, Rating.Easy, retrievability);
|
|
1283
1247
|
this.next_interval(next_again, next_hard, next_good, next_easy, interval);
|
|
1284
1248
|
this.next_state(next_again, next_hard, next_good, next_easy);
|
|
1285
1249
|
next_again.lapses += 1;
|
|
1286
1250
|
this.update_next(next_again, next_hard, next_good, next_easy);
|
|
1287
1251
|
return this.next.get(grade);
|
|
1288
1252
|
}
|
|
1289
|
-
/**
|
|
1290
|
-
* Review next_ds
|
|
1291
|
-
*/
|
|
1292
|
-
next_ds(next_again, next_hard, next_good, next_easy, difficulty, stability, retrievability) {
|
|
1293
|
-
next_again.difficulty = this.algorithm.next_difficulty(
|
|
1294
|
-
difficulty,
|
|
1295
|
-
Rating.Again
|
|
1296
|
-
);
|
|
1297
|
-
const s_after_fail = this.algorithm.next_forget_stability(
|
|
1298
|
-
difficulty,
|
|
1299
|
-
stability,
|
|
1300
|
-
retrievability
|
|
1301
|
-
);
|
|
1302
|
-
next_again.stability = clamp(stability, S_MIN, s_after_fail);
|
|
1303
|
-
next_hard.difficulty = this.algorithm.next_difficulty(
|
|
1304
|
-
difficulty,
|
|
1305
|
-
Rating.Hard
|
|
1306
|
-
);
|
|
1307
|
-
next_hard.stability = this.algorithm.next_recall_stability(
|
|
1308
|
-
difficulty,
|
|
1309
|
-
stability,
|
|
1310
|
-
retrievability,
|
|
1311
|
-
Rating.Hard
|
|
1312
|
-
);
|
|
1313
|
-
next_good.difficulty = this.algorithm.next_difficulty(
|
|
1314
|
-
difficulty,
|
|
1315
|
-
Rating.Good
|
|
1316
|
-
);
|
|
1317
|
-
next_good.stability = this.algorithm.next_recall_stability(
|
|
1318
|
-
difficulty,
|
|
1319
|
-
stability,
|
|
1320
|
-
retrievability,
|
|
1321
|
-
Rating.Good
|
|
1322
|
-
);
|
|
1323
|
-
next_easy.difficulty = this.algorithm.next_difficulty(
|
|
1324
|
-
difficulty,
|
|
1325
|
-
Rating.Easy
|
|
1326
|
-
);
|
|
1327
|
-
next_easy.stability = this.algorithm.next_recall_stability(
|
|
1328
|
-
difficulty,
|
|
1329
|
-
stability,
|
|
1330
|
-
retrievability,
|
|
1331
|
-
Rating.Easy
|
|
1332
|
-
);
|
|
1333
|
-
}
|
|
1334
1253
|
/**
|
|
1335
1254
|
* Review/New next_interval
|
|
1336
1255
|
*/
|
|
@@ -2055,6 +1974,7 @@
|
|
|
2055
1974
|
exports.generatorParameters = generatorParameters;
|
|
2056
1975
|
exports.get_fuzz_range = get_fuzz_range;
|
|
2057
1976
|
exports.migrateParameters = migrateParameters;
|
|
1977
|
+
exports.roundTo = roundTo;
|
|
2058
1978
|
exports.show_diff_message = show_diff_message;
|
|
2059
1979
|
|
|
2060
1980
|
}));
|