@contractspec/module.learning-journey 2.3.0 → 2.5.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.
Files changed (52) hide show
  1. package/dist/browser/engines/index.js +149 -0
  2. package/dist/browser/engines/xp.js +149 -0
  3. package/dist/browser/entities/index.js +4 -0
  4. package/dist/browser/entities/learner.js +4 -0
  5. package/dist/browser/i18n/catalogs/en.js +43 -0
  6. package/dist/browser/i18n/catalogs/es.js +43 -0
  7. package/dist/browser/i18n/catalogs/fr.js +43 -0
  8. package/dist/browser/i18n/catalogs/index.js +127 -0
  9. package/dist/browser/i18n/index.js +169 -0
  10. package/dist/browser/i18n/keys.js +16 -0
  11. package/dist/browser/i18n/locale.js +13 -0
  12. package/dist/browser/i18n/messages.js +139 -0
  13. package/dist/browser/index.js +153 -0
  14. package/dist/engines/index.js +149 -0
  15. package/dist/engines/xp.d.ts +7 -0
  16. package/dist/engines/xp.js +149 -0
  17. package/dist/entities/index.d.ts +1 -0
  18. package/dist/entities/index.js +4 -0
  19. package/dist/entities/learner.d.ts +2 -0
  20. package/dist/entities/learner.js +4 -0
  21. package/dist/i18n/catalogs/en.d.ts +6 -0
  22. package/dist/i18n/catalogs/en.js +44 -0
  23. package/dist/i18n/catalogs/es.d.ts +6 -0
  24. package/dist/i18n/catalogs/es.js +44 -0
  25. package/dist/i18n/catalogs/fr.d.ts +6 -0
  26. package/dist/i18n/catalogs/fr.js +44 -0
  27. package/dist/i18n/catalogs/index.d.ts +8 -0
  28. package/dist/i18n/catalogs/index.js +128 -0
  29. package/dist/i18n/i18n.test.d.ts +1 -0
  30. package/dist/i18n/index.d.ts +14 -0
  31. package/dist/i18n/index.js +170 -0
  32. package/dist/i18n/keys.d.ts +25 -0
  33. package/dist/i18n/keys.js +17 -0
  34. package/dist/i18n/locale.d.ts +8 -0
  35. package/dist/i18n/locale.js +14 -0
  36. package/dist/i18n/messages.d.ts +14 -0
  37. package/dist/i18n/messages.js +140 -0
  38. package/dist/index.js +153 -0
  39. package/dist/node/engines/index.js +149 -0
  40. package/dist/node/engines/xp.js +149 -0
  41. package/dist/node/entities/index.js +4 -0
  42. package/dist/node/entities/learner.js +4 -0
  43. package/dist/node/i18n/catalogs/en.js +43 -0
  44. package/dist/node/i18n/catalogs/es.js +43 -0
  45. package/dist/node/i18n/catalogs/fr.js +43 -0
  46. package/dist/node/i18n/catalogs/index.js +127 -0
  47. package/dist/node/i18n/index.js +169 -0
  48. package/dist/node/i18n/keys.js +16 -0
  49. package/dist/node/i18n/locale.js +13 -0
  50. package/dist/node/i18n/messages.js +139 -0
  51. package/dist/node/index.js +153 -0
  52. package/package.json +146 -5
@@ -0,0 +1,170 @@
1
+ // @bun
2
+ // src/i18n/catalogs/en.ts
3
+ import { defineTranslation } from "@contractspec/lib.contracts-spec/translations";
4
+ var enMessages = defineTranslation({
5
+ meta: {
6
+ key: "learning-journey.messages",
7
+ version: "1.0.0",
8
+ domain: "learning-journey",
9
+ description: "XP source labels for the learning-journey module",
10
+ owners: ["platform"],
11
+ stability: "experimental"
12
+ },
13
+ locale: "en",
14
+ fallback: "en",
15
+ messages: {
16
+ "xp.source.base": {
17
+ value: "Base",
18
+ description: "XP breakdown label for base XP"
19
+ },
20
+ "xp.source.scoreBonus": {
21
+ value: "Score Bonus",
22
+ description: "XP breakdown label for score-based bonus"
23
+ },
24
+ "xp.source.perfectScore": {
25
+ value: "Perfect Score",
26
+ description: "XP breakdown label for perfect score bonus"
27
+ },
28
+ "xp.source.firstAttempt": {
29
+ value: "First Attempt",
30
+ description: "XP breakdown label for first attempt bonus"
31
+ },
32
+ "xp.source.retryPenalty": {
33
+ value: "Retry Penalty",
34
+ description: "XP breakdown label for retry penalty"
35
+ },
36
+ "xp.source.streakBonus": {
37
+ value: "Streak Bonus",
38
+ description: "XP breakdown label for streak bonus"
39
+ }
40
+ }
41
+ });
42
+
43
+ // src/i18n/catalogs/fr.ts
44
+ import { defineTranslation as defineTranslation2 } from "@contractspec/lib.contracts-spec/translations";
45
+ var frMessages = defineTranslation2({
46
+ meta: {
47
+ key: "learning-journey.messages",
48
+ version: "1.0.0",
49
+ domain: "learning-journey",
50
+ description: "XP source labels (French)",
51
+ owners: ["platform"],
52
+ stability: "experimental"
53
+ },
54
+ locale: "fr",
55
+ fallback: "en",
56
+ messages: {
57
+ "xp.source.base": {
58
+ value: "Base",
59
+ description: "XP breakdown label for base XP"
60
+ },
61
+ "xp.source.scoreBonus": {
62
+ value: "Bonus de score",
63
+ description: "XP breakdown label for score-based bonus"
64
+ },
65
+ "xp.source.perfectScore": {
66
+ value: "Score parfait",
67
+ description: "XP breakdown label for perfect score bonus"
68
+ },
69
+ "xp.source.firstAttempt": {
70
+ value: "Premier essai",
71
+ description: "XP breakdown label for first attempt bonus"
72
+ },
73
+ "xp.source.retryPenalty": {
74
+ value: "P\xE9nalit\xE9 de r\xE9essai",
75
+ description: "XP breakdown label for retry penalty"
76
+ },
77
+ "xp.source.streakBonus": {
78
+ value: "Bonus de s\xE9rie",
79
+ description: "XP breakdown label for streak bonus"
80
+ }
81
+ }
82
+ });
83
+
84
+ // src/i18n/catalogs/es.ts
85
+ import { defineTranslation as defineTranslation3 } from "@contractspec/lib.contracts-spec/translations";
86
+ var esMessages = defineTranslation3({
87
+ meta: {
88
+ key: "learning-journey.messages",
89
+ version: "1.0.0",
90
+ domain: "learning-journey",
91
+ description: "XP source labels (Spanish)",
92
+ owners: ["platform"],
93
+ stability: "experimental"
94
+ },
95
+ locale: "es",
96
+ fallback: "en",
97
+ messages: {
98
+ "xp.source.base": {
99
+ value: "Base",
100
+ description: "XP breakdown label for base XP"
101
+ },
102
+ "xp.source.scoreBonus": {
103
+ value: "Bonificaci\xF3n por puntuaci\xF3n",
104
+ description: "XP breakdown label for score-based bonus"
105
+ },
106
+ "xp.source.perfectScore": {
107
+ value: "Puntuaci\xF3n perfecta",
108
+ description: "XP breakdown label for perfect score bonus"
109
+ },
110
+ "xp.source.firstAttempt": {
111
+ value: "Primer intento",
112
+ description: "XP breakdown label for first attempt bonus"
113
+ },
114
+ "xp.source.retryPenalty": {
115
+ value: "Penalizaci\xF3n por reintento",
116
+ description: "XP breakdown label for retry penalty"
117
+ },
118
+ "xp.source.streakBonus": {
119
+ value: "Bonificaci\xF3n por racha",
120
+ description: "XP breakdown label for streak bonus"
121
+ }
122
+ }
123
+ });
124
+
125
+ // src/i18n/messages.ts
126
+ import {
127
+ createI18nFactory
128
+ } from "@contractspec/lib.contracts-spec/translations";
129
+ var factory = createI18nFactory({
130
+ specKey: "learning-journey.messages",
131
+ catalogs: [enMessages, frMessages, esMessages]
132
+ });
133
+ var createLearningJourneyI18n = factory.create;
134
+ var getDefaultI18n = factory.getDefault;
135
+ var resetI18nRegistry = factory.resetRegistry;
136
+
137
+ // src/i18n/locale.ts
138
+ import {
139
+ DEFAULT_LOCALE,
140
+ SUPPORTED_LOCALES,
141
+ resolveLocale,
142
+ isSupportedLocale
143
+ } from "@contractspec/lib.contracts-spec/translations";
144
+
145
+ // src/i18n/keys.ts
146
+ var XP_SOURCE_KEYS = {
147
+ "xp.source.base": "xp.source.base",
148
+ "xp.source.scoreBonus": "xp.source.scoreBonus",
149
+ "xp.source.perfectScore": "xp.source.perfectScore",
150
+ "xp.source.firstAttempt": "xp.source.firstAttempt",
151
+ "xp.source.retryPenalty": "xp.source.retryPenalty",
152
+ "xp.source.streakBonus": "xp.source.streakBonus"
153
+ };
154
+ var I18N_KEYS = {
155
+ ...XP_SOURCE_KEYS
156
+ };
157
+ export {
158
+ resolveLocale,
159
+ resetI18nRegistry,
160
+ isSupportedLocale,
161
+ getDefaultI18n,
162
+ frMessages,
163
+ esMessages,
164
+ enMessages,
165
+ createLearningJourneyI18n,
166
+ XP_SOURCE_KEYS,
167
+ SUPPORTED_LOCALES,
168
+ I18N_KEYS,
169
+ DEFAULT_LOCALE
170
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Typed message keys for the learning-journey i18n system.
3
+ *
4
+ * Keys cover XP breakdown source labels shown in UIs.
5
+ *
6
+ * @module i18n/keys
7
+ */
8
+ export declare const XP_SOURCE_KEYS: {
9
+ readonly 'xp.source.base': "xp.source.base";
10
+ readonly 'xp.source.scoreBonus': "xp.source.scoreBonus";
11
+ readonly 'xp.source.perfectScore': "xp.source.perfectScore";
12
+ readonly 'xp.source.firstAttempt': "xp.source.firstAttempt";
13
+ readonly 'xp.source.retryPenalty': "xp.source.retryPenalty";
14
+ readonly 'xp.source.streakBonus': "xp.source.streakBonus";
15
+ };
16
+ export declare const I18N_KEYS: {
17
+ readonly 'xp.source.base': "xp.source.base";
18
+ readonly 'xp.source.scoreBonus': "xp.source.scoreBonus";
19
+ readonly 'xp.source.perfectScore': "xp.source.perfectScore";
20
+ readonly 'xp.source.firstAttempt': "xp.source.firstAttempt";
21
+ readonly 'xp.source.retryPenalty': "xp.source.retryPenalty";
22
+ readonly 'xp.source.streakBonus': "xp.source.streakBonus";
23
+ };
24
+ /** Union type of all valid learning-journey i18n keys */
25
+ export type LearningJourneyMessageKey = keyof typeof I18N_KEYS;
@@ -0,0 +1,17 @@
1
+ // @bun
2
+ // src/i18n/keys.ts
3
+ var XP_SOURCE_KEYS = {
4
+ "xp.source.base": "xp.source.base",
5
+ "xp.source.scoreBonus": "xp.source.scoreBonus",
6
+ "xp.source.perfectScore": "xp.source.perfectScore",
7
+ "xp.source.firstAttempt": "xp.source.firstAttempt",
8
+ "xp.source.retryPenalty": "xp.source.retryPenalty",
9
+ "xp.source.streakBonus": "xp.source.streakBonus"
10
+ };
11
+ var I18N_KEYS = {
12
+ ...XP_SOURCE_KEYS
13
+ };
14
+ export {
15
+ XP_SOURCE_KEYS,
16
+ I18N_KEYS
17
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Locale utilities for the learning-journey package.
3
+ *
4
+ * Re-exported from the shared i18n factory in contracts-spec.
5
+ *
6
+ * @module i18n/locale
7
+ */
8
+ export { DEFAULT_LOCALE, SUPPORTED_LOCALES, resolveLocale, isSupportedLocale, type SupportedLocale, } from '@contractspec/lib.contracts-spec/translations';
@@ -0,0 +1,14 @@
1
+ // @bun
2
+ // src/i18n/locale.ts
3
+ import {
4
+ DEFAULT_LOCALE,
5
+ SUPPORTED_LOCALES,
6
+ resolveLocale,
7
+ isSupportedLocale
8
+ } from "@contractspec/lib.contracts-spec/translations";
9
+ export {
10
+ resolveLocale,
11
+ isSupportedLocale,
12
+ SUPPORTED_LOCALES,
13
+ DEFAULT_LOCALE
14
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Translation helper for the learning-journey package.
3
+ * @module i18n/messages
4
+ */
5
+ import { type I18nInstance } from '@contractspec/lib.contracts-spec/translations';
6
+ import type { LearningJourneyMessageKey } from './keys';
7
+ /** I18n instance type for the learning-journey package. */
8
+ export type LearningJourneyI18n = I18nInstance<LearningJourneyMessageKey>;
9
+ /** Create an i18n instance for a given locale. */
10
+ export declare const createLearningJourneyI18n: (optionsLocale?: string, runtimeLocale?: string) => I18nInstance<"xp.source.base" | "xp.source.scoreBonus" | "xp.source.perfectScore" | "xp.source.firstAttempt" | "xp.source.retryPenalty" | "xp.source.streakBonus">;
11
+ /** Create a default (English) i18n instance. */
12
+ export declare const getDefaultI18n: () => I18nInstance<"xp.source.base" | "xp.source.scoreBonus" | "xp.source.perfectScore" | "xp.source.firstAttempt" | "xp.source.retryPenalty" | "xp.source.streakBonus">;
13
+ /** Reset the shared registry (useful for testing). @internal */
14
+ export declare const resetI18nRegistry: () => void;
@@ -0,0 +1,140 @@
1
+ // @bun
2
+ // src/i18n/catalogs/en.ts
3
+ import { defineTranslation } from "@contractspec/lib.contracts-spec/translations";
4
+ var enMessages = defineTranslation({
5
+ meta: {
6
+ key: "learning-journey.messages",
7
+ version: "1.0.0",
8
+ domain: "learning-journey",
9
+ description: "XP source labels for the learning-journey module",
10
+ owners: ["platform"],
11
+ stability: "experimental"
12
+ },
13
+ locale: "en",
14
+ fallback: "en",
15
+ messages: {
16
+ "xp.source.base": {
17
+ value: "Base",
18
+ description: "XP breakdown label for base XP"
19
+ },
20
+ "xp.source.scoreBonus": {
21
+ value: "Score Bonus",
22
+ description: "XP breakdown label for score-based bonus"
23
+ },
24
+ "xp.source.perfectScore": {
25
+ value: "Perfect Score",
26
+ description: "XP breakdown label for perfect score bonus"
27
+ },
28
+ "xp.source.firstAttempt": {
29
+ value: "First Attempt",
30
+ description: "XP breakdown label for first attempt bonus"
31
+ },
32
+ "xp.source.retryPenalty": {
33
+ value: "Retry Penalty",
34
+ description: "XP breakdown label for retry penalty"
35
+ },
36
+ "xp.source.streakBonus": {
37
+ value: "Streak Bonus",
38
+ description: "XP breakdown label for streak bonus"
39
+ }
40
+ }
41
+ });
42
+
43
+ // src/i18n/catalogs/fr.ts
44
+ import { defineTranslation as defineTranslation2 } from "@contractspec/lib.contracts-spec/translations";
45
+ var frMessages = defineTranslation2({
46
+ meta: {
47
+ key: "learning-journey.messages",
48
+ version: "1.0.0",
49
+ domain: "learning-journey",
50
+ description: "XP source labels (French)",
51
+ owners: ["platform"],
52
+ stability: "experimental"
53
+ },
54
+ locale: "fr",
55
+ fallback: "en",
56
+ messages: {
57
+ "xp.source.base": {
58
+ value: "Base",
59
+ description: "XP breakdown label for base XP"
60
+ },
61
+ "xp.source.scoreBonus": {
62
+ value: "Bonus de score",
63
+ description: "XP breakdown label for score-based bonus"
64
+ },
65
+ "xp.source.perfectScore": {
66
+ value: "Score parfait",
67
+ description: "XP breakdown label for perfect score bonus"
68
+ },
69
+ "xp.source.firstAttempt": {
70
+ value: "Premier essai",
71
+ description: "XP breakdown label for first attempt bonus"
72
+ },
73
+ "xp.source.retryPenalty": {
74
+ value: "P\xE9nalit\xE9 de r\xE9essai",
75
+ description: "XP breakdown label for retry penalty"
76
+ },
77
+ "xp.source.streakBonus": {
78
+ value: "Bonus de s\xE9rie",
79
+ description: "XP breakdown label for streak bonus"
80
+ }
81
+ }
82
+ });
83
+
84
+ // src/i18n/catalogs/es.ts
85
+ import { defineTranslation as defineTranslation3 } from "@contractspec/lib.contracts-spec/translations";
86
+ var esMessages = defineTranslation3({
87
+ meta: {
88
+ key: "learning-journey.messages",
89
+ version: "1.0.0",
90
+ domain: "learning-journey",
91
+ description: "XP source labels (Spanish)",
92
+ owners: ["platform"],
93
+ stability: "experimental"
94
+ },
95
+ locale: "es",
96
+ fallback: "en",
97
+ messages: {
98
+ "xp.source.base": {
99
+ value: "Base",
100
+ description: "XP breakdown label for base XP"
101
+ },
102
+ "xp.source.scoreBonus": {
103
+ value: "Bonificaci\xF3n por puntuaci\xF3n",
104
+ description: "XP breakdown label for score-based bonus"
105
+ },
106
+ "xp.source.perfectScore": {
107
+ value: "Puntuaci\xF3n perfecta",
108
+ description: "XP breakdown label for perfect score bonus"
109
+ },
110
+ "xp.source.firstAttempt": {
111
+ value: "Primer intento",
112
+ description: "XP breakdown label for first attempt bonus"
113
+ },
114
+ "xp.source.retryPenalty": {
115
+ value: "Penalizaci\xF3n por reintento",
116
+ description: "XP breakdown label for retry penalty"
117
+ },
118
+ "xp.source.streakBonus": {
119
+ value: "Bonificaci\xF3n por racha",
120
+ description: "XP breakdown label for streak bonus"
121
+ }
122
+ }
123
+ });
124
+
125
+ // src/i18n/messages.ts
126
+ import {
127
+ createI18nFactory
128
+ } from "@contractspec/lib.contracts-spec/translations";
129
+ var factory = createI18nFactory({
130
+ specKey: "learning-journey.messages",
131
+ catalogs: [enMessages, frMessages, esMessages]
132
+ });
133
+ var createLearningJourneyI18n = factory.create;
134
+ var getDefaultI18n = factory.getDefault;
135
+ var resetI18nRegistry = factory.resetRegistry;
136
+ export {
137
+ resetI18nRegistry,
138
+ getDefaultI18n,
139
+ createLearningJourneyI18n
140
+ };
package/dist/index.js CHANGED
@@ -865,6 +865,141 @@ class SRSEngine {
865
865
  }
866
866
  var srsEngine = new SRSEngine;
867
867
 
868
+ // src/i18n/catalogs/en.ts
869
+ import { defineTranslation } from "@contractspec/lib.contracts-spec/translations";
870
+ var enMessages = defineTranslation({
871
+ meta: {
872
+ key: "learning-journey.messages",
873
+ version: "1.0.0",
874
+ domain: "learning-journey",
875
+ description: "XP source labels for the learning-journey module",
876
+ owners: ["platform"],
877
+ stability: "experimental"
878
+ },
879
+ locale: "en",
880
+ fallback: "en",
881
+ messages: {
882
+ "xp.source.base": {
883
+ value: "Base",
884
+ description: "XP breakdown label for base XP"
885
+ },
886
+ "xp.source.scoreBonus": {
887
+ value: "Score Bonus",
888
+ description: "XP breakdown label for score-based bonus"
889
+ },
890
+ "xp.source.perfectScore": {
891
+ value: "Perfect Score",
892
+ description: "XP breakdown label for perfect score bonus"
893
+ },
894
+ "xp.source.firstAttempt": {
895
+ value: "First Attempt",
896
+ description: "XP breakdown label for first attempt bonus"
897
+ },
898
+ "xp.source.retryPenalty": {
899
+ value: "Retry Penalty",
900
+ description: "XP breakdown label for retry penalty"
901
+ },
902
+ "xp.source.streakBonus": {
903
+ value: "Streak Bonus",
904
+ description: "XP breakdown label for streak bonus"
905
+ }
906
+ }
907
+ });
908
+
909
+ // src/i18n/catalogs/fr.ts
910
+ import { defineTranslation as defineTranslation2 } from "@contractspec/lib.contracts-spec/translations";
911
+ var frMessages = defineTranslation2({
912
+ meta: {
913
+ key: "learning-journey.messages",
914
+ version: "1.0.0",
915
+ domain: "learning-journey",
916
+ description: "XP source labels (French)",
917
+ owners: ["platform"],
918
+ stability: "experimental"
919
+ },
920
+ locale: "fr",
921
+ fallback: "en",
922
+ messages: {
923
+ "xp.source.base": {
924
+ value: "Base",
925
+ description: "XP breakdown label for base XP"
926
+ },
927
+ "xp.source.scoreBonus": {
928
+ value: "Bonus de score",
929
+ description: "XP breakdown label for score-based bonus"
930
+ },
931
+ "xp.source.perfectScore": {
932
+ value: "Score parfait",
933
+ description: "XP breakdown label for perfect score bonus"
934
+ },
935
+ "xp.source.firstAttempt": {
936
+ value: "Premier essai",
937
+ description: "XP breakdown label for first attempt bonus"
938
+ },
939
+ "xp.source.retryPenalty": {
940
+ value: "P\xE9nalit\xE9 de r\xE9essai",
941
+ description: "XP breakdown label for retry penalty"
942
+ },
943
+ "xp.source.streakBonus": {
944
+ value: "Bonus de s\xE9rie",
945
+ description: "XP breakdown label for streak bonus"
946
+ }
947
+ }
948
+ });
949
+
950
+ // src/i18n/catalogs/es.ts
951
+ import { defineTranslation as defineTranslation3 } from "@contractspec/lib.contracts-spec/translations";
952
+ var esMessages = defineTranslation3({
953
+ meta: {
954
+ key: "learning-journey.messages",
955
+ version: "1.0.0",
956
+ domain: "learning-journey",
957
+ description: "XP source labels (Spanish)",
958
+ owners: ["platform"],
959
+ stability: "experimental"
960
+ },
961
+ locale: "es",
962
+ fallback: "en",
963
+ messages: {
964
+ "xp.source.base": {
965
+ value: "Base",
966
+ description: "XP breakdown label for base XP"
967
+ },
968
+ "xp.source.scoreBonus": {
969
+ value: "Bonificaci\xF3n por puntuaci\xF3n",
970
+ description: "XP breakdown label for score-based bonus"
971
+ },
972
+ "xp.source.perfectScore": {
973
+ value: "Puntuaci\xF3n perfecta",
974
+ description: "XP breakdown label for perfect score bonus"
975
+ },
976
+ "xp.source.firstAttempt": {
977
+ value: "Primer intento",
978
+ description: "XP breakdown label for first attempt bonus"
979
+ },
980
+ "xp.source.retryPenalty": {
981
+ value: "Penalizaci\xF3n por reintento",
982
+ description: "XP breakdown label for retry penalty"
983
+ },
984
+ "xp.source.streakBonus": {
985
+ value: "Bonificaci\xF3n por racha",
986
+ description: "XP breakdown label for streak bonus"
987
+ }
988
+ }
989
+ });
990
+
991
+ // src/i18n/messages.ts
992
+ import {
993
+ createI18nFactory
994
+ } from "@contractspec/lib.contracts-spec/translations";
995
+ var factory = createI18nFactory({
996
+ specKey: "learning-journey.messages",
997
+ catalogs: [enMessages, frMessages, esMessages]
998
+ });
999
+ var createLearningJourneyI18n = factory.create;
1000
+ var getDefaultI18n = factory.getDefault;
1001
+ var resetI18nRegistry = factory.resetRegistry;
1002
+
868
1003
  // src/engines/xp.ts
869
1004
  var DEFAULT_XP_CONFIG = {
870
1005
  baseValues: {
@@ -1030,6 +1165,19 @@ class XPEngine {
1030
1165
  return 0;
1031
1166
  }
1032
1167
  }
1168
+ var SOURCE_KEY_MAP = {
1169
+ base: "xp.source.base",
1170
+ score_bonus: "xp.source.scoreBonus",
1171
+ perfect_score: "xp.source.perfectScore",
1172
+ first_attempt: "xp.source.firstAttempt",
1173
+ retry_penalty: "xp.source.retryPenalty",
1174
+ streak_bonus: "xp.source.streakBonus"
1175
+ };
1176
+ function getXpSourceLabel(source, locale) {
1177
+ const i18n = createLearningJourneyI18n(locale);
1178
+ const i18nKey = SOURCE_KEY_MAP[source];
1179
+ return i18nKey ? i18n.t(i18nKey) : source;
1180
+ }
1033
1181
  var xpEngine = new XPEngine;
1034
1182
 
1035
1183
  // src/engines/streak.ts
@@ -2379,6 +2527,10 @@ var LearnerEntity = defineEntity5({
2379
2527
  isOptional: true,
2380
2528
  description: "Last learning activity"
2381
2529
  }),
2530
+ locale: field5.string({
2531
+ isOptional: true,
2532
+ description: 'Preferred locale for learning content (e.g. "en", "fr", "es")'
2533
+ }),
2382
2534
  timezone: field5.string({
2383
2535
  default: '"UTC"',
2384
2536
  description: "Learner timezone"
@@ -3722,6 +3874,7 @@ export {
3722
3874
  learningJourneyEntities,
3723
3875
  learnerEnums,
3724
3876
  learnerEntities,
3877
+ getXpSourceLabel,
3725
3878
  gamificationEnums,
3726
3879
  gamificationEntities,
3727
3880
  flashcardEnums,