@pie-element/match 4.9.8 → 4.10.1-beta.1443

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.
@@ -5,9 +5,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
+ exports.createCorrectResponseSession = void 0;
8
9
  exports.createDefaultModel = createDefaultModel;
9
10
  exports.model = model;
10
- exports.createCorrectResponseSession = exports.normalize = exports.outcome = void 0;
11
+ exports.validate = exports.outcome = exports.normalize = void 0;
11
12
 
12
13
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
13
14
 
@@ -29,9 +30,9 @@ var _debug = _interopRequireDefault(require("debug"));
29
30
 
30
31
  var _defaults = _interopRequireDefault(require("./defaults"));
31
32
 
32
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
33
+ 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
34
 
34
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
35
+ 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
36
 
36
37
  var log = (0, _debug["default"])('@pie-element:match:controller');
37
38
 
@@ -48,9 +49,18 @@ var getResponseCorrectness = function getResponseCorrectness(model, answers) {
48
49
  }
49
50
 
50
51
  var totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);
51
- var correctAnswers = checkboxMode ? getCheckboxes(rows, answers).correctAnswers : getCorrectRadios(rows, answers);
52
+ var correctAnswers;
53
+ var incorrectAnswers = 0;
54
+
55
+ if (checkboxMode) {
56
+ var checkboxes = getCheckboxes(rows, answers);
57
+ correctAnswers = checkboxes.correctAnswers;
58
+ incorrectAnswers = checkboxes.incorrectAnswers;
59
+ } else {
60
+ correctAnswers = getCorrectRadios(rows, answers);
61
+ }
52
62
 
53
- if (totalCorrectAnswers === correctAnswers) {
63
+ if (totalCorrectAnswers === correctAnswers && !incorrectAnswers) {
54
64
  return 'correct';
55
65
  } else if (correctAnswers === 0) {
56
66
  return 'incorrect';
@@ -318,4 +328,101 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
318
328
  };
319
329
 
320
330
  exports.createCorrectResponseSession = createCorrectResponseSession;
331
+
332
+ var markupToText = function markupToText(s) {
333
+ return s.replace(/(<([^>]+)>)/ig, '');
334
+ };
335
+
336
+ var validate = function validate() {
337
+ var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
338
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
339
+ var rows = model.rows,
340
+ choiceMode = model.choiceMode,
341
+ headers = model.headers;
342
+ var minQuestions = config.minQuestions,
343
+ maxQuestions = config.maxQuestions,
344
+ maxLengthQuestionsHeading = config.maxLengthQuestionsHeading,
345
+ maxAnswers = config.maxAnswers,
346
+ maxLengthAnswers = config.maxLengthAnswers,
347
+ maxLengthFirstColumnHeading = config.maxLengthFirstColumnHeading;
348
+ var rowsErrors = {};
349
+ var columnsErrors = {};
350
+ var errors = {};
351
+
352
+ if (rows.length < minQuestions) {
353
+ errors.noOfRowsError = "There should be at least ".concat(minQuestions, " question rows.");
354
+ } else if (rows.length > maxQuestions) {
355
+ errors.noOfRowsError = "No more than ".concat(maxQuestions, " question rows should be defined.");
356
+ }
357
+
358
+ (rows || []).forEach(function (row, index) {
359
+ var id = row.id,
360
+ _row$values = row.values,
361
+ values = _row$values === void 0 ? [] : _row$values,
362
+ title = row.title;
363
+ var hasCorrectResponse = false;
364
+ rowsErrors[id] = '';
365
+
366
+ if (maxLengthQuestionsHeading && markupToText(title).length > maxLengthQuestionsHeading) {
367
+ rowsErrors[id] += "Questions rows content length should not be more than ".concat(maxLengthQuestionsHeading, " characters. ");
368
+ } else if (title === '' || title === '<div></div>') {
369
+ rowsErrors[id] += 'Content should not be empty. ';
370
+ } else {
371
+ var identicalAnswer = rows.slice(index + 1).some(function (r) {
372
+ return r.title === title;
373
+ });
374
+
375
+ if (identicalAnswer) {
376
+ rowsErrors[id] = 'Content should be unique. ';
377
+ }
378
+ }
379
+
380
+ values.forEach(function (value) {
381
+ if (value) {
382
+ hasCorrectResponse = true;
383
+ }
384
+ });
385
+
386
+ if (!hasCorrectResponse) {
387
+ rowsErrors[id] += 'No correct response defined.';
388
+ }
389
+ });
390
+
391
+ if (maxAnswers && headers.length - 1 > maxAnswers) {
392
+ errors.columnsLengthError = "There should be maximum ".concat(maxAnswers, " answers.");
393
+ }
394
+
395
+ if (maxLengthFirstColumnHeading && headers[0].length > maxLengthFirstColumnHeading) {
396
+ columnsErrors[0] = "The first column heading should have the maximum length of ".concat(maxLengthFirstColumnHeading, " characters.");
397
+ }
398
+
399
+ (headers || []).slice(1).forEach(function (heading, index) {
400
+ if (heading === '' || heading === '<div></div>') {
401
+ columnsErrors[index + 1] = 'Content should not be empty.';
402
+ } else if (maxLengthAnswers && heading.length > maxLengthAnswers) {
403
+ columnsErrors[index + 1] = "Content length should be maximum ".concat(maxLengthAnswers, " characters.");
404
+ } else {
405
+ var identicalAnswer = headers.slice(index + 2).some(function (h) {
406
+ return h === heading;
407
+ });
408
+
409
+ if (identicalAnswer) {
410
+ columnsErrors[index + 2] = 'Content should be unique.';
411
+ }
412
+ }
413
+ });
414
+
415
+ if (!(0, _isEmpty["default"])(rowsErrors)) {
416
+ errors.rowsErrors = rowsErrors;
417
+ 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.';
418
+ }
419
+
420
+ if (!(0, _isEmpty["default"])(columnsErrors)) {
421
+ errors.columnsErrors = columnsErrors;
422
+ }
423
+
424
+ return errors;
425
+ };
426
+
427
+ exports.validate = validate;
321
428
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","getResponseCorrectness","model","answers","env","isPartialScoring","partialScoring","enabled","rows","checkboxMode","choiceMode","Object","keys","length","totalCorrectAnswers","getTotalCorrectAnswers","getTotalCorrect","correctAnswers","getCheckboxes","getCorrectRadios","getCorrectness","question","mode","incorrectAnswers","forEach","row","answer","id","values","v","i","matchingTable","layout","noOfTotalCorrectAnswers","value","getPartialScore","totalCorrect","total","extraAnswers","score","parseFloat","toFixed","getOutComeScore","correctness","outcome","session","Promise","resolve","undefined","completed","empty","out","createDefaultModel","defaults","normalize","feedbackEnabled","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","updateSession","normalizedQuestion","correctResponse","correctInfo","lockChoiceOrder","fb","feedback","then","allowFeedback","prompt","config","shuffled","disabled","view","role","teacherInstructions","rationale","assign","createCorrectResponseSession","r"],"mappings":"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","sourcesContent":["import isEqual from 'lodash/isEqual';\nimport isEmpty from 'lodash/isEmpty';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';\nimport debug from 'debug';\n\nconst log = debug('@pie-element:match:controller');\n\nimport defaults from './defaults';\n\nconst getResponseCorrectness = (model, answers, env = {}) => {\n const isPartialScoring = partialScoring.enabled(model, env);\n const rows = model.rows;\n const checkboxMode = model.choiceMode === 'checkbox';\n\n if (!answers || Object.keys(answers).length === 0) {\n return 'unanswered';\n }\n\n const totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);\n const correctAnswers = checkboxMode\n ? getCheckboxes(rows, answers).correctAnswers\n : getCorrectRadios(rows, answers);\n\n if (totalCorrectAnswers === correctAnswers) {\n return 'correct';\n } else if (correctAnswers === 0) {\n return 'incorrect';\n } else if (isPartialScoring) {\n return 'partial';\n }\n\n return 'incorrect';\n};\n\nconst getCorrectness = (question, env, answers = {}) => {\n if (env.mode === 'evaluate') {\n return getResponseCorrectness(question, answers, env);\n }\n};\n\nconst getCheckboxes = (rows, answers) => {\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n\n rows.forEach(row => {\n const answer = answers[row.id];\n\n if (answer) {\n row.values.forEach((v, i) => {\n if (answer[i] && answer[i] === v ) {\n correctAnswers += 1;\n } else if (answer[i] && answer[i] !== v ){\n incorrectAnswers += 1;\n }\n });\n }\n });\n\n return { correctAnswers, incorrectAnswers };\n};\n\nconst getCorrectRadios = (rows, answers) => {\n let correctAnswers = 0;\n\n rows.forEach(row => {\n if (isEqual(row.values, answers[row.id])) {\n correctAnswers += 1;\n }\n });\n\n return correctAnswers;\n};\n\nconst getTotalCorrect = question => {\n const checkboxMode = question.choiceMode === 'checkbox';\n const matchingTable = checkboxMode ? question.layout - 1 : 1;\n return (question.rows.length || 0) * matchingTable;\n};\n\nconst getTotalCorrectAnswers = question => {\n let noOfTotalCorrectAnswers = 0;\n\n question.rows.forEach(row => {\n row.values.forEach(value => {\n if(value) {\n noOfTotalCorrectAnswers += 1;\n }\n });\n });\n\n return noOfTotalCorrectAnswers;\n};\n\nconst getPartialScore = (question, answers) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n\n if(checkboxMode) {\n const { correctAnswers, incorrectAnswers } = getCheckboxes(question.rows, answers);\n const totalCorrect = getTotalCorrectAnswers(question);\n\n const total = totalCorrect === 0 ? 1 : totalCorrect;\n\n if (correctAnswers + incorrectAnswers > totalCorrect) {\n const extraAnswers = (correctAnswers + incorrectAnswers) - totalCorrect;\n const score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));\n\n return score < 0 ? 0 : score;\n } else {\n return parseFloat((correctAnswers / total).toFixed(2));\n }\n } else {\n const correctAnswers = getCorrectRadios(question.rows, answers);\n const totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);\n\n return parseFloat((correctAnswers / totalCorrect).toFixed(2));\n }\n};\n\nconst getOutComeScore = (question, env, answers = {}) => {\n const correctness = getCorrectness(question, env, answers);\n const isPartialScoring = partialScoring.enabled(question, env);\n\n return correctness === 'correct'\n ? 1\n : correctness === 'partial' && isPartialScoring\n ? getPartialScore(question, answers)\n : 0;\n};\n\nexport const outcome = (question, session, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined });\n } else {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const out = {\n score: getOutComeScore(question, env, session.answers)\n };\n\n resolve(out);\n }\n });\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise(resolve => {\n resolve({\n ...defaults,\n ...model\n });\n });\n}\n\nexport const normalize = question => ({\n feedbackEnabled: true,\n promptEnabled: true,\n rationaleEnabled: 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 function model(question, session, env, updateSession) {\n return new Promise(async resolve => {\n const normalizedQuestion = cloneDeep(normalize(question));\n let correctness, score;\n\n if ((!session || isEmpty(session)) && env.mode === 'evaluate') {\n correctness = 'unanswered';\n score = '0%';\n } else {\n correctness = getCorrectness(normalizedQuestion, env, session && session.answers);\n score = `${getOutComeScore(normalizedQuestion, env, session && session.answers) *\n 100}%`;\n }\n\n const correctResponse = {};\n const correctInfo = {\n score,\n correctness\n };\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n normalizedQuestion.rows = await getShuffledChoices(\n normalizedQuestion.rows,\n session,\n updateSession,\n 'id'\n );\n }\n\n normalizedQuestion.rows.forEach(row => {\n correctResponse[row.id] = row.values;\n\n if (env.mode !== 'evaluate') {\n delete row.values;\n }\n });\n\n const fb =\n env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled\n ? getFeedbackForCorrectness(correctInfo.correctness, normalizedQuestion.feedback)\n : Promise.resolve(undefined);\n\n fb.then(feedback => {\n const out = {\n allowFeedback: normalizedQuestion.feedbackEnabled,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n config: {\n ...normalizedQuestion,\n shuffled: !normalizedQuestion.lockChoiceOrder\n },\n feedback,\n disabled: env.mode !== 'gather',\n view: env.mode === 'view'\n };\n\n if (\n env.role === 'instructor' &&\n (env.mode === 'view' || env.mode === 'evaluate')\n ) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n out.config.rationale = null;\n out.config.teacherInstructions = null;\n }\n\n if (env.mode === 'evaluate') {\n Object.assign(out, {\n correctResponse,\n correctness: correctInfo,\n });\n }\n\n log('out: ', out);\n resolve(out);\n });\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { rows } = question;\n const answers = {};\n\n rows.forEach(r => {\n answers[r.id] = r.values;\n });\n\n resolve({\n answers,\n id: '1'\n });\n } else {\n resolve(null);\n }\n });\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["log","getResponseCorrectness","model","answers","env","isPartialScoring","partialScoring","enabled","rows","checkboxMode","choiceMode","Object","keys","length","totalCorrectAnswers","getTotalCorrectAnswers","getTotalCorrect","correctAnswers","incorrectAnswers","checkboxes","getCheckboxes","getCorrectRadios","getCorrectness","question","mode","forEach","row","answer","id","values","v","i","matchingTable","layout","noOfTotalCorrectAnswers","value","getPartialScore","totalCorrect","total","extraAnswers","score","parseFloat","toFixed","getOutComeScore","correctness","outcome","session","Promise","resolve","undefined","completed","empty","out","createDefaultModel","defaults","normalize","feedbackEnabled","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","updateSession","normalizedQuestion","correctResponse","correctInfo","lockChoiceOrder","fb","feedback","then","allowFeedback","prompt","config","shuffled","disabled","view","role","teacherInstructions","rationale","assign","createCorrectResponseSession","r","markupToText","s","replace","validate","headers","minQuestions","maxQuestions","maxLengthQuestionsHeading","maxAnswers","maxLengthAnswers","maxLengthFirstColumnHeading","rowsErrors","columnsErrors","errors","noOfRowsError","index","title","hasCorrectResponse","identicalAnswer","slice","some","columnsLengthError","heading","h","correctResponseError"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAIA;;;;;;AAFA,IAAMA,GAAG,GAAG,uBAAM,+BAAN,CAAZ;;AAIA,IAAMC,sBAAsB,GAAG,SAAzBA,sBAAyB,CAACC,KAAD,EAAQC,OAAR,EAA8B;AAAA,MAAbC,GAAa,uEAAP,EAAO;;AAC3D,MAAMC,gBAAgB,GAAGC,gCAAeC,OAAf,CAAuBL,KAAvB,EAA8BE,GAA9B,CAAzB;;AACA,MAAMI,IAAI,GAAGN,KAAK,CAACM,IAAnB;AACA,MAAMC,YAAY,GAAGP,KAAK,CAACQ,UAAN,KAAqB,UAA1C;;AAEA,MAAI,CAACP,OAAD,IAAYQ,MAAM,CAACC,IAAP,CAAYT,OAAZ,EAAqBU,MAArB,KAAgC,CAAhD,EAAmD;AACjD,WAAO,YAAP;AACD;;AAED,MAAMC,mBAAmB,GAAGL,YAAY,GAAGM,sBAAsB,CAACb,KAAD,CAAzB,GAAmCc,eAAe,CAACd,KAAD,CAA1F;AACA,MAAIe,cAAJ;AACA,MAAIC,gBAAgB,GAAG,CAAvB;;AAEA,MAAIT,YAAJ,EAAkB;AAChB,QAAMU,UAAU,GAAGC,aAAa,CAACZ,IAAD,EAAOL,OAAP,CAAhC;AAEAc,IAAAA,cAAc,GAAGE,UAAU,CAACF,cAA5B;AACAC,IAAAA,gBAAgB,GAAGC,UAAU,CAACD,gBAA9B;AACD,GALD,MAKO;AACLD,IAAAA,cAAc,GAAGI,gBAAgB,CAACb,IAAD,EAAOL,OAAP,CAAjC;AACD;;AAED,MAAIW,mBAAmB,KAAKG,cAAxB,IAA0C,CAACC,gBAA/C,EAAiE;AAC/D,WAAO,SAAP;AACD,GAFD,MAEO,IAAID,cAAc,KAAK,CAAvB,EAA0B;AAC/B,WAAO,WAAP;AACD,GAFM,MAEA,IAAIZ,gBAAJ,EAAsB;AAC3B,WAAO,SAAP;AACD;;AAED,SAAO,WAAP;AACD,CA/BD;;AAiCA,IAAMiB,cAAc,GAAG,SAAjBA,cAAiB,CAACC,QAAD,EAAWnB,GAAX,EAAiC;AAAA,MAAjBD,OAAiB,uEAAP,EAAO;;AACtD,MAAIC,GAAG,CAACoB,IAAJ,KAAa,UAAjB,EAA6B;AAC3B,WAAOvB,sBAAsB,CAACsB,QAAD,EAAWpB,OAAX,EAAoBC,GAApB,CAA7B;AACD;AACF,CAJD;;AAMA,IAAMgB,aAAa,GAAG,SAAhBA,aAAgB,CAACZ,IAAD,EAAOL,OAAP,EAAmB;AACvC,MAAIc,cAAc,GAAG,CAArB;AACA,MAAIC,gBAAgB,GAAG,CAAvB;AAEAV,EAAAA,IAAI,CAACiB,OAAL,CAAa,UAACC,GAAD,EAAS;AACpB,QAAMC,MAAM,GAAGxB,OAAO,CAACuB,GAAG,CAACE,EAAL,CAAtB;;AAEA,QAAID,MAAJ,EAAY;AACVD,MAAAA,GAAG,CAACG,MAAJ,CAAWJ,OAAX,CAAmB,UAACK,CAAD,EAAIC,CAAJ,EAAU;AAC3B,YAAIJ,MAAM,CAACI,CAAD,CAAN,IAAaJ,MAAM,CAACI,CAAD,CAAN,KAAcD,CAA/B,EAAkC;AAChCb,UAAAA,cAAc,IAAI,CAAlB;AACD,SAFD,MAEO,IAAIU,MAAM,CAACI,CAAD,CAAN,IAAaJ,MAAM,CAACI,CAAD,CAAN,KAAcD,CAA/B,EAAkC;AACvCZ,UAAAA,gBAAgB,IAAI,CAApB;AACD;AACF,OAND;AAOD;AACF,GAZD;AAcA,SAAO;AAAED,IAAAA,cAAc,EAAdA,cAAF;AAAkBC,IAAAA,gBAAgB,EAAhBA;AAAlB,GAAP;AACD,CAnBD;;AAqBA,IAAMG,gBAAgB,GAAG,SAAnBA,gBAAmB,CAACb,IAAD,EAAOL,OAAP,EAAmB;AAC1C,MAAIc,cAAc,GAAG,CAArB;AAEAT,EAAAA,IAAI,CAACiB,OAAL,CAAa,UAACC,GAAD,EAAS;AACpB,QAAI,yBAAQA,GAAG,CAACG,MAAZ,EAAoB1B,OAAO,CAACuB,GAAG,CAACE,EAAL,CAA3B,CAAJ,EAA0C;AACxCX,MAAAA,cAAc,IAAI,CAAlB;AACD;AACF,GAJD;AAMA,SAAOA,cAAP;AACD,CAVD;;AAYA,IAAMD,eAAe,GAAG,SAAlBA,eAAkB,CAACO,QAAD,EAAc;AACpC,MAAMd,YAAY,GAAGc,QAAQ,CAACb,UAAT,KAAwB,UAA7C;AACA,MAAMsB,aAAa,GAAGvB,YAAY,GAAGc,QAAQ,CAACU,MAAT,GAAkB,CAArB,GAAyB,CAA3D;AACA,SAAO,CAACV,QAAQ,CAACf,IAAT,CAAcK,MAAd,IAAwB,CAAzB,IAA8BmB,aAArC;AACD,CAJD;;AAMA,IAAMjB,sBAAsB,GAAG,SAAzBA,sBAAyB,CAACQ,QAAD,EAAc;AAC3C,MAAIW,uBAAuB,GAAG,CAA9B;AAEAX,EAAAA,QAAQ,CAACf,IAAT,CAAciB,OAAd,CAAsB,UAACC,GAAD,EAAS;AAC7BA,IAAAA,GAAG,CAACG,MAAJ,CAAWJ,OAAX,CAAmB,UAACU,KAAD,EAAW;AAC5B,UAAIA,KAAJ,EAAW;AACTD,QAAAA,uBAAuB,IAAI,CAA3B;AACD;AACF,KAJD;AAKD,GAND;AAQA,SAAOA,uBAAP;AACD,CAZD;;AAcA,IAAME,eAAe,GAAG,SAAlBA,eAAkB,CAACb,QAAD,EAAWpB,OAAX,EAAuB;AAC7C,MAAMM,YAAY,GAAGc,QAAQ,CAACb,UAAT,KAAwB,UAA7C;;AAEA,MAAID,YAAJ,EAAkB;AAChB,yBAA6CW,aAAa,CAACG,QAAQ,CAACf,IAAV,EAAgBL,OAAhB,CAA1D;AAAA,QAAQc,cAAR,kBAAQA,cAAR;AAAA,QAAwBC,gBAAxB,kBAAwBA,gBAAxB;;AACA,QAAMmB,YAAY,GAAGtB,sBAAsB,CAACQ,QAAD,CAA3C;AAEA,QAAMe,KAAK,GAAGD,YAAY,KAAK,CAAjB,GAAqB,CAArB,GAAyBA,YAAvC;;AAEA,QAAIpB,cAAc,GAAGC,gBAAjB,GAAoCmB,YAAxC,EAAsD;AACpD,UAAME,YAAY,GAAGtB,cAAc,GAAGC,gBAAjB,GAAoCmB,YAAzD;AACA,UAAMG,KAAK,GAAGC,UAAU,CAAC,CAAC,CAACxB,cAAc,GAAGsB,YAAlB,IAAkCD,KAAnC,EAA0CI,OAA1C,CAAkD,CAAlD,CAAD,CAAxB;AAEA,aAAOF,KAAK,GAAG,CAAR,GAAY,CAAZ,GAAgBA,KAAvB;AACD,KALD,MAKO;AACL,aAAOC,UAAU,CAAC,CAACxB,cAAc,GAAGqB,KAAlB,EAAyBI,OAAzB,CAAiC,CAAjC,CAAD,CAAjB;AACD;AACF,GAdD,MAcO;AACL,QAAMzB,eAAc,GAAGI,gBAAgB,CAACE,QAAQ,CAACf,IAAV,EAAgBL,OAAhB,CAAvC;;AACA,QAAMkC,aAAY,GAAGrB,eAAe,CAACO,QAAD,CAAf,KAA8B,CAA9B,GAAkC,CAAlC,GAAsCP,eAAe,CAACO,QAAD,CAA1E;;AAEA,WAAOkB,UAAU,CAAC,CAACxB,eAAc,GAAGoB,aAAlB,EAAgCK,OAAhC,CAAwC,CAAxC,CAAD,CAAjB;AACD;AACF,CAvBD;;AAyBA,IAAMC,eAAe,GAAG,SAAlBA,eAAkB,CAACpB,QAAD,EAAWnB,GAAX,EAAiC;AAAA,MAAjBD,OAAiB,uEAAP,EAAO;AACvD,MAAMyC,WAAW,GAAGtB,cAAc,CAACC,QAAD,EAAWnB,GAAX,EAAgBD,OAAhB,CAAlC;;AACA,MAAME,gBAAgB,GAAGC,gCAAeC,OAAf,CAAuBgB,QAAvB,EAAiCnB,GAAjC,CAAzB;;AAEA,SAAOwC,WAAW,KAAK,SAAhB,GACH,CADG,GAEHA,WAAW,KAAK,SAAhB,IAA6BvC,gBAA7B,GACE+B,eAAe,CAACb,QAAD,EAAWpB,OAAX,CADjB,GAEE,CAJN;AAKD,CATD;;AAWO,IAAM0C,OAAO,GAAG,SAAVA,OAAU,CAACtB,QAAD,EAAWuB,OAAX,EAAoB1C,GAApB,EAA4B;AACjD,SAAO,IAAI2C,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9B,QAAI5C,GAAG,CAACoB,IAAJ,KAAa,UAAjB,EAA6B;AAC3BwB,MAAAA,OAAO,CAAC;AAAER,QAAAA,KAAK,EAAES,SAAT;AAAoBC,QAAAA,SAAS,EAAED;AAA/B,OAAD,CAAP;AACD,KAFD,MAEO;AACL,UAAI,CAACH,OAAD,IAAY,yBAAQA,OAAR,CAAhB,EAAkC;AAChCE,QAAAA,OAAO,CAAC;AAAER,UAAAA,KAAK,EAAE,CAAT;AAAYW,UAAAA,KAAK,EAAE;AAAnB,SAAD,CAAP;AACD;;AAED,UAAMC,GAAG,GAAG;AACVZ,QAAAA,KAAK,EAAEG,eAAe,CAACpB,QAAD,EAAWnB,GAAX,EAAgB0C,OAAO,CAAC3C,OAAxB;AADZ,OAAZ;AAIA6C,MAAAA,OAAO,CAACI,GAAD,CAAP;AACD;AACF,GAdM,CAAP;AAeD,CAhBM;;;;AAkBA,SAASC,kBAAT,GAAwC;AAAA,MAAZnD,KAAY,uEAAJ,EAAI;AAC7C,SAAO,IAAI6C,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9BA,IAAAA,OAAO,iCACFM,oBADE,GAEFpD,KAFE,EAAP;AAID,GALM,CAAP;AAMD;;AAEM,IAAMqD,SAAS,GAAG,SAAZA,SAAY,CAAChC,QAAD;AAAA;AACvBiC,IAAAA,eAAe,EAAE,IADM;AAEvBC,IAAAA,aAAa,EAAE,IAFQ;AAGvBC,IAAAA,gBAAgB,EAAE,IAHK;AAIvBC,IAAAA,0BAA0B,EAAE,IAJL;AAKvBC,IAAAA,0BAA0B,EAAE;AALL,KAMpBrC,QANoB;AAAA,CAAlB;AASP;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACO,SAASrB,KAAT,CAAeqB,QAAf,EAAyBuB,OAAzB,EAAkC1C,GAAlC,EAAuCyD,aAAvC,EAAsD;AAC3D,SAAO,IAAId,OAAJ;AAAA,6FAAY,iBAAOC,OAAP;AAAA;AAAA;AAAA;AAAA;AAAA;AACXc,cAAAA,kBADW,GACU,2BAAUP,SAAS,CAAChC,QAAD,CAAnB,CADV;;AAIjB,kBAAI,CAAC,CAACuB,OAAD,IAAY,yBAAQA,OAAR,CAAb,KAAkC1C,GAAG,CAACoB,IAAJ,KAAa,UAAnD,EAA+D;AAC7DoB,gBAAAA,WAAW,GAAG,YAAd;AACAJ,gBAAAA,KAAK,GAAG,IAAR;AACD,eAHD,MAGO;AACLI,gBAAAA,WAAW,GAAGtB,cAAc,CAACwC,kBAAD,EAAqB1D,GAArB,EAA0B0C,OAAO,IAAIA,OAAO,CAAC3C,OAA7C,CAA5B;AACAqC,gBAAAA,KAAK,aAAMG,eAAe,CAACmB,kBAAD,EAAqB1D,GAArB,EAA0B0C,OAAO,IAAIA,OAAO,CAAC3C,OAA7C,CAAf,GAAuE,GAA7E,MAAL;AACD;;AAEK4D,cAAAA,eAZW,GAYO,EAZP;AAaXC,cAAAA,WAbW,GAaG;AAClBxB,gBAAAA,KAAK,EAALA,KADkB;AAElBI,gBAAAA,WAAW,EAAXA;AAFkB,eAbH;AAkBXqB,cAAAA,eAlBW,GAkBO,kCAAYH,kBAAZ,EAAgChB,OAAhC,EAAyC1C,GAAzC,CAlBP;;AAAA,kBAoBZ6D,eApBY;AAAA;AAAA;AAAA;;AAAA;AAAA,qBAqBiB,yCAAmBH,kBAAkB,CAACtD,IAAtC,EAA4CsC,OAA5C,EAAqDe,aAArD,EAAoE,IAApE,CArBjB;;AAAA;AAqBfC,cAAAA,kBAAkB,CAACtD,IArBJ;;AAAA;AAwBjBsD,cAAAA,kBAAkB,CAACtD,IAAnB,CAAwBiB,OAAxB,CAAgC,UAACC,GAAD,EAAS;AACvCqC,gBAAAA,eAAe,CAACrC,GAAG,CAACE,EAAL,CAAf,GAA0BF,GAAG,CAACG,MAA9B;;AAEA,oBAAIzB,GAAG,CAACoB,IAAJ,KAAa,UAAjB,EAA6B;AAC3B,yBAAOE,GAAG,CAACG,MAAX;AACD;AACF,eAND;AAQMqC,cAAAA,EAhCW,GAiCf9D,GAAG,CAACoB,IAAJ,KAAa,UAAb,IAA2BsC,kBAAkB,CAACN,eAA9C,GACI,yCAA0BQ,WAAW,CAACpB,WAAtC,EAAmDkB,kBAAkB,CAACK,QAAtE,CADJ,GAEIpB,OAAO,CAACC,OAAR,CAAgBC,SAAhB,CAnCW;AAqCjBiB,cAAAA,EAAE,CAACE,IAAH,CAAQ,UAACD,QAAD,EAAc;AACpB,oBAAMf,GAAG,GAAG;AACViB,kBAAAA,aAAa,EAAEP,kBAAkB,CAACN,eADxB;AAEVc,kBAAAA,MAAM,EAAER,kBAAkB,CAACL,aAAnB,GAAmCK,kBAAkB,CAACQ,MAAtD,GAA+D,IAF7D;AAGVC,kBAAAA,MAAM,kCACDT,kBADC;AAEJU,oBAAAA,QAAQ,EAAE,CAACV,kBAAkB,CAACG;AAF1B,oBAHI;AAOVE,kBAAAA,QAAQ,EAARA,QAPU;AAQVM,kBAAAA,QAAQ,EAAErE,GAAG,CAACoB,IAAJ,KAAa,QARb;AASVkD,kBAAAA,IAAI,EAAEtE,GAAG,CAACoB,IAAJ,KAAa;AATT,iBAAZ;;AAYA,oBAAIpB,GAAG,CAACuE,IAAJ,KAAa,YAAb,KAA8BvE,GAAG,CAACoB,IAAJ,KAAa,MAAb,IAAuBpB,GAAG,CAACoB,IAAJ,KAAa,UAAlE,CAAJ,EAAmF;AACjF4B,kBAAAA,GAAG,CAACwB,mBAAJ,GAA0Bd,kBAAkB,CAACH,0BAAnB,GACtBG,kBAAkB,CAACc,mBADG,GAEtB,IAFJ;AAGAxB,kBAAAA,GAAG,CAACyB,SAAJ,GAAgBf,kBAAkB,CAACJ,gBAAnB,GAAsCI,kBAAkB,CAACe,SAAzD,GAAqE,IAArF;AACD,iBALD,MAKO;AACLzB,kBAAAA,GAAG,CAACyB,SAAJ,GAAgB,IAAhB;AACAzB,kBAAAA,GAAG,CAACwB,mBAAJ,GAA0B,IAA1B;AACAxB,kBAAAA,GAAG,CAACmB,MAAJ,CAAWM,SAAX,GAAuB,IAAvB;AACAzB,kBAAAA,GAAG,CAACmB,MAAJ,CAAWK,mBAAX,GAAiC,IAAjC;AACD;;AAED,oBAAIxE,GAAG,CAACoB,IAAJ,KAAa,UAAjB,EAA6B;AAC3Bb,kBAAAA,MAAM,CAACmE,MAAP,CAAc1B,GAAd,EAAmB;AACjBW,oBAAAA,eAAe,EAAfA,eADiB;AAEjBnB,oBAAAA,WAAW,EAAEoB;AAFI,mBAAnB;AAID;;AAEDhE,gBAAAA,GAAG,CAAC,OAAD,EAAUoD,GAAV,CAAH;AACAJ,gBAAAA,OAAO,CAACI,GAAD,CAAP;AACD,eAlCD;;AArCiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAAZ;;AAAA;AAAA;AAAA;AAAA,MAAP;AAyED;;AAEM,IAAM2B,4BAA4B,GAAG,SAA/BA,4BAA+B,CAACxD,QAAD,EAAWnB,GAAX,EAAmB;AAC7D,SAAO,IAAI2C,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9B,QAAI5C,GAAG,CAACoB,IAAJ,KAAa,UAAb,IAA2BpB,GAAG,CAACuE,IAAJ,KAAa,YAA5C,EAA0D;AACxD,UAAQnE,IAAR,GAAiBe,QAAjB,CAAQf,IAAR;AACA,UAAML,OAAO,GAAG,EAAhB;AAEAK,MAAAA,IAAI,CAACiB,OAAL,CAAa,UAACuD,CAAD,EAAO;AAClB7E,QAAAA,OAAO,CAAC6E,CAAC,CAACpD,EAAH,CAAP,GAAgBoD,CAAC,CAACnD,MAAlB;AACD,OAFD;AAIAmB,MAAAA,OAAO,CAAC;AACN7C,QAAAA,OAAO,EAAPA,OADM;AAENyB,QAAAA,EAAE,EAAE;AAFE,OAAD,CAAP;AAID,KAZD,MAYO;AACLoB,MAAAA,OAAO,CAAC,IAAD,CAAP;AACD;AACF,GAhBM,CAAP;AAiBD,CAlBM;;;;AAoBP,IAAMiC,YAAY,GAAG,SAAfA,YAAe,CAACC,CAAD,EAAO;AAC1B,SAAOA,CAAC,CAACC,OAAF,CAAU,eAAV,EAA2B,EAA3B,CAAP;AACD,CAFD;;AAIO,IAAMC,QAAQ,GAAG,SAAXA,QAAW,GAA6B;AAAA,MAA5BlF,KAA4B,uEAApB,EAAoB;AAAA,MAAhBqE,MAAgB,uEAAP,EAAO;AACnD,MAAQ/D,IAAR,GAAsCN,KAAtC,CAAQM,IAAR;AAAA,MAAcE,UAAd,GAAsCR,KAAtC,CAAcQ,UAAd;AAAA,MAA0B2E,OAA1B,GAAsCnF,KAAtC,CAA0BmF,OAA1B;AACA,MACEC,YADF,GAOIf,MAPJ,CACEe,YADF;AAAA,MAEEC,YAFF,GAOIhB,MAPJ,CAEEgB,YAFF;AAAA,MAGEC,yBAHF,GAOIjB,MAPJ,CAGEiB,yBAHF;AAAA,MAIEC,UAJF,GAOIlB,MAPJ,CAIEkB,UAJF;AAAA,MAKEC,gBALF,GAOInB,MAPJ,CAKEmB,gBALF;AAAA,MAMEC,2BANF,GAOIpB,MAPJ,CAMEoB,2BANF;AAQA,MAAMC,UAAU,GAAG,EAAnB;AACA,MAAMC,aAAa,GAAG,EAAtB;AACA,MAAMC,MAAM,GAAG,EAAf;;AAEA,MAAItF,IAAI,CAACK,MAAL,GAAcyE,YAAlB,EAAgC;AAC9BQ,IAAAA,MAAM,CAACC,aAAP,sCAAmDT,YAAnD;AACD,GAFD,MAEO,IAAI9E,IAAI,CAACK,MAAL,GAAc0E,YAAlB,EAAgC;AACrCO,IAAAA,MAAM,CAACC,aAAP,0BAAuCR,YAAvC;AACD;;AAED,GAAC/E,IAAI,IAAI,EAAT,EAAaiB,OAAb,CAAqB,UAACC,GAAD,EAAMsE,KAAN,EAAgB;AACnC,QAAQpE,EAAR,GAAmCF,GAAnC,CAAQE,EAAR;AAAA,sBAAmCF,GAAnC,CAAYG,MAAZ;AAAA,QAAYA,MAAZ,4BAAqB,EAArB;AAAA,QAAyBoE,KAAzB,GAAmCvE,GAAnC,CAAyBuE,KAAzB;AACA,QAAIC,kBAAkB,GAAG,KAAzB;AAEAN,IAAAA,UAAU,CAAChE,EAAD,CAAV,GAAiB,EAAjB;;AAEA,QAAI4D,yBAAyB,IAAIP,YAAY,CAACgB,KAAD,CAAZ,CAAoBpF,MAApB,GAA6B2E,yBAA9D,EAAyF;AACvFI,MAAAA,UAAU,CAAChE,EAAD,CAAV,oEAA2E4D,yBAA3E;AACD,KAFD,MAEO,IAAIS,KAAK,KAAK,EAAV,IAAgBA,KAAK,KAAK,aAA9B,EAA6C;AAClDL,MAAAA,UAAU,CAAChE,EAAD,CAAV,IAAkB,+BAAlB;AACD,KAFM,MAEA;AACL,UAAMuE,eAAe,GAAG3F,IAAI,CAAC4F,KAAL,CAAWJ,KAAK,GAAG,CAAnB,EAAsBK,IAAtB,CAA2B,UAACrB,CAAD,EAAO;AACxD,eAAOA,CAAC,CAACiB,KAAF,KAAYA,KAAnB;AACD,OAFuB,CAAxB;;AAIA,UAAIE,eAAJ,EAAqB;AACnBP,QAAAA,UAAU,CAAChE,EAAD,CAAV,GAAiB,4BAAjB;AACD;AACF;;AAEDC,IAAAA,MAAM,CAACJ,OAAP,CAAe,UAACU,KAAD,EAAW;AACxB,UAAIA,KAAJ,EAAW;AACT+D,QAAAA,kBAAkB,GAAG,IAArB;AACD;AACF,KAJD;;AAMA,QAAI,CAACA,kBAAL,EAAyB;AACvBN,MAAAA,UAAU,CAAChE,EAAD,CAAV,IAAkB,8BAAlB;AACD;AACF,GA7BD;;AA+BA,MAAI6D,UAAU,IAAIJ,OAAO,CAACxE,MAAR,GAAiB,CAAjB,GAAqB4E,UAAvC,EAAmD;AACjDK,IAAAA,MAAM,CAACQ,kBAAP,qCAAuDb,UAAvD;AACD;;AAED,MAAIE,2BAA2B,IAAIN,OAAO,CAAC,CAAD,CAAP,CAAWxE,MAAX,GAAoB8E,2BAAvD,EAAoF;AAClFE,IAAAA,aAAa,CAAC,CAAD,CAAb,wEAAiFF,2BAAjF;AACD;;AAED,GAACN,OAAO,IAAI,EAAZ,EAAgBe,KAAhB,CAAsB,CAAtB,EAAyB3E,OAAzB,CAAiC,UAAC8E,OAAD,EAAUP,KAAV,EAAoB;AACnD,QAAIO,OAAO,KAAK,EAAZ,IAAkBA,OAAO,KAAK,aAAlC,EAAiD;AAC/CV,MAAAA,aAAa,CAACG,KAAK,GAAG,CAAT,CAAb,GAA2B,8BAA3B;AACD,KAFD,MAEO,IAAIN,gBAAgB,IAAIa,OAAO,CAAC1F,MAAR,GAAiB6E,gBAAzC,EAA2D;AAChEG,MAAAA,aAAa,CAACG,KAAK,GAAG,CAAT,CAAb,8CAA+DN,gBAA/D;AACD,KAFM,MAEA;AACL,UAAMS,eAAe,GAAGd,OAAO,CAACe,KAAR,CAAcJ,KAAK,GAAG,CAAtB,EAAyBK,IAAzB,CAA8B,UAACG,CAAD,EAAO;AAC3D,eAAOA,CAAC,KAAKD,OAAb;AACD,OAFuB,CAAxB;;AAIA,UAAIJ,eAAJ,EAAqB;AACnBN,QAAAA,aAAa,CAACG,KAAK,GAAG,CAAT,CAAb,GAA2B,2BAA3B;AACD;AACF;AACF,GAdD;;AAiBA,MAAI,CAAC,yBAAQJ,UAAR,CAAL,EAA0B;AACxBE,IAAAA,MAAM,CAACF,UAAP,GAAoBA,UAApB;AACAE,IAAAA,MAAM,CAACW,oBAAP,GACE/F,UAAU,KAAK,OAAf,GACI,2DADJ,GAEI,sEAHN;AAID;;AAED,MAAI,CAAC,yBAAQmF,aAAR,CAAL,EAA6B;AAC3BC,IAAAA,MAAM,CAACD,aAAP,GAAuBA,aAAvB;AACD;;AAED,SAAOC,MAAP;AACD,CAzFM","sourcesContent":["import isEqual from 'lodash/isEqual';\nimport isEmpty from 'lodash/isEmpty';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';\nimport debug from 'debug';\n\nconst log = debug('@pie-element:match:controller');\n\nimport defaults from './defaults';\n\nconst getResponseCorrectness = (model, answers, env = {}) => {\n const isPartialScoring = partialScoring.enabled(model, env);\n const rows = model.rows;\n const checkboxMode = model.choiceMode === 'checkbox';\n\n if (!answers || Object.keys(answers).length === 0) {\n return 'unanswered';\n }\n\n const totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);\n let correctAnswers;\n let incorrectAnswers = 0;\n\n if (checkboxMode) {\n const checkboxes = getCheckboxes(rows, answers);\n\n correctAnswers = checkboxes.correctAnswers;\n incorrectAnswers = checkboxes.incorrectAnswers;\n } else {\n correctAnswers = getCorrectRadios(rows, answers);\n }\n\n if (totalCorrectAnswers === correctAnswers && !incorrectAnswers) {\n return 'correct';\n } else if (correctAnswers === 0) {\n return 'incorrect';\n } else if (isPartialScoring) {\n return 'partial';\n }\n\n return 'incorrect';\n};\n\nconst getCorrectness = (question, env, answers = {}) => {\n if (env.mode === 'evaluate') {\n return getResponseCorrectness(question, answers, env);\n }\n};\n\nconst getCheckboxes = (rows, answers) => {\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n\n rows.forEach((row) => {\n const answer = answers[row.id];\n\n if (answer) {\n row.values.forEach((v, i) => {\n if (answer[i] && answer[i] === v) {\n correctAnswers += 1;\n } else if (answer[i] && answer[i] !== v) {\n incorrectAnswers += 1;\n }\n });\n }\n });\n\n return { correctAnswers, incorrectAnswers };\n};\n\nconst getCorrectRadios = (rows, answers) => {\n let correctAnswers = 0;\n\n rows.forEach((row) => {\n if (isEqual(row.values, answers[row.id])) {\n correctAnswers += 1;\n }\n });\n\n return correctAnswers;\n};\n\nconst getTotalCorrect = (question) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n const matchingTable = checkboxMode ? question.layout - 1 : 1;\n return (question.rows.length || 0) * matchingTable;\n};\n\nconst getTotalCorrectAnswers = (question) => {\n let noOfTotalCorrectAnswers = 0;\n\n question.rows.forEach((row) => {\n row.values.forEach((value) => {\n if (value) {\n noOfTotalCorrectAnswers += 1;\n }\n });\n });\n\n return noOfTotalCorrectAnswers;\n};\n\nconst getPartialScore = (question, answers) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n\n if (checkboxMode) {\n const { correctAnswers, incorrectAnswers } = getCheckboxes(question.rows, answers);\n const totalCorrect = getTotalCorrectAnswers(question);\n\n const total = totalCorrect === 0 ? 1 : totalCorrect;\n\n if (correctAnswers + incorrectAnswers > totalCorrect) {\n const extraAnswers = correctAnswers + incorrectAnswers - totalCorrect;\n const score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));\n\n return score < 0 ? 0 : score;\n } else {\n return parseFloat((correctAnswers / total).toFixed(2));\n }\n } else {\n const correctAnswers = getCorrectRadios(question.rows, answers);\n const totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);\n\n return parseFloat((correctAnswers / totalCorrect).toFixed(2));\n }\n};\n\nconst getOutComeScore = (question, env, answers = {}) => {\n const correctness = getCorrectness(question, env, answers);\n const isPartialScoring = partialScoring.enabled(question, env);\n\n return correctness === 'correct'\n ? 1\n : correctness === 'partial' && isPartialScoring\n ? getPartialScore(question, answers)\n : 0;\n};\n\nexport const outcome = (question, session, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined });\n } else {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const out = {\n score: getOutComeScore(question, env, session.answers),\n };\n\n resolve(out);\n }\n });\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n}\n\nexport const normalize = (question) => ({\n feedbackEnabled: true,\n promptEnabled: true,\n rationaleEnabled: 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 function model(question, session, env, updateSession) {\n return new Promise(async (resolve) => {\n const normalizedQuestion = cloneDeep(normalize(question));\n let correctness, score;\n\n if ((!session || isEmpty(session)) && env.mode === 'evaluate') {\n correctness = 'unanswered';\n score = '0%';\n } else {\n correctness = getCorrectness(normalizedQuestion, env, session && session.answers);\n score = `${getOutComeScore(normalizedQuestion, env, session && session.answers) * 100}%`;\n }\n\n const correctResponse = {};\n const correctInfo = {\n score,\n correctness,\n };\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n normalizedQuestion.rows = await getShuffledChoices(normalizedQuestion.rows, session, updateSession, 'id');\n }\n\n normalizedQuestion.rows.forEach((row) => {\n correctResponse[row.id] = row.values;\n\n if (env.mode !== 'evaluate') {\n delete row.values;\n }\n });\n\n const fb =\n env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled\n ? getFeedbackForCorrectness(correctInfo.correctness, normalizedQuestion.feedback)\n : Promise.resolve(undefined);\n\n fb.then((feedback) => {\n const out = {\n allowFeedback: normalizedQuestion.feedbackEnabled,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n config: {\n ...normalizedQuestion,\n shuffled: !normalizedQuestion.lockChoiceOrder,\n },\n feedback,\n disabled: env.mode !== 'gather',\n view: env.mode === 'view',\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n out.config.rationale = null;\n out.config.teacherInstructions = null;\n }\n\n if (env.mode === 'evaluate') {\n Object.assign(out, {\n correctResponse,\n correctness: correctInfo,\n });\n }\n\n log('out: ', out);\n resolve(out);\n });\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { rows } = question;\n const answers = {};\n\n rows.forEach((r) => {\n answers[r.id] = r.values;\n });\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\nconst markupToText = (s) => {\n return s.replace(/(<([^>]+)>)/ig, '');\n};\n\nexport const validate = (model = {}, config = {}) => {\n const { rows, choiceMode, headers } = model;\n const {\n minQuestions,\n maxQuestions,\n maxLengthQuestionsHeading,\n maxAnswers,\n maxLengthAnswers,\n maxLengthFirstColumnHeading\n } = config;\n const rowsErrors = {};\n const columnsErrors = {};\n const errors = {};\n\n if (rows.length < minQuestions) {\n errors.noOfRowsError = `There should be at least ${minQuestions} question rows.`;\n } else if (rows.length > maxQuestions) {\n errors.noOfRowsError = `No more than ${maxQuestions} question rows should be defined.`;\n }\n\n (rows || []).forEach((row, index) => {\n const { id, values = [], title } = row;\n let hasCorrectResponse = false;\n\n rowsErrors[id] = '';\n\n if (maxLengthQuestionsHeading && markupToText(title).length > maxLengthQuestionsHeading) {\n rowsErrors[id] += `Questions rows content length should not be more than ${maxLengthQuestionsHeading} characters. `;\n } else if (title === '' || title === '<div></div>') {\n rowsErrors[id] += 'Content should not be empty. ';\n } else {\n const identicalAnswer = rows.slice(index + 1).some((r) => {\n return r.title === title;\n });\n\n if (identicalAnswer) {\n rowsErrors[id] = 'Content should be unique. ';\n }\n }\n\n values.forEach((value) => {\n if (value) {\n hasCorrectResponse = true;\n }\n });\n\n if (!hasCorrectResponse) {\n rowsErrors[id] += 'No correct response defined.';\n }\n });\n\n if (maxAnswers && headers.length - 1 > maxAnswers) {\n errors.columnsLengthError = `There should be maximum ${maxAnswers} answers.`;\n }\n\n if (maxLengthFirstColumnHeading && headers[0].length > maxLengthFirstColumnHeading) {\n columnsErrors[0] = `The first column heading should have the maximum length of ${maxLengthFirstColumnHeading} characters.`;\n }\n\n (headers || []).slice(1).forEach((heading, index) => {\n if (heading === '' || heading === '<div></div>') {\n columnsErrors[index + 1] = 'Content should not be empty.';\n } else if (maxLengthAnswers && heading.length > maxLengthAnswers) {\n columnsErrors[index + 1] = `Content length should be maximum ${maxLengthAnswers} characters.`;\n } else {\n const identicalAnswer = headers.slice(index + 2).some((h) => {\n return h === heading;\n });\n\n if (identicalAnswer) {\n columnsErrors[index + 2] = 'Content should be unique.';\n }\n }\n });\n\n\n if (!isEmpty(rowsErrors)) {\n errors.rowsErrors = rowsErrors;\n errors.correctResponseError =\n choiceMode === 'radio'\n ? 'There should be a correct response defined for every row.'\n : 'There should be at least one correct response defined for every row.';\n }\n\n if (!isEmpty(columnsErrors)) {\n errors.columnsErrors = columnsErrors;\n }\n\n return errors;\n};\n"],"file":"index.js"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pie-element/match-controller",
3
3
  "private": true,
4
- "version": "4.4.7",
4
+ "version": "4.6.1",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "module": "src/index.js",
@@ -9,8 +9,8 @@
9
9
  "test": "./node_modules/.bin/jest"
10
10
  },
11
11
  "dependencies": {
12
- "@pie-lib/controller-utils": "^0.2.26",
13
- "@pie-lib/feedback": "^0.4.27",
12
+ "@pie-lib/controller-utils": "^0.2.42",
13
+ "@pie-lib/feedback": "^0.4.42",
14
14
  "debug": "^3.1.0"
15
15
  },
16
16
  "devDependencies": {
@@ -131,6 +131,27 @@
131
131
  }
132
132
  }
133
133
  },
134
+ "settingsPanelDisabled": {
135
+ "description": "Indicates if the settings panel is not available",
136
+ "type": "boolean",
137
+ "title": "settingsPanelDisabled"
138
+ },
139
+ "spellCheck": {
140
+ "title": "ConfigureProp",
141
+ "type": "object",
142
+ "properties": {
143
+ "settings": {
144
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
145
+ "type": "boolean",
146
+ "title": "settings"
147
+ },
148
+ "label": {
149
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
150
+ "type": "string",
151
+ "title": "label"
152
+ }
153
+ }
154
+ },
134
155
  "rationale": {
135
156
  "title": "ConfigureProp",
136
157
  "type": "object",
@@ -195,6 +216,109 @@
195
216
  }
196
217
  }
197
218
  },
219
+ "maxImageWidth": {
220
+ "title": "ConfigureMaxImageDimensionsProp",
221
+ "type": "object",
222
+ "properties": {
223
+ "teacherInstructions": {
224
+ "description": "Indicates the max dimension for images in teacher instructions",
225
+ "type": "number",
226
+ "title": "teacherInstructions"
227
+ },
228
+ "prompt": {
229
+ "description": "Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified",
230
+ "type": "number",
231
+ "title": "prompt"
232
+ },
233
+ "rationale": {
234
+ "description": "Indicates the max dimension for images in rationale",
235
+ "type": "number",
236
+ "title": "rationale"
237
+ },
238
+ "rowTitles": {
239
+ "description": "Indicates the max dimension for images in row labels",
240
+ "type": "number",
241
+ "title": "rowTitles"
242
+ }
243
+ }
244
+ },
245
+ "maxImageHeight": {
246
+ "title": "ConfigureMaxImageDimensionsProp",
247
+ "type": "object",
248
+ "properties": {
249
+ "teacherInstructions": {
250
+ "description": "Indicates the max dimension for images in teacher instructions",
251
+ "type": "number",
252
+ "title": "teacherInstructions"
253
+ },
254
+ "prompt": {
255
+ "description": "Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified",
256
+ "type": "number",
257
+ "title": "prompt"
258
+ },
259
+ "rationale": {
260
+ "description": "Indicates the max dimension for images in rationale",
261
+ "type": "number",
262
+ "title": "rationale"
263
+ },
264
+ "rowTitles": {
265
+ "description": "Indicates the max dimension for images in row labels",
266
+ "type": "number",
267
+ "title": "rowTitles"
268
+ }
269
+ }
270
+ },
271
+ "withRubric": {
272
+ "title": "ConfigureProp",
273
+ "type": "object",
274
+ "properties": {
275
+ "settings": {
276
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
277
+ "type": "boolean",
278
+ "title": "settings"
279
+ },
280
+ "label": {
281
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
282
+ "type": "string",
283
+ "title": "label"
284
+ }
285
+ }
286
+ },
287
+ "minQuestions": {
288
+ "description": "Indicates the minimum number of question rows",
289
+ "type": "number",
290
+ "title": "minQuestions"
291
+ },
292
+ "maxQuestions": {
293
+ "description": "Indicates the maximum number of question rows",
294
+ "type": "number",
295
+ "title": "maxQuestions"
296
+ },
297
+ "maxLengthQuestionsHeading": {
298
+ "description": "Indicates the maximum length of question rows headings",
299
+ "type": "number",
300
+ "title": "maxLengthQuestionsHeading"
301
+ },
302
+ "maxAnswers": {
303
+ "description": "Indicates the maximum number of answer columns",
304
+ "type": "number",
305
+ "title": "maxAnswers"
306
+ },
307
+ "maxLengthAnswers": {
308
+ "description": "Indicates the maximum length of answer columns headings",
309
+ "type": "number",
310
+ "title": "maxLengthAnswers"
311
+ },
312
+ "maxLengthFirstColumnHeading": {
313
+ "description": "Indicates the maximum length of first column headings",
314
+ "type": "number",
315
+ "title": "maxLengthFirstColumnHeading"
316
+ },
317
+ "width": {
318
+ "description": "How large (in px) should match be",
319
+ "type": "string",
320
+ "title": "width"
321
+ },
198
322
  "showPrompt": {
199
323
  "description": "Determines whether prompt field will be displayed or not",
200
324
  "default": true,
@@ -214,6 +338,9 @@
214
338
  "title": "settingsPartialScoring"
215
339
  }
216
340
  },
341
+ "required": [
342
+ "width"
343
+ ],
217
344
  "definitions": {
218
345
  "ConfigureProp": {
219
346
  "title": "ConfigureProp",
@@ -230,6 +357,32 @@
230
357
  "title": "label"
231
358
  }
232
359
  }
360
+ },
361
+ "ConfigureMaxImageDimensionsProp": {
362
+ "title": "ConfigureMaxImageDimensionsProp",
363
+ "type": "object",
364
+ "properties": {
365
+ "teacherInstructions": {
366
+ "description": "Indicates the max dimension for images in teacher instructions",
367
+ "type": "number",
368
+ "title": "teacherInstructions"
369
+ },
370
+ "prompt": {
371
+ "description": "Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified",
372
+ "type": "number",
373
+ "title": "prompt"
374
+ },
375
+ "rationale": {
376
+ "description": "Indicates the max dimension for images in rationale",
377
+ "type": "number",
378
+ "title": "rationale"
379
+ },
380
+ "rowTitles": {
381
+ "description": "Indicates the max dimension for images in row labels",
382
+ "type": "number",
383
+ "title": "rowTitles"
384
+ }
385
+ }
233
386
  }
234
387
  },
235
388
  "$schema": "http://json-schema.org/draft-07/schema#"
@@ -98,6 +98,22 @@ Indicates if the item has to be displayed in the Settings Panel
98
98
 
99
99
  Indicates the label for the item that has to be displayed in the Settings Panel
100
100
 
101
+ # `settingsPanelDisabled` (boolean)
102
+
103
+ Indicates if the settings panel is not available
104
+
105
+ # `spellCheck` (object)
106
+
107
+ Properties of the `spellCheck` object:
108
+
109
+ ## `settings` (boolean)
110
+
111
+ Indicates if the item has to be displayed in the Settings Panel
112
+
113
+ ## `label` (string)
114
+
115
+ Indicates the label for the item that has to be displayed in the Settings Panel
116
+
101
117
  # `rationale` (object)
102
118
 
103
119
  Properties of the `rationale` object:
@@ -146,6 +162,86 @@ Indicates if the item has to be displayed in the Settings Panel
146
162
 
147
163
  Indicates the label for the item that has to be displayed in the Settings Panel
148
164
 
165
+ # `maxImageWidth` (object)
166
+
167
+ Properties of the `maxImageWidth` object:
168
+
169
+ ## `teacherInstructions` (number)
170
+
171
+ Indicates the max dimension for images in teacher instructions
172
+
173
+ ## `prompt` (number)
174
+
175
+ Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
176
+
177
+ ## `rationale` (number)
178
+
179
+ Indicates the max dimension for images in rationale
180
+
181
+ ## `rowTitles` (number)
182
+
183
+ Indicates the max dimension for images in row labels
184
+
185
+ # `maxImageHeight` (object)
186
+
187
+ Properties of the `maxImageHeight` object:
188
+
189
+ ## `teacherInstructions` (number)
190
+
191
+ Indicates the max dimension for images in teacher instructions
192
+
193
+ ## `prompt` (number)
194
+
195
+ Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
196
+
197
+ ## `rationale` (number)
198
+
199
+ Indicates the max dimension for images in rationale
200
+
201
+ ## `rowTitles` (number)
202
+
203
+ Indicates the max dimension for images in row labels
204
+
205
+ # `withRubric` (object)
206
+
207
+ Properties of the `withRubric` object:
208
+
209
+ ## `settings` (boolean)
210
+
211
+ Indicates if the item has to be displayed in the Settings Panel
212
+
213
+ ## `label` (string)
214
+
215
+ Indicates the label for the item that has to be displayed in the Settings Panel
216
+
217
+ # `minQuestions` (number)
218
+
219
+ Indicates the minimum number of question rows
220
+
221
+ # `maxQuestions` (number)
222
+
223
+ Indicates the maximum number of question rows
224
+
225
+ # `maxLengthQuestionsHeading` (number)
226
+
227
+ Indicates the maximum length of question rows headings
228
+
229
+ # `maxAnswers` (number)
230
+
231
+ Indicates the maximum number of answer columns
232
+
233
+ # `maxLengthAnswers` (number)
234
+
235
+ Indicates the maximum length of answer columns headings
236
+
237
+ # `maxLengthFirstColumnHeading` (number)
238
+
239
+ Indicates the maximum length of first column headings
240
+
241
+ # `width` (string, required)
242
+
243
+ How large (in px) should match be
244
+
149
245
  # `showPrompt` (boolean)
150
246
 
151
247
  Determines whether prompt field will be displayed or not
@@ -180,4 +276,24 @@ Indicates if the item has to be displayed in the Settings Panel
180
276
 
181
277
  ### `label` (string)
182
278
 
183
- Indicates the label for the item that has to be displayed in the Settings Panel
279
+ Indicates the label for the item that has to be displayed in the Settings Panel
280
+
281
+ ## `ConfigureMaxImageDimensionsProp` (object)
282
+
283
+ Properties of the `ConfigureMaxImageDimensionsProp` object:
284
+
285
+ ### `teacherInstructions` (number)
286
+
287
+ Indicates the max dimension for images in teacher instructions
288
+
289
+ ### `prompt` (number)
290
+
291
+ Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
292
+
293
+ ### `rationale` (number)
294
+
295
+ Indicates the max dimension for images in rationale
296
+
297
+ ### `rowTitles` (number)
298
+
299
+ Indicates the max dimension for images in row labels
@@ -2,7 +2,7 @@ const { model } = require('./generate');
2
2
 
3
3
  module.exports = {
4
4
  elements: {
5
- 'match-element': '../..'
5
+ 'match-element': '../..',
6
6
  },
7
- models: [model('1', 'match-element')]
7
+ models: [model('1', 'match-element')],
8
8
  };
@@ -5,16 +5,16 @@ exports.model = (id, element) => ({
5
5
  feedback: {
6
6
  correct: {
7
7
  type: 'none',
8
- default: 'Correct'
8
+ default: 'Correct',
9
9
  },
10
10
  partial: {
11
11
  type: 'none',
12
- default: 'Nearly'
12
+ default: 'Nearly',
13
13
  },
14
14
  incorrect: {
15
15
  type: 'none',
16
- default: 'Incorrect'
17
- }
16
+ default: 'Incorrect',
17
+ },
18
18
  },
19
19
  headers: ['Column 1', 'Column 2', 'Column 3'],
20
20
  layout: 3,
@@ -25,25 +25,26 @@ exports.model = (id, element) => ({
25
25
  {
26
26
  id: 1,
27
27
  title: 'Question Text 1',
28
- values: [false, false]
28
+ values: [false, false],
29
29
  },
30
30
  {
31
31
  id: 2,
32
32
  title: 'Question Text 2',
33
- values: [false, false]
33
+ values: [false, false],
34
34
  },
35
35
  {
36
36
  id: 3,
37
37
  title: 'Question Text 3',
38
- values: [false, false]
38
+ values: [false, false],
39
39
  },
40
40
  {
41
41
  id: 4,
42
42
  title: 'Question Text 4',
43
- values: [false, false]
44
- }
43
+ values: [false, false],
44
+ },
45
45
  ],
46
46
  promptEnabled: true,
47
47
  prompt: 'Select correct answers.',
48
- toolbarEditorPosition: 'bottom'
48
+ toolbarEditorPosition: 'bottom',
49
+ rubricEnabled: false,
49
50
  });