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/dist/index.d.ts CHANGED
@@ -325,9 +325,10 @@ declare class FSRSAlgorithm {
325
325
  * @param memory_state - The current state of memory, which can be null.
326
326
  * @param t - The time elapsed since the last review.
327
327
  * @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])
328
+ * @param r - Optional retrievability value. If not provided, it will be calculated.
328
329
  * @returns The next state of memory with updated difficulty and stability.
329
330
  */
330
- next_state(memory_state: FSRSState | null, t: number, g: number): FSRSState;
331
+ next_state(memory_state: FSRSState | null, t: number, g: number, r?: number): FSRSState;
331
332
  }
332
333
 
333
334
  declare enum StrategyMode {
@@ -560,6 +561,7 @@ declare function get_fuzz_range(interval: number, elapsed_days: number, maximum_
560
561
  max_ivl: number;
561
562
  };
562
563
  declare function clamp(value: number, min: number, max: number): number;
564
+ declare function roundTo(num: number, decimals: number): number;
563
565
  declare function dateDiffInDays(last: Date, cur: Date): number;
564
566
 
565
567
  declare const ConvertStepUnitToMinutes: (step: StepUnit) => number;
@@ -587,5 +589,5 @@ declare function DefaultInitSeedStrategy(this: AbstractScheduler): string;
587
589
  */
588
590
  declare function GenSeedStrategyWithCardId(card_id_field: string | number): TSeedStrategy;
589
591
 
590
- export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, show_diff_message };
592
+ export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, roundTo, show_diff_message };
591
593
  export type { Card, CardInput, DateInput, FSRSHistory, FSRSParameters, FSRSReview, FSRSState, Grade, GradeType, IFSRS, IPreview, IReschedule, IScheduler, RatingType, RecordLog, RecordLogItem, RescheduleOptions, ReviewLog, ReviewLogInput, StateType, StepUnit, Steps, TLearningStepsStrategy, TSchedulerStrategy, TSeedStrategy, TStrategyHandler, TimeUnit, double, int, unit };
package/dist/index.mjs CHANGED
@@ -52,8 +52,12 @@ class TypeConvert {
52
52
  throw new Error(`Invalid state:[${value}]`);
53
53
  }
54
54
  static time(value) {
55
- if (typeof value === "object" && value instanceof Date) {
55
+ if (value instanceof Date) {
56
56
  return value;
57
+ }
58
+ const date = new Date(value);
59
+ if (typeof value === "object" && value !== null && !Number.isNaN(Date.parse(value) || +date)) {
60
+ return date;
57
61
  } else if (typeof value === "string") {
58
62
  const timestamp = Date.parse(value);
59
63
  if (!Number.isNaN(timestamp)) {
@@ -77,15 +81,19 @@ class TypeConvert {
77
81
  }
78
82
  }
79
83
 
84
+ /* istanbul ignore next -- @preserve */
80
85
  Date.prototype.scheduler = function(t, isDay) {
81
86
  return date_scheduler(this, t, isDay);
82
87
  };
88
+ /* istanbul ignore next -- @preserve */
83
89
  Date.prototype.diff = function(pre, unit) {
84
90
  return date_diff(this, pre, unit);
85
91
  };
92
+ /* istanbul ignore next -- @preserve */
86
93
  Date.prototype.format = function() {
87
94
  return formatDate(this);
88
95
  };
96
+ /* istanbul ignore next -- @preserve */
89
97
  Date.prototype.dueFormat = function(last_review, unit, timeUnit) {
90
98
  return show_diff_message(this, last_review, unit, timeUnit);
91
99
  };
@@ -145,12 +153,15 @@ function show_diff_message(due, last_review, unit, timeUnit = TIMEUNITFORMAT) {
145
153
  }
146
154
  return `${Math.floor(diff)}${unit ? timeUnit[i] : ""}`;
147
155
  }
156
+ /* istanbul ignore next -- @preserve */
148
157
  function fixDate(value) {
149
158
  return TypeConvert.time(value);
150
159
  }
160
+ /* istanbul ignore next -- @preserve */
151
161
  function fixState(value) {
152
162
  return TypeConvert.state(value);
153
163
  }
164
+ /* istanbul ignore next -- @preserve */
154
165
  function fixRating(value) {
155
166
  return TypeConvert.rating(value);
156
167
  }
@@ -194,6 +205,10 @@ function get_fuzz_range(interval, elapsed_days, maximum_interval) {
194
205
  function clamp(value, min, max) {
195
206
  return Math.min(Math.max(value, min), max);
196
207
  }
208
+ function roundTo(num, decimals) {
209
+ const factor = 10 ** decimals;
210
+ return Math.round(num * factor) / factor;
211
+ }
197
212
  function dateDiffInDays(last, cur) {
198
213
  const utc1 = Date.UTC(
199
214
  last.getUTCFullYear(),
@@ -466,7 +481,7 @@ function alea(seed) {
466
481
  return prng;
467
482
  }
468
483
 
469
- const version="5.2.2";
484
+ const version="5.3.0";
470
485
 
471
486
  const default_request_retention = 0.9;
472
487
  const default_maximum_interval = 36500;
@@ -640,11 +655,11 @@ function createEmptyCard(now, afterHandler) {
640
655
  const computeDecayFactor = (decayOrParams) => {
641
656
  const decay = typeof decayOrParams === "number" ? -decayOrParams : -decayOrParams[20];
642
657
  const factor = Math.exp(Math.pow(decay, -1) * Math.log(0.9)) - 1;
643
- return { decay, factor: +factor.toFixed(8) };
658
+ return { decay, factor: roundTo(factor, 8) };
644
659
  };
645
660
  function forgetting_curve(decayOrParams, elapsed_days, stability) {
646
661
  const { decay, factor } = computeDecayFactor(decayOrParams);
647
- return +Math.pow(1 + factor * elapsed_days / stability, decay).toFixed(8);
662
+ return roundTo(Math.pow(1 + factor * elapsed_days / stability, decay), 8);
648
663
  }
649
664
  class FSRSAlgorithm {
650
665
  param;
@@ -678,7 +693,7 @@ class FSRSAlgorithm {
678
693
  throw new Error("Requested retention rate should be in the range (0,1]");
679
694
  }
680
695
  const { decay, factor } = computeDecayFactor(this.param.w);
681
- return +((Math.pow(request_retention, 1 / decay) - 1) / factor).toFixed(8);
696
+ return roundTo((Math.pow(request_retention, 1 / decay) - 1) / factor, 8);
682
697
  }
683
698
  /**
684
699
  * Get the parameters of the algorithm.
@@ -745,8 +760,9 @@ class FSRSAlgorithm {
745
760
  * @return {number} Difficulty $$D \in [1,10]$$
746
761
  */
747
762
  init_difficulty(g) {
748
- const d = this.param.w[4] - Math.exp((g - 1) * this.param.w[5]) + 1;
749
- return +d.toFixed(8);
763
+ const w = this.param.w;
764
+ const d = w[4] - Math.exp((g - 1) * w[5]) + 1;
765
+ return roundTo(d, 8);
750
766
  }
751
767
  /**
752
768
  * If fuzzing is disabled or ivl is less than 2.5, it returns the original interval.
@@ -781,7 +797,7 @@ class FSRSAlgorithm {
781
797
  * @see https://github.com/open-spaced-repetition/fsrs4anki/issues/697
782
798
  */
783
799
  linear_damping(delta_d, old_d) {
784
- return +(delta_d * (10 - old_d) / 9).toFixed(8);
800
+ return roundTo(delta_d * (10 - old_d) / 9, 8);
785
801
  }
786
802
  /**
787
803
  * The formula used is :
@@ -809,9 +825,8 @@ class FSRSAlgorithm {
809
825
  * @return {number} difficulty
810
826
  */
811
827
  mean_reversion(init, current) {
812
- return +(this.param.w[7] * init + (1 - this.param.w[7]) * current).toFixed(
813
- 8
814
- );
828
+ const w = this.param.w;
829
+ return roundTo(w[7] * init + (1 - w[7]) * current, 8);
815
830
  }
816
831
  /**
817
832
  * The formula used is :
@@ -823,13 +838,17 @@ class FSRSAlgorithm {
823
838
  * @return {number} S^\prime_r new stability after recall
824
839
  */
825
840
  next_recall_stability(d, s, r, g) {
826
- const hard_penalty = Rating.Hard === g ? this.param.w[15] : 1;
827
- const easy_bound = Rating.Easy === g ? this.param.w[16] : 1;
828
- return +clamp(
829
- s * (1 + Math.exp(this.param.w[8]) * (11 - d) * Math.pow(s, -this.param.w[9]) * (Math.exp((1 - r) * this.param.w[10]) - 1) * hard_penalty * easy_bound),
830
- S_MIN,
831
- 36500
832
- ).toFixed(8);
841
+ const w = this.param.w;
842
+ const hard_penalty = Rating.Hard === g ? w[15] : 1;
843
+ const easy_bound = Rating.Easy === g ? w[16] : 1;
844
+ return roundTo(
845
+ clamp(
846
+ s * (1 + Math.exp(w[8]) * (11 - d) * Math.pow(s, -w[9]) * (Math.exp((1 - r) * w[10]) - 1) * hard_penalty * easy_bound),
847
+ S_MIN,
848
+ 36500
849
+ ),
850
+ 8
851
+ );
833
852
  }
834
853
  /**
835
854
  * The formula used is :
@@ -842,11 +861,15 @@ class FSRSAlgorithm {
842
861
  * @return {number} S^\prime_f new stability after forgetting
843
862
  */
844
863
  next_forget_stability(d, s, r) {
845
- return +clamp(
846
- this.param.w[11] * Math.pow(d, -this.param.w[12]) * (Math.pow(s + 1, this.param.w[13]) - 1) * Math.exp((1 - r) * this.param.w[14]),
847
- S_MIN,
848
- 36500
849
- ).toFixed(8);
864
+ const w = this.param.w;
865
+ return roundTo(
866
+ clamp(
867
+ w[11] * Math.pow(d, -w[12]) * (Math.pow(s + 1, w[13]) - 1) * Math.exp((1 - r) * w[14]),
868
+ S_MIN,
869
+ 36500
870
+ ),
871
+ 8
872
+ );
850
873
  }
851
874
  /**
852
875
  * The formula used is :
@@ -855,9 +878,10 @@ class FSRSAlgorithm {
855
878
  * @param {Grade} g Grade (Rating[0.again,1.hard,2.good,3.easy])
856
879
  */
857
880
  next_short_term_stability(s, g) {
858
- const sinc = Math.pow(s, -this.param.w[19]) * Math.exp(this.param.w[17] * (g - 3 + this.param.w[18]));
859
- const maskedSinc = g >= 3 ? Math.max(sinc, 1) : sinc;
860
- return +clamp(s * maskedSinc, S_MIN, 36500).toFixed(8);
881
+ const w = this.param.w;
882
+ const sinc = Math.pow(s, -w[19]) * Math.exp(w[17] * (g - 3 + w[18]));
883
+ const maskedSinc = g >= Rating.Hard ? Math.max(sinc, 1) : sinc;
884
+ return roundTo(clamp(s * maskedSinc, S_MIN, 36500), 8);
861
885
  }
862
886
  /**
863
887
  * The formula used is :
@@ -873,9 +897,10 @@ class FSRSAlgorithm {
873
897
  * @param memory_state - The current state of memory, which can be null.
874
898
  * @param t - The time elapsed since the last review.
875
899
  * @param {Rating} g Grade (Rating[0.Manual,1.Again,2.Hard,3.Good,4.Easy])
900
+ * @param r - Optional retrievability value. If not provided, it will be calculated.
876
901
  * @returns The next state of memory with updated difficulty and stability.
877
902
  */
878
- next_state(memory_state, t, g) {
903
+ next_state(memory_state, t, g, r) {
879
904
  const { difficulty: d, stability: s } = memory_state ?? {
880
905
  difficulty: 0,
881
906
  stability: 0
@@ -903,22 +928,22 @@ class FSRSAlgorithm {
903
928
  `Invalid memory state { difficulty: ${d}, stability: ${s} }`
904
929
  );
905
930
  }
906
- const r = this.forgetting_curve(t, s);
907
- const s_after_success = this.next_recall_stability(d, s, r, g);
908
- const s_after_fail = this.next_forget_stability(d, s, r);
909
- const s_after_short_term = this.next_short_term_stability(s, g);
910
- let new_s = s_after_success;
911
- if (g === 1) {
931
+ const w = this.param.w;
932
+ r = typeof r === "number" ? r : this.forgetting_curve(t, s);
933
+ let new_s;
934
+ if (t === 0 && this.param.enable_short_term) {
935
+ new_s = this.next_short_term_stability(s, g);
936
+ } else if (g === 1) {
937
+ const s_after_fail = this.next_forget_stability(d, s, r);
912
938
  let [w_17, w_18] = [0, 0];
913
939
  if (this.param.enable_short_term) {
914
- w_17 = this.param.w[17];
915
- w_18 = this.param.w[18];
940
+ w_17 = w[17];
941
+ w_18 = w[18];
916
942
  }
917
943
  const next_s_min = s / Math.exp(w_17 * w_18);
918
- new_s = clamp(+next_s_min.toFixed(8), S_MIN, s_after_fail);
919
- }
920
- if (t === 0 && this.param.enable_short_term) {
921
- new_s = s_after_short_term;
944
+ new_s = clamp(roundTo(next_s_min, 8), S_MIN, s_after_fail);
945
+ } else {
946
+ new_s = this.next_recall_stability(d, s, r, g);
922
947
  }
923
948
  const new_d = this.next_difficulty(d, g);
924
949
  return { difficulty: new_d, stability: new_s };
@@ -1003,9 +1028,7 @@ class BasicScheduler extends AbstractScheduler {
1003
1028
  if (exist) {
1004
1029
  return exist;
1005
1030
  }
1006
- const next = TypeConvert.card(this.current);
1007
- next.difficulty = clamp(this.algorithm.init_difficulty(grade), 1, 10);
1008
- next.stability = this.algorithm.init_stability(grade);
1031
+ const next = this.next_ds(this.elapsed_days, grade);
1009
1032
  this.applyLearningSteps(next, grade, State.Learning);
1010
1033
  const item = {
1011
1034
  card: next,
@@ -1019,14 +1042,11 @@ class BasicScheduler extends AbstractScheduler {
1019
1042
  if (exist) {
1020
1043
  return exist;
1021
1044
  }
1022
- const { state, difficulty, stability } = this.last;
1023
- const next = TypeConvert.card(this.current);
1024
- next.difficulty = this.algorithm.next_difficulty(difficulty, grade);
1025
- next.stability = this.algorithm.next_short_term_stability(stability, grade);
1045
+ const next = this.next_ds(this.elapsed_days, grade);
1026
1046
  this.applyLearningSteps(
1027
1047
  next,
1028
1048
  grade,
1029
- state
1049
+ this.last.state
1030
1050
  /** Learning or Relearning */
1031
1051
  );
1032
1052
  const item = {
@@ -1042,21 +1062,14 @@ class BasicScheduler extends AbstractScheduler {
1042
1062
  return exist;
1043
1063
  }
1044
1064
  const interval = this.elapsed_days;
1045
- const { difficulty, stability } = this.last;
1046
- const retrievability = this.algorithm.forgetting_curve(interval, stability);
1047
- const next_again = TypeConvert.card(this.current);
1048
- const next_hard = TypeConvert.card(this.current);
1049
- const next_good = TypeConvert.card(this.current);
1050
- const next_easy = TypeConvert.card(this.current);
1051
- this.next_ds(
1052
- next_again,
1053
- next_hard,
1054
- next_good,
1055
- next_easy,
1056
- difficulty,
1057
- stability,
1058
- retrievability
1065
+ const retrievability = this.algorithm.forgetting_curve(
1066
+ interval,
1067
+ this.current.stability
1059
1068
  );
1069
+ const next_again = this.next_ds(interval, Rating.Again, retrievability);
1070
+ const next_hard = this.next_ds(interval, Rating.Hard, retrievability);
1071
+ const next_good = this.next_ds(interval, Rating.Good, retrievability);
1072
+ const next_easy = this.next_ds(interval, Rating.Easy, retrievability);
1060
1073
  this.next_interval(next_hard, next_good, next_easy, interval);
1061
1074
  this.next_state(next_hard, next_good, next_easy);
1062
1075
  this.applyLearningSteps(next_again, Rating.Again, State.Relearning);
@@ -1086,50 +1099,20 @@ class BasicScheduler extends AbstractScheduler {
1086
1099
  /**
1087
1100
  * Review next_ds
1088
1101
  */
1089
- next_ds(next_again, next_hard, next_good, next_easy, difficulty, stability, retrievability) {
1090
- next_again.difficulty = this.algorithm.next_difficulty(
1091
- difficulty,
1092
- Rating.Again
1093
- );
1094
- const nextSMin = stability / Math.exp(
1095
- this.algorithm.parameters.w[17] * this.algorithm.parameters.w[18]
1096
- );
1097
- const s_after_fail = this.algorithm.next_forget_stability(
1098
- difficulty,
1099
- stability,
1100
- retrievability
1101
- );
1102
- next_again.stability = clamp(+nextSMin.toFixed(8), S_MIN, s_after_fail);
1103
- next_hard.difficulty = this.algorithm.next_difficulty(
1104
- difficulty,
1105
- Rating.Hard
1106
- );
1107
- next_hard.stability = this.algorithm.next_recall_stability(
1108
- difficulty,
1109
- stability,
1110
- retrievability,
1111
- Rating.Hard
1112
- );
1113
- next_good.difficulty = this.algorithm.next_difficulty(
1114
- difficulty,
1115
- Rating.Good
1116
- );
1117
- next_good.stability = this.algorithm.next_recall_stability(
1118
- difficulty,
1119
- stability,
1120
- retrievability,
1121
- Rating.Good
1122
- );
1123
- next_easy.difficulty = this.algorithm.next_difficulty(
1124
- difficulty,
1125
- Rating.Easy
1126
- );
1127
- next_easy.stability = this.algorithm.next_recall_stability(
1128
- difficulty,
1129
- stability,
1130
- retrievability,
1131
- Rating.Easy
1102
+ next_ds(t, g, r) {
1103
+ const next_state = this.algorithm.next_state(
1104
+ {
1105
+ difficulty: this.current.difficulty,
1106
+ stability: this.current.stability
1107
+ },
1108
+ t,
1109
+ g,
1110
+ r
1132
1111
  );
1112
+ const card = TypeConvert.card(this.current);
1113
+ card.difficulty = next_state.difficulty;
1114
+ card.stability = next_state.stability;
1115
+ return card;
1133
1116
  }
1134
1117
  /**
1135
1118
  * Review next_interval
@@ -1172,12 +1155,11 @@ class LongTermScheduler extends AbstractScheduler {
1172
1155
  }
1173
1156
  this.current.scheduled_days = 0;
1174
1157
  this.current.elapsed_days = 0;
1175
- const next_again = TypeConvert.card(this.current);
1176
- const next_hard = TypeConvert.card(this.current);
1177
- const next_good = TypeConvert.card(this.current);
1178
- const next_easy = TypeConvert.card(this.current);
1179
- this.init_ds(next_again, next_hard, next_good, next_easy);
1180
1158
  const first_interval = 0;
1159
+ const next_again = this.next_ds(first_interval, Rating.Again);
1160
+ const next_hard = this.next_ds(first_interval, Rating.Hard);
1161
+ const next_good = this.next_ds(first_interval, Rating.Good);
1162
+ const next_easy = this.next_ds(first_interval, Rating.Easy);
1181
1163
  this.next_interval(
1182
1164
  next_again,
1183
1165
  next_hard,
@@ -1189,31 +1171,20 @@ class LongTermScheduler extends AbstractScheduler {
1189
1171
  this.update_next(next_again, next_hard, next_good, next_easy);
1190
1172
  return this.next.get(grade);
1191
1173
  }
1192
- init_ds(next_again, next_hard, next_good, next_easy) {
1193
- next_again.difficulty = clamp(
1194
- this.algorithm.init_difficulty(Rating.Again),
1195
- 1,
1196
- 10
1197
- );
1198
- next_again.stability = this.algorithm.init_stability(Rating.Again);
1199
- next_hard.difficulty = clamp(
1200
- this.algorithm.init_difficulty(Rating.Hard),
1201
- 1,
1202
- 10
1203
- );
1204
- next_hard.stability = this.algorithm.init_stability(Rating.Hard);
1205
- next_good.difficulty = clamp(
1206
- this.algorithm.init_difficulty(Rating.Good),
1207
- 1,
1208
- 10
1209
- );
1210
- next_good.stability = this.algorithm.init_stability(Rating.Good);
1211
- next_easy.difficulty = clamp(
1212
- this.algorithm.init_difficulty(Rating.Easy),
1213
- 1,
1214
- 10
1174
+ next_ds(t, g, r) {
1175
+ const next_state = this.algorithm.next_state(
1176
+ {
1177
+ difficulty: this.current.difficulty,
1178
+ stability: this.current.stability
1179
+ },
1180
+ t,
1181
+ g,
1182
+ r
1215
1183
  );
1216
- next_easy.stability = this.algorithm.init_stability(Rating.Easy);
1184
+ const card = TypeConvert.card(this.current);
1185
+ card.difficulty = next_state.difficulty;
1186
+ card.stability = next_state.stability;
1187
+ return card;
1217
1188
  }
1218
1189
  /**
1219
1190
  * @see https://github.com/open-spaced-repetition/ts-fsrs/issues/98#issuecomment-2241923194
@@ -1227,72 +1198,20 @@ class LongTermScheduler extends AbstractScheduler {
1227
1198
  return exist;
1228
1199
  }
1229
1200
  const interval = this.elapsed_days;
1230
- const { difficulty, stability } = this.last;
1231
- const retrievability = this.algorithm.forgetting_curve(interval, stability);
1232
- const next_again = TypeConvert.card(this.current);
1233
- const next_hard = TypeConvert.card(this.current);
1234
- const next_good = TypeConvert.card(this.current);
1235
- const next_easy = TypeConvert.card(this.current);
1236
- this.next_ds(
1237
- next_again,
1238
- next_hard,
1239
- next_good,
1240
- next_easy,
1241
- difficulty,
1242
- stability,
1243
- retrievability
1201
+ const retrievability = this.algorithm.forgetting_curve(
1202
+ interval,
1203
+ this.current.stability
1244
1204
  );
1205
+ const next_again = this.next_ds(interval, Rating.Again, retrievability);
1206
+ const next_hard = this.next_ds(interval, Rating.Hard, retrievability);
1207
+ const next_good = this.next_ds(interval, Rating.Good, retrievability);
1208
+ const next_easy = this.next_ds(interval, Rating.Easy, retrievability);
1245
1209
  this.next_interval(next_again, next_hard, next_good, next_easy, interval);
1246
1210
  this.next_state(next_again, next_hard, next_good, next_easy);
1247
1211
  next_again.lapses += 1;
1248
1212
  this.update_next(next_again, next_hard, next_good, next_easy);
1249
1213
  return this.next.get(grade);
1250
1214
  }
1251
- /**
1252
- * Review next_ds
1253
- */
1254
- next_ds(next_again, next_hard, next_good, next_easy, difficulty, stability, retrievability) {
1255
- next_again.difficulty = this.algorithm.next_difficulty(
1256
- difficulty,
1257
- Rating.Again
1258
- );
1259
- const s_after_fail = this.algorithm.next_forget_stability(
1260
- difficulty,
1261
- stability,
1262
- retrievability
1263
- );
1264
- next_again.stability = clamp(stability, S_MIN, s_after_fail);
1265
- next_hard.difficulty = this.algorithm.next_difficulty(
1266
- difficulty,
1267
- Rating.Hard
1268
- );
1269
- next_hard.stability = this.algorithm.next_recall_stability(
1270
- difficulty,
1271
- stability,
1272
- retrievability,
1273
- Rating.Hard
1274
- );
1275
- next_good.difficulty = this.algorithm.next_difficulty(
1276
- difficulty,
1277
- Rating.Good
1278
- );
1279
- next_good.stability = this.algorithm.next_recall_stability(
1280
- difficulty,
1281
- stability,
1282
- retrievability,
1283
- Rating.Good
1284
- );
1285
- next_easy.difficulty = this.algorithm.next_difficulty(
1286
- difficulty,
1287
- Rating.Easy
1288
- );
1289
- next_easy.stability = this.algorithm.next_recall_stability(
1290
- difficulty,
1291
- stability,
1292
- retrievability,
1293
- Rating.Easy
1294
- );
1295
- }
1296
1215
  /**
1297
1216
  * Review/New next_interval
1298
1217
  */
@@ -1936,5 +1855,5 @@ const fsrs = (params) => {
1936
1855
  return new FSRS(params || {});
1937
1856
  };
1938
1857
 
1939
- export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, show_diff_message };
1858
+ export { AbstractScheduler, BasicLearningStepsStrategy, CLAMP_PARAMETERS, ConvertStepUnitToMinutes, DefaultInitSeedStrategy, FSRS, FSRS5_DEFAULT_DECAY, FSRS6_DEFAULT_DECAY, FSRSAlgorithm, FSRSVersion, GenSeedStrategyWithCardId, Grades, INIT_S_MAX, Rating, S_MAX, S_MIN, State, StrategyMode, TypeConvert, W17_W18_Ceiling, checkParameters, clamp, clipParameters, computeDecayFactor, createEmptyCard, dateDiffInDays, date_diff, date_scheduler, default_enable_fuzz, default_enable_short_term, default_learning_steps, default_maximum_interval, default_relearning_steps, default_request_retention, default_w, fixDate, fixRating, fixState, forgetting_curve, formatDate, fsrs, generatorParameters, get_fuzz_range, migrateParameters, roundTo, show_diff_message };
1940
1859
  //# sourceMappingURL=index.mjs.map