@pie-element/categorize 6.6.0 → 6.6.1-beta.587
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 +538 -0
- package/configure/CHANGELOG.md +474 -0
- package/configure/lib/defaults.js +56 -5
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/design/builder.js +8 -5
- package/configure/lib/design/builder.js.map +1 -1
- package/configure/lib/design/buttons.js +6 -4
- package/configure/lib/design/buttons.js.map +1 -1
- package/configure/lib/design/categories/RowLabel.js +68 -0
- package/configure/lib/design/categories/RowLabel.js.map +1 -0
- package/configure/lib/design/categories/alternateResponses.js +122 -18
- package/configure/lib/design/categories/alternateResponses.js.map +1 -1
- package/configure/lib/design/categories/category.js +53 -6
- package/configure/lib/design/categories/category.js.map +1 -1
- package/configure/lib/design/categories/choice-preview.js +19 -6
- package/configure/lib/design/categories/choice-preview.js.map +1 -1
- package/configure/lib/design/categories/droppable-placeholder.js +25 -5
- package/configure/lib/design/categories/droppable-placeholder.js.map +1 -1
- package/configure/lib/design/categories/index.js +172 -82
- package/configure/lib/design/categories/index.js.map +1 -1
- package/configure/lib/design/choices/choice.js +83 -13
- package/configure/lib/design/choices/choice.js.map +1 -1
- package/configure/lib/design/choices/config.js +10 -136
- package/configure/lib/design/choices/config.js.map +1 -1
- package/configure/lib/design/choices/index.js +89 -13
- package/configure/lib/design/choices/index.js.map +1 -1
- package/configure/lib/design/header.js +18 -6
- package/configure/lib/design/header.js.map +1 -1
- package/configure/lib/design/index.js +165 -50
- package/configure/lib/design/index.js.map +1 -1
- package/configure/lib/design/input-header.js +69 -11
- package/configure/lib/design/input-header.js.map +1 -1
- package/configure/lib/index.js +18 -4
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +4 -2
- package/configure/lib/main.js.map +1 -1
- package/configure/lib/utils.js +27 -0
- package/configure/lib/utils.js.map +1 -0
- package/configure/package.json +9 -9
- package/controller/CHANGELOG.md +128 -0
- package/controller/lib/defaults.js +20 -1
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +173 -30
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +60 -0
- package/controller/lib/utils.js.map +1 -0
- package/controller/package.json +4 -4
- package/docs/config-schema.json +181 -0
- package/docs/config-schema.json.md +141 -1
- package/docs/demo/config.js +2 -2
- package/docs/demo/generate.js +5 -8
- package/docs/demo/index.html +1 -1
- package/docs/pie-schema.json +63 -11
- package/docs/pie-schema.json.md +51 -11
- package/lib/categorize/categories.js +30 -24
- package/lib/categorize/categories.js.map +1 -1
- package/lib/categorize/category.js +15 -12
- package/lib/categorize/category.js.map +1 -1
- package/lib/categorize/choice.js +19 -12
- package/lib/categorize/choice.js.map +1 -1
- package/lib/categorize/choices.js +35 -16
- package/lib/categorize/choices.js.map +1 -1
- package/lib/categorize/droppable-placeholder.js +6 -4
- package/lib/categorize/droppable-placeholder.js.map +1 -1
- package/lib/categorize/grid-content.js +3 -3
- package/lib/categorize/grid-content.js.map +1 -1
- package/lib/categorize/index.js +71 -37
- package/lib/categorize/index.js.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/package.json +9 -8
package/controller/lib/index.js
CHANGED
|
@@ -5,16 +5,19 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
+
exports.outcome = exports.normalize = exports.model = exports.getTotalScore = exports.getPartialScore = exports.getCorrectness = exports.createDefaultModel = exports.createCorrectResponseSession = void 0;
|
|
8
9
|
Object.defineProperty(exports, "score", {
|
|
9
10
|
enumerable: true,
|
|
10
11
|
get: function get() {
|
|
11
12
|
return _categorize.score;
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
|
-
exports.
|
|
15
|
+
exports.validate = void 0;
|
|
15
16
|
|
|
16
17
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
17
18
|
|
|
19
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
20
|
+
|
|
18
21
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
19
22
|
|
|
20
23
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
@@ -25,13 +28,15 @@ var _categorize = require("@pie-lib/categorize");
|
|
|
25
28
|
|
|
26
29
|
var _feedback = require("@pie-lib/feedback");
|
|
27
30
|
|
|
31
|
+
var _utils = require("./utils");
|
|
32
|
+
|
|
28
33
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
29
34
|
|
|
30
35
|
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
31
36
|
|
|
32
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
37
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
33
38
|
|
|
34
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
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; }
|
|
35
40
|
|
|
36
41
|
var getPartialScore = function getPartialScore(correctResponse, builtCategories) {
|
|
37
42
|
// in the resulted best scenario we make a sum with all the correct responses
|
|
@@ -71,6 +76,14 @@ var getPartialScore = function getPartialScore(correctResponse, builtCategories)
|
|
|
71
76
|
|
|
72
77
|
exports.getPartialScore = getPartialScore;
|
|
73
78
|
|
|
79
|
+
var getAlternates = function getAlternates(correctResponse) {
|
|
80
|
+
return correctResponse.map(function (c) {
|
|
81
|
+
return c.alternateResponses;
|
|
82
|
+
}).filter(function (alternate) {
|
|
83
|
+
return alternate;
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
74
87
|
var getTotalScore = function getTotalScore(question, session, env) {
|
|
75
88
|
if (!session) {
|
|
76
89
|
return 0;
|
|
@@ -98,16 +111,12 @@ var getTotalScore = function getTotalScore(question, session, env) {
|
|
|
98
111
|
builtCategories = _buildState.categories,
|
|
99
112
|
correct = _buildState.correct;
|
|
100
113
|
|
|
101
|
-
var
|
|
102
|
-
return c.alternateResponses;
|
|
103
|
-
}).filter(function (alternate) {
|
|
104
|
-
return alternate;
|
|
105
|
-
});
|
|
114
|
+
var alternates = getAlternates(correctResponse);
|
|
106
115
|
|
|
107
116
|
var enabled = _controllerUtils.partialScoring.enabled(question, env); // if there are any alternates, there will be no partial scoring!
|
|
108
117
|
|
|
109
118
|
|
|
110
|
-
if (enabled && !
|
|
119
|
+
if (enabled && !alternates.length) {
|
|
111
120
|
// we apply partial scoring
|
|
112
121
|
return getPartialScore(correctResponse, builtCategories);
|
|
113
122
|
} // else we apply dichotomous
|
|
@@ -148,13 +157,7 @@ var createDefaultModel = function createDefaultModel() {
|
|
|
148
157
|
exports.createDefaultModel = createDefaultModel;
|
|
149
158
|
|
|
150
159
|
var normalize = function normalize(question) {
|
|
151
|
-
return _objectSpread({
|
|
152
|
-
feedbackEnabled: true,
|
|
153
|
-
rationaleEnabled: true,
|
|
154
|
-
promptEnabled: true,
|
|
155
|
-
teacherInstructionsEnabled: true,
|
|
156
|
-
studentInstructionsEnabled: true
|
|
157
|
-
}, question);
|
|
160
|
+
return _objectSpread(_objectSpread({}, _defaults["default"]), question);
|
|
158
161
|
};
|
|
159
162
|
/**
|
|
160
163
|
*
|
|
@@ -170,7 +173,7 @@ exports.normalize = normalize;
|
|
|
170
173
|
var model = function model(question, session, env, updateSession) {
|
|
171
174
|
return new Promise( /*#__PURE__*/function () {
|
|
172
175
|
var _ref6 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(resolve) {
|
|
173
|
-
var normalizedQuestion, answerCorrectness, _ref7, mode, role, categories, categoriesPerRow,
|
|
176
|
+
var normalizedQuestion, answerCorrectness, _ref7, mode, role, categories, categoriesPerRow, choicesLabel, choicesPosition, correctResponse, feedback, feedbackEnabled, promptEnabled, prompt, rowLabels, rationaleEnabled, rationale, note, teacherInstructionsEnabled, teacherInstructions, choices, fb, lockChoiceOrder, filteredCorrectResponse, alternates, out;
|
|
174
177
|
|
|
175
178
|
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
176
179
|
while (1) {
|
|
@@ -183,49 +186,59 @@ var model = function model(question, session, env, updateSession) {
|
|
|
183
186
|
case 3:
|
|
184
187
|
answerCorrectness = _context.sent;
|
|
185
188
|
_ref7 = env || {}, mode = _ref7.mode, role = _ref7.role;
|
|
186
|
-
categories = normalizedQuestion.categories, categoriesPerRow = normalizedQuestion.categoriesPerRow,
|
|
189
|
+
categories = normalizedQuestion.categories, categoriesPerRow = normalizedQuestion.categoriesPerRow, choicesLabel = normalizedQuestion.choicesLabel, choicesPosition = normalizedQuestion.choicesPosition, correctResponse = normalizedQuestion.correctResponse, feedback = normalizedQuestion.feedback, feedbackEnabled = normalizedQuestion.feedbackEnabled, promptEnabled = normalizedQuestion.promptEnabled, prompt = normalizedQuestion.prompt, rowLabels = normalizedQuestion.rowLabels, rationaleEnabled = normalizedQuestion.rationaleEnabled, rationale = normalizedQuestion.rationale, note = normalizedQuestion.note, teacherInstructionsEnabled = normalizedQuestion.teacherInstructionsEnabled, teacherInstructions = normalizedQuestion.teacherInstructions;
|
|
187
190
|
choices = normalizedQuestion.choices;
|
|
188
191
|
lockChoiceOrder = (0, _controllerUtils.lockChoices)(normalizedQuestion, session, env);
|
|
192
|
+
filteredCorrectResponse = correctResponse.map(function (response) {
|
|
193
|
+
var filteredChoices = (response.choices || []).filter(function (choice) {
|
|
194
|
+
return choice !== 'null';
|
|
195
|
+
});
|
|
196
|
+
return _objectSpread(_objectSpread({}, response), {}, {
|
|
197
|
+
choices: filteredChoices
|
|
198
|
+
});
|
|
199
|
+
});
|
|
189
200
|
|
|
190
201
|
if (!(mode === 'evaluate' && feedbackEnabled)) {
|
|
191
|
-
_context.next =
|
|
202
|
+
_context.next = 13;
|
|
192
203
|
break;
|
|
193
204
|
}
|
|
194
205
|
|
|
195
|
-
_context.next =
|
|
206
|
+
_context.next = 12;
|
|
196
207
|
return (0, _feedback.getFeedbackForCorrectness)(answerCorrectness, feedback);
|
|
197
208
|
|
|
198
|
-
case
|
|
209
|
+
case 12:
|
|
199
210
|
fb = _context.sent;
|
|
200
211
|
|
|
201
|
-
case
|
|
212
|
+
case 13:
|
|
202
213
|
if (lockChoiceOrder) {
|
|
203
|
-
_context.next =
|
|
214
|
+
_context.next = 17;
|
|
204
215
|
break;
|
|
205
216
|
}
|
|
206
217
|
|
|
207
|
-
_context.next =
|
|
218
|
+
_context.next = 16;
|
|
208
219
|
return (0, _controllerUtils.getShuffledChoices)(choices, session, updateSession, 'id');
|
|
209
220
|
|
|
210
|
-
case
|
|
221
|
+
case 16:
|
|
211
222
|
choices = _context.sent;
|
|
212
223
|
|
|
213
|
-
case
|
|
224
|
+
case 17:
|
|
225
|
+
alternates = getAlternates(filteredCorrectResponse);
|
|
214
226
|
out = {
|
|
215
227
|
categories: categories || [],
|
|
216
228
|
categoriesPerRow: categoriesPerRow || 2,
|
|
217
229
|
correctness: answerCorrectness,
|
|
218
230
|
choices: choices || [],
|
|
219
231
|
choicesLabel: choicesLabel || '',
|
|
220
|
-
choicesPerRow: choicesPerRow || 2,
|
|
221
232
|
choicesPosition: choicesPosition,
|
|
222
233
|
disabled: mode !== 'gather',
|
|
223
234
|
feedback: fb,
|
|
224
235
|
lockChoiceOrder: lockChoiceOrder,
|
|
225
236
|
prompt: promptEnabled ? prompt : null,
|
|
226
|
-
removeTilesAfterPlacing: removeTilesAfterPlacing,
|
|
227
237
|
rowLabels: rowLabels,
|
|
228
|
-
|
|
238
|
+
note: note,
|
|
239
|
+
env: env,
|
|
240
|
+
showNote: alternates && alternates.length > 0,
|
|
241
|
+
correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined
|
|
229
242
|
};
|
|
230
243
|
|
|
231
244
|
if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
|
|
@@ -238,7 +251,7 @@ var model = function model(question, session, env, updateSession) {
|
|
|
238
251
|
|
|
239
252
|
resolve(out);
|
|
240
253
|
|
|
241
|
-
case
|
|
254
|
+
case 21:
|
|
242
255
|
case "end":
|
|
243
256
|
return _context.stop();
|
|
244
257
|
}
|
|
@@ -288,4 +301,134 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
|
|
|
288
301
|
};
|
|
289
302
|
|
|
290
303
|
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
304
|
+
|
|
305
|
+
var validate = function validate() {
|
|
306
|
+
var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
307
|
+
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
308
|
+
var categories = model.categories,
|
|
309
|
+
choices = model.choices,
|
|
310
|
+
correctResponse = model.correctResponse;
|
|
311
|
+
var _config$minChoices = config.minChoices,
|
|
312
|
+
minChoices = _config$minChoices === void 0 ? 1 : _config$minChoices,
|
|
313
|
+
_config$maxChoices = config.maxChoices,
|
|
314
|
+
maxChoices = _config$maxChoices === void 0 ? 15 : _config$maxChoices,
|
|
315
|
+
_config$minCategories = config.minCategories,
|
|
316
|
+
minCategories = _config$minCategories === void 0 ? 1 : _config$minCategories,
|
|
317
|
+
_config$maxCategories = config.maxCategories,
|
|
318
|
+
maxCategories = _config$maxCategories === void 0 ? 12 : _config$maxCategories,
|
|
319
|
+
_config$maxLengthPerC = config.maxLengthPerChoice,
|
|
320
|
+
maxLengthPerChoice = _config$maxLengthPerC === void 0 ? 300 : _config$maxLengthPerC,
|
|
321
|
+
_config$maxLengthPerC2 = config.maxLengthPerCategory,
|
|
322
|
+
maxLengthPerCategory = _config$maxLengthPerC2 === void 0 ? 150 : _config$maxLengthPerC2;
|
|
323
|
+
var reversedChoices = (0, _toConsumableArray2["default"])(choices || []).reverse();
|
|
324
|
+
var errors = {};
|
|
325
|
+
var choicesErrors = {};
|
|
326
|
+
var categoriesErrors = {};
|
|
327
|
+
(categories || []).forEach(function (category) {
|
|
328
|
+
var id = category.id,
|
|
329
|
+
label = category.label;
|
|
330
|
+
var parsedLabel = label.replace(/<(?:.|\n)*?>/gm, '');
|
|
331
|
+
|
|
332
|
+
if (parsedLabel.length > maxLengthPerCategory) {
|
|
333
|
+
categoriesErrors[id] = "Category labels should be no more than ".concat(maxLengthPerCategory, " characters long.");
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
(reversedChoices || []).forEach(function (choice, index) {
|
|
337
|
+
var id = choice.id,
|
|
338
|
+
content = choice.content;
|
|
339
|
+
var parsedContent = content.replace(/<(?:.|\n)*?>/gm, '');
|
|
340
|
+
|
|
341
|
+
if (parsedContent.length > maxLengthPerChoice) {
|
|
342
|
+
choicesErrors[id] = "Tokens should be no more than ".concat(maxLengthPerChoice, " characters long.");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (content === '' || content === '<div></div>') {
|
|
346
|
+
choicesErrors[id] = 'Tokens should not be empty.';
|
|
347
|
+
} else {
|
|
348
|
+
var identicalAnswer = reversedChoices.slice(index + 1).some(function (c) {
|
|
349
|
+
return c.content === content;
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
if (identicalAnswer) {
|
|
353
|
+
choicesErrors[id] = 'Tokens content should be unique.';
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
var nbOfCategories = (categories || []).length;
|
|
358
|
+
var nbOfChoices = (choices || []).length;
|
|
359
|
+
|
|
360
|
+
if (nbOfCategories > maxCategories) {
|
|
361
|
+
errors.categoriesError = "No more than ".concat(maxCategories, " categories should be defined.");
|
|
362
|
+
} else if (nbOfCategories < minCategories) {
|
|
363
|
+
errors.categoriesError = "There should be at least ".concat(minCategories, " category defined.");
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (nbOfChoices < minChoices) {
|
|
367
|
+
errors.choicesError = "There should be at least ".concat(minChoices, " choices defined.");
|
|
368
|
+
} else if (nbOfChoices > maxChoices) {
|
|
369
|
+
errors.choicesError = "No more than ".concat(maxChoices, " choices should be defined.");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (nbOfChoices && nbOfCategories) {
|
|
373
|
+
var hasAssociations = false;
|
|
374
|
+
(correctResponse || []).forEach(function (response) {
|
|
375
|
+
var _response$choices = response.choices,
|
|
376
|
+
choices = _response$choices === void 0 ? [] : _response$choices,
|
|
377
|
+
_response$alternateRe = response.alternateResponses,
|
|
378
|
+
alternateResponses = _response$alternateRe === void 0 ? [] : _response$alternateRe;
|
|
379
|
+
|
|
380
|
+
if (choices.length) {
|
|
381
|
+
hasAssociations = true;
|
|
382
|
+
} else {
|
|
383
|
+
alternateResponses.forEach(function (alternate) {
|
|
384
|
+
if ((alternate || []).length) {
|
|
385
|
+
hasAssociations = true;
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
var duplicateAlternateIndex = -1;
|
|
391
|
+
var duplicateCategory = '';
|
|
392
|
+
(correctResponse || []).forEach(function (response) {
|
|
393
|
+
var _response$choices2 = response.choices,
|
|
394
|
+
choices = _response$choices2 === void 0 ? [] : _response$choices2,
|
|
395
|
+
_response$alternateRe2 = response.alternateResponses,
|
|
396
|
+
alternateResponses = _response$alternateRe2 === void 0 ? [] : _response$alternateRe2,
|
|
397
|
+
category = response.category;
|
|
398
|
+
|
|
399
|
+
if (duplicateAlternateIndex === -1) {
|
|
400
|
+
duplicateAlternateIndex = (0, _utils.isCorrectResponseDuplicated)(choices, alternateResponses);
|
|
401
|
+
|
|
402
|
+
if (duplicateAlternateIndex === -1) {
|
|
403
|
+
duplicateAlternateIndex = (0, _utils.isAlternateDuplicated)(alternateResponses);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
duplicateCategory = category;
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
if (duplicateAlternateIndex > -1) {
|
|
411
|
+
errors.duplicateAlternate = {
|
|
412
|
+
index: duplicateAlternateIndex,
|
|
413
|
+
category: duplicateCategory
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (!hasAssociations) {
|
|
418
|
+
errors.associationError = 'At least one token should be assigned to at least one category.';
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (!(0, _isEmpty["default"])(choicesErrors)) {
|
|
423
|
+
errors.choicesErrors = choicesErrors;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (!(0, _isEmpty["default"])(categoriesErrors)) {
|
|
427
|
+
errors.categoriesErrors = categoriesErrors;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return errors;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
exports.validate = validate;
|
|
291
434
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["getPartialScore","correctResponse","builtCategories","reduce","acc","choices","placements","length","score","filter","ch","correct","maxScore","extraPlacements","totalScore","parseFloat","toFixed","getTotalScore","question","session","env","Object","keys","categories","answers","hasAlternates","map","c","alternateResponses","alternate","enabled","partialScoring","getCorrectness","Promise","resolve","mode","undefined","createDefaultModel","model","defaults","normalize","feedbackEnabled","rationaleEnabled","promptEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","updateSession","normalizedQuestion","answerCorrectness","role","categoriesPerRow","choicesPerRow","choicesLabel","choicesPosition","feedback","prompt","removeTilesAfterPlacing","rowLabels","rationale","teacherInstructions","lockChoiceOrder","fb","out","correctness","disabled","outcome","reject","Error","empty","createCorrectResponseSession","id"],"mappings":"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","sourcesContent":["import isEmpty from 'lodash/isEmpty';\nimport { buildState, score } from '@pie-lib/categorize';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport {\n lockChoices,\n getShuffledChoices,\n partialScoring,\n} from '@pie-lib/controller-utils';\nimport defaults from './defaults';\n\n// eslint-disable-next-line no-console\n\nexport { score };\n\nexport const getPartialScore = (correctResponse, builtCategories) => {\n // in the resulted best scenario we make a sum with all the correct responses\n // and all the placements\n const { placements, score } = builtCategories.reduce(\n (acc, { choices = [] }) => ({\n placements: acc.placements + choices.length,\n score: acc.score + choices.filter((ch) => ch.correct).length,\n }),\n { placements: 0, score: 0 }\n );\n\n // in the correct response, we make a sum of the max possible score\n const { maxScore } = correctResponse.reduce(\n (acc, { choices }) => ({\n maxScore: acc.maxScore + choices.length,\n }),\n { maxScore: 0 }\n );\n\n // if there are any extra placements, we subtract from the obtained score\n const extraPlacements = placements > maxScore ? placements - maxScore : 0;\n const totalScore = (score - extraPlacements) / maxScore;\n\n return totalScore < 0 ? 0 : parseFloat(totalScore.toFixed(2));\n};\n\nexport const getTotalScore = (question, session, env) => {\n if (!session) {\n return 0;\n }\n\n if (Object.keys(session).length === 0) {\n return 0;\n }\n const { categories, choices } = question || {};\n let { correctResponse } = question || {};\n let { answers } = session || {};\n answers = answers || [];\n correctResponse = correctResponse || [];\n\n // this function is used in pie-ui/categorize as well, in order to get the best scenario\n // so we get the best scenario and calculate the score\n const { categories: builtCategories, correct } = buildState(\n categories,\n choices,\n answers,\n correctResponse\n );\n\n const hasAlternates = correctResponse\n .map((c) => c.alternateResponses)\n .filter((alternate) => alternate);\n const enabled = partialScoring.enabled(question, env);\n\n // if there are any alternates, there will be no partial scoring!\n if (enabled && !hasAlternates.length) {\n // we apply partial scoring\n return getPartialScore(correctResponse, builtCategories);\n }\n\n // else we apply dichotomous\n return correct ? 1 : 0;\n};\n\nexport const getCorrectness = (question, session, env) => {\n return new Promise((resolve) => {\n if (env.mode === 'evaluate') {\n const score = getTotalScore(question, session, env);\n if (score === 1) {\n resolve('correct');\n } else if (score === 0) {\n resolve('incorrect');\n } else {\n resolve('partially-correct');\n }\n } else {\n resolve(undefined);\n }\n });\n};\n\nexport const createDefaultModel = (model = {}) =>\n new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nexport const normalize = (question) => ({\n feedbackEnabled: true,\n rationaleEnabled: true,\n promptEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport const model = (question, session, env, updateSession) =>\n new Promise(async (resolve) => {\n const normalizedQuestion = normalize(question);\n const answerCorrectness = await getCorrectness(normalizedQuestion, session, env);\n\n const { mode, role } = env || {};\n\n const {\n categories,\n categoriesPerRow,\n choicesPerRow,\n choicesLabel,\n choicesPosition,\n correctResponse,\n feedback,\n feedbackEnabled,\n promptEnabled,\n prompt,\n removeTilesAfterPlacing,\n rowLabels,\n rationaleEnabled,\n rationale,\n teacherInstructionsEnabled,\n teacherInstructions,\n } = normalizedQuestion;\n let { choices } = normalizedQuestion;\n let fb;\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (mode === 'evaluate' && feedbackEnabled) {\n fb = await getFeedbackForCorrectness(\n answerCorrectness,\n feedback\n );\n }\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'id');\n }\n\n const out = {\n categories: categories || [],\n categoriesPerRow: categoriesPerRow || 2,\n correctness: answerCorrectness,\n choices: choices || [],\n choicesLabel: choicesLabel || '',\n choicesPerRow: choicesPerRow || 2,\n choicesPosition,\n disabled: mode !== 'gather',\n feedback: fb,\n lockChoiceOrder,\n prompt: promptEnabled ? prompt : null,\n removeTilesAfterPlacing,\n rowLabels,\n correctResponse: mode === 'evaluate' ? correctResponse : undefined,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = rationaleEnabled ? rationale : null;\n out.teacherInstructions = teacherInstructionsEnabled\n ? teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n\nexport const outcome = (question, session, env) => {\n if (env.mode !== 'evaluate') {\n return Promise.reject(\n new Error('Can not call outcome when mode is not evaluate')\n );\n } else {\n return new Promise((resolve) => {\n resolve({\n score: getTotalScore(question, session, env),\n empty: !session || isEmpty(session),\n });\n });\n }\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n const { mode, role } = env || {};\n\n if (mode !== 'evaluate' && role === 'instructor') {\n const { correctResponse } = question;\n\n resolve({ answers: correctResponse, id: 1 });\n } else {\n return resolve(null);\n }\n });\n};\n"],"file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["getPartialScore","correctResponse","builtCategories","reduce","acc","choices","placements","length","score","filter","ch","correct","maxScore","extraPlacements","totalScore","parseFloat","toFixed","getAlternates","map","c","alternateResponses","alternate","getTotalScore","question","session","env","Object","keys","categories","answers","alternates","enabled","partialScoring","getCorrectness","Promise","resolve","mode","undefined","createDefaultModel","model","defaults","normalize","updateSession","normalizedQuestion","answerCorrectness","role","categoriesPerRow","choicesLabel","choicesPosition","feedback","feedbackEnabled","promptEnabled","prompt","rowLabels","rationaleEnabled","rationale","note","teacherInstructionsEnabled","teacherInstructions","lockChoiceOrder","filteredCorrectResponse","response","filteredChoices","choice","fb","out","correctness","disabled","showNote","outcome","reject","Error","empty","createCorrectResponseSession","id","validate","config","minChoices","maxChoices","minCategories","maxCategories","maxLengthPerChoice","maxLengthPerCategory","reversedChoices","reverse","errors","choicesErrors","categoriesErrors","forEach","category","label","parsedLabel","replace","index","content","parsedContent","identicalAnswer","slice","some","nbOfCategories","nbOfChoices","categoriesError","choicesError","hasAssociations","duplicateAlternateIndex","duplicateCategory","duplicateAlternate","associationError"],"mappings":"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","sourcesContent":["import isEmpty from 'lodash/isEmpty';\nimport { buildState, score } from '@pie-lib/categorize';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport { isAlternateDuplicated, isCorrectResponseDuplicated } from './utils';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';\nimport defaults from './defaults';\n\n// eslint-disable-next-line no-console\n\nexport { score };\n\nexport const getPartialScore = (correctResponse, builtCategories) => {\n // in the resulted best scenario we make a sum with all the correct responses\n // and all the placements\n const { placements, score } = builtCategories.reduce(\n (acc, { choices = [] }) => ({\n placements: acc.placements + choices.length,\n score: acc.score + choices.filter((ch) => ch.correct).length,\n }),\n { placements: 0, score: 0 },\n );\n\n // in the correct response, we make a sum of the max possible score\n const { maxScore } = correctResponse.reduce(\n (acc, { choices }) => ({\n maxScore: acc.maxScore + choices.length,\n }),\n { maxScore: 0 },\n );\n\n // if there are any extra placements, we subtract from the obtained score\n const extraPlacements = placements > maxScore ? placements - maxScore : 0;\n const totalScore = (score - extraPlacements) / maxScore;\n\n return totalScore < 0 ? 0 : parseFloat(totalScore.toFixed(2));\n};\n\nconst getAlternates = (correctResponse) =>\n correctResponse.map((c) => c.alternateResponses).filter((alternate) => alternate);\n\nexport const getTotalScore = (question, session, env) => {\n if (!session) {\n return 0;\n }\n\n if (Object.keys(session).length === 0) {\n return 0;\n }\n const { categories, choices } = question || {};\n let { correctResponse } = question || {};\n let { answers } = session || {};\n answers = answers || [];\n correctResponse = correctResponse || [];\n\n // this function is used in pie-ui/categorize as well, in order to get the best scenario\n // so we get the best scenario and calculate the score\n const { categories: builtCategories, correct } = buildState(categories, choices, answers, correctResponse);\n\n const alternates = getAlternates(correctResponse);\n const enabled = partialScoring.enabled(question, env);\n\n // if there are any alternates, there will be no partial scoring!\n if (enabled && !alternates.length) {\n // we apply partial scoring\n return getPartialScore(correctResponse, builtCategories);\n }\n\n // else we apply dichotomous\n return correct ? 1 : 0;\n};\n\nexport const getCorrectness = (question, session, env) => {\n return new Promise((resolve) => {\n if (env.mode === 'evaluate') {\n const score = getTotalScore(question, session, env);\n if (score === 1) {\n resolve('correct');\n } else if (score === 0) {\n resolve('incorrect');\n } else {\n resolve('partially-correct');\n }\n } else {\n resolve(undefined);\n }\n });\n};\n\nexport const createDefaultModel = (model = {}) =>\n new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nexport const normalize = (question) => ({\n ...defaults,\n ...question,\n});\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport const model = (question, session, env, updateSession) =>\n new Promise(async (resolve) => {\n const normalizedQuestion = normalize(question);\n const answerCorrectness = await getCorrectness(normalizedQuestion, session, env);\n\n const { mode, role } = env || {};\n\n const {\n categories,\n categoriesPerRow,\n choicesLabel,\n choicesPosition,\n correctResponse,\n feedback,\n feedbackEnabled,\n promptEnabled,\n prompt,\n rowLabels,\n rationaleEnabled,\n rationale,\n note,\n teacherInstructionsEnabled,\n teacherInstructions,\n } = normalizedQuestion;\n let { choices } = normalizedQuestion;\n let fb;\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n const filteredCorrectResponse = correctResponse.map((response) => {\n const filteredChoices = (response.choices || []).filter((choice) => choice !== 'null');\n return { ...response, choices: filteredChoices };\n });\n\n if (mode === 'evaluate' && feedbackEnabled) {\n fb = await getFeedbackForCorrectness(answerCorrectness, feedback);\n }\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'id');\n }\n\n const alternates = getAlternates(filteredCorrectResponse);\n const out = {\n categories: categories || [],\n categoriesPerRow: categoriesPerRow || 2,\n correctness: answerCorrectness,\n choices: choices || [],\n choicesLabel: choicesLabel || '',\n choicesPosition,\n disabled: mode !== 'gather',\n feedback: fb,\n lockChoiceOrder,\n prompt: promptEnabled ? prompt : null,\n rowLabels,\n note,\n env,\n showNote: alternates && alternates.length > 0,\n correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = rationaleEnabled ? rationale : null;\n out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n\nexport const outcome = (question, session, env) => {\n if (env.mode !== 'evaluate') {\n return Promise.reject(new Error('Can not call outcome when mode is not evaluate'));\n } else {\n return new Promise((resolve) => {\n resolve({\n score: getTotalScore(question, session, env),\n empty: !session || isEmpty(session),\n });\n });\n }\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n const { mode, role } = env || {};\n\n if (mode !== 'evaluate' && role === 'instructor') {\n const { correctResponse } = question;\n\n resolve({ answers: correctResponse, id: 1 });\n } else {\n return resolve(null);\n }\n });\n};\n\nexport const validate = (model = {}, config = {}) => {\n const { categories, choices, correctResponse } = model;\n const { minChoices = 1, maxChoices = 15, minCategories = 1, maxCategories = 12, maxLengthPerChoice = 300, maxLengthPerCategory = 150 } = config;\n const reversedChoices = [ ...choices || []].reverse();\n const errors = {};\n const choicesErrors = {};\n const categoriesErrors = {};\n\n (categories || []).forEach((category) => {\n const {id, label} = category;\n const parsedLabel = label.replace(/<(?:.|\\n)*?>/gm, '');\n if (parsedLabel.length > maxLengthPerCategory){\n categoriesErrors[id] = `Category labels should be no more than ${maxLengthPerCategory} characters long.`;\n }\n });\n\n (reversedChoices || []).forEach((choice, index) => {\n const { id, content } = choice;\n const parsedContent = content.replace(/<(?:.|\\n)*?>/gm, '');\n if (parsedContent.length > maxLengthPerChoice){\n choicesErrors[id] = `Tokens should be no more than ${maxLengthPerChoice} characters long.`;\n }\n if (content === '' || content === '<div></div>') {\n choicesErrors[id] = 'Tokens should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some(c => c.content === content);\n\n if (identicalAnswer) {\n choicesErrors[id] = 'Tokens content should be unique.';\n }\n }\n });\n\n const nbOfCategories = (categories || []).length;\n const nbOfChoices = (choices || []).length;\n\n if (nbOfCategories > maxCategories) {\n errors.categoriesError = `No more than ${maxCategories} categories should be defined.`;\n } else if (nbOfCategories < minCategories) {\n errors.categoriesError = `There should be at least ${minCategories} category defined.`;\n }\n\n if (nbOfChoices < minChoices) {\n errors.choicesError = `There should be at least ${minChoices} choices defined.`;\n } else if (nbOfChoices > maxChoices) {\n errors.choicesError = `No more than ${maxChoices} choices should be defined.`;\n }\n\n if (nbOfChoices && nbOfCategories) {\n let hasAssociations = false;\n\n (correctResponse || []).forEach(response => {\n const { choices = [], alternateResponses = [] } = response;\n\n if (choices.length) {\n hasAssociations = true;\n } else {\n alternateResponses.forEach(alternate => {\n if ((alternate || []).length) {\n hasAssociations = true;\n }\n });\n }\n });\n\n let duplicateAlternateIndex = -1;\n let duplicateCategory = '';\n (correctResponse || []).forEach(response => {\n const { choices = [], alternateResponses = [], category } = response;\n if (duplicateAlternateIndex === -1) {\n duplicateAlternateIndex = isCorrectResponseDuplicated(choices,alternateResponses);\n if (duplicateAlternateIndex === -1) {\n duplicateAlternateIndex = isAlternateDuplicated(alternateResponses);\n }\n duplicateCategory = category;\n }\n });\n\n if (duplicateAlternateIndex > -1) {\n errors.duplicateAlternate = {index:duplicateAlternateIndex, category:duplicateCategory};\n }\n\n if (!hasAssociations) {\n errors.associationError = 'At least one token should be assigned to at least one category.';\n }\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choicesErrors = choicesErrors;\n }\n\n if (!isEmpty(categoriesErrors)) {\n errors.categoriesErrors = categoriesErrors;\n }\n return errors;\n};\n"],"file":"index.js"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.multiplePlacements = exports.isCorrectResponseDuplicated = exports.isAlternateDuplicated = void 0;
|
|
9
|
+
|
|
10
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
11
|
+
|
|
12
|
+
// used in configure too, for consistency modify it there too
|
|
13
|
+
var multiplePlacements = {
|
|
14
|
+
enabled: 'Yes',
|
|
15
|
+
disabled: 'No',
|
|
16
|
+
perChoice: 'Set Per Choice'
|
|
17
|
+
}; // used to validate the config
|
|
18
|
+
|
|
19
|
+
exports.multiplePlacements = multiplePlacements;
|
|
20
|
+
|
|
21
|
+
var isCorrectResponseDuplicated = function isCorrectResponseDuplicated(choices, alternate) {
|
|
22
|
+
if (choices.length < 1 || alternate.length < 1) {
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var stringChoices = JSON.stringify(choices.sort());
|
|
27
|
+
var stringAlternate = alternate.reduce(function (total, current) {
|
|
28
|
+
return current.length > 0 ? [].concat((0, _toConsumableArray2["default"])(total), [JSON.stringify(current.sort())]) : total;
|
|
29
|
+
}, []);
|
|
30
|
+
var foundIndexDuplicate = stringAlternate.findIndex(function (alternate) {
|
|
31
|
+
return alternate.length && alternate === stringChoices;
|
|
32
|
+
});
|
|
33
|
+
return foundIndexDuplicate;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
exports.isCorrectResponseDuplicated = isCorrectResponseDuplicated;
|
|
37
|
+
|
|
38
|
+
var isAlternateDuplicated = function isAlternateDuplicated(alternate) {
|
|
39
|
+
if (alternate.length <= 1) {
|
|
40
|
+
return -1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var elementSet = new Set();
|
|
44
|
+
var stringAlternate = alternate.reduce(function (total, current) {
|
|
45
|
+
return current.length > 0 ? [].concat((0, _toConsumableArray2["default"])(total), [JSON.stringify(current.sort())]) : total;
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
for (var i = 0; i < stringAlternate.length; i++) {
|
|
49
|
+
if (elementSet.has(stringAlternate[i]) && stringAlternate[i]) {
|
|
50
|
+
return i;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
elementSet.add(stringAlternate[i]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return -1;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
exports.isAlternateDuplicated = isAlternateDuplicated;
|
|
60
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.js"],"names":["multiplePlacements","enabled","disabled","perChoice","isCorrectResponseDuplicated","choices","alternate","length","stringChoices","JSON","stringify","sort","stringAlternate","reduce","total","current","foundIndexDuplicate","findIndex","isAlternateDuplicated","elementSet","Set","i","has","add"],"mappings":";;;;;;;;;;;AAAA;AACO,IAAMA,kBAAkB,GAAG;AAAEC,EAAAA,OAAO,EAAE,KAAX;AAAkBC,EAAAA,QAAQ,EAAE,IAA5B;AAAkCC,EAAAA,SAAS,EAAE;AAA7C,CAA3B,C,CAEP;;;;AACO,IAAMC,2BAA2B,GAAG,SAA9BA,2BAA8B,CAACC,OAAD,EAASC,SAAT,EAAuB;AAC9D,MAAID,OAAO,CAACE,MAAR,GAAiB,CAAjB,IAAsBD,SAAS,CAACC,MAAV,GAAmB,CAA7C,EAA+C;AAC3C,WAAO,CAAC,CAAR;AACH;;AACD,MAAMC,aAAa,GAAIC,IAAI,CAACC,SAAL,CAAeL,OAAO,CAACM,IAAR,EAAf,CAAvB;AACA,MAAMC,eAAe,GAAGN,SAAS,CAACO,MAAV,CAAiB,UAACC,KAAD,EAAQC,OAAR;AAAA,WAAoBA,OAAO,CAACR,MAAR,GAAiB,CAAjB,iDAAyBO,KAAzB,IAAgCL,IAAI,CAACC,SAAL,CAAeK,OAAO,CAACJ,IAAR,EAAf,CAAhC,KAAkEG,KAAtF;AAAA,GAAjB,EAA8G,EAA9G,CAAxB;AACA,MAAME,mBAAmB,GAAGJ,eAAe,CAACK,SAAhB,CAA0B,UAAAX,SAAS;AAAA,WAAIA,SAAS,CAACC,MAAV,IAAqBD,SAAS,KAAKE,aAAvC;AAAA,GAAnC,CAA5B;AACA,SAAOQ,mBAAP;AACH,CARM;;;;AAUA,IAAME,qBAAqB,GAAG,SAAxBA,qBAAwB,CAACZ,SAAD,EAAe;AAChD,MAAIA,SAAS,CAACC,MAAV,IAAoB,CAAxB,EAA0B;AACtB,WAAO,CAAC,CAAR;AACH;;AACD,MAAMY,UAAU,GAAG,IAAIC,GAAJ,EAAnB;AACA,MAAMR,eAAe,GAAGN,SAAS,CAACO,MAAV,CAAiB,UAACC,KAAD,EAAQC,OAAR;AAAA,WAAoBA,OAAO,CAACR,MAAR,GAAiB,CAAjB,iDAAyBO,KAAzB,IAAgCL,IAAI,CAACC,SAAL,CAAeK,OAAO,CAACJ,IAAR,EAAf,CAAhC,KAAkEG,KAAtF;AAAA,GAAjB,EAA8G,EAA9G,CAAxB;;AACA,OAAK,IAAIO,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGT,eAAe,CAACL,MAApC,EAA4Cc,CAAC,EAA7C,EAAiD;AAC7C,QAAIF,UAAU,CAACG,GAAX,CAAeV,eAAe,CAACS,CAAD,CAA9B,KAAsCT,eAAe,CAACS,CAAD,CAAzD,EAA8D;AAC1D,aAAOA,CAAP;AACH;;AACDF,IAAAA,UAAU,CAACI,GAAX,CAAeX,eAAe,CAACS,CAAD,CAA9B;AACH;;AAED,SAAO,CAAC,CAAR;AACH,CAdM","sourcesContent":["// used in configure too, for consistency modify it there too\nexport const multiplePlacements = { enabled: 'Yes', disabled: 'No', perChoice: 'Set Per Choice' };\n\n// used to validate the config\nexport const isCorrectResponseDuplicated = (choices,alternate) => {\n if (choices.length < 1 || alternate.length < 1){\n return -1;\n }\n const stringChoices = JSON.stringify(choices.sort());\n const stringAlternate = alternate.reduce((total, current) => current.length > 0 ? [...total, JSON.stringify(current.sort())] : total, []);\n const foundIndexDuplicate = stringAlternate.findIndex(alternate => alternate.length && alternate === stringChoices);\n return foundIndexDuplicate;\n};\n\nexport const isAlternateDuplicated = (alternate) => {\n if (alternate.length <= 1){\n return -1;\n }\n const elementSet = new Set();\n const stringAlternate = alternate.reduce((total, current) => current.length > 0 ? [...total, JSON.stringify(current.sort())] : total, []);\n for (let i = 0; i < stringAlternate.length; i++) {\n if (elementSet.has(stringAlternate[i]) && stringAlternate[i]) {\n return i;\n }\n elementSet.add(stringAlternate[i]);\n }\n\n return -1;\n};\n"],"file":"utils.js"}
|
package/controller/package.json
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"name": "@pie-element/categorize-controller",
|
|
3
3
|
"private": true,
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@pie-lib/categorize": "^0.
|
|
6
|
-
"@pie-lib/controller-utils": "^0.2.
|
|
7
|
-
"@pie-lib/feedback": "^0.4.
|
|
5
|
+
"@pie-lib/categorize": "^0.8.12",
|
|
6
|
+
"@pie-lib/controller-utils": "^0.2.42",
|
|
7
|
+
"@pie-lib/feedback": "^0.4.42",
|
|
8
8
|
"lodash": "^4.17.15"
|
|
9
9
|
},
|
|
10
|
-
"version": "5.
|
|
10
|
+
"version": "5.7.0",
|
|
11
11
|
"description": "",
|
|
12
12
|
"scripts": {},
|
|
13
13
|
"main": "lib/index.js",
|