@pie-element/ebsr 12.3.4-next.0 → 13.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 +23 -36
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/index.js +114 -202
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +188 -271
- package/configure/lib/main.js.map +1 -1
- package/configure/node_modules/@pie-element/multiple-choice/CHANGELOG.json +1972 -0
- package/configure/node_modules/@pie-element/multiple-choice/CHANGELOG.md +4213 -0
- package/configure/node_modules/@pie-element/multiple-choice/PRINT.md +35 -0
- package/configure/node_modules/@pie-element/multiple-choice/README.md +56 -0
- package/configure/node_modules/@pie-element/multiple-choice/choice.png +0 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/CHANGELOG.json +1387 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/CHANGELOG.md +3351 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/__tests__/root.test.js +248 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/defaults.js +200 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/defaults.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/index.js +211 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/index.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/main.js +477 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/main.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/utils.js +18 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/lib/utils.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/configure/package.json +22 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/CHANGELOG.json +527 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/CHANGELOG.md +2316 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/__tests__/index.test.js +520 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/__tests__/utils.test.js +8 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/defaults.js +33 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/defaults.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/index.js +251 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/index.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/utils.js +16 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/lib/utils.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/controller/package.json +15 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/config-schema.json +2993 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/config-schema.json.md +2217 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/demo/config.js +8 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/demo/generate.js +61 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/demo/index.html +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/demo/pie.manifest.json +11 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/demo/session.js +7 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/pie-schema.json +1332 -0
- package/configure/node_modules/@pie-element/multiple-choice/docs/pie-schema.json.md +1015 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/choice-input-test.js +117 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/index-test.js +151 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/key-events-test.js +95 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/multiple-choice-test.js +223 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/session-updater-test.js +70 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/choice-input.js +370 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/choice-input.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/choice.js +197 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/choice.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/feedback-tick.js +130 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/feedback-tick.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/index.js +292 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/index.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/main.js +54 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/main.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/multiple-choice.js +386 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/multiple-choice.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/print.js +92 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/print.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/session-updater.js +37 -0
- package/configure/node_modules/@pie-element/multiple-choice/lib/session-updater.js.map +1 -0
- package/configure/node_modules/@pie-element/multiple-choice/package.json +39 -0
- package/configure/package.json +9 -6
- package/configure/src/__tests__/index.test.js +99 -108
- package/configure/src/index.js +13 -6
- package/configure/src/main.jsx +14 -18
- package/controller/lib/defaults.js +20 -32
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +224 -349
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +4 -18
- package/controller/lib/utils.js.map +1 -1
- package/controller/package.json +3 -3
- package/lib/index.js +113 -181
- package/lib/index.js.map +1 -1
- package/lib/print.js +120 -204
- package/lib/print.js.map +1 -1
- package/package.json +5 -9
- package/src/__tests__/index.test.js +18 -5
- package/configure/src/__tests__/__snapshots__/index.test.js.snap +0 -83
- package/module/configure.js +0 -1
- package/module/controller.js +0 -6469
- package/module/demo.js +0 -77
- package/module/element.js +0 -1
- package/module/index.html +0 -21
- package/module/manifest.json +0 -14
- package/module/print-demo.js +0 -115
- package/module/print.html +0 -18
- package/module/print.js +0 -1
package/controller/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
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
|
});
|
|
@@ -10,108 +9,77 @@ exports.model = model;
|
|
|
10
9
|
exports.normalize = void 0;
|
|
11
10
|
exports.outcome = outcome;
|
|
12
11
|
exports.validate = void 0;
|
|
13
|
-
|
|
14
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
15
|
-
|
|
16
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
17
|
-
|
|
18
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
19
|
-
|
|
20
|
-
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
21
|
-
|
|
22
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
23
|
-
|
|
24
12
|
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
25
|
-
|
|
26
13
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
27
|
-
|
|
28
14
|
var _utils = require("./utils");
|
|
29
|
-
|
|
30
15
|
var _get = _interopRequireDefault(require("lodash/get"));
|
|
31
|
-
|
|
32
16
|
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
|
33
|
-
|
|
34
17
|
var _translator = _interopRequireDefault(require("@pie-lib/translator"));
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (env.mode === 'evaluate') {
|
|
58
|
-
out.correct = !!choice.correct;
|
|
59
|
-
|
|
60
|
-
if (model.feedbackEnabled) {
|
|
61
|
-
var feedbackType = choice.feedback && choice.feedback.type || 'none';
|
|
62
|
-
|
|
63
|
-
if (feedbackType === 'default') {
|
|
64
|
-
out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];
|
|
65
|
-
} else if (feedbackType === 'custom') {
|
|
66
|
-
out.feedback = choice.feedback.value;
|
|
67
|
-
}
|
|
18
|
+
const {
|
|
19
|
+
translator
|
|
20
|
+
} = _translator.default;
|
|
21
|
+
const prepareChoice = (model, env, defaultFeedback) => choice => {
|
|
22
|
+
const out = {
|
|
23
|
+
label: choice.label,
|
|
24
|
+
value: choice.value
|
|
25
|
+
};
|
|
26
|
+
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
27
|
+
out.rationale = model.rationaleEnabled ? choice.rationale : null;
|
|
28
|
+
} else {
|
|
29
|
+
out.rationale = null;
|
|
30
|
+
}
|
|
31
|
+
if (env.mode === 'evaluate') {
|
|
32
|
+
out.correct = !!choice.correct;
|
|
33
|
+
if (model.feedbackEnabled) {
|
|
34
|
+
const feedbackType = choice.feedback && choice.feedback.type || 'none';
|
|
35
|
+
if (feedbackType === 'default') {
|
|
36
|
+
out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];
|
|
37
|
+
} else if (feedbackType === 'custom') {
|
|
38
|
+
out.feedback = choice.feedback.value;
|
|
68
39
|
}
|
|
69
40
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
73
43
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
var defaultFeedback = Object.assign({
|
|
44
|
+
const parsePart = (part, key, session, env) => {
|
|
45
|
+
const defaultFeedback = Object.assign({
|
|
77
46
|
correct: 'Correct',
|
|
78
47
|
incorrect: 'Incorrect'
|
|
79
48
|
}, part.defaultFeedback);
|
|
80
|
-
|
|
81
|
-
return
|
|
82
|
-
|
|
49
|
+
let choices = part.choices ? part.choices.map(prepareChoice(part, env, defaultFeedback)) : [];
|
|
50
|
+
return {
|
|
51
|
+
...part,
|
|
52
|
+
choices,
|
|
83
53
|
disabled: env.mode !== 'gather',
|
|
84
54
|
complete: {
|
|
85
|
-
min: part.choices.filter(
|
|
86
|
-
return c.correct;
|
|
87
|
-
}).length
|
|
55
|
+
min: part.choices.filter(c => c.correct).length
|
|
88
56
|
},
|
|
89
57
|
responseCorrect: env.mode === 'evaluate' ? (0, _utils.isResponseCorrect)(part, key, session) : undefined
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
var normalizePart = function normalizePart(model, base) {
|
|
94
|
-
return _objectSpread(_objectSpread(_objectSpread({}, base), model), {}, {
|
|
95
|
-
choicesLayout: model.choicesLayout || model.verticalMode === false && 'horizontal' || 'vertical'
|
|
96
|
-
});
|
|
58
|
+
};
|
|
97
59
|
};
|
|
60
|
+
const normalizePart = (model, base) => ({
|
|
61
|
+
...base,
|
|
62
|
+
...model,
|
|
63
|
+
choicesLayout: model.choicesLayout || model.verticalMode === false && 'horizontal' || 'vertical'
|
|
64
|
+
});
|
|
65
|
+
const normalize = ({
|
|
66
|
+
partA = {},
|
|
67
|
+
partB = {},
|
|
68
|
+
language,
|
|
69
|
+
...question
|
|
70
|
+
}) => ({
|
|
71
|
+
..._defaults.default,
|
|
72
|
+
...question,
|
|
73
|
+
partA: normalizePart(partA, {
|
|
74
|
+
..._defaults.default.partA,
|
|
75
|
+
language
|
|
76
|
+
}),
|
|
77
|
+
partB: normalizePart(partB, {
|
|
78
|
+
..._defaults.default.partB,
|
|
79
|
+
language
|
|
80
|
+
})
|
|
81
|
+
});
|
|
98
82
|
|
|
99
|
-
var normalize = function normalize(_ref) {
|
|
100
|
-
var _ref$partA = _ref.partA,
|
|
101
|
-
partA = _ref$partA === void 0 ? {} : _ref$partA,
|
|
102
|
-
_ref$partB = _ref.partB,
|
|
103
|
-
partB = _ref$partB === void 0 ? {} : _ref$partB,
|
|
104
|
-
language = _ref.language,
|
|
105
|
-
question = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
|
|
106
|
-
return _objectSpread(_objectSpread(_objectSpread({}, _defaults["default"]), question), {}, {
|
|
107
|
-
partA: normalizePart(partA, _objectSpread(_objectSpread({}, _defaults["default"].partA), {}, {
|
|
108
|
-
language: language
|
|
109
|
-
})),
|
|
110
|
-
partB: normalizePart(partB, _objectSpread(_objectSpread({}, _defaults["default"].partB), {}, {
|
|
111
|
-
language: language
|
|
112
|
-
}))
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
83
|
/**
|
|
116
84
|
*
|
|
117
85
|
* @param {*} question
|
|
@@ -119,185 +87,117 @@ var normalize = function normalize(_ref) {
|
|
|
119
87
|
* @param {*} env
|
|
120
88
|
* @param {*} updateSession - optional - a function that will set the properties passed into it on the session.
|
|
121
89
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
90
|
exports.normalize = normalize;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (normalizedQuestion.partLabels) {
|
|
200
|
-
language = normalizedQuestion.language;
|
|
201
|
-
partA.partLabel = translator.t('ebsr.part', {
|
|
202
|
-
lng: language,
|
|
203
|
-
index: normalizedQuestion.partLabelType === 'Letters' ? 'A' : '1'
|
|
204
|
-
});
|
|
205
|
-
partB.partLabel = translator.t('ebsr.part', {
|
|
206
|
-
lng: language,
|
|
207
|
-
index: normalizedQuestion.partLabelType === 'Letters' ? 'B' : '2'
|
|
208
|
-
});
|
|
209
|
-
} else {
|
|
210
|
-
partA.partLabel = undefined;
|
|
211
|
-
partB.partLabel = undefined;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
215
|
-
partA.teacherInstructions = normalizedQuestion.partA.teacherInstructionsEnabled ? normalizedQuestion.partA.teacherInstructions : null;
|
|
216
|
-
partB.teacherInstructions = normalizedQuestion.partB.teacherInstructionsEnabled ? normalizedQuestion.partB.teacherInstructions : null;
|
|
217
|
-
} else {
|
|
218
|
-
partA.teacherInstructions = null;
|
|
219
|
-
partB.teacherInstructions = null;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
partA.prompt = normalizedQuestion.partA.promptEnabled ? normalizedQuestion.partA.prompt : null;
|
|
223
|
-
partB.prompt = normalizedQuestion.partB.promptEnabled ? normalizedQuestion.partB.prompt : null;
|
|
224
|
-
return _context.abrupt("return", new Promise(function (resolve) {
|
|
225
|
-
resolve({
|
|
226
|
-
disabled: env.mode !== 'gather',
|
|
227
|
-
mode: env.mode,
|
|
228
|
-
extraCSSRules: normalizedQuestion.extraCSSRules,
|
|
229
|
-
partA: partA,
|
|
230
|
-
partB: partB
|
|
231
|
-
});
|
|
232
|
-
}));
|
|
233
|
-
|
|
234
|
-
case 25:
|
|
235
|
-
case "end":
|
|
236
|
-
return _context.stop();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}, _callee);
|
|
240
|
-
}));
|
|
241
|
-
return _model.apply(this, arguments);
|
|
91
|
+
async function model(question, session, env, updateSession) {
|
|
92
|
+
const normalizedQuestion = normalize(question);
|
|
93
|
+
const partA = parsePart(normalizedQuestion.partA, 'partA', session, env);
|
|
94
|
+
const partB = parsePart(normalizedQuestion.partB, 'partB', session, env);
|
|
95
|
+
const shuffledValues = {};
|
|
96
|
+
const us = part => (id, element, update) => new Promise(resolve => {
|
|
97
|
+
shuffledValues[part] = update.shuffledValues;
|
|
98
|
+
resolve();
|
|
99
|
+
});
|
|
100
|
+
const partASession = (0, _get.default)(session, 'value.partA');
|
|
101
|
+
const partALockChoiceOrder = (0, _controllerUtils.lockChoices)(normalizedQuestion.partA, partASession, env);
|
|
102
|
+
const {
|
|
103
|
+
choices: partAChoices
|
|
104
|
+
} = partA || {};
|
|
105
|
+
const {
|
|
106
|
+
choices: partBChoices
|
|
107
|
+
} = partB || {};
|
|
108
|
+
if (!partALockChoiceOrder && partAChoices && partAChoices.length) {
|
|
109
|
+
partA.choices = await (0, _controllerUtils.getShuffledChoices)(partAChoices, {
|
|
110
|
+
shuffledValues: (session.shuffledValues || {}).partA
|
|
111
|
+
}, us('partA'), 'value');
|
|
112
|
+
}
|
|
113
|
+
const partBSession = (0, _get.default)(session, 'value.partB');
|
|
114
|
+
const partBLockChoiceOrder = (0, _controllerUtils.lockChoices)(normalizedQuestion.partB, partBSession, env);
|
|
115
|
+
if (!partBLockChoiceOrder && partBChoices && partBChoices.length) {
|
|
116
|
+
partB.choices = await (0, _controllerUtils.getShuffledChoices)(partBChoices, {
|
|
117
|
+
shuffledValues: (session.shuffledValues || {}).partB
|
|
118
|
+
}, us('partB'), 'value');
|
|
119
|
+
}
|
|
120
|
+
if (!(0, _isEmpty.default)(shuffledValues)) {
|
|
121
|
+
if (updateSession && typeof updateSession === 'function') {
|
|
122
|
+
updateSession(session.id, session.element, {
|
|
123
|
+
shuffledValues
|
|
124
|
+
}).catch(e => {
|
|
125
|
+
// eslint-disable-next-line no-console
|
|
126
|
+
console.error('update session failed', e);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (normalizedQuestion.partLabels) {
|
|
131
|
+
const language = normalizedQuestion.language;
|
|
132
|
+
partA.partLabel = translator.t('ebsr.part', {
|
|
133
|
+
lng: language,
|
|
134
|
+
index: normalizedQuestion.partLabelType === 'Letters' ? 'A' : '1'
|
|
135
|
+
});
|
|
136
|
+
partB.partLabel = translator.t('ebsr.part', {
|
|
137
|
+
lng: language,
|
|
138
|
+
index: normalizedQuestion.partLabelType === 'Letters' ? 'B' : '2'
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
partA.partLabel = undefined;
|
|
142
|
+
partB.partLabel = undefined;
|
|
143
|
+
}
|
|
144
|
+
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
145
|
+
partA.teacherInstructions = normalizedQuestion.partA.teacherInstructionsEnabled ? normalizedQuestion.partA.teacherInstructions : null;
|
|
146
|
+
partB.teacherInstructions = normalizedQuestion.partB.teacherInstructionsEnabled ? normalizedQuestion.partB.teacherInstructions : null;
|
|
147
|
+
} else {
|
|
148
|
+
partA.teacherInstructions = null;
|
|
149
|
+
partB.teacherInstructions = null;
|
|
150
|
+
}
|
|
151
|
+
partA.prompt = normalizedQuestion.partA.promptEnabled ? normalizedQuestion.partA.prompt : null;
|
|
152
|
+
partB.prompt = normalizedQuestion.partB.promptEnabled ? normalizedQuestion.partB.prompt : null;
|
|
153
|
+
return new Promise(resolve => {
|
|
154
|
+
resolve({
|
|
155
|
+
disabled: env.mode !== 'gather',
|
|
156
|
+
mode: env.mode,
|
|
157
|
+
extraCSSRules: normalizedQuestion.extraCSSRules,
|
|
158
|
+
partA,
|
|
159
|
+
partB
|
|
160
|
+
});
|
|
161
|
+
});
|
|
242
162
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
resolve(_objectSpread(_objectSpread({}, _defaults["default"]), model));
|
|
163
|
+
const createDefaultModel = (model = {}) => new Promise(resolve => {
|
|
164
|
+
resolve({
|
|
165
|
+
..._defaults.default,
|
|
166
|
+
...model
|
|
248
167
|
});
|
|
249
|
-
};
|
|
250
|
-
|
|
168
|
+
});
|
|
251
169
|
exports.createDefaultModel = createDefaultModel;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
sessionPartValue = _ref3.value;
|
|
266
|
-
|
|
267
|
-
var chosen = function chosen(c) {
|
|
268
|
-
return !!(sessionPartValue || []).find(function (v) {
|
|
269
|
-
return v === c.value;
|
|
270
|
-
});
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
var correctAndNotChosen = function correctAndNotChosen(c) {
|
|
274
|
-
return isCorrect(c) && !chosen(c);
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
var incorrectAndChosen = function incorrectAndChosen(c) {
|
|
278
|
-
return !isCorrect(c) && chosen(c);
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
var correctChoices = choices.reduce(function (total, choice) {
|
|
170
|
+
const isCorrect = c => c.correct === true;
|
|
171
|
+
const getScore = (config, sessionPart, key, partialScoringEnabled) => {
|
|
172
|
+
const {
|
|
173
|
+
choices = []
|
|
174
|
+
} = config && config[key] || {};
|
|
175
|
+
const maxScore = choices.length;
|
|
176
|
+
const {
|
|
177
|
+
value: sessionPartValue
|
|
178
|
+
} = sessionPart || {};
|
|
179
|
+
const chosen = c => !!(sessionPartValue || []).find(v => v === c.value);
|
|
180
|
+
const correctAndNotChosen = c => isCorrect(c) && !chosen(c);
|
|
181
|
+
const incorrectAndChosen = c => !isCorrect(c) && chosen(c);
|
|
182
|
+
const correctChoices = choices.reduce((total, choice) => {
|
|
282
183
|
if (correctAndNotChosen(choice) || incorrectAndChosen(choice)) {
|
|
283
184
|
return total - 1;
|
|
284
185
|
} else {
|
|
285
186
|
return total;
|
|
286
187
|
}
|
|
287
|
-
}, choices.length);
|
|
188
|
+
}, choices.length);
|
|
288
189
|
|
|
190
|
+
// determine score for a part
|
|
289
191
|
if (!partialScoringEnabled && correctChoices < maxScore) {
|
|
290
192
|
return 0;
|
|
291
193
|
}
|
|
292
|
-
|
|
293
194
|
return parseFloat(maxScore ? (correctChoices / maxScore).toFixed(2) : 0);
|
|
294
195
|
};
|
|
295
|
-
|
|
296
196
|
function outcome(config, session, env) {
|
|
297
|
-
return new Promise(
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
197
|
+
return new Promise(resolve => {
|
|
198
|
+
const {
|
|
199
|
+
value
|
|
200
|
+
} = session || {};
|
|
301
201
|
if (!session || !value) {
|
|
302
202
|
resolve({
|
|
303
203
|
score: 0,
|
|
@@ -306,24 +206,21 @@ function outcome(config, session, env) {
|
|
|
306
206
|
empty: true
|
|
307
207
|
});
|
|
308
208
|
}
|
|
309
|
-
|
|
310
209
|
if (value) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
var scoreB = getScore(config, partB, 'partB', partialScoringEnabled);
|
|
319
|
-
|
|
210
|
+
const {
|
|
211
|
+
partA,
|
|
212
|
+
partB
|
|
213
|
+
} = value || {};
|
|
214
|
+
const partialScoringEnabled = _controllerUtils.partialScoring.enabled(config, env);
|
|
215
|
+
const scoreA = getScore(config, partA, 'partA', partialScoringEnabled);
|
|
216
|
+
const scoreB = getScore(config, partB, 'partB', partialScoringEnabled);
|
|
320
217
|
if (!partialScoringEnabled) {
|
|
321
218
|
// The EBSR item is worth 1 point
|
|
322
219
|
// That point is awarded if and only if both parts are fully correct, otherwise no points are awarded
|
|
323
220
|
resolve({
|
|
324
221
|
score: scoreA === 1 && scoreB === 1 ? 1 : 0,
|
|
325
|
-
scoreA
|
|
326
|
-
scoreB
|
|
222
|
+
scoreA,
|
|
223
|
+
scoreB,
|
|
327
224
|
max: 1
|
|
328
225
|
});
|
|
329
226
|
} else {
|
|
@@ -333,16 +230,16 @@ function outcome(config, session, env) {
|
|
|
333
230
|
// If Part A and Part B are both correct, 2 points are awarded
|
|
334
231
|
resolve({
|
|
335
232
|
score: 2,
|
|
336
|
-
scoreA
|
|
337
|
-
scoreB
|
|
233
|
+
scoreA,
|
|
234
|
+
scoreB,
|
|
338
235
|
max: 2
|
|
339
236
|
});
|
|
340
237
|
} else {
|
|
341
238
|
// If Part A is correct and part B is incorrect, 1 point is awarded
|
|
342
239
|
resolve({
|
|
343
240
|
score: 1,
|
|
344
|
-
scoreA
|
|
345
|
-
scoreB
|
|
241
|
+
scoreA,
|
|
242
|
+
scoreB,
|
|
346
243
|
max: 2
|
|
347
244
|
});
|
|
348
245
|
}
|
|
@@ -350,8 +247,8 @@ function outcome(config, session, env) {
|
|
|
350
247
|
// For all other combinations, no points are awarded
|
|
351
248
|
resolve({
|
|
352
249
|
score: 0,
|
|
353
|
-
scoreA
|
|
354
|
-
scoreB
|
|
250
|
+
scoreA,
|
|
251
|
+
scoreB,
|
|
355
252
|
max: 2
|
|
356
253
|
});
|
|
357
254
|
}
|
|
@@ -359,27 +256,28 @@ function outcome(config, session, env) {
|
|
|
359
256
|
}
|
|
360
257
|
});
|
|
361
258
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
259
|
+
const returnPartCorrect = choices => {
|
|
260
|
+
let answers = [];
|
|
261
|
+
choices.forEach(i => {
|
|
262
|
+
const {
|
|
263
|
+
correct,
|
|
264
|
+
value
|
|
265
|
+
} = i;
|
|
369
266
|
if (correct) {
|
|
370
267
|
answers.push(value);
|
|
371
268
|
}
|
|
372
269
|
});
|
|
373
270
|
return answers;
|
|
374
271
|
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
return new Promise(function (resolve) {
|
|
272
|
+
const createCorrectResponseSession = (question, env) => {
|
|
273
|
+
return new Promise(resolve => {
|
|
378
274
|
if (env.mode !== 'evaluate' && env.role === 'instructor') {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
275
|
+
const {
|
|
276
|
+
partA,
|
|
277
|
+
partB
|
|
278
|
+
} = question;
|
|
279
|
+
const partACorrect = returnPartCorrect(partA.choices);
|
|
280
|
+
const partBCorrect = returnPartCorrect(partB.choices);
|
|
383
281
|
resolve({
|
|
384
282
|
value: {
|
|
385
283
|
partA: {
|
|
@@ -397,109 +295,86 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
|
|
|
397
295
|
resolve(null);
|
|
398
296
|
}
|
|
399
297
|
});
|
|
400
|
-
}; // remove all html tags
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
404
|
-
|
|
405
|
-
var getInnerText = function getInnerText(html) {
|
|
406
|
-
return (html || '').replaceAll(/<[^>]*>/g, '');
|
|
407
|
-
}; // remove all html tags except img, iframe and source tag for audio
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
var getContent = function getContent(html) {
|
|
411
|
-
return (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
412
298
|
};
|
|
413
299
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
300
|
+
// remove all html tags
|
|
301
|
+
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
302
|
+
const getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, '');
|
|
303
|
+
|
|
304
|
+
// remove all html tags except img, iframe and source tag for audio
|
|
305
|
+
const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
306
|
+
const validatePart = (model = {}, config = {}) => {
|
|
307
|
+
const {
|
|
308
|
+
choices
|
|
309
|
+
} = model;
|
|
310
|
+
const {
|
|
311
|
+
minAnswerChoices = 2,
|
|
312
|
+
maxAnswerChoices
|
|
313
|
+
} = config;
|
|
314
|
+
const reversedChoices = [...(choices || [])].reverse();
|
|
315
|
+
const errors = {};
|
|
316
|
+
const choicesErrors = {};
|
|
317
|
+
const rationaleErrors = {};
|
|
318
|
+
let hasCorrectResponse = false;
|
|
319
|
+
['teacherInstructions', 'prompt'].forEach(field => {
|
|
320
|
+
if (config[field]?.required && !getContent(model[field])) {
|
|
430
321
|
errors[field] = 'This field is required.';
|
|
431
322
|
}
|
|
432
323
|
});
|
|
433
|
-
reversedChoices.forEach(
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
324
|
+
reversedChoices.forEach((choice, index) => {
|
|
325
|
+
const {
|
|
326
|
+
correct,
|
|
327
|
+
value,
|
|
328
|
+
label,
|
|
329
|
+
rationale
|
|
330
|
+
} = choice;
|
|
441
331
|
if (correct) {
|
|
442
332
|
hasCorrectResponse = true;
|
|
443
333
|
}
|
|
444
|
-
|
|
445
334
|
if (!getContent(label)) {
|
|
446
335
|
choicesErrors[value] = 'Content should not be empty.';
|
|
447
336
|
} else {
|
|
448
|
-
|
|
449
|
-
return c.label === label;
|
|
450
|
-
});
|
|
451
|
-
|
|
337
|
+
const identicalAnswer = reversedChoices.slice(index + 1).some(c => c.label === label);
|
|
452
338
|
if (identicalAnswer) {
|
|
453
339
|
choicesErrors[value] = 'Content should be unique.';
|
|
454
340
|
}
|
|
455
341
|
}
|
|
456
|
-
|
|
457
|
-
if ((_config$rationale = config.rationale) !== null && _config$rationale !== void 0 && _config$rationale.required && !getContent(rationale)) {
|
|
342
|
+
if (config.rationale?.required && !getContent(rationale)) {
|
|
458
343
|
rationaleErrors[value] = 'This field is required.';
|
|
459
344
|
}
|
|
460
345
|
});
|
|
461
|
-
|
|
462
|
-
|
|
346
|
+
const nbOfChoices = (choices || []).length;
|
|
463
347
|
if (nbOfChoices < minAnswerChoices) {
|
|
464
|
-
errors.answerChoices =
|
|
348
|
+
errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;
|
|
465
349
|
} else if (nbOfChoices > maxAnswerChoices) {
|
|
466
|
-
errors.answerChoices =
|
|
350
|
+
errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;
|
|
467
351
|
}
|
|
468
|
-
|
|
469
352
|
if (!hasCorrectResponse) {
|
|
470
353
|
errors.correctResponse = 'No correct response defined.';
|
|
471
354
|
}
|
|
472
|
-
|
|
473
|
-
if (!(0, _isEmpty["default"])(choicesErrors)) {
|
|
355
|
+
if (!(0, _isEmpty.default)(choicesErrors)) {
|
|
474
356
|
errors.choices = choicesErrors;
|
|
475
357
|
}
|
|
476
|
-
|
|
477
|
-
if (!(0, _isEmpty["default"])(rationaleErrors)) {
|
|
358
|
+
if (!(0, _isEmpty.default)(rationaleErrors)) {
|
|
478
359
|
errors.rationale = rationaleErrors;
|
|
479
360
|
}
|
|
480
|
-
|
|
481
361
|
return errors;
|
|
482
362
|
};
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
partBConfig = _ref7.partB;
|
|
495
|
-
|
|
496
|
-
var partAErrors = validatePart(partA, partAConfig);
|
|
497
|
-
var partBErrors = validatePart(partB, partBConfig);
|
|
363
|
+
const validate = (model = {}, config = {}) => {
|
|
364
|
+
const {
|
|
365
|
+
partA,
|
|
366
|
+
partB
|
|
367
|
+
} = model || {};
|
|
368
|
+
const {
|
|
369
|
+
partA: partAConfig,
|
|
370
|
+
partB: partBConfig
|
|
371
|
+
} = config || {};
|
|
372
|
+
const partAErrors = validatePart(partA, partAConfig);
|
|
373
|
+
const partBErrors = validatePart(partB, partBConfig);
|
|
498
374
|
return {
|
|
499
375
|
partA: partAErrors,
|
|
500
376
|
partB: partBErrors
|
|
501
377
|
};
|
|
502
378
|
};
|
|
503
|
-
|
|
504
379
|
exports.validate = validate;
|
|
505
380
|
//# sourceMappingURL=index.js.map
|