@pie-element/hotspot 4.8.1 → 4.8.4-next.1014

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/configure/CHANGELOG.md +146 -0
  3. package/configure/lib/defaults.js +17 -0
  4. package/configure/lib/defaults.js.map +1 -1
  5. package/configure/lib/hotspot-container.js +18 -6
  6. package/configure/lib/hotspot-container.js.map +1 -1
  7. package/configure/lib/hotspot-drawable.js +11 -5
  8. package/configure/lib/hotspot-drawable.js.map +1 -1
  9. package/configure/lib/hotspot-palette.js +1 -1
  10. package/configure/lib/hotspot-palette.js.map +1 -1
  11. package/configure/lib/hotspot-polygon.js +1 -1
  12. package/configure/lib/hotspot-polygon.js.map +1 -1
  13. package/configure/lib/hotspot-rectangle.js +1 -1
  14. package/configure/lib/hotspot-rectangle.js.map +1 -1
  15. package/configure/lib/index.js +3 -3
  16. package/configure/lib/index.js.map +1 -1
  17. package/configure/lib/root.js +96 -13
  18. package/configure/lib/root.js.map +1 -1
  19. package/configure/lib/utils.js +18 -4
  20. package/configure/lib/utils.js.map +1 -1
  21. package/configure/package.json +3 -3
  22. package/configure/src/__tests__/__snapshots__/hotspot-container.test.js.snap +1 -0
  23. package/configure/src/__tests__/__snapshots__/root.test.js.snap +48 -4
  24. package/configure/src/defaults.js +17 -0
  25. package/configure/src/hotspot-container.jsx +10 -1
  26. package/configure/src/hotspot-drawable.jsx +8 -2
  27. package/configure/src/root.jsx +80 -9
  28. package/configure/src/utils.js +23 -1
  29. package/controller/CHANGELOG.md +27 -0
  30. package/controller/lib/index.js +44 -5
  31. package/controller/lib/index.js.map +1 -1
  32. package/controller/lib/utils.js.map +1 -1
  33. package/controller/package.json +1 -1
  34. package/controller/src/index.js +26 -0
  35. package/docs/config-schema.json +196 -0
  36. package/docs/config-schema.json.md +153 -0
  37. package/docs/demo/generate.js +1 -0
  38. package/docs/pie-schema.json +53 -0
  39. package/docs/pie-schema.json.md +43 -0
  40. package/lib/hotspot/container.js +33 -4
  41. package/lib/hotspot/container.js.map +1 -1
  42. package/lib/hotspot/image.js +35 -8
  43. package/lib/hotspot/image.js.map +1 -1
  44. package/lib/hotspot/index.js +61 -17
  45. package/lib/hotspot/index.js.map +1 -1
  46. package/lib/hotspot/polygon.js +16 -17
  47. package/lib/hotspot/polygon.js.map +1 -1
  48. package/lib/hotspot/rectangle.js +16 -17
  49. package/lib/hotspot/rectangle.js.map +1 -1
  50. package/lib/index.js +4 -1
  51. package/lib/index.js.map +1 -1
  52. package/lib/session-updater.js.map +1 -1
  53. package/package.json +4 -4
  54. package/src/__tests__/image-test.jsx +9 -1
  55. package/src/__tests__/polygon-test.jsx +2 -1
  56. package/src/__tests__/rectangle-test.jsx +2 -1
  57. package/src/hotspot/container.jsx +34 -2
  58. package/src/hotspot/image.jsx +29 -12
  59. package/src/hotspot/index.jsx +54 -6
  60. package/src/hotspot/polygon.jsx +11 -15
  61. package/src/hotspot/rectangle.jsx +11 -15
  62. package/src/index.js +5 -0
@@ -5,9 +5,11 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
+ exports.createDefaultModel = exports.createCorrectResponseSession = void 0;
8
9
  exports.model = model;
10
+ exports.normalize = void 0;
9
11
  exports.outcome = outcome;
10
- exports.createCorrectResponseSession = exports.createDefaultModel = exports.normalize = void 0;
12
+ exports.validate = void 0;
11
13
 
12
14
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
15
 
@@ -25,9 +27,12 @@ var _utils = require("./utils");
25
27
 
26
28
  var _defaults = _interopRequireDefault(require("./defaults"));
27
29
 
28
- 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; }
30
+ var _excluded = ["index"],
31
+ _excluded2 = ["index"];
29
32
 
30
- 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; }
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; }
34
+
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; }
31
36
 
32
37
  var log = (0, _debug["default"])('pie-elements:hotspot:controller');
33
38
 
@@ -72,13 +77,13 @@ function model(question, session, env) {
72
77
  // eslint-disable-next-line no-unused-vars
73
78
  rectangles: (rectangles || []).map(function (_ref2) {
74
79
  var index = _ref2.index,
75
- rectProps = (0, _objectWithoutProperties2["default"])(_ref2, ["index"]);
80
+ rectProps = (0, _objectWithoutProperties2["default"])(_ref2, _excluded);
76
81
  return _objectSpread({}, rectProps);
77
82
  }),
78
83
  // eslint-disable-next-line no-unused-vars
79
84
  polygons: (polygons || []).map(function (_ref3) {
80
85
  var index = _ref3.index,
81
- polyProps = (0, _objectWithoutProperties2["default"])(_ref3, ["index"]);
86
+ polyProps = (0, _objectWithoutProperties2["default"])(_ref3, _excluded2);
82
87
  return _objectSpread({}, polyProps);
83
88
  })
84
89
  }),
@@ -221,4 +226,38 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
221
226
  };
222
227
 
223
228
  exports.createCorrectResponseSession = createCorrectResponseSession;
229
+
230
+ var validate = function validate() {
231
+ var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
232
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
233
+ var shapes = model.shapes;
234
+ var _config$minShapes = config.minShapes,
235
+ minShapes = _config$minShapes === void 0 ? 2 : _config$minShapes,
236
+ maxShapes = config.maxShapes,
237
+ maxSelections = config.maxSelections;
238
+ var errors = {};
239
+ var allShapes = Object.values(shapes || {}).reduce(function (acc, shape) {
240
+ return [].concat((0, _toConsumableArray2["default"])(acc), (0, _toConsumableArray2["default"])(shape));
241
+ }, []);
242
+ var nbOfSelections = (allShapes || []).reduce(function (acc, shape) {
243
+ return shape.correct ? acc + 1 : acc;
244
+ }, 0);
245
+ var nbOfShapes = (allShapes || []).length;
246
+
247
+ if (nbOfShapes < minShapes) {
248
+ errors.shapesError = "There should be at least ".concat(minShapes, " shapes defined.");
249
+ } else if (nbOfShapes > maxShapes) {
250
+ errors.shapesError = "No more than ".concat(maxShapes, " shapes should be defined.");
251
+ }
252
+
253
+ if (nbOfSelections < 1) {
254
+ errors.selectionsError = 'There should be at least 1 shape selected.';
255
+ } else if (nbOfSelections > maxSelections) {
256
+ errors.selectionsError = "No more than ".concat(maxSelections, " shapes should be selected.");
257
+ }
258
+
259
+ return errors;
260
+ };
261
+
262
+ exports.validate = validate;
224
263
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","strokeWidth","model","session","env","normalizedQuestion","imageUrl","dimensions","hotspotColor","multipleCorrect","outlineColor","partialScoring","prompt","shapes","rectangles","polygons","Promise","resolve","out","disabled","mode","map","index","rectProps","polyProps","responseCorrect","undefined","role","rationale","teacherInstructions","createDefaultModel","defaults","getScore","config","answers","partialScoringEnabled","enabled","correctAnswers","selectedChoices","choices","correctChoices","filter","choice","correct","forEach","shape","selected","answer","id","correctlySelected","extraAnswers","length","total","str","toFixed","parseFloat","outcome","score","empty","returnShapesCorrect","i","push","createCorrectResponseSession","rectangleCorrect","polygonsCorrect"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nimport { isResponseCorrect } from './utils';\n\nimport defaults from './defaults';\n\nconst log = debug('pie-elements:hotspot:controller');\n\nexport const normalize = question => ({\n promptEnabled: true,\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n strokeWidth: 5,\n ...question,\n});\n\nexport function model(question, session, env) {\n const normalizedQuestion = normalize(question);\n const {\n imageUrl,\n dimensions,\n hotspotColor,\n multipleCorrect,\n outlineColor,\n partialScoring,\n prompt,\n shapes\n } = normalizedQuestion;\n const { rectangles, polygons } = shapes || {};\n\n return new Promise(resolve => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n dimensions,\n imageUrl,\n outlineColor,\n hotspotColor,\n multipleCorrect,\n partialScoring,\n shapes: {\n ...shapes,\n // eslint-disable-next-line no-unused-vars\n rectangles: (rectangles || []).map(({ index, ...rectProps }) => ({ ...rectProps })),\n // eslint-disable-next-line no-unused-vars\n polygons: (polygons || []).map(({ index, ...polyProps }) => ({ ...polyProps }))\n },\n responseCorrect:\n env.mode === 'evaluate'\n ? isResponseCorrect(normalizedQuestion, session)\n : undefined\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n out.prompt = normalizedQuestion.promptEnabled ? prompt : null;\n out.strokeWidth = normalizedQuestion.strokeWidth;\n\n // console.log(out);\n resolve(out);\n });\n}\n\nexport const createDefaultModel = (model = {}) =>\n new Promise(resolve => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nconst getScore = (config, session, env = {}) => {\n const { answers } = session || {};\n\n if (!config.shapes || (!config.shapes.rectangles && !config.shapes.polygons)) {\n return 0;\n }\n\n const { shapes: { rectangles = [], polygons = [] } = {} } = config;\n const partialScoringEnabled = partialScoring.enabled(config, env);\n\n if (!partialScoringEnabled) {\n return isResponseCorrect(config, session) ? 1 : 0;\n }\n\n let correctAnswers = 0;\n let selectedChoices = 0;\n\n const choices = [...rectangles, ...polygons];\n\n const correctChoices = choices.filter(choice => choice.correct);\n\n choices.forEach(shape => {\n const selected = answers && answers.filter(answer => answer.id === shape.id)[0];\n const correctlySelected = shape.correct && selected;\n\n if(selected) {\n selectedChoices +=1;\n }\n\n if (correctlySelected) {\n correctAnswers += 1;\n }\n });\n\n const extraAnswers = selectedChoices > correctChoices.length ? selectedChoices - correctChoices.length : 0;\n\n const total = correctChoices.length === 0 ? 1 : correctChoices.length;\n const str = ((correctAnswers - extraAnswers) / total).toFixed(2);\n\n return str < 0 ? 0 : parseFloat(str);\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise(resolve => {\n log('outcome...');\n\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n if (session.answers) {\n const score = getScore(config, session, env);\n resolve({ score });\n } else {\n resolve({score: 0, empty: true})\n }\n });\n}\n\nconst returnShapesCorrect = (shapes) => {\n let answers = [];\n\n shapes.forEach(i => {\n const { correct, id } = i;\n if (correct) {\n answers.push({ id });\n }\n });\n return answers;\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { shapes: { rectangles = [], polygons = {} } = {} } = question;\n\n const rectangleCorrect = returnShapesCorrect(rectangles);\n const polygonsCorrect = returnShapesCorrect(polygons);\n\n resolve({\n answers: [\n ...rectangleCorrect,\n ...polygonsCorrect\n ],\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","normalize","question","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","strokeWidth","model","session","env","normalizedQuestion","imageUrl","dimensions","hotspotColor","multipleCorrect","outlineColor","partialScoring","prompt","shapes","rectangles","polygons","Promise","resolve","out","disabled","mode","map","index","rectProps","polyProps","responseCorrect","undefined","role","rationale","teacherInstructions","createDefaultModel","defaults","getScore","config","answers","partialScoringEnabled","enabled","correctAnswers","selectedChoices","choices","correctChoices","filter","choice","correct","forEach","shape","selected","answer","id","correctlySelected","extraAnswers","length","total","str","toFixed","parseFloat","outcome","score","empty","returnShapesCorrect","i","push","createCorrectResponseSession","rectangleCorrect","polygonsCorrect","validate","minShapes","maxShapes","maxSelections","errors","allShapes","Object","values","reduce","acc","nbOfSelections","nbOfShapes","shapesError","selectionsError"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nimport { isResponseCorrect } from './utils';\n\nimport defaults from './defaults';\n\nconst log = debug('pie-elements:hotspot:controller');\n\nexport const normalize = question => ({\n promptEnabled: true,\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n strokeWidth: 5,\n ...question,\n});\n\nexport function model(question, session, env) {\n const normalizedQuestion = normalize(question);\n const {\n imageUrl,\n dimensions,\n hotspotColor,\n multipleCorrect,\n outlineColor,\n partialScoring,\n prompt,\n shapes\n } = normalizedQuestion;\n const { rectangles, polygons } = shapes || {};\n\n return new Promise(resolve => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n dimensions,\n imageUrl,\n outlineColor,\n hotspotColor,\n multipleCorrect,\n partialScoring,\n shapes: {\n ...shapes,\n // eslint-disable-next-line no-unused-vars\n rectangles: (rectangles || []).map(({ index, ...rectProps }) => ({ ...rectProps })),\n // eslint-disable-next-line no-unused-vars\n polygons: (polygons || []).map(({ index, ...polyProps }) => ({ ...polyProps }))\n },\n responseCorrect:\n env.mode === 'evaluate'\n ? isResponseCorrect(normalizedQuestion, session)\n : undefined\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n out.prompt = normalizedQuestion.promptEnabled ? prompt : null;\n out.strokeWidth = normalizedQuestion.strokeWidth;\n\n // console.log(out);\n resolve(out);\n });\n}\n\nexport const createDefaultModel = (model = {}) =>\n new Promise(resolve => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nconst getScore = (config, session, env = {}) => {\n const { answers } = session || {};\n\n if (!config.shapes || (!config.shapes.rectangles && !config.shapes.polygons)) {\n return 0;\n }\n\n const { shapes: { rectangles = [], polygons = [] } = {} } = config;\n const partialScoringEnabled = partialScoring.enabled(config, env);\n\n if (!partialScoringEnabled) {\n return isResponseCorrect(config, session) ? 1 : 0;\n }\n\n let correctAnswers = 0;\n let selectedChoices = 0;\n\n const choices = [...rectangles, ...polygons];\n\n const correctChoices = choices.filter(choice => choice.correct);\n\n choices.forEach(shape => {\n const selected = answers && answers.filter(answer => answer.id === shape.id)[0];\n const correctlySelected = shape.correct && selected;\n\n if(selected) {\n selectedChoices +=1;\n }\n\n if (correctlySelected) {\n correctAnswers += 1;\n }\n });\n\n const extraAnswers = selectedChoices > correctChoices.length ? selectedChoices - correctChoices.length : 0;\n\n const total = correctChoices.length === 0 ? 1 : correctChoices.length;\n const str = ((correctAnswers - extraAnswers) / total).toFixed(2);\n\n return str < 0 ? 0 : parseFloat(str);\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise(resolve => {\n log('outcome...');\n\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n if (session.answers) {\n const score = getScore(config, session, env);\n resolve({ score });\n } else {\n resolve({score: 0, empty: true})\n }\n });\n}\n\nconst returnShapesCorrect = (shapes) => {\n let answers = [];\n\n shapes.forEach(i => {\n const { correct, id } = i;\n if (correct) {\n answers.push({ id });\n }\n });\n return answers;\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { shapes: { rectangles = [], polygons = {} } = {} } = question;\n\n const rectangleCorrect = returnShapesCorrect(rectangles);\n const polygonsCorrect = returnShapesCorrect(polygons);\n\n resolve({\n answers: [\n ...rectangleCorrect,\n ...polygonsCorrect\n ],\n id: '1'\n });\n } else {\n resolve(null);\n }\n });\n};\n\nexport const validate = (model = {}, config = {}) => {\n const { shapes } = model;\n const { minShapes = 2, maxShapes, maxSelections } = config;\n const errors = {};\n\n const allShapes = Object.values(shapes || {}).reduce((acc, shape) => [...acc, ...shape], []);\n\n const nbOfSelections = (allShapes || []).reduce((acc, shape) => shape.correct ? acc + 1 : acc, 0);\n\n const nbOfShapes = (allShapes || []).length;\n\n if (nbOfShapes < minShapes) {\n errors.shapesError = `There should be at least ${minShapes} shapes defined.`;\n } else if (nbOfShapes > maxShapes) {\n errors.shapesError = `No more than ${maxShapes} shapes should be defined.`;\n }\n\n if (nbOfSelections < 1) {\n errors.selectionsError = 'There should be at least 1 shape selected.';\n } else if (nbOfSelections > maxSelections) {\n errors.selectionsError = `No more than ${maxSelections} shapes should be selected.`;\n }\n\n return errors;\n};\n"],"file":"index.js"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.js"],"names":["getCorrectResponse","choices","filter","c","correct","map","id","sort","isResponseCorrect","question","session","shapes","rectangles","polygons","correctResponseIds","answers","length","answerIds","a"],"mappings":";;;;;;;;;;;AAAA;;AACA;;AAEO,IAAMA,kBAAkB,GAAG,SAArBA,kBAAqB,CAACC,OAAD;AAAA,SAAaA,OAAO,CACnDC,MAD4C,CACrC,UAAAC,CAAC;AAAA,WAAIA,CAAC,CAACC,OAAN;AAAA,GADoC,EAE5CC,GAF4C,CAExC,UAAAF,CAAC;AAAA,WAAIA,CAAC,CAACG,EAAN;AAAA,GAFuC,EAG5CC,IAH4C,EAAb;AAAA,CAA3B;;;;AAKA,IAAMC,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,QAAD,EAAWC,OAAX,EAAuB;AAAA,yBACTD,QADS,CAC9CE,MAD8C;AAAA,MACpCC,UADoC,oBACpCA,UADoC;AAAA,MACxBC,QADwB,oBACxBA,QADwB;AAEtD,MAAMZ,OAAO,iDAAOW,UAAP,uCAAsBC,QAAtB,EAAb;AACA,MAAIC,kBAAkB,GAAGd,kBAAkB,CAACC,OAAD,CAA3C;;AAEA,MAAI,CAACS,OAAD,IAAY,yBAAQA,OAAR,CAAhB,EAAkC;AAChC,WAAO,KAAP;AACD;;AAED,MAAIA,OAAO,CAACK,OAAR,IAAmBL,OAAO,CAACK,OAAR,CAAgBC,MAAvC,EAA+C;AAC7C,QAAIC,SAAS,GAAG,CAACP,OAAO,CAACK,OAAR,IAAmB,EAApB,EAAwBV,GAAxB,CAA4B,UAAAa,CAAC;AAAA,aAAIA,CAAC,CAACZ,EAAN;AAAA,KAA7B,CAAhB;AAEA,WAAO,yBAAQW,SAAS,CAACV,IAAV,EAAR,EAA0BO,kBAA1B,CAAP;AACD,GAJD,MAIO,IAAI,EAAEA,kBAAkB,IAAIA,kBAAkB,CAACE,MAA3C,CAAJ,EAAwD;AAC7D,WAAO,IAAP;AACD;;AAED,SAAO,KAAP;AACD,CAlBM","sourcesContent":["import isEqual from 'lodash/isEqual';\nimport isEmpty from 'lodash/isEmpty';\n\nexport const getCorrectResponse = (choices) => choices\n .filter(c => c.correct)\n .map(c => c.id)\n .sort();\n\nexport const isResponseCorrect = (question, session) => {\n const { shapes: { rectangles, polygons } } = question;\n const choices = [...rectangles, ...polygons];\n let correctResponseIds = getCorrectResponse(choices);\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n if (session.answers && session.answers.length) {\n let answerIds = (session.answers || []).map(a => a.id);\n\n return isEqual(answerIds.sort(), correctResponseIds);\n } else if (!(correctResponseIds && correctResponseIds.length)) {\n return true;\n }\n\n return false;\n};\n"],"file":"utils.js"}
1
+ {"version":3,"sources":["../src/utils.js"],"names":["getCorrectResponse","choices","filter","c","correct","map","id","sort","isResponseCorrect","question","session","shapes","rectangles","polygons","correctResponseIds","answers","length","answerIds","a"],"mappings":";;;;;;;;;;;AAAA;;AACA;;AAEO,IAAMA,kBAAkB,GAAG,SAArBA,kBAAqB,CAACC,OAAD;AAAA,SAAaA,OAAO,CACnDC,MAD4C,CACrC,UAAAC,CAAC;AAAA,WAAIA,CAAC,CAACC,OAAN;AAAA,GADoC,EAE5CC,GAF4C,CAExC,UAAAF,CAAC;AAAA,WAAIA,CAAC,CAACG,EAAN;AAAA,GAFuC,EAG5CC,IAH4C,EAAb;AAAA,CAA3B;;;;AAKA,IAAMC,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,QAAD,EAAWC,OAAX,EAAuB;AACtD,yBAA6CD,QAA7C,CAAQE,MAAR;AAAA,MAAkBC,UAAlB,oBAAkBA,UAAlB;AAAA,MAA8BC,QAA9B,oBAA8BA,QAA9B;AACA,MAAMZ,OAAO,iDAAOW,UAAP,uCAAsBC,QAAtB,EAAb;AACA,MAAIC,kBAAkB,GAAGd,kBAAkB,CAACC,OAAD,CAA3C;;AAEA,MAAI,CAACS,OAAD,IAAY,yBAAQA,OAAR,CAAhB,EAAkC;AAChC,WAAO,KAAP;AACD;;AAED,MAAIA,OAAO,CAACK,OAAR,IAAmBL,OAAO,CAACK,OAAR,CAAgBC,MAAvC,EAA+C;AAC7C,QAAIC,SAAS,GAAG,CAACP,OAAO,CAACK,OAAR,IAAmB,EAApB,EAAwBV,GAAxB,CAA4B,UAAAa,CAAC;AAAA,aAAIA,CAAC,CAACZ,EAAN;AAAA,KAA7B,CAAhB;AAEA,WAAO,yBAAQW,SAAS,CAACV,IAAV,EAAR,EAA0BO,kBAA1B,CAAP;AACD,GAJD,MAIO,IAAI,EAAEA,kBAAkB,IAAIA,kBAAkB,CAACE,MAA3C,CAAJ,EAAwD;AAC7D,WAAO,IAAP;AACD;;AAED,SAAO,KAAP;AACD,CAlBM","sourcesContent":["import isEqual from 'lodash/isEqual';\nimport isEmpty from 'lodash/isEmpty';\n\nexport const getCorrectResponse = (choices) => choices\n .filter(c => c.correct)\n .map(c => c.id)\n .sort();\n\nexport const isResponseCorrect = (question, session) => {\n const { shapes: { rectangles, polygons } } = question;\n const choices = [...rectangles, ...polygons];\n let correctResponseIds = getCorrectResponse(choices);\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n if (session.answers && session.answers.length) {\n let answerIds = (session.answers || []).map(a => a.id);\n\n return isEqual(answerIds.sort(), correctResponseIds);\n } else if (!(correctResponseIds && correctResponseIds.length)) {\n return true;\n }\n\n return false;\n};\n"],"file":"utils.js"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pie-element/hotspot-controller",
3
3
  "private": true,
4
- "version": "3.4.1",
4
+ "version": "3.4.8",
5
5
  "description": "",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -169,3 +169,29 @@ export const createCorrectResponseSession = (question, env) => {
169
169
  }
170
170
  });
171
171
  };
172
+
173
+ export const validate = (model = {}, config = {}) => {
174
+ const { shapes } = model;
175
+ const { minShapes = 2, maxShapes, maxSelections } = config;
176
+ const errors = {};
177
+
178
+ const allShapes = Object.values(shapes || {}).reduce((acc, shape) => [...acc, ...shape], []);
179
+
180
+ const nbOfSelections = (allShapes || []).reduce((acc, shape) => shape.correct ? acc + 1 : acc, 0);
181
+
182
+ const nbOfShapes = (allShapes || []).length;
183
+
184
+ if (nbOfShapes < minShapes) {
185
+ errors.shapesError = `There should be at least ${minShapes} shapes defined.`;
186
+ } else if (nbOfShapes > maxShapes) {
187
+ errors.shapesError = `No more than ${maxShapes} shapes should be defined.`;
188
+ }
189
+
190
+ if (nbOfSelections < 1) {
191
+ errors.selectionsError = 'There should be at least 1 shape selected.';
192
+ } else if (nbOfSelections > maxSelections) {
193
+ errors.selectionsError = `No more than ${maxSelections} shapes should be selected.`;
194
+ }
195
+
196
+ return errors;
197
+ };
@@ -0,0 +1,196 @@
1
+ {
2
+ "description": "Config Object for @pie-elements/hotspot",
3
+ "additionalProperties": false,
4
+ "type": "object",
5
+ "properties": {
6
+ "multipleCorrect": {
7
+ "title": "ConfigureProp",
8
+ "type": "object",
9
+ "properties": {
10
+ "settings": {
11
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
12
+ "type": "boolean",
13
+ "title": "settings"
14
+ },
15
+ "label": {
16
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
17
+ "type": "string",
18
+ "title": "label"
19
+ }
20
+ }
21
+ },
22
+ "partialScoring": {
23
+ "title": "ConfigureProp",
24
+ "type": "object",
25
+ "properties": {
26
+ "settings": {
27
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
28
+ "type": "boolean",
29
+ "title": "settings"
30
+ },
31
+ "label": {
32
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
33
+ "type": "string",
34
+ "title": "label"
35
+ }
36
+ }
37
+ },
38
+ "rationale": {
39
+ "title": "ConfigureProp",
40
+ "type": "object",
41
+ "properties": {
42
+ "settings": {
43
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
44
+ "type": "boolean",
45
+ "title": "settings"
46
+ },
47
+ "label": {
48
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
49
+ "type": "string",
50
+ "title": "label"
51
+ }
52
+ }
53
+ },
54
+ "spellCheck": {
55
+ "title": "ConfigureProp",
56
+ "type": "object",
57
+ "properties": {
58
+ "settings": {
59
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
60
+ "type": "boolean",
61
+ "title": "settings"
62
+ },
63
+ "label": {
64
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
65
+ "type": "string",
66
+ "title": "label"
67
+ }
68
+ }
69
+ },
70
+ "preserveAspectRatio": {
71
+ "title": "ConfigureProp",
72
+ "type": "object",
73
+ "properties": {
74
+ "settings": {
75
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
76
+ "type": "boolean",
77
+ "title": "settings"
78
+ },
79
+ "label": {
80
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
81
+ "type": "string",
82
+ "title": "label"
83
+ }
84
+ }
85
+ },
86
+ "minShapes": {
87
+ "description": "Minimum number of shapes",
88
+ "type": "number",
89
+ "title": "minShapes"
90
+ },
91
+ "maxShapes": {
92
+ "description": "Maximum number of shapes",
93
+ "type": "number",
94
+ "title": "maxShapes"
95
+ },
96
+ "maxSelections": {
97
+ "description": "Maximum number of selected shapes in correct answer",
98
+ "type": "number",
99
+ "title": "maxSelections"
100
+ },
101
+ "maxImageWidth": {
102
+ "title": "ConfigureMaxImageDimensionsProp",
103
+ "type": "object",
104
+ "properties": {
105
+ "teacherInstructions": {
106
+ "description": "Indicates the max dimension for images in teacher instructions",
107
+ "type": "number",
108
+ "title": "teacherInstructions"
109
+ },
110
+ "prompt": {
111
+ "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",
112
+ "type": "number",
113
+ "title": "prompt"
114
+ },
115
+ "rationale": {
116
+ "description": "Indicates the max dimension for images in rationale",
117
+ "type": "number",
118
+ "title": "rationale"
119
+ }
120
+ }
121
+ },
122
+ "maxImageHeight": {
123
+ "title": "ConfigureMaxImageDimensionsProp",
124
+ "type": "object",
125
+ "properties": {
126
+ "teacherInstructions": {
127
+ "description": "Indicates the max dimension for images in teacher instructions",
128
+ "type": "number",
129
+ "title": "teacherInstructions"
130
+ },
131
+ "prompt": {
132
+ "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",
133
+ "type": "number",
134
+ "title": "prompt"
135
+ },
136
+ "rationale": {
137
+ "description": "Indicates the max dimension for images in rationale",
138
+ "type": "number",
139
+ "title": "rationale"
140
+ }
141
+ }
142
+ },
143
+ "showPrompt": {
144
+ "description": "Determines whether prompt field will be displayed or not",
145
+ "default": true,
146
+ "type": "boolean",
147
+ "title": "showPrompt"
148
+ },
149
+ "promptLabel": {
150
+ "description": "The label for the item stem/prompt field",
151
+ "default": "Item Stemm",
152
+ "type": "string",
153
+ "title": "promptLabel"
154
+ }
155
+ },
156
+ "definitions": {
157
+ "ConfigureProp": {
158
+ "title": "ConfigureProp",
159
+ "type": "object",
160
+ "properties": {
161
+ "settings": {
162
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
163
+ "type": "boolean",
164
+ "title": "settings"
165
+ },
166
+ "label": {
167
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
168
+ "type": "string",
169
+ "title": "label"
170
+ }
171
+ }
172
+ },
173
+ "ConfigureMaxImageDimensionsProp": {
174
+ "title": "ConfigureMaxImageDimensionsProp",
175
+ "type": "object",
176
+ "properties": {
177
+ "teacherInstructions": {
178
+ "description": "Indicates the max dimension for images in teacher instructions",
179
+ "type": "number",
180
+ "title": "teacherInstructions"
181
+ },
182
+ "prompt": {
183
+ "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",
184
+ "type": "number",
185
+ "title": "prompt"
186
+ },
187
+ "rationale": {
188
+ "description": "Indicates the max dimension for images in rationale",
189
+ "type": "number",
190
+ "title": "rationale"
191
+ }
192
+ }
193
+ }
194
+ },
195
+ "$schema": "http://json-schema.org/draft-07/schema#"
196
+ }
@@ -0,0 +1,153 @@
1
+ Config Object for @pie-elements/hotspot
2
+
3
+ The schema defines the following properties:
4
+
5
+ # `multipleCorrect` (object)
6
+
7
+ Properties of the `multipleCorrect` object:
8
+
9
+ ## `settings` (boolean)
10
+
11
+ Indicates if the item has to be displayed in the Settings Panel
12
+
13
+ ## `label` (string)
14
+
15
+ Indicates the label for the item that has to be displayed in the Settings Panel
16
+
17
+ # `partialScoring` (object)
18
+
19
+ Properties of the `partialScoring` object:
20
+
21
+ ## `settings` (boolean)
22
+
23
+ Indicates if the item has to be displayed in the Settings Panel
24
+
25
+ ## `label` (string)
26
+
27
+ Indicates the label for the item that has to be displayed in the Settings Panel
28
+
29
+ # `rationale` (object)
30
+
31
+ Properties of the `rationale` object:
32
+
33
+ ## `settings` (boolean)
34
+
35
+ Indicates if the item has to be displayed in the Settings Panel
36
+
37
+ ## `label` (string)
38
+
39
+ Indicates the label for the item that has to be displayed in the Settings Panel
40
+
41
+ # `spellCheck` (object)
42
+
43
+ Properties of the `spellCheck` object:
44
+
45
+ ## `settings` (boolean)
46
+
47
+ Indicates if the item has to be displayed in the Settings Panel
48
+
49
+ ## `label` (string)
50
+
51
+ Indicates the label for the item that has to be displayed in the Settings Panel
52
+
53
+ # `preserveAspectRatio` (object)
54
+
55
+ Properties of the `preserveAspectRatio` object:
56
+
57
+ ## `settings` (boolean)
58
+
59
+ Indicates if the item has to be displayed in the Settings Panel
60
+
61
+ ## `label` (string)
62
+
63
+ Indicates the label for the item that has to be displayed in the Settings Panel
64
+
65
+ # `minShapes` (number)
66
+
67
+ Minimum number of shapes
68
+
69
+ # `maxShapes` (number)
70
+
71
+ Maximum number of shapes
72
+
73
+ # `maxSelections` (number)
74
+
75
+ Maximum number of selected shapes in correct answer
76
+
77
+ # `maxImageWidth` (object)
78
+
79
+ Properties of the `maxImageWidth` object:
80
+
81
+ ## `teacherInstructions` (number)
82
+
83
+ Indicates the max dimension for images in teacher instructions
84
+
85
+ ## `prompt` (number)
86
+
87
+ Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
88
+
89
+ ## `rationale` (number)
90
+
91
+ Indicates the max dimension for images in rationale
92
+
93
+ # `maxImageHeight` (object)
94
+
95
+ Properties of the `maxImageHeight` object:
96
+
97
+ ## `teacherInstructions` (number)
98
+
99
+ Indicates the max dimension for images in teacher instructions
100
+
101
+ ## `prompt` (number)
102
+
103
+ Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
104
+
105
+ ## `rationale` (number)
106
+
107
+ Indicates the max dimension for images in rationale
108
+
109
+ # `showPrompt` (boolean)
110
+
111
+ Determines whether prompt field will be displayed or not
112
+
113
+ Default: `true`
114
+
115
+ # `promptLabel` (string)
116
+
117
+ The label for the item stem/prompt field
118
+
119
+ Default: `"Item Stemm"`
120
+
121
+ ---
122
+
123
+ # Sub Schemas
124
+
125
+ The schema defines the following additional types:
126
+
127
+ ## `ConfigureProp` (object)
128
+
129
+ Properties of the `ConfigureProp` object:
130
+
131
+ ### `settings` (boolean)
132
+
133
+ Indicates if the item has to be displayed in the Settings Panel
134
+
135
+ ### `label` (string)
136
+
137
+ Indicates the label for the item that has to be displayed in the Settings Panel
138
+
139
+ ## `ConfigureMaxImageDimensionsProp` (object)
140
+
141
+ Properties of the `ConfigureMaxImageDimensionsProp` object:
142
+
143
+ ### `teacherInstructions` (number)
144
+
145
+ Indicates the max dimension for images in teacher instructions
146
+
147
+ ### `prompt` (number)
148
+
149
+ Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
150
+
151
+ ### `rationale` (number)
152
+
153
+ Indicates the max dimension for images in rationale
@@ -63,5 +63,6 @@ exports.model = (id, element) => ({
63
63
  },
64
64
  rationale: null,
65
65
  teacherInstructions: null,
66
+ toolbarEditorPosition: 'bottom',
66
67
  prompt: '<div><audio controls="controls" src="https://storage.googleapis.com/pie-prod-221718-assets/audio/77f3f61e-5f2d-425f-80a5-fb814dfa5e4c"></audio><br><br>Choose ALL of the words with the long /o/ sound.</div>',
67
68
  });
@@ -200,6 +200,11 @@
200
200
  "type": "boolean",
201
201
  "title": "studentInstructionsEnabled"
202
202
  },
203
+ "spellCheckEnabled": {
204
+ "description": "Indicates if spellcheck is enabled for the author. Default value is true",
205
+ "type": "boolean",
206
+ "title": "spellCheckEnabled"
207
+ },
203
208
  "strokeWidth": {
204
209
  "description": "Indicates the width of the outline for a selection",
205
210
  "type": "number",
@@ -210,6 +215,16 @@
210
215
  "type": "boolean",
211
216
  "title": "teacherInstructionsEnabled"
212
217
  },
218
+ "toolbarEditorPosition": {
219
+ "description": "Indicates the editor's toolbar position which can be 'bottom' or 'top'",
220
+ "default": ": 'bottom'",
221
+ "enum": [
222
+ "bottom",
223
+ "top"
224
+ ],
225
+ "type": "string",
226
+ "title": "toolbarEditorPosition"
227
+ },
213
228
  "id": {
214
229
  "description": "Identifier to identify the Pie Element in html markup, Must be unique within a pie item config.",
215
230
  "type": "string",
@@ -229,11 +244,49 @@
229
244
  "partialScoring",
230
245
  "rationaleEnabled",
231
246
  "shapes",
247
+ "spellCheckEnabled",
232
248
  "strokeWidth",
233
249
  "studentInstructionsEnabled",
234
250
  "teacherInstructionsEnabled"
235
251
  ],
236
252
  "definitions": {
253
+ "ConfigureProp": {
254
+ "title": "ConfigureProp",
255
+ "type": "object",
256
+ "properties": {
257
+ "settings": {
258
+ "description": "Indicates if the item has to be displayed in the Settings Panel",
259
+ "type": "boolean",
260
+ "title": "settings"
261
+ },
262
+ "label": {
263
+ "description": "Indicates the label for the item that has to be displayed in the Settings Panel",
264
+ "type": "string",
265
+ "title": "label"
266
+ }
267
+ }
268
+ },
269
+ "ConfigureMaxImageDimensionsProp": {
270
+ "title": "ConfigureMaxImageDimensionsProp",
271
+ "type": "object",
272
+ "properties": {
273
+ "teacherInstructions": {
274
+ "description": "Indicates the max dimension for images in teacher instructions",
275
+ "type": "number",
276
+ "title": "teacherInstructions"
277
+ },
278
+ "prompt": {
279
+ "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",
280
+ "type": "number",
281
+ "title": "prompt"
282
+ },
283
+ "rationale": {
284
+ "description": "Indicates the max dimension for images in rationale",
285
+ "type": "number",
286
+ "title": "rationale"
287
+ }
288
+ }
289
+ },
237
290
  "Shape": {
238
291
  "title": "Shape",
239
292
  "type": "object",