@pie-element/match 11.0.5-esm.1 → 11.1.2-next.1
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/CHANGELOG.md +1083 -2579
- package/configure/CHANGELOG.md +928 -2260
- package/configure/lib/add-row.js +27 -73
- package/configure/lib/add-row.js.map +1 -1
- package/configure/lib/answer-config-block.js +262 -335
- package/configure/lib/answer-config-block.js.map +1 -1
- package/configure/lib/common.js +18 -33
- package/configure/lib/common.js.map +1 -1
- package/configure/lib/configure.js +330 -420
- package/configure/lib/configure.js.map +1 -1
- package/configure/lib/defaults.js +5 -4
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/general-config-block.js +123 -190
- package/configure/lib/general-config-block.js.map +1 -1
- package/configure/lib/index.js +117 -190
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/row.js +283 -373
- package/configure/lib/row.js.map +1 -1
- package/configure/lib/utils.js +4 -15
- package/configure/lib/utils.js.map +1 -1
- package/configure/package.json +15 -14
- package/controller/CHANGELOG.md +630 -1541
- package/controller/lib/defaults.js +2 -3
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +173 -301
- package/controller/lib/index.js.map +1 -1
- package/controller/package.json +6 -6
- package/lib/answer-grid.js +145 -242
- package/lib/answer-grid.js.map +1 -1
- package/lib/index.js +59 -108
- package/lib/index.js.map +1 -1
- package/lib/main.js +123 -191
- package/lib/main.js.map +1 -1
- package/package.json +15 -29
- package/esm/configure.js +0 -3936
- package/esm/configure.js.map +0 -1
- package/esm/controller.js +0 -428
- package/esm/controller.js.map +0 -1
- package/esm/element.js +0 -472
- package/esm/element.js.map +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
|
});
|
|
@@ -9,61 +8,29 @@ exports.createCorrectResponseSession = void 0;
|
|
|
9
8
|
exports.createDefaultModel = createDefaultModel;
|
|
10
9
|
exports.model = model;
|
|
11
10
|
exports.validate = exports.outcome = exports.normalize = void 0;
|
|
12
|
-
|
|
13
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
14
|
-
|
|
15
|
-
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
16
|
-
|
|
17
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
18
|
-
|
|
19
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
20
|
-
|
|
21
|
-
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
22
|
-
|
|
23
|
-
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
|
24
|
-
|
|
25
|
-
var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
|
|
26
|
-
|
|
11
|
+
var _lodashEs = require("lodash-es");
|
|
27
12
|
var _feedback = require("@pie-lib/feedback");
|
|
28
|
-
|
|
29
13
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
30
|
-
|
|
31
14
|
var _debug = _interopRequireDefault(require("debug"));
|
|
32
|
-
|
|
33
15
|
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
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; }
|
|
40
|
-
|
|
41
|
-
var log = (0, _debug["default"])('@pie-element:match:controller');
|
|
42
|
-
|
|
43
|
-
var getResponseCorrectness = function getResponseCorrectness(model, answers) {
|
|
44
|
-
var env = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
45
|
-
|
|
46
|
-
var isPartialScoring = _controllerUtils.partialScoring.enabled(model, env);
|
|
47
|
-
|
|
48
|
-
var rows = model.rows;
|
|
49
|
-
var checkboxMode = model.choiceMode === 'checkbox';
|
|
50
|
-
|
|
16
|
+
const log = (0, _debug.default)('@pie-element:match:controller');
|
|
17
|
+
const getResponseCorrectness = (model, answers, env = {}) => {
|
|
18
|
+
const isPartialScoring = _controllerUtils.partialScoring.enabled(model, env);
|
|
19
|
+
const rows = model.rows;
|
|
20
|
+
const checkboxMode = model.choiceMode === 'checkbox';
|
|
51
21
|
if (!answers || Object.keys(answers).length === 0) {
|
|
52
22
|
return 'unanswered';
|
|
53
23
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
var incorrectAnswers = 0;
|
|
58
|
-
|
|
24
|
+
const totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);
|
|
25
|
+
let correctAnswers;
|
|
26
|
+
let incorrectAnswers = 0;
|
|
59
27
|
if (checkboxMode) {
|
|
60
|
-
|
|
28
|
+
const checkboxes = getCheckboxes(rows, answers);
|
|
61
29
|
correctAnswers = checkboxes.correctAnswers;
|
|
62
30
|
incorrectAnswers = checkboxes.incorrectAnswers;
|
|
63
31
|
} else {
|
|
64
32
|
correctAnswers = getCorrectRadios(rows, answers);
|
|
65
33
|
}
|
|
66
|
-
|
|
67
34
|
if (totalCorrectAnswers === correctAnswers && !incorrectAnswers) {
|
|
68
35
|
return 'correct';
|
|
69
36
|
} else if (correctAnswers === 0) {
|
|
@@ -71,26 +38,20 @@ var getResponseCorrectness = function getResponseCorrectness(model, answers) {
|
|
|
71
38
|
} else if (isPartialScoring) {
|
|
72
39
|
return 'partial';
|
|
73
40
|
}
|
|
74
|
-
|
|
75
41
|
return 'incorrect';
|
|
76
42
|
};
|
|
77
|
-
|
|
78
|
-
var getCorrectness = function getCorrectness(question, env) {
|
|
79
|
-
var answers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
80
|
-
|
|
43
|
+
const getCorrectness = (question, env, answers = {}) => {
|
|
81
44
|
if (env.mode === 'evaluate') {
|
|
82
45
|
return getResponseCorrectness(question, answers, env);
|
|
83
46
|
}
|
|
84
47
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
var answer = answers[row.id];
|
|
91
|
-
|
|
48
|
+
const getCheckboxes = (rows, answers) => {
|
|
49
|
+
let correctAnswers = 0;
|
|
50
|
+
let incorrectAnswers = 0;
|
|
51
|
+
rows.forEach(row => {
|
|
52
|
+
const answer = answers[row.id];
|
|
92
53
|
if (answer) {
|
|
93
|
-
row.values.forEach(
|
|
54
|
+
row.values.forEach((v, i) => {
|
|
94
55
|
if (answer[i] && answer[i] === v) {
|
|
95
56
|
correctAnswers += 1;
|
|
96
57
|
} else if (answer[i] && answer[i] !== v) {
|
|
@@ -100,31 +61,28 @@ var getCheckboxes = function getCheckboxes(rows, answers) {
|
|
|
100
61
|
}
|
|
101
62
|
});
|
|
102
63
|
return {
|
|
103
|
-
correctAnswers
|
|
104
|
-
incorrectAnswers
|
|
64
|
+
correctAnswers,
|
|
65
|
+
incorrectAnswers
|
|
105
66
|
};
|
|
106
67
|
};
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if ((0, _isEqual["default"])(row.values, answers[row.id])) {
|
|
68
|
+
const getCorrectRadios = (rows, answers) => {
|
|
69
|
+
let correctAnswers = 0;
|
|
70
|
+
rows.forEach(row => {
|
|
71
|
+
if ((0, _lodashEs.isEqual)(row.values, answers[row.id])) {
|
|
112
72
|
correctAnswers += 1;
|
|
113
73
|
}
|
|
114
74
|
});
|
|
115
75
|
return correctAnswers;
|
|
116
76
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
var matchingTable = checkboxMode ? question.layout - 1 : 1;
|
|
77
|
+
const getTotalCorrect = question => {
|
|
78
|
+
const checkboxMode = question.choiceMode === 'checkbox';
|
|
79
|
+
const matchingTable = checkboxMode ? question.layout - 1 : 1;
|
|
121
80
|
return (question.rows.length || 0) * matchingTable;
|
|
122
81
|
};
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
row.values.forEach(function (value) {
|
|
82
|
+
const getTotalCorrectAnswers = question => {
|
|
83
|
+
let noOfTotalCorrectAnswers = 0;
|
|
84
|
+
question.rows.forEach(row => {
|
|
85
|
+
row.values.forEach(value => {
|
|
128
86
|
if (value) {
|
|
129
87
|
noOfTotalCorrectAnswers += 1;
|
|
130
88
|
}
|
|
@@ -132,78 +90,68 @@ var getTotalCorrectAnswers = function getTotalCorrectAnswers(question) {
|
|
|
132
90
|
});
|
|
133
91
|
return noOfTotalCorrectAnswers;
|
|
134
92
|
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
var checkboxMode = question.choiceMode === 'checkbox';
|
|
138
|
-
|
|
93
|
+
const getPartialScore = (question, answers) => {
|
|
94
|
+
const checkboxMode = question.choiceMode === 'checkbox';
|
|
139
95
|
if (checkboxMode) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
96
|
+
const {
|
|
97
|
+
correctAnswers,
|
|
98
|
+
incorrectAnswers
|
|
99
|
+
} = getCheckboxes(question.rows, answers);
|
|
100
|
+
const totalCorrect = getTotalCorrectAnswers(question);
|
|
101
|
+
const total = totalCorrect === 0 ? 1 : totalCorrect;
|
|
147
102
|
if (correctAnswers + incorrectAnswers > totalCorrect) {
|
|
148
|
-
|
|
149
|
-
|
|
103
|
+
const extraAnswers = correctAnswers + incorrectAnswers - totalCorrect;
|
|
104
|
+
const score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));
|
|
150
105
|
return score < 0 ? 0 : score;
|
|
151
106
|
} else {
|
|
152
107
|
return parseFloat((correctAnswers / total).toFixed(2));
|
|
153
108
|
}
|
|
154
109
|
} else {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return parseFloat((_correctAnswers / _totalCorrect).toFixed(2));
|
|
110
|
+
const correctAnswers = getCorrectRadios(question.rows, answers);
|
|
111
|
+
const totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);
|
|
112
|
+
return parseFloat((correctAnswers / totalCorrect).toFixed(2));
|
|
160
113
|
}
|
|
161
114
|
};
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
var correctness = getCorrectness(question, env, answers);
|
|
166
|
-
|
|
167
|
-
var isPartialScoring = _controllerUtils.partialScoring.enabled(question, env);
|
|
168
|
-
|
|
115
|
+
const getOutComeScore = (question, env, answers = {}) => {
|
|
116
|
+
const correctness = getCorrectness(question, env, answers);
|
|
117
|
+
const isPartialScoring = _controllerUtils.partialScoring.enabled(question, env);
|
|
169
118
|
return correctness === 'correct' ? 1 : correctness === 'partial' && isPartialScoring ? getPartialScore(question, answers) : 0;
|
|
170
119
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return new Promise(function (resolve) {
|
|
120
|
+
const outcome = (question, session, env) => {
|
|
121
|
+
return new Promise(resolve => {
|
|
174
122
|
if (env.mode !== 'evaluate') {
|
|
175
123
|
resolve({
|
|
176
124
|
score: undefined,
|
|
177
125
|
completed: undefined
|
|
178
126
|
});
|
|
179
127
|
} else {
|
|
180
|
-
if (!session || (0,
|
|
128
|
+
if (!session || (0, _lodashEs.isEmpty)(session)) {
|
|
181
129
|
resolve({
|
|
182
130
|
score: 0,
|
|
183
131
|
empty: true
|
|
184
132
|
});
|
|
185
133
|
}
|
|
186
|
-
|
|
187
|
-
var out = {
|
|
134
|
+
const out = {
|
|
188
135
|
score: getOutComeScore(question, env, session.answers)
|
|
189
136
|
};
|
|
190
137
|
resolve(out);
|
|
191
138
|
}
|
|
192
139
|
});
|
|
193
140
|
};
|
|
194
|
-
|
|
195
141
|
exports.outcome = outcome;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
142
|
+
function createDefaultModel(model = {}) {
|
|
143
|
+
return new Promise(resolve => {
|
|
144
|
+
resolve({
|
|
145
|
+
..._defaults.default,
|
|
146
|
+
...model
|
|
147
|
+
});
|
|
201
148
|
});
|
|
202
149
|
}
|
|
150
|
+
const normalize = question => ({
|
|
151
|
+
..._defaults.default,
|
|
152
|
+
...question
|
|
153
|
+
});
|
|
203
154
|
|
|
204
|
-
var normalize = function normalize(question) {
|
|
205
|
-
return _objectSpread(_objectSpread({}, _defaults["default"]), question);
|
|
206
|
-
};
|
|
207
155
|
/**
|
|
208
156
|
*
|
|
209
157
|
* @param {*} question
|
|
@@ -211,258 +159,182 @@ var normalize = function normalize(question) {
|
|
|
211
159
|
* @param {*} env
|
|
212
160
|
* @param {*} updateSession - optional - a function that will set the properties passed into it on the session.
|
|
213
161
|
*/
|
|
214
|
-
|
|
215
|
-
|
|
216
162
|
exports.normalize = normalize;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
feedback: feedback,
|
|
277
|
-
disabled: env.mode !== 'gather',
|
|
278
|
-
view: env.mode === 'view'
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
282
|
-
out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;
|
|
283
|
-
out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;
|
|
284
|
-
} else {
|
|
285
|
-
out.rationale = null;
|
|
286
|
-
out.teacherInstructions = null;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (env.mode === 'evaluate') {
|
|
290
|
-
Object.assign(out, {
|
|
291
|
-
correctResponse: correctResponse,
|
|
292
|
-
correctness: correctInfo
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
log('out: ', out);
|
|
297
|
-
resolve(out);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
case 12:
|
|
301
|
-
case "end":
|
|
302
|
-
return _context.stop();
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}, _callee);
|
|
306
|
-
}));
|
|
307
|
-
|
|
308
|
-
return function (_x) {
|
|
309
|
-
return _ref.apply(this, arguments);
|
|
310
|
-
};
|
|
311
|
-
}());
|
|
163
|
+
async function model(question, session, env, updateSession) {
|
|
164
|
+
const normalizedQuestion = (0, _lodashEs.cloneDeep)(normalize(question));
|
|
165
|
+
let correctness, score;
|
|
166
|
+
if ((!session || (0, _lodashEs.isEmpty)(session)) && env.mode === 'evaluate') {
|
|
167
|
+
correctness = 'unanswered';
|
|
168
|
+
score = '0%';
|
|
169
|
+
} else {
|
|
170
|
+
correctness = getCorrectness(normalizedQuestion, env, session && session.answers);
|
|
171
|
+
score = `${getOutComeScore(normalizedQuestion, env, session && session.answers) * 100}%`;
|
|
172
|
+
}
|
|
173
|
+
const correctResponse = {};
|
|
174
|
+
const correctInfo = {
|
|
175
|
+
score,
|
|
176
|
+
correctness
|
|
177
|
+
};
|
|
178
|
+
const lockChoiceOrder = (0, _controllerUtils.lockChoices)(normalizedQuestion, session, env);
|
|
179
|
+
if (!lockChoiceOrder) {
|
|
180
|
+
normalizedQuestion.rows = await (0, _controllerUtils.getShuffledChoices)(normalizedQuestion.rows, session, updateSession, 'id');
|
|
181
|
+
}
|
|
182
|
+
normalizedQuestion.rows.forEach(row => {
|
|
183
|
+
correctResponse[row.id] = row.values;
|
|
184
|
+
if (env.mode !== 'evaluate') {
|
|
185
|
+
delete row.values;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const feedback = env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled ? await (0, _feedback.getFeedbackForCorrectness)(correctInfo.correctness, normalizedQuestion.feedback) : undefined;
|
|
189
|
+
const {
|
|
190
|
+
extraCSSRules,
|
|
191
|
+
feedbackEnabled,
|
|
192
|
+
promptEnabled,
|
|
193
|
+
prompt,
|
|
194
|
+
lockChoiceOrder: _,
|
|
195
|
+
...essentials
|
|
196
|
+
} = normalizedQuestion;
|
|
197
|
+
const out = {
|
|
198
|
+
...essentials,
|
|
199
|
+
extraCSSRules,
|
|
200
|
+
allowFeedback: feedbackEnabled,
|
|
201
|
+
prompt: promptEnabled ? prompt : null,
|
|
202
|
+
shuffled: !lockChoiceOrder,
|
|
203
|
+
feedback,
|
|
204
|
+
disabled: env.mode !== 'gather',
|
|
205
|
+
view: env.mode === 'view'
|
|
206
|
+
};
|
|
207
|
+
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
208
|
+
out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;
|
|
209
|
+
out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;
|
|
210
|
+
} else {
|
|
211
|
+
out.rationale = null;
|
|
212
|
+
out.teacherInstructions = null;
|
|
213
|
+
}
|
|
214
|
+
if (env.mode === 'evaluate') {
|
|
215
|
+
Object.assign(out, {
|
|
216
|
+
correctResponse,
|
|
217
|
+
correctness: correctInfo
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
log('out: ', out);
|
|
221
|
+
return out;
|
|
312
222
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return new Promise(function (resolve) {
|
|
223
|
+
const createCorrectResponseSession = (question, env) => {
|
|
224
|
+
return new Promise(resolve => {
|
|
316
225
|
if (env.mode !== 'evaluate' && env.role === 'instructor') {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
226
|
+
const {
|
|
227
|
+
rows
|
|
228
|
+
} = question;
|
|
229
|
+
const answers = {};
|
|
230
|
+
rows.forEach(r => {
|
|
320
231
|
answers[r.id] = r.values;
|
|
321
232
|
});
|
|
322
233
|
resolve({
|
|
323
|
-
answers
|
|
234
|
+
answers,
|
|
324
235
|
id: '1'
|
|
325
236
|
});
|
|
326
237
|
} else {
|
|
327
238
|
resolve(null);
|
|
328
239
|
}
|
|
329
240
|
});
|
|
330
|
-
}; // remove all html tags
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
334
|
-
|
|
335
|
-
var getInnerText = function getInnerText(html) {
|
|
336
|
-
return (html || '').replaceAll(/<[^>]*>/g, '');
|
|
337
|
-
}; // remove all html tags except img, iframe and source tag for audio
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
var getContent = function getContent(html) {
|
|
341
|
-
return (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
342
241
|
};
|
|
343
242
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
243
|
+
// remove all html tags
|
|
244
|
+
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
245
|
+
const getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, '');
|
|
246
|
+
|
|
247
|
+
// remove all html tags except img, iframe and source tag for audio
|
|
248
|
+
const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
249
|
+
const validate = (model = {}, config = {}) => {
|
|
250
|
+
const {
|
|
251
|
+
rows,
|
|
252
|
+
choiceMode,
|
|
253
|
+
headers
|
|
254
|
+
} = model;
|
|
255
|
+
const {
|
|
256
|
+
minQuestions,
|
|
257
|
+
maxQuestions,
|
|
258
|
+
maxLengthQuestionsHeading,
|
|
259
|
+
maxAnswers,
|
|
260
|
+
maxLengthAnswers,
|
|
261
|
+
maxLengthFirstColumnHeading
|
|
262
|
+
} = config;
|
|
263
|
+
const rowsErrors = {};
|
|
264
|
+
const columnsErrors = {};
|
|
265
|
+
const errors = {};
|
|
266
|
+
['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
|
|
267
|
+
if (config[field]?.required && !getContent(model[field])) {
|
|
363
268
|
errors[field] = 'This field is required.';
|
|
364
269
|
}
|
|
365
270
|
});
|
|
366
|
-
|
|
367
271
|
if (rows.length < minQuestions) {
|
|
368
|
-
errors.noOfRowsError =
|
|
272
|
+
errors.noOfRowsError = `There should be at least ${minQuestions} question rows.`;
|
|
369
273
|
} else if (rows.length > maxQuestions) {
|
|
370
|
-
errors.noOfRowsError =
|
|
274
|
+
errors.noOfRowsError = `No more than ${maxQuestions} question rows should be defined.`;
|
|
371
275
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
276
|
+
(rows || []).forEach((row, index) => {
|
|
277
|
+
const {
|
|
278
|
+
id,
|
|
279
|
+
values = [],
|
|
280
|
+
title
|
|
281
|
+
} = row;
|
|
378
282
|
rowsErrors[id] = '';
|
|
379
|
-
|
|
380
283
|
if (maxLengthQuestionsHeading && getInnerText(title).length > maxLengthQuestionsHeading) {
|
|
381
|
-
rowsErrors[id] +=
|
|
284
|
+
rowsErrors[id] += `Content length should be maximum ${maxLengthQuestionsHeading} characters. `;
|
|
382
285
|
}
|
|
383
|
-
|
|
384
286
|
if (!getContent(title)) {
|
|
385
287
|
rowsErrors[id] += 'Content should not be empty. ';
|
|
386
288
|
} else {
|
|
387
289
|
// check for identical content with the previous answers
|
|
388
|
-
|
|
389
|
-
return getContent(r.title) === getContent(title);
|
|
390
|
-
});
|
|
391
|
-
|
|
290
|
+
const identicalAnswer = rows.slice(0, index).some(r => getContent(r.title) === getContent(title));
|
|
392
291
|
if (identicalAnswer) {
|
|
393
292
|
rowsErrors[id] += 'Content should be unique. ';
|
|
394
293
|
}
|
|
395
294
|
}
|
|
396
|
-
|
|
397
|
-
var hasCorrectResponse = values.some(function (value) {
|
|
398
|
-
return !!value;
|
|
399
|
-
});
|
|
400
|
-
|
|
295
|
+
const hasCorrectResponse = values.some(value => !!value);
|
|
401
296
|
if (!hasCorrectResponse) {
|
|
402
297
|
rowsErrors[id] += 'No correct response defined.';
|
|
403
298
|
}
|
|
404
299
|
});
|
|
405
|
-
|
|
406
300
|
if (maxAnswers && headers.length - 1 > maxAnswers) {
|
|
407
|
-
errors.columnsLengthError =
|
|
301
|
+
errors.columnsLengthError = `There should be maximum ${maxAnswers} answers.`;
|
|
408
302
|
}
|
|
409
|
-
|
|
410
303
|
if (maxLengthFirstColumnHeading && headers[0].length > maxLengthFirstColumnHeading) {
|
|
411
|
-
columnsErrors[0] =
|
|
304
|
+
columnsErrors[0] = `Content length should be maximum ${maxLengthFirstColumnHeading} characters.`;
|
|
412
305
|
}
|
|
413
|
-
|
|
414
|
-
var headersContent = (headers || []).map(function (heading) {
|
|
415
|
-
return getContent(heading);
|
|
416
|
-
});
|
|
306
|
+
const headersContent = (headers || []).map(heading => getContent(heading));
|
|
417
307
|
headersContent.shift(); // remove first column since it does not require validation
|
|
418
308
|
|
|
419
|
-
headersContent.forEach(
|
|
420
|
-
|
|
421
|
-
|
|
309
|
+
headersContent.forEach((heading, index) => {
|
|
310
|
+
const headerIndex = index + 1; // we need to add 1 because we removed first header from validation
|
|
422
311
|
columnsErrors[headerIndex] = '';
|
|
423
|
-
|
|
424
312
|
if (maxLengthAnswers && getInnerText(heading).length > maxLengthAnswers) {
|
|
425
|
-
columnsErrors[headerIndex] +=
|
|
313
|
+
columnsErrors[headerIndex] += `Content length should be maximum ${maxLengthAnswers} characters. `;
|
|
426
314
|
}
|
|
427
|
-
|
|
428
315
|
if (!heading) {
|
|
429
316
|
columnsErrors[headerIndex] += 'Content should not be empty.';
|
|
430
317
|
} else {
|
|
431
318
|
// check for identical content with the previous headers
|
|
432
|
-
|
|
433
|
-
return head === heading;
|
|
434
|
-
});
|
|
435
|
-
|
|
319
|
+
const identicalAnswer = headersContent.slice(0, index).some(head => head === heading);
|
|
436
320
|
if (identicalAnswer) {
|
|
437
321
|
columnsErrors[index + 1] += 'Content should be unique.';
|
|
438
322
|
}
|
|
439
323
|
}
|
|
440
324
|
});
|
|
441
|
-
|
|
442
|
-
return (error || '').length;
|
|
443
|
-
});
|
|
444
|
-
|
|
325
|
+
const hasRowErrors = Object.values(rowsErrors).some(error => (error || '').length);
|
|
445
326
|
if (hasRowErrors) {
|
|
446
327
|
errors.rowsErrors = rowsErrors;
|
|
447
|
-
|
|
448
|
-
return (error || '').includes('No correct response defined.');
|
|
449
|
-
});
|
|
450
|
-
|
|
328
|
+
const noCorrectAnswer = Object.values(rowsErrors).some(error => (error || '').includes('No correct response defined.'));
|
|
451
329
|
if (noCorrectAnswer) {
|
|
452
330
|
errors.correctResponseError = choiceMode === 'radio' ? 'There should be a correct response defined for every row.' : 'There should be at least one correct response defined for every row.';
|
|
453
331
|
}
|
|
454
332
|
}
|
|
455
|
-
|
|
456
|
-
var hasColumnErrors = Object.values(columnsErrors).some(function (error) {
|
|
457
|
-
return (error || '').length;
|
|
458
|
-
});
|
|
459
|
-
|
|
333
|
+
const hasColumnErrors = Object.values(columnsErrors).some(error => (error || '').length);
|
|
460
334
|
if (hasColumnErrors) {
|
|
461
335
|
errors.columnsErrors = columnsErrors;
|
|
462
336
|
}
|
|
463
|
-
|
|
464
337
|
return errors;
|
|
465
338
|
};
|
|
466
|
-
|
|
467
339
|
exports.validate = validate;
|
|
468
340
|
//# sourceMappingURL=index.js.map
|