@pie-element/categorize 11.3.4-next.0 → 12.0.0-beta.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/configure/lib/defaults.js +2 -5
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/design/builder.js +15 -33
- package/configure/lib/design/builder.js.map +1 -1
- package/configure/lib/design/buttons.js +41 -95
- package/configure/lib/design/buttons.js.map +1 -1
- package/configure/lib/design/categories/RowLabel.js +32 -45
- package/configure/lib/design/categories/RowLabel.js.map +1 -1
- package/configure/lib/design/categories/alternateResponses.js +96 -251
- package/configure/lib/design/categories/alternateResponses.js.map +1 -1
- package/configure/lib/design/categories/category.js +135 -208
- package/configure/lib/design/categories/category.js.map +1 -1
- package/configure/lib/design/categories/choice-preview.js +61 -126
- package/configure/lib/design/categories/choice-preview.js.map +1 -1
- package/configure/lib/design/categories/droppable-placeholder.js +73 -165
- package/configure/lib/design/categories/droppable-placeholder.js.map +1 -1
- package/configure/lib/design/categories/index.js +195 -384
- package/configure/lib/design/categories/index.js.map +1 -1
- package/configure/lib/design/choices/choice.js +155 -264
- package/configure/lib/design/choices/choice.js.map +1 -1
- package/configure/lib/design/choices/config.js +42 -98
- package/configure/lib/design/choices/config.js.map +1 -1
- package/configure/lib/design/choices/index.js +148 -236
- package/configure/lib/design/choices/index.js.map +1 -1
- package/configure/lib/design/header.js +57 -111
- package/configure/lib/design/header.js.map +1 -1
- package/configure/lib/design/index.js +631 -476
- package/configure/lib/design/index.js.map +1 -1
- package/configure/lib/design/input-header.js +93 -149
- package/configure/lib/design/input-header.js.map +1 -1
- package/configure/lib/design/utils.js +4 -15
- package/configure/lib/design/utils.js.map +1 -1
- package/configure/lib/index.js +120 -183
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +30 -74
- package/configure/lib/main.js.map +1 -1
- package/configure/lib/utils.js +22 -32
- package/configure/lib/utils.js.map +1 -1
- package/configure/package.json +15 -15
- package/controller/lib/defaults.js +2 -5
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +237 -318
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +28 -65
- package/controller/lib/utils.js.map +1 -1
- package/controller/package.json +5 -5
- package/lib/categorize/categories.js +106 -164
- package/lib/categorize/categories.js.map +1 -1
- package/lib/categorize/category.js +73 -123
- package/lib/categorize/category.js.map +1 -1
- package/lib/categorize/choice.js +118 -245
- package/lib/categorize/choice.js.map +1 -1
- package/lib/categorize/choices.js +66 -131
- package/lib/categorize/choices.js.map +1 -1
- package/lib/categorize/droppable-placeholder.js +46 -103
- package/lib/categorize/droppable-placeholder.js.map +1 -1
- package/lib/categorize/grid-content.js +39 -87
- package/lib/categorize/grid-content.js.map +1 -1
- package/lib/categorize/index.js +341 -317
- package/lib/categorize/index.js.map +1 -1
- package/lib/index.js +285 -306
- package/lib/index.js.map +1 -1
- package/package.json +16 -14
package/controller/lib/index.js
CHANGED
|
@@ -1,144 +1,110 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.outcome = exports.normalize = exports.model = exports.getTotalScore = exports.getPartialScore = exports.getCorrectness = exports.createDefaultModel = exports.createCorrectResponseSession = void 0;
|
|
9
8
|
Object.defineProperty(exports, "score", {
|
|
10
9
|
enumerable: true,
|
|
11
|
-
get: function
|
|
10
|
+
get: function () {
|
|
12
11
|
return _categorize.score;
|
|
13
12
|
}
|
|
14
13
|
});
|
|
15
14
|
exports.validate = void 0;
|
|
16
|
-
|
|
17
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
18
|
-
|
|
19
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
20
|
-
|
|
21
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
22
|
-
|
|
23
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
24
|
-
|
|
25
15
|
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
|
26
|
-
|
|
27
16
|
var _categorize = require("@pie-lib/categorize");
|
|
28
|
-
|
|
29
17
|
var _feedback = require("@pie-lib/feedback");
|
|
30
|
-
|
|
31
18
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
32
|
-
|
|
33
19
|
var _translator = _interopRequireDefault(require("@pie-lib/translator"));
|
|
34
|
-
|
|
35
20
|
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
36
|
-
|
|
37
21
|
var _utils = require("./utils");
|
|
22
|
+
const {
|
|
23
|
+
translator
|
|
24
|
+
} = _translator.default;
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
42
|
-
|
|
43
|
-
var translator = _translator["default"].translator;
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
44
27
|
|
|
45
|
-
|
|
28
|
+
const getPartialScore = (correctResponse, builtCategories) => {
|
|
46
29
|
// in the resulted best scenario we make a sum with all the correct responses
|
|
47
30
|
// and all the placements
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}, {
|
|
31
|
+
const {
|
|
32
|
+
placements,
|
|
33
|
+
score
|
|
34
|
+
} = builtCategories.reduce((acc, {
|
|
35
|
+
choices = []
|
|
36
|
+
}) => ({
|
|
37
|
+
placements: acc.placements + choices.length,
|
|
38
|
+
score: acc.score + choices.filter(ch => ch.correct).length
|
|
39
|
+
}), {
|
|
58
40
|
placements: 0,
|
|
59
41
|
score: 0
|
|
60
|
-
})
|
|
61
|
-
placements = _builtCategories$redu.placements,
|
|
62
|
-
score = _builtCategories$redu.score; // in the correct response, we make a sum of the max possible score
|
|
63
|
-
|
|
42
|
+
});
|
|
64
43
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
44
|
+
// in the correct response, we make a sum of the max possible score
|
|
45
|
+
const {
|
|
46
|
+
maxScore
|
|
47
|
+
} = correctResponse.reduce((acc, {
|
|
48
|
+
choices
|
|
49
|
+
}) => ({
|
|
50
|
+
maxScore: acc.maxScore + choices.length
|
|
51
|
+
}), {
|
|
71
52
|
maxScore: 0
|
|
72
|
-
})
|
|
73
|
-
maxScore = _correctResponse$redu.maxScore; // if there are any extra placements, we subtract from the obtained score
|
|
74
|
-
|
|
53
|
+
});
|
|
75
54
|
|
|
76
|
-
|
|
77
|
-
|
|
55
|
+
// if there are any extra placements, we subtract from the obtained score
|
|
56
|
+
const extraPlacements = placements > maxScore ? placements - maxScore : 0;
|
|
57
|
+
const totalScore = (score - extraPlacements) / maxScore;
|
|
78
58
|
return totalScore < 0 ? 0 : parseFloat(totalScore.toFixed(2));
|
|
79
59
|
};
|
|
80
|
-
|
|
81
60
|
exports.getPartialScore = getPartialScore;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return correctResponse.map(function (c) {
|
|
85
|
-
return c.alternateResponses;
|
|
86
|
-
}).filter(function (alternate) {
|
|
87
|
-
return alternate;
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
var getTotalScore = function getTotalScore(question, session, env) {
|
|
61
|
+
const getAlternates = correctResponse => correctResponse.map(c => c.alternateResponses).filter(alternate => alternate);
|
|
62
|
+
const getTotalScore = (question, session, env) => {
|
|
92
63
|
if (!session) {
|
|
93
64
|
return 0;
|
|
94
65
|
}
|
|
95
|
-
|
|
96
66
|
if (Object.keys(session).length === 0) {
|
|
97
67
|
return 0;
|
|
98
68
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
69
|
+
const {
|
|
70
|
+
categories,
|
|
71
|
+
choices
|
|
72
|
+
} = question || {};
|
|
73
|
+
let {
|
|
74
|
+
correctResponse
|
|
75
|
+
} = question || {};
|
|
76
|
+
let {
|
|
77
|
+
answers
|
|
78
|
+
} = session || {};
|
|
110
79
|
answers = answers || [];
|
|
111
|
-
correctResponse = correctResponse || [];
|
|
112
|
-
// so we get the best scenario and calculate the score
|
|
113
|
-
|
|
114
|
-
var _buildState = (0, _categorize.buildState)(categories, choices, answers, correctResponse),
|
|
115
|
-
builtCategories = _buildState.categories,
|
|
116
|
-
correct = _buildState.correct;
|
|
117
|
-
|
|
118
|
-
var alternates = getAlternates(correctResponse);
|
|
119
|
-
|
|
120
|
-
var enabled = _controllerUtils.partialScoring.enabled(question, env); // if there are any alternates, there will be no partial scoring!
|
|
121
|
-
|
|
80
|
+
correctResponse = correctResponse || [];
|
|
122
81
|
|
|
82
|
+
// this function is used in pie-ui/categorize as well, in order to get the best scenario
|
|
83
|
+
// so we get the best scenario and calculate the score
|
|
84
|
+
const {
|
|
85
|
+
categories: builtCategories,
|
|
86
|
+
correct
|
|
87
|
+
} = (0, _categorize.buildState)(categories, choices, answers, correctResponse);
|
|
88
|
+
const alternates = getAlternates(correctResponse);
|
|
89
|
+
const enabled = _controllerUtils.partialScoring.enabled(question, env);
|
|
90
|
+
|
|
91
|
+
// if there are any alternates, there will be no partial scoring!
|
|
123
92
|
if (enabled && !alternates.length) {
|
|
124
93
|
// we apply partial scoring
|
|
125
94
|
return getPartialScore(correctResponse, builtCategories);
|
|
126
|
-
}
|
|
127
|
-
|
|
95
|
+
}
|
|
128
96
|
|
|
97
|
+
// else we apply dichotomous
|
|
129
98
|
return correct ? 1 : 0;
|
|
130
99
|
};
|
|
131
|
-
|
|
132
100
|
exports.getTotalScore = getTotalScore;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return new Promise(function (resolve) {
|
|
101
|
+
const getCorrectness = (question, session, env) => {
|
|
102
|
+
return new Promise(resolve => {
|
|
136
103
|
if (env.mode === 'evaluate') {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (_score === 1) {
|
|
104
|
+
const score = getTotalScore(question, session, env);
|
|
105
|
+
if (score === 1) {
|
|
140
106
|
resolve('correct');
|
|
141
|
-
} else if (
|
|
107
|
+
} else if (score === 0) {
|
|
142
108
|
resolve('incorrect');
|
|
143
109
|
} else {
|
|
144
110
|
resolve('partially-correct');
|
|
@@ -148,21 +114,19 @@ var getCorrectness = function getCorrectness(question, session, env) {
|
|
|
148
114
|
}
|
|
149
115
|
});
|
|
150
116
|
};
|
|
151
|
-
|
|
152
117
|
exports.getCorrectness = getCorrectness;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
resolve(_objectSpread(_objectSpread({}, _defaults["default"]), model));
|
|
118
|
+
const createDefaultModel = (model = {}) => new Promise(resolve => {
|
|
119
|
+
resolve({
|
|
120
|
+
..._defaults.default,
|
|
121
|
+
...model
|
|
158
122
|
});
|
|
159
|
-
};
|
|
160
|
-
|
|
123
|
+
});
|
|
161
124
|
exports.createDefaultModel = createDefaultModel;
|
|
125
|
+
const normalize = question => ({
|
|
126
|
+
..._defaults.default,
|
|
127
|
+
...question
|
|
128
|
+
});
|
|
162
129
|
|
|
163
|
-
var normalize = function normalize(question) {
|
|
164
|
-
return _objectSpread(_objectSpread({}, _defaults["default"]), question);
|
|
165
|
-
};
|
|
166
130
|
/**
|
|
167
131
|
*
|
|
168
132
|
* @param {*} question
|
|
@@ -170,148 +134,129 @@ var normalize = function normalize(question) {
|
|
|
170
134
|
* @param {*} env
|
|
171
135
|
* @param {*} updateSession - optional - a function that will set the properties passed into it on the session.
|
|
172
136
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
137
|
exports.normalize = normalize;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
_context.next = 17;
|
|
219
|
-
break;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
_context.next = 16;
|
|
223
|
-
return (0, _controllerUtils.getShuffledChoices)(choices, session, updateSession, 'id');
|
|
224
|
-
|
|
225
|
-
case 16:
|
|
226
|
-
choices = _context.sent;
|
|
227
|
-
|
|
228
|
-
case 17:
|
|
229
|
-
if (!note) {
|
|
230
|
-
note = translator.t('common:commonCorrectAnswerWithAlternates', {
|
|
231
|
-
lng: language
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
alternates = getAlternates(filteredCorrectResponse);
|
|
236
|
-
_getCompleteResponseD = (0, _utils.getCompleteResponseDetails)(filteredCorrectResponse, normalizedQuestion.allowAlternateEnabled ? alternates : [], normalizedQuestion.choices), responseAreasToBeFilled = _getCompleteResponseD.responseAreasToBeFilled, possibleResponses = _getCompleteResponseD.possibleResponses, hasUnplacedChoices = _getCompleteResponseD.hasUnplacedChoices;
|
|
237
|
-
out = {
|
|
238
|
-
categories: categories || [],
|
|
239
|
-
categoriesPerRow: categoriesPerRow || 2,
|
|
240
|
-
maxChoicesPerCategory: maxChoicesPerCategory,
|
|
241
|
-
correctness: answerCorrectness,
|
|
242
|
-
choices: choices || [],
|
|
243
|
-
choicesLabel: choicesLabel || '',
|
|
244
|
-
choicesPosition: choicesPosition,
|
|
245
|
-
disabled: mode !== 'gather',
|
|
246
|
-
feedback: fb,
|
|
247
|
-
lockChoiceOrder: lockChoiceOrder,
|
|
248
|
-
prompt: promptEnabled ? prompt : null,
|
|
249
|
-
rowLabels: rowLabels,
|
|
250
|
-
note: note,
|
|
251
|
-
env: env,
|
|
252
|
-
showNote: alternates && alternates.length > 0,
|
|
253
|
-
correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,
|
|
254
|
-
language: language,
|
|
255
|
-
extraCSSRules: extraCSSRules,
|
|
256
|
-
fontSizeFactor: fontSizeFactor,
|
|
257
|
-
minRowHeight: minRowHeight,
|
|
258
|
-
autoplayAudioEnabled: autoplayAudioEnabled,
|
|
259
|
-
completeAudioEnabled: completeAudioEnabled,
|
|
260
|
-
customAudioButton: customAudioButton,
|
|
261
|
-
possibleResponses: possibleResponses,
|
|
262
|
-
responseAreasToBeFilled: responseAreasToBeFilled,
|
|
263
|
-
hasUnplacedChoices: hasUnplacedChoices
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
|
|
267
|
-
out.rationale = rationaleEnabled ? rationale : null;
|
|
268
|
-
out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;
|
|
269
|
-
} else {
|
|
270
|
-
out.rationale = null;
|
|
271
|
-
out.teacherInstructions = null;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
resolve(out);
|
|
275
|
-
|
|
276
|
-
case 23:
|
|
277
|
-
case "end":
|
|
278
|
-
return _context.stop();
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}, _callee);
|
|
282
|
-
}));
|
|
283
|
-
|
|
284
|
-
return function (_x) {
|
|
285
|
-
return _ref6.apply(this, arguments);
|
|
138
|
+
const model = async (question, session, env, updateSession) => {
|
|
139
|
+
const normalizedQuestion = normalize(question);
|
|
140
|
+
const answerCorrectness = await getCorrectness(normalizedQuestion, session, env);
|
|
141
|
+
const {
|
|
142
|
+
mode,
|
|
143
|
+
role
|
|
144
|
+
} = env || {};
|
|
145
|
+
const {
|
|
146
|
+
categories,
|
|
147
|
+
categoriesPerRow,
|
|
148
|
+
choicesLabel,
|
|
149
|
+
choicesPosition,
|
|
150
|
+
correctResponse,
|
|
151
|
+
feedback,
|
|
152
|
+
feedbackEnabled,
|
|
153
|
+
promptEnabled,
|
|
154
|
+
prompt,
|
|
155
|
+
rowLabels,
|
|
156
|
+
rationaleEnabled,
|
|
157
|
+
rationale,
|
|
158
|
+
teacherInstructionsEnabled,
|
|
159
|
+
teacherInstructions,
|
|
160
|
+
language,
|
|
161
|
+
maxChoicesPerCategory,
|
|
162
|
+
extraCSSRules,
|
|
163
|
+
minRowHeight,
|
|
164
|
+
fontSizeFactor,
|
|
165
|
+
autoplayAudioEnabled,
|
|
166
|
+
completeAudioEnabled,
|
|
167
|
+
customAudioButton
|
|
168
|
+
} = normalizedQuestion;
|
|
169
|
+
let {
|
|
170
|
+
choices,
|
|
171
|
+
note
|
|
172
|
+
} = normalizedQuestion;
|
|
173
|
+
let fb;
|
|
174
|
+
const lockChoiceOrder = (0, _controllerUtils.lockChoices)(normalizedQuestion, session, env);
|
|
175
|
+
const filteredCorrectResponse = correctResponse.map(response => {
|
|
176
|
+
const filteredChoices = (response.choices || []).filter(choice => choice !== 'null');
|
|
177
|
+
return {
|
|
178
|
+
...response,
|
|
179
|
+
choices: filteredChoices
|
|
286
180
|
};
|
|
287
|
-
}
|
|
181
|
+
});
|
|
182
|
+
if (mode === 'evaluate' && feedbackEnabled) {
|
|
183
|
+
fb = await (0, _feedback.getFeedbackForCorrectness)(answerCorrectness, feedback);
|
|
184
|
+
}
|
|
185
|
+
if (!lockChoiceOrder) {
|
|
186
|
+
choices = await (0, _controllerUtils.getShuffledChoices)(choices, session, updateSession, 'id');
|
|
187
|
+
}
|
|
188
|
+
if (!note) {
|
|
189
|
+
note = translator.t('common:commonCorrectAnswerWithAlternates', {
|
|
190
|
+
lng: language
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const alternates = getAlternates(filteredCorrectResponse);
|
|
194
|
+
const {
|
|
195
|
+
responseAreasToBeFilled,
|
|
196
|
+
possibleResponses,
|
|
197
|
+
hasUnplacedChoices
|
|
198
|
+
} = (0, _utils.getCompleteResponseDetails)(filteredCorrectResponse, normalizedQuestion.allowAlternateEnabled ? alternates : [], normalizedQuestion.choices);
|
|
199
|
+
const out = {
|
|
200
|
+
categories: categories || [],
|
|
201
|
+
categoriesPerRow: categoriesPerRow || 2,
|
|
202
|
+
maxChoicesPerCategory,
|
|
203
|
+
correctness: answerCorrectness,
|
|
204
|
+
choices: choices || [],
|
|
205
|
+
choicesLabel: choicesLabel || '',
|
|
206
|
+
choicesPosition,
|
|
207
|
+
disabled: mode !== 'gather',
|
|
208
|
+
feedback: fb,
|
|
209
|
+
lockChoiceOrder,
|
|
210
|
+
prompt: promptEnabled ? prompt : null,
|
|
211
|
+
rowLabels,
|
|
212
|
+
note,
|
|
213
|
+
env,
|
|
214
|
+
showNote: alternates && alternates.length > 0,
|
|
215
|
+
correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,
|
|
216
|
+
language,
|
|
217
|
+
extraCSSRules,
|
|
218
|
+
fontSizeFactor,
|
|
219
|
+
minRowHeight: minRowHeight,
|
|
220
|
+
autoplayAudioEnabled,
|
|
221
|
+
completeAudioEnabled,
|
|
222
|
+
customAudioButton,
|
|
223
|
+
possibleResponses,
|
|
224
|
+
responseAreasToBeFilled,
|
|
225
|
+
hasUnplacedChoices
|
|
226
|
+
};
|
|
227
|
+
if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
|
|
228
|
+
out.rationale = rationaleEnabled ? rationale : null;
|
|
229
|
+
out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;
|
|
230
|
+
} else {
|
|
231
|
+
out.rationale = null;
|
|
232
|
+
out.teacherInstructions = null;
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
288
235
|
};
|
|
289
|
-
|
|
290
236
|
exports.model = model;
|
|
291
|
-
|
|
292
|
-
var outcome = function outcome(question, session, env) {
|
|
237
|
+
const outcome = (question, session, env) => {
|
|
293
238
|
if (env.mode !== 'evaluate') {
|
|
294
239
|
return Promise.reject(new Error('Can not call outcome when mode is not evaluate'));
|
|
295
240
|
} else {
|
|
296
|
-
return new Promise(
|
|
241
|
+
return new Promise(resolve => {
|
|
297
242
|
resolve({
|
|
298
243
|
score: getTotalScore(question, session, env),
|
|
299
|
-
empty: !session || (0, _isEmpty
|
|
244
|
+
empty: !session || (0, _isEmpty.default)(session)
|
|
300
245
|
});
|
|
301
246
|
});
|
|
302
247
|
}
|
|
303
248
|
};
|
|
304
|
-
|
|
305
249
|
exports.outcome = outcome;
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
250
|
+
const createCorrectResponseSession = (question, env) => {
|
|
251
|
+
return new Promise(resolve => {
|
|
252
|
+
const {
|
|
253
|
+
mode,
|
|
254
|
+
role
|
|
255
|
+
} = env || {};
|
|
313
256
|
if (mode !== 'evaluate' && role === 'instructor') {
|
|
314
|
-
|
|
257
|
+
const {
|
|
258
|
+
correctResponse
|
|
259
|
+
} = question;
|
|
315
260
|
resolve({
|
|
316
261
|
answers: correctResponse,
|
|
317
262
|
id: 1
|
|
@@ -320,151 +265,125 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
|
|
|
320
265
|
return resolve(null);
|
|
321
266
|
}
|
|
322
267
|
});
|
|
323
|
-
}; // remove all html tags
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
327
|
-
|
|
328
|
-
var getInnerText = function getInnerText(html) {
|
|
329
|
-
return (html || '').replaceAll(/<[^>]*>/g, '');
|
|
330
|
-
}; // remove all html tags except img, iframe and source tag for audio
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
var getContent = function getContent(html) {
|
|
334
|
-
return (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
335
268
|
};
|
|
336
269
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
270
|
+
// remove all html tags
|
|
271
|
+
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
272
|
+
const getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, '');
|
|
273
|
+
|
|
274
|
+
// remove all html tags except img, iframe and source tag for audio
|
|
275
|
+
const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
276
|
+
const validate = (model = {}, config = {}) => {
|
|
277
|
+
const {
|
|
278
|
+
categories,
|
|
279
|
+
choices,
|
|
280
|
+
correctResponse,
|
|
281
|
+
maxAnswerChoices
|
|
282
|
+
} = model;
|
|
283
|
+
const {
|
|
284
|
+
minChoices = 1,
|
|
285
|
+
minCategories = 1,
|
|
286
|
+
maxCategories = 12,
|
|
287
|
+
maxLengthPerChoice = 300,
|
|
288
|
+
maxLengthPerCategory = 150
|
|
289
|
+
} = config;
|
|
290
|
+
const reversedChoices = [...(choices || [])].reverse();
|
|
291
|
+
const errors = {};
|
|
292
|
+
const choicesErrors = {};
|
|
293
|
+
const categoriesErrors = {};
|
|
294
|
+
['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
|
|
295
|
+
if (config[field]?.required && !getContent(model[field])) {
|
|
362
296
|
errors[field] = 'This field is required.';
|
|
363
297
|
}
|
|
364
298
|
});
|
|
365
|
-
(categories || []).forEach(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
299
|
+
(categories || []).forEach(category => {
|
|
300
|
+
const {
|
|
301
|
+
id,
|
|
302
|
+
label
|
|
303
|
+
} = category;
|
|
369
304
|
if (getInnerText(label).length > maxLengthPerCategory) {
|
|
370
|
-
categoriesErrors[id] =
|
|
305
|
+
categoriesErrors[id] = `Category labels should be no more than ${maxLengthPerCategory} characters long.`;
|
|
371
306
|
}
|
|
372
307
|
});
|
|
373
|
-
(reversedChoices || []).forEach(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
308
|
+
(reversedChoices || []).forEach((choice, index) => {
|
|
309
|
+
const {
|
|
310
|
+
id,
|
|
311
|
+
content
|
|
312
|
+
} = choice;
|
|
377
313
|
if (getInnerText(content).length > maxLengthPerChoice) {
|
|
378
|
-
choicesErrors[id] =
|
|
314
|
+
choicesErrors[id] = `Tokens should be no more than ${maxLengthPerChoice} characters long.`;
|
|
379
315
|
}
|
|
380
|
-
|
|
381
316
|
if (!getContent(content)) {
|
|
382
317
|
choicesErrors[id] = 'Tokens should not be empty.';
|
|
383
318
|
} else {
|
|
384
|
-
|
|
385
|
-
return c.content === content;
|
|
386
|
-
});
|
|
387
|
-
|
|
319
|
+
const identicalAnswer = reversedChoices.slice(index + 1).some(c => c.content === content);
|
|
388
320
|
if (identicalAnswer) {
|
|
389
321
|
choicesErrors[id] = 'Tokens content should be unique.';
|
|
390
322
|
}
|
|
391
323
|
}
|
|
392
324
|
});
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
325
|
+
const nbOfCategories = (categories || []).length;
|
|
326
|
+
const nbOfChoices = (choices || []).length;
|
|
396
327
|
if (nbOfCategories > maxCategories) {
|
|
397
|
-
errors.categoriesError =
|
|
328
|
+
errors.categoriesError = `No more than ${maxCategories} categories should be defined.`;
|
|
398
329
|
} else if (nbOfCategories < minCategories) {
|
|
399
|
-
errors.categoriesError =
|
|
330
|
+
errors.categoriesError = `There should be at least ${minCategories} category defined.`;
|
|
400
331
|
}
|
|
401
|
-
|
|
402
332
|
if (nbOfChoices < minChoices) {
|
|
403
|
-
errors.choicesError =
|
|
333
|
+
errors.choicesError = `There should be at least ${minChoices} choices defined.`;
|
|
404
334
|
} else if (nbOfChoices > maxAnswerChoices) {
|
|
405
|
-
errors.choicesError =
|
|
335
|
+
errors.choicesError = `No more than ${maxAnswerChoices} choices should be defined.`;
|
|
406
336
|
}
|
|
407
|
-
|
|
408
337
|
if (nbOfChoices && nbOfCategories) {
|
|
409
|
-
|
|
410
|
-
(correctResponse || []).forEach(
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
338
|
+
let hasAssociations = false;
|
|
339
|
+
(correctResponse || []).forEach(response => {
|
|
340
|
+
const {
|
|
341
|
+
choices = [],
|
|
342
|
+
alternateResponses = []
|
|
343
|
+
} = response;
|
|
416
344
|
if (choices.length) {
|
|
417
345
|
hasAssociations = true;
|
|
418
346
|
} else {
|
|
419
|
-
alternateResponses.forEach(
|
|
347
|
+
alternateResponses.forEach(alternate => {
|
|
420
348
|
if ((alternate || []).length) {
|
|
421
349
|
hasAssociations = true;
|
|
422
350
|
}
|
|
423
351
|
});
|
|
424
352
|
}
|
|
425
353
|
});
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
(correctResponse || []).forEach(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
354
|
+
let duplicateAlternateIndex = -1;
|
|
355
|
+
let duplicateCategory = '';
|
|
356
|
+
(correctResponse || []).forEach(response => {
|
|
357
|
+
const {
|
|
358
|
+
choices = [],
|
|
359
|
+
alternateResponses = [],
|
|
360
|
+
category
|
|
361
|
+
} = response;
|
|
435
362
|
if (duplicateAlternateIndex === -1) {
|
|
436
363
|
duplicateAlternateIndex = (0, _utils.isCorrectResponseDuplicated)(choices, alternateResponses);
|
|
437
|
-
|
|
438
364
|
if (duplicateAlternateIndex === -1) {
|
|
439
365
|
duplicateAlternateIndex = (0, _utils.isAlternateDuplicated)(alternateResponses);
|
|
440
366
|
}
|
|
441
|
-
|
|
442
367
|
duplicateCategory = category;
|
|
443
368
|
}
|
|
444
369
|
});
|
|
445
|
-
|
|
446
370
|
if (duplicateAlternateIndex > -1) {
|
|
447
371
|
errors.duplicateAlternate = {
|
|
448
372
|
index: duplicateAlternateIndex,
|
|
449
373
|
category: duplicateCategory
|
|
450
374
|
};
|
|
451
375
|
}
|
|
452
|
-
|
|
453
376
|
if (!hasAssociations) {
|
|
454
377
|
errors.associationError = 'At least one token should be assigned to at least one category.';
|
|
455
378
|
}
|
|
456
379
|
}
|
|
457
|
-
|
|
458
|
-
if (!(0, _isEmpty["default"])(choicesErrors)) {
|
|
380
|
+
if (!(0, _isEmpty.default)(choicesErrors)) {
|
|
459
381
|
errors.choicesErrors = choicesErrors;
|
|
460
382
|
}
|
|
461
|
-
|
|
462
|
-
if (!(0, _isEmpty["default"])(categoriesErrors)) {
|
|
383
|
+
if (!(0, _isEmpty.default)(categoriesErrors)) {
|
|
463
384
|
errors.categoriesErrors = categoriesErrors;
|
|
464
385
|
}
|
|
465
|
-
|
|
466
386
|
return errors;
|
|
467
387
|
};
|
|
468
|
-
|
|
469
388
|
exports.validate = validate;
|
|
470
389
|
//# sourceMappingURL=index.js.map
|