@contractspec/module.learning-journey 3.7.6 → 3.7.7
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/README.md +65 -188
- package/dist/browser/contracts/index.js +148 -148
- package/dist/browser/contracts/models.js +1 -1
- package/dist/browser/contracts/onboarding.js +5 -5
- package/dist/browser/contracts/operations.js +4 -4
- package/dist/browser/engines/index.js +173 -173
- package/dist/browser/engines/xp.js +18 -18
- package/dist/browser/events.js +1 -1
- package/dist/browser/i18n/catalogs/index.js +18 -18
- package/dist/browser/i18n/index.js +26 -26
- package/dist/browser/i18n/locale.js +2 -2
- package/dist/browser/i18n/messages.js +18 -18
- package/dist/browser/index.js +336 -335
- package/dist/contracts/index.d.ts +2 -2
- package/dist/contracts/index.js +148 -148
- package/dist/contracts/models.js +1 -1
- package/dist/contracts/onboarding.js +5 -5
- package/dist/contracts/operations.js +4 -4
- package/dist/engines/index.d.ts +1 -1
- package/dist/engines/index.js +173 -173
- package/dist/engines/xp.js +18 -18
- package/dist/events.js +1 -1
- package/dist/i18n/catalogs/index.d.ts +1 -1
- package/dist/i18n/catalogs/index.js +18 -18
- package/dist/i18n/index.d.ts +7 -7
- package/dist/i18n/index.js +26 -26
- package/dist/i18n/locale.d.ts +1 -1
- package/dist/i18n/locale.js +2 -2
- package/dist/i18n/messages.js +18 -18
- package/dist/index.d.ts +3 -3
- package/dist/index.js +336 -335
- package/dist/node/contracts/index.js +148 -148
- package/dist/node/contracts/models.js +1 -1
- package/dist/node/contracts/onboarding.js +5 -5
- package/dist/node/contracts/operations.js +4 -4
- package/dist/node/engines/index.js +173 -173
- package/dist/node/engines/xp.js +18 -18
- package/dist/node/events.js +1 -1
- package/dist/node/i18n/catalogs/index.js +18 -18
- package/dist/node/i18n/index.js +26 -26
- package/dist/node/i18n/locale.js +2 -2
- package/dist/node/i18n/messages.js +18 -18
- package/dist/node/index.js +336 -335
- package/package.json +4 -4
|
@@ -192,6 +192,161 @@ class SRSEngine {
|
|
|
192
192
|
}
|
|
193
193
|
var srsEngine = new SRSEngine;
|
|
194
194
|
|
|
195
|
+
// src/engines/streak.ts
|
|
196
|
+
var DEFAULT_STREAK_CONFIG = {
|
|
197
|
+
timezone: "UTC",
|
|
198
|
+
freezesPerMonth: 2,
|
|
199
|
+
maxFreezes: 5,
|
|
200
|
+
gracePeriodHours: 4
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
class StreakEngine {
|
|
204
|
+
config;
|
|
205
|
+
constructor(config = {}) {
|
|
206
|
+
this.config = { ...DEFAULT_STREAK_CONFIG, ...config };
|
|
207
|
+
}
|
|
208
|
+
update(state, now = new Date) {
|
|
209
|
+
const todayDate = this.getDateString(now);
|
|
210
|
+
const result = {
|
|
211
|
+
state: { ...state },
|
|
212
|
+
streakMaintained: false,
|
|
213
|
+
streakLost: false,
|
|
214
|
+
freezeUsed: false,
|
|
215
|
+
newStreak: false,
|
|
216
|
+
daysMissed: 0
|
|
217
|
+
};
|
|
218
|
+
if (!state.lastActivityDate) {
|
|
219
|
+
result.state.currentStreak = 1;
|
|
220
|
+
result.state.longestStreak = Math.max(1, state.longestStreak);
|
|
221
|
+
result.state.lastActivityAt = now;
|
|
222
|
+
result.state.lastActivityDate = todayDate;
|
|
223
|
+
result.newStreak = true;
|
|
224
|
+
result.streakMaintained = true;
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
if (state.lastActivityDate === todayDate) {
|
|
228
|
+
result.state.lastActivityAt = now;
|
|
229
|
+
result.streakMaintained = true;
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
const daysSinceActivity = this.getDaysBetween(state.lastActivityDate, todayDate);
|
|
233
|
+
if (daysSinceActivity === 1) {
|
|
234
|
+
result.state.currentStreak = state.currentStreak + 1;
|
|
235
|
+
result.state.longestStreak = Math.max(result.state.currentStreak, state.longestStreak);
|
|
236
|
+
result.state.lastActivityAt = now;
|
|
237
|
+
result.state.lastActivityDate = todayDate;
|
|
238
|
+
result.streakMaintained = true;
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
result.daysMissed = daysSinceActivity - 1;
|
|
242
|
+
const freezesNeeded = result.daysMissed;
|
|
243
|
+
if (freezesNeeded <= state.freezesRemaining) {
|
|
244
|
+
result.state.freezesRemaining = state.freezesRemaining - freezesNeeded;
|
|
245
|
+
result.state.freezeUsedAt = now;
|
|
246
|
+
result.state.currentStreak = state.currentStreak + 1;
|
|
247
|
+
result.state.longestStreak = Math.max(result.state.currentStreak, state.longestStreak);
|
|
248
|
+
result.state.lastActivityAt = now;
|
|
249
|
+
result.state.lastActivityDate = todayDate;
|
|
250
|
+
result.freezeUsed = true;
|
|
251
|
+
result.streakMaintained = true;
|
|
252
|
+
return result;
|
|
253
|
+
}
|
|
254
|
+
result.streakLost = true;
|
|
255
|
+
result.state.currentStreak = 1;
|
|
256
|
+
result.state.lastActivityAt = now;
|
|
257
|
+
result.state.lastActivityDate = todayDate;
|
|
258
|
+
result.newStreak = true;
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
checkStatus(state, now = new Date) {
|
|
262
|
+
if (!state.lastActivityDate) {
|
|
263
|
+
return {
|
|
264
|
+
isActive: false,
|
|
265
|
+
willExpireAt: null,
|
|
266
|
+
canUseFreeze: false,
|
|
267
|
+
daysUntilExpiry: 0
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const todayDate = this.getDateString(now);
|
|
271
|
+
const daysSinceActivity = this.getDaysBetween(state.lastActivityDate, todayDate);
|
|
272
|
+
if (daysSinceActivity === 0) {
|
|
273
|
+
const tomorrow = this.addDays(now, 1);
|
|
274
|
+
tomorrow.setHours(23, 59, 59, 999);
|
|
275
|
+
return {
|
|
276
|
+
isActive: true,
|
|
277
|
+
willExpireAt: tomorrow,
|
|
278
|
+
canUseFreeze: state.freezesRemaining > 0,
|
|
279
|
+
daysUntilExpiry: 1
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if (daysSinceActivity === 1) {
|
|
283
|
+
const endOfDay = new Date(now);
|
|
284
|
+
endOfDay.setHours(23 + this.config.gracePeriodHours, 59, 59, 999);
|
|
285
|
+
return {
|
|
286
|
+
isActive: true,
|
|
287
|
+
willExpireAt: endOfDay,
|
|
288
|
+
canUseFreeze: state.freezesRemaining > 0,
|
|
289
|
+
daysUntilExpiry: 0
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
const missedDays = daysSinceActivity - 1;
|
|
293
|
+
return {
|
|
294
|
+
isActive: missedDays <= state.freezesRemaining,
|
|
295
|
+
willExpireAt: null,
|
|
296
|
+
canUseFreeze: missedDays <= state.freezesRemaining,
|
|
297
|
+
daysUntilExpiry: -missedDays
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
useFreeze(state, now = new Date) {
|
|
301
|
+
if (state.freezesRemaining <= 0) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
...state,
|
|
306
|
+
freezesRemaining: state.freezesRemaining - 1,
|
|
307
|
+
freezeUsedAt: now
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
awardMonthlyFreezes(state) {
|
|
311
|
+
return {
|
|
312
|
+
...state,
|
|
313
|
+
freezesRemaining: Math.min(state.freezesRemaining + this.config.freezesPerMonth, this.config.maxFreezes)
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
getInitialState() {
|
|
317
|
+
return {
|
|
318
|
+
currentStreak: 0,
|
|
319
|
+
longestStreak: 0,
|
|
320
|
+
lastActivityAt: null,
|
|
321
|
+
lastActivityDate: null,
|
|
322
|
+
freezesRemaining: this.config.freezesPerMonth,
|
|
323
|
+
freezeUsedAt: null
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
getMilestones(currentStreak) {
|
|
327
|
+
const milestones = [3, 7, 14, 30, 60, 90, 180, 365, 500, 1000];
|
|
328
|
+
const achieved = milestones.filter((m) => currentStreak >= m);
|
|
329
|
+
const next = milestones.find((m) => currentStreak < m) ?? null;
|
|
330
|
+
return { achieved, next };
|
|
331
|
+
}
|
|
332
|
+
getDateString(date) {
|
|
333
|
+
const year = date.getFullYear();
|
|
334
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
335
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
336
|
+
return `${year}-${month}-${day}`;
|
|
337
|
+
}
|
|
338
|
+
getDaysBetween(dateStr1, dateStr2) {
|
|
339
|
+
const date1 = new Date(dateStr1);
|
|
340
|
+
const date2 = new Date(dateStr2);
|
|
341
|
+
const diffTime = date2.getTime() - date1.getTime();
|
|
342
|
+
return Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
343
|
+
}
|
|
344
|
+
addDays(date, days) {
|
|
345
|
+
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
var streakEngine = new StreakEngine;
|
|
349
|
+
|
|
195
350
|
// src/i18n/catalogs/en.ts
|
|
196
351
|
import { defineTranslation } from "@contractspec/lib.contracts-spec/translations";
|
|
197
352
|
var enMessages = defineTranslation({
|
|
@@ -233,18 +388,18 @@ var enMessages = defineTranslation({
|
|
|
233
388
|
}
|
|
234
389
|
});
|
|
235
390
|
|
|
236
|
-
// src/i18n/catalogs/
|
|
391
|
+
// src/i18n/catalogs/es.ts
|
|
237
392
|
import { defineTranslation as defineTranslation2 } from "@contractspec/lib.contracts-spec/translations";
|
|
238
|
-
var
|
|
393
|
+
var esMessages = defineTranslation2({
|
|
239
394
|
meta: {
|
|
240
395
|
key: "learning-journey.messages",
|
|
241
396
|
version: "1.0.0",
|
|
242
397
|
domain: "learning-journey",
|
|
243
|
-
description: "XP source labels (
|
|
398
|
+
description: "XP source labels (Spanish)",
|
|
244
399
|
owners: ["platform"],
|
|
245
400
|
stability: "experimental"
|
|
246
401
|
},
|
|
247
|
-
locale: "
|
|
402
|
+
locale: "es",
|
|
248
403
|
fallback: "en",
|
|
249
404
|
messages: {
|
|
250
405
|
"xp.source.base": {
|
|
@@ -252,40 +407,40 @@ var frMessages = defineTranslation2({
|
|
|
252
407
|
description: "XP breakdown label for base XP"
|
|
253
408
|
},
|
|
254
409
|
"xp.source.scoreBonus": {
|
|
255
|
-
value: "
|
|
410
|
+
value: "Bonificación por puntuación",
|
|
256
411
|
description: "XP breakdown label for score-based bonus"
|
|
257
412
|
},
|
|
258
413
|
"xp.source.perfectScore": {
|
|
259
|
-
value: "
|
|
414
|
+
value: "Puntuación perfecta",
|
|
260
415
|
description: "XP breakdown label for perfect score bonus"
|
|
261
416
|
},
|
|
262
417
|
"xp.source.firstAttempt": {
|
|
263
|
-
value: "
|
|
418
|
+
value: "Primer intento",
|
|
264
419
|
description: "XP breakdown label for first attempt bonus"
|
|
265
420
|
},
|
|
266
421
|
"xp.source.retryPenalty": {
|
|
267
|
-
value: "
|
|
422
|
+
value: "Penalización por reintento",
|
|
268
423
|
description: "XP breakdown label for retry penalty"
|
|
269
424
|
},
|
|
270
425
|
"xp.source.streakBonus": {
|
|
271
|
-
value: "
|
|
426
|
+
value: "Bonificación por racha",
|
|
272
427
|
description: "XP breakdown label for streak bonus"
|
|
273
428
|
}
|
|
274
429
|
}
|
|
275
430
|
});
|
|
276
431
|
|
|
277
|
-
// src/i18n/catalogs/
|
|
432
|
+
// src/i18n/catalogs/fr.ts
|
|
278
433
|
import { defineTranslation as defineTranslation3 } from "@contractspec/lib.contracts-spec/translations";
|
|
279
|
-
var
|
|
434
|
+
var frMessages = defineTranslation3({
|
|
280
435
|
meta: {
|
|
281
436
|
key: "learning-journey.messages",
|
|
282
437
|
version: "1.0.0",
|
|
283
438
|
domain: "learning-journey",
|
|
284
|
-
description: "XP source labels (
|
|
439
|
+
description: "XP source labels (French)",
|
|
285
440
|
owners: ["platform"],
|
|
286
441
|
stability: "experimental"
|
|
287
442
|
},
|
|
288
|
-
locale: "
|
|
443
|
+
locale: "fr",
|
|
289
444
|
fallback: "en",
|
|
290
445
|
messages: {
|
|
291
446
|
"xp.source.base": {
|
|
@@ -293,23 +448,23 @@ var esMessages = defineTranslation3({
|
|
|
293
448
|
description: "XP breakdown label for base XP"
|
|
294
449
|
},
|
|
295
450
|
"xp.source.scoreBonus": {
|
|
296
|
-
value: "
|
|
451
|
+
value: "Bonus de score",
|
|
297
452
|
description: "XP breakdown label for score-based bonus"
|
|
298
453
|
},
|
|
299
454
|
"xp.source.perfectScore": {
|
|
300
|
-
value: "
|
|
455
|
+
value: "Score parfait",
|
|
301
456
|
description: "XP breakdown label for perfect score bonus"
|
|
302
457
|
},
|
|
303
458
|
"xp.source.firstAttempt": {
|
|
304
|
-
value: "
|
|
459
|
+
value: "Premier essai",
|
|
305
460
|
description: "XP breakdown label for first attempt bonus"
|
|
306
461
|
},
|
|
307
462
|
"xp.source.retryPenalty": {
|
|
308
|
-
value: "
|
|
463
|
+
value: "Pénalité de réessai",
|
|
309
464
|
description: "XP breakdown label for retry penalty"
|
|
310
465
|
},
|
|
311
466
|
"xp.source.streakBonus": {
|
|
312
|
-
value: "
|
|
467
|
+
value: "Bonus de série",
|
|
313
468
|
description: "XP breakdown label for streak bonus"
|
|
314
469
|
}
|
|
315
470
|
}
|
|
@@ -506,161 +661,6 @@ function getXpSourceLabel(source, locale) {
|
|
|
506
661
|
return i18nKey ? i18n.t(i18nKey) : source;
|
|
507
662
|
}
|
|
508
663
|
var xpEngine = new XPEngine;
|
|
509
|
-
|
|
510
|
-
// src/engines/streak.ts
|
|
511
|
-
var DEFAULT_STREAK_CONFIG = {
|
|
512
|
-
timezone: "UTC",
|
|
513
|
-
freezesPerMonth: 2,
|
|
514
|
-
maxFreezes: 5,
|
|
515
|
-
gracePeriodHours: 4
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
class StreakEngine {
|
|
519
|
-
config;
|
|
520
|
-
constructor(config = {}) {
|
|
521
|
-
this.config = { ...DEFAULT_STREAK_CONFIG, ...config };
|
|
522
|
-
}
|
|
523
|
-
update(state, now = new Date) {
|
|
524
|
-
const todayDate = this.getDateString(now);
|
|
525
|
-
const result = {
|
|
526
|
-
state: { ...state },
|
|
527
|
-
streakMaintained: false,
|
|
528
|
-
streakLost: false,
|
|
529
|
-
freezeUsed: false,
|
|
530
|
-
newStreak: false,
|
|
531
|
-
daysMissed: 0
|
|
532
|
-
};
|
|
533
|
-
if (!state.lastActivityDate) {
|
|
534
|
-
result.state.currentStreak = 1;
|
|
535
|
-
result.state.longestStreak = Math.max(1, state.longestStreak);
|
|
536
|
-
result.state.lastActivityAt = now;
|
|
537
|
-
result.state.lastActivityDate = todayDate;
|
|
538
|
-
result.newStreak = true;
|
|
539
|
-
result.streakMaintained = true;
|
|
540
|
-
return result;
|
|
541
|
-
}
|
|
542
|
-
if (state.lastActivityDate === todayDate) {
|
|
543
|
-
result.state.lastActivityAt = now;
|
|
544
|
-
result.streakMaintained = true;
|
|
545
|
-
return result;
|
|
546
|
-
}
|
|
547
|
-
const daysSinceActivity = this.getDaysBetween(state.lastActivityDate, todayDate);
|
|
548
|
-
if (daysSinceActivity === 1) {
|
|
549
|
-
result.state.currentStreak = state.currentStreak + 1;
|
|
550
|
-
result.state.longestStreak = Math.max(result.state.currentStreak, state.longestStreak);
|
|
551
|
-
result.state.lastActivityAt = now;
|
|
552
|
-
result.state.lastActivityDate = todayDate;
|
|
553
|
-
result.streakMaintained = true;
|
|
554
|
-
return result;
|
|
555
|
-
}
|
|
556
|
-
result.daysMissed = daysSinceActivity - 1;
|
|
557
|
-
const freezesNeeded = result.daysMissed;
|
|
558
|
-
if (freezesNeeded <= state.freezesRemaining) {
|
|
559
|
-
result.state.freezesRemaining = state.freezesRemaining - freezesNeeded;
|
|
560
|
-
result.state.freezeUsedAt = now;
|
|
561
|
-
result.state.currentStreak = state.currentStreak + 1;
|
|
562
|
-
result.state.longestStreak = Math.max(result.state.currentStreak, state.longestStreak);
|
|
563
|
-
result.state.lastActivityAt = now;
|
|
564
|
-
result.state.lastActivityDate = todayDate;
|
|
565
|
-
result.freezeUsed = true;
|
|
566
|
-
result.streakMaintained = true;
|
|
567
|
-
return result;
|
|
568
|
-
}
|
|
569
|
-
result.streakLost = true;
|
|
570
|
-
result.state.currentStreak = 1;
|
|
571
|
-
result.state.lastActivityAt = now;
|
|
572
|
-
result.state.lastActivityDate = todayDate;
|
|
573
|
-
result.newStreak = true;
|
|
574
|
-
return result;
|
|
575
|
-
}
|
|
576
|
-
checkStatus(state, now = new Date) {
|
|
577
|
-
if (!state.lastActivityDate) {
|
|
578
|
-
return {
|
|
579
|
-
isActive: false,
|
|
580
|
-
willExpireAt: null,
|
|
581
|
-
canUseFreeze: false,
|
|
582
|
-
daysUntilExpiry: 0
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
const todayDate = this.getDateString(now);
|
|
586
|
-
const daysSinceActivity = this.getDaysBetween(state.lastActivityDate, todayDate);
|
|
587
|
-
if (daysSinceActivity === 0) {
|
|
588
|
-
const tomorrow = this.addDays(now, 1);
|
|
589
|
-
tomorrow.setHours(23, 59, 59, 999);
|
|
590
|
-
return {
|
|
591
|
-
isActive: true,
|
|
592
|
-
willExpireAt: tomorrow,
|
|
593
|
-
canUseFreeze: state.freezesRemaining > 0,
|
|
594
|
-
daysUntilExpiry: 1
|
|
595
|
-
};
|
|
596
|
-
}
|
|
597
|
-
if (daysSinceActivity === 1) {
|
|
598
|
-
const endOfDay = new Date(now);
|
|
599
|
-
endOfDay.setHours(23 + this.config.gracePeriodHours, 59, 59, 999);
|
|
600
|
-
return {
|
|
601
|
-
isActive: true,
|
|
602
|
-
willExpireAt: endOfDay,
|
|
603
|
-
canUseFreeze: state.freezesRemaining > 0,
|
|
604
|
-
daysUntilExpiry: 0
|
|
605
|
-
};
|
|
606
|
-
}
|
|
607
|
-
const missedDays = daysSinceActivity - 1;
|
|
608
|
-
return {
|
|
609
|
-
isActive: missedDays <= state.freezesRemaining,
|
|
610
|
-
willExpireAt: null,
|
|
611
|
-
canUseFreeze: missedDays <= state.freezesRemaining,
|
|
612
|
-
daysUntilExpiry: -missedDays
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
useFreeze(state, now = new Date) {
|
|
616
|
-
if (state.freezesRemaining <= 0) {
|
|
617
|
-
return null;
|
|
618
|
-
}
|
|
619
|
-
return {
|
|
620
|
-
...state,
|
|
621
|
-
freezesRemaining: state.freezesRemaining - 1,
|
|
622
|
-
freezeUsedAt: now
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
awardMonthlyFreezes(state) {
|
|
626
|
-
return {
|
|
627
|
-
...state,
|
|
628
|
-
freezesRemaining: Math.min(state.freezesRemaining + this.config.freezesPerMonth, this.config.maxFreezes)
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
getInitialState() {
|
|
632
|
-
return {
|
|
633
|
-
currentStreak: 0,
|
|
634
|
-
longestStreak: 0,
|
|
635
|
-
lastActivityAt: null,
|
|
636
|
-
lastActivityDate: null,
|
|
637
|
-
freezesRemaining: this.config.freezesPerMonth,
|
|
638
|
-
freezeUsedAt: null
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
getMilestones(currentStreak) {
|
|
642
|
-
const milestones = [3, 7, 14, 30, 60, 90, 180, 365, 500, 1000];
|
|
643
|
-
const achieved = milestones.filter((m) => currentStreak >= m);
|
|
644
|
-
const next = milestones.find((m) => currentStreak < m) ?? null;
|
|
645
|
-
return { achieved, next };
|
|
646
|
-
}
|
|
647
|
-
getDateString(date) {
|
|
648
|
-
const year = date.getFullYear();
|
|
649
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
650
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
651
|
-
return `${year}-${month}-${day}`;
|
|
652
|
-
}
|
|
653
|
-
getDaysBetween(dateStr1, dateStr2) {
|
|
654
|
-
const date1 = new Date(dateStr1);
|
|
655
|
-
const date2 = new Date(dateStr2);
|
|
656
|
-
const diffTime = date2.getTime() - date1.getTime();
|
|
657
|
-
return Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
658
|
-
}
|
|
659
|
-
addDays(date, days) {
|
|
660
|
-
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
var streakEngine = new StreakEngine;
|
|
664
664
|
export {
|
|
665
665
|
xpEngine,
|
|
666
666
|
streakEngine,
|
package/dist/node/engines/xp.js
CHANGED
|
@@ -39,18 +39,18 @@ var enMessages = defineTranslation({
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
// src/i18n/catalogs/
|
|
42
|
+
// src/i18n/catalogs/es.ts
|
|
43
43
|
import { defineTranslation as defineTranslation2 } from "@contractspec/lib.contracts-spec/translations";
|
|
44
|
-
var
|
|
44
|
+
var esMessages = defineTranslation2({
|
|
45
45
|
meta: {
|
|
46
46
|
key: "learning-journey.messages",
|
|
47
47
|
version: "1.0.0",
|
|
48
48
|
domain: "learning-journey",
|
|
49
|
-
description: "XP source labels (
|
|
49
|
+
description: "XP source labels (Spanish)",
|
|
50
50
|
owners: ["platform"],
|
|
51
51
|
stability: "experimental"
|
|
52
52
|
},
|
|
53
|
-
locale: "
|
|
53
|
+
locale: "es",
|
|
54
54
|
fallback: "en",
|
|
55
55
|
messages: {
|
|
56
56
|
"xp.source.base": {
|
|
@@ -58,40 +58,40 @@ var frMessages = defineTranslation2({
|
|
|
58
58
|
description: "XP breakdown label for base XP"
|
|
59
59
|
},
|
|
60
60
|
"xp.source.scoreBonus": {
|
|
61
|
-
value: "
|
|
61
|
+
value: "Bonificación por puntuación",
|
|
62
62
|
description: "XP breakdown label for score-based bonus"
|
|
63
63
|
},
|
|
64
64
|
"xp.source.perfectScore": {
|
|
65
|
-
value: "
|
|
65
|
+
value: "Puntuación perfecta",
|
|
66
66
|
description: "XP breakdown label for perfect score bonus"
|
|
67
67
|
},
|
|
68
68
|
"xp.source.firstAttempt": {
|
|
69
|
-
value: "
|
|
69
|
+
value: "Primer intento",
|
|
70
70
|
description: "XP breakdown label for first attempt bonus"
|
|
71
71
|
},
|
|
72
72
|
"xp.source.retryPenalty": {
|
|
73
|
-
value: "
|
|
73
|
+
value: "Penalización por reintento",
|
|
74
74
|
description: "XP breakdown label for retry penalty"
|
|
75
75
|
},
|
|
76
76
|
"xp.source.streakBonus": {
|
|
77
|
-
value: "
|
|
77
|
+
value: "Bonificación por racha",
|
|
78
78
|
description: "XP breakdown label for streak bonus"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
// src/i18n/catalogs/
|
|
83
|
+
// src/i18n/catalogs/fr.ts
|
|
84
84
|
import { defineTranslation as defineTranslation3 } from "@contractspec/lib.contracts-spec/translations";
|
|
85
|
-
var
|
|
85
|
+
var frMessages = defineTranslation3({
|
|
86
86
|
meta: {
|
|
87
87
|
key: "learning-journey.messages",
|
|
88
88
|
version: "1.0.0",
|
|
89
89
|
domain: "learning-journey",
|
|
90
|
-
description: "XP source labels (
|
|
90
|
+
description: "XP source labels (French)",
|
|
91
91
|
owners: ["platform"],
|
|
92
92
|
stability: "experimental"
|
|
93
93
|
},
|
|
94
|
-
locale: "
|
|
94
|
+
locale: "fr",
|
|
95
95
|
fallback: "en",
|
|
96
96
|
messages: {
|
|
97
97
|
"xp.source.base": {
|
|
@@ -99,23 +99,23 @@ var esMessages = defineTranslation3({
|
|
|
99
99
|
description: "XP breakdown label for base XP"
|
|
100
100
|
},
|
|
101
101
|
"xp.source.scoreBonus": {
|
|
102
|
-
value: "
|
|
102
|
+
value: "Bonus de score",
|
|
103
103
|
description: "XP breakdown label for score-based bonus"
|
|
104
104
|
},
|
|
105
105
|
"xp.source.perfectScore": {
|
|
106
|
-
value: "
|
|
106
|
+
value: "Score parfait",
|
|
107
107
|
description: "XP breakdown label for perfect score bonus"
|
|
108
108
|
},
|
|
109
109
|
"xp.source.firstAttempt": {
|
|
110
|
-
value: "
|
|
110
|
+
value: "Premier essai",
|
|
111
111
|
description: "XP breakdown label for first attempt bonus"
|
|
112
112
|
},
|
|
113
113
|
"xp.source.retryPenalty": {
|
|
114
|
-
value: "
|
|
114
|
+
value: "Pénalité de réessai",
|
|
115
115
|
description: "XP breakdown label for retry penalty"
|
|
116
116
|
},
|
|
117
117
|
"xp.source.streakBonus": {
|
|
118
|
-
value: "
|
|
118
|
+
value: "Bonus de série",
|
|
119
119
|
description: "XP breakdown label for streak bonus"
|
|
120
120
|
}
|
|
121
121
|
}
|
package/dist/node/events.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
|
|
3
3
|
|
|
4
4
|
// src/events.ts
|
|
5
|
-
import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
|
|
6
5
|
import { defineEvent } from "@contractspec/lib.contracts-spec";
|
|
6
|
+
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
7
7
|
var CoursePublishedPayload = defineSchemaModel({
|
|
8
8
|
name: "CoursePublishedEventPayload",
|
|
9
9
|
description: "Payload when a course is published",
|
|
@@ -39,18 +39,18 @@ var enMessages = defineTranslation({
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
// src/i18n/catalogs/
|
|
42
|
+
// src/i18n/catalogs/es.ts
|
|
43
43
|
import { defineTranslation as defineTranslation2 } from "@contractspec/lib.contracts-spec/translations";
|
|
44
|
-
var
|
|
44
|
+
var esMessages = defineTranslation2({
|
|
45
45
|
meta: {
|
|
46
46
|
key: "learning-journey.messages",
|
|
47
47
|
version: "1.0.0",
|
|
48
48
|
domain: "learning-journey",
|
|
49
|
-
description: "XP source labels (
|
|
49
|
+
description: "XP source labels (Spanish)",
|
|
50
50
|
owners: ["platform"],
|
|
51
51
|
stability: "experimental"
|
|
52
52
|
},
|
|
53
|
-
locale: "
|
|
53
|
+
locale: "es",
|
|
54
54
|
fallback: "en",
|
|
55
55
|
messages: {
|
|
56
56
|
"xp.source.base": {
|
|
@@ -58,40 +58,40 @@ var frMessages = defineTranslation2({
|
|
|
58
58
|
description: "XP breakdown label for base XP"
|
|
59
59
|
},
|
|
60
60
|
"xp.source.scoreBonus": {
|
|
61
|
-
value: "
|
|
61
|
+
value: "Bonificación por puntuación",
|
|
62
62
|
description: "XP breakdown label for score-based bonus"
|
|
63
63
|
},
|
|
64
64
|
"xp.source.perfectScore": {
|
|
65
|
-
value: "
|
|
65
|
+
value: "Puntuación perfecta",
|
|
66
66
|
description: "XP breakdown label for perfect score bonus"
|
|
67
67
|
},
|
|
68
68
|
"xp.source.firstAttempt": {
|
|
69
|
-
value: "
|
|
69
|
+
value: "Primer intento",
|
|
70
70
|
description: "XP breakdown label for first attempt bonus"
|
|
71
71
|
},
|
|
72
72
|
"xp.source.retryPenalty": {
|
|
73
|
-
value: "
|
|
73
|
+
value: "Penalización por reintento",
|
|
74
74
|
description: "XP breakdown label for retry penalty"
|
|
75
75
|
},
|
|
76
76
|
"xp.source.streakBonus": {
|
|
77
|
-
value: "
|
|
77
|
+
value: "Bonificación por racha",
|
|
78
78
|
description: "XP breakdown label for streak bonus"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
// src/i18n/catalogs/
|
|
83
|
+
// src/i18n/catalogs/fr.ts
|
|
84
84
|
import { defineTranslation as defineTranslation3 } from "@contractspec/lib.contracts-spec/translations";
|
|
85
|
-
var
|
|
85
|
+
var frMessages = defineTranslation3({
|
|
86
86
|
meta: {
|
|
87
87
|
key: "learning-journey.messages",
|
|
88
88
|
version: "1.0.0",
|
|
89
89
|
domain: "learning-journey",
|
|
90
|
-
description: "XP source labels (
|
|
90
|
+
description: "XP source labels (French)",
|
|
91
91
|
owners: ["platform"],
|
|
92
92
|
stability: "experimental"
|
|
93
93
|
},
|
|
94
|
-
locale: "
|
|
94
|
+
locale: "fr",
|
|
95
95
|
fallback: "en",
|
|
96
96
|
messages: {
|
|
97
97
|
"xp.source.base": {
|
|
@@ -99,23 +99,23 @@ var esMessages = defineTranslation3({
|
|
|
99
99
|
description: "XP breakdown label for base XP"
|
|
100
100
|
},
|
|
101
101
|
"xp.source.scoreBonus": {
|
|
102
|
-
value: "
|
|
102
|
+
value: "Bonus de score",
|
|
103
103
|
description: "XP breakdown label for score-based bonus"
|
|
104
104
|
},
|
|
105
105
|
"xp.source.perfectScore": {
|
|
106
|
-
value: "
|
|
106
|
+
value: "Score parfait",
|
|
107
107
|
description: "XP breakdown label for perfect score bonus"
|
|
108
108
|
},
|
|
109
109
|
"xp.source.firstAttempt": {
|
|
110
|
-
value: "
|
|
110
|
+
value: "Premier essai",
|
|
111
111
|
description: "XP breakdown label for first attempt bonus"
|
|
112
112
|
},
|
|
113
113
|
"xp.source.retryPenalty": {
|
|
114
|
-
value: "
|
|
114
|
+
value: "Pénalité de réessai",
|
|
115
115
|
description: "XP breakdown label for retry penalty"
|
|
116
116
|
},
|
|
117
117
|
"xp.source.streakBonus": {
|
|
118
|
-
value: "
|
|
118
|
+
value: "Bonus de série",
|
|
119
119
|
description: "XP breakdown label for streak bonus"
|
|
120
120
|
}
|
|
121
121
|
}
|