@pie-element/drag-in-the-blank 8.0.1 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [8.2.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank@8.0.0...@pie-element/drag-in-the-blank@8.2.0) (2025-10-10)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * tests ([a473075](https://github.com/pie-framework/pie-elements/commit/a473075d3942e900b1e7137483ea6064951549c2))
12
+ * **drag-in-the-blank:** prevent duplicate IDs when adding choices after removal PD-5225 ([31c1357](https://github.com/pie-framework/pie-elements/commit/31c13578e73397ae1334b7abd06545f3299cdf28))
13
+
14
+
15
+ ### Features
16
+
17
+ * update completion rule for categorize, ditb, and image-cloze PD-5179 ([cd03a6e](https://github.com/pie-framework/pie-elements/commit/cd03a6e56e51cc3778749b3679b87f9122405936))
18
+ * update libs PD-5208, PD-5211, PD-5199, PD-5218, PD-5217 ([da327fa](https://github.com/pie-framework/pie-elements/commit/da327fa501f6e9eff1c0b30b5ef092426a91f78b))
19
+
20
+
21
+
22
+
23
+
24
+ # [8.1.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank@7.0.0...@pie-element/drag-in-the-blank@8.1.0) (2025-10-07)
25
+
26
+ **Note:** Version bump only for package @pie-element/drag-in-the-blank
27
+
28
+
29
+
30
+
31
+
6
32
  # [8.0.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank@6.13.4...@pie-element/drag-in-the-blank@8.0.0) (2025-10-02)
7
33
 
8
34
 
@@ -3,6 +3,31 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [7.2.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-configure@7.0.1...@pie-element/drag-in-the-blank-configure@7.2.0) (2025-10-10)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * tests ([a473075](https://github.com/pie-framework/pie-elements/commit/a473075d3942e900b1e7137483ea6064951549c2))
12
+ * **drag-in-the-blank:** prevent duplicate IDs when adding choices after removal PD-5225 ([31c1357](https://github.com/pie-framework/pie-elements/commit/31c13578e73397ae1334b7abd06545f3299cdf28))
13
+
14
+
15
+ ### Features
16
+
17
+ * update libs PD-5208, PD-5211, PD-5199, PD-5218, PD-5217 ([da327fa](https://github.com/pie-framework/pie-elements/commit/da327fa501f6e9eff1c0b30b5ef092426a91f78b))
18
+
19
+
20
+
21
+
22
+
23
+ # [7.1.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-configure@7.0.0...@pie-element/drag-in-the-blank-configure@7.1.0) (2025-10-07)
24
+
25
+ **Note:** Version bump only for package @pie-element/drag-in-the-blank-configure
26
+
27
+
28
+
29
+
30
+
6
31
  ## [7.0.1](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-configure@6.7.0...@pie-element/drag-in-the-blank-configure@7.0.1) (2025-10-02)
7
32
 
8
33
  **Note:** Version bump only for package @pie-element/drag-in-the-blank-configure
@@ -200,13 +200,18 @@ var Choices = /*#__PURE__*/function (_React$Component) {
200
200
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onAddChoice", function () {
201
201
  var _this$props2 = _this.props,
202
202
  oldChoices = _this$props2.model.choices,
203
- onChange = _this$props2.onChange;
203
+ onChange = _this$props2.onChange; // find the maximum existing id and add 1 to generate the new id so we avoid duplicates
204
+
205
+ var maxId = oldChoices.length > 0 ? Math.max.apply(Math, (0, _toConsumableArray2["default"])(oldChoices.map(function (choice) {
206
+ return parseInt(choice.id, 10) || 0;
207
+ }))) : -1;
208
+ var newId = "".concat(maxId + 1);
204
209
 
205
210
  _this.setState({
206
- focusedEl: "".concat(oldChoices.length)
211
+ focusedEl: newId
207
212
  }, function () {
208
213
  onChange([].concat((0, _toConsumableArray2["default"])(oldChoices), [{
209
- id: "".concat(oldChoices.length),
214
+ id: newId,
210
215
  value: ''
211
216
  }]));
212
217
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/choices.jsx"],"names":["styles","theme","design","display","flexDirection","marginBottom","spacing","unit","addButton","marginLeft","altChoices","alignItems","flexWrap","justifyContent","marginTop","margin","errorText","fontSize","typography","color","palette","error","main","paddingBottom","Choices","warning","open","domNode","ReactDOM","findDOMNode","prevValue","val","key","props","onChange","model","choices","correctResponse","alternateResponses","duplicatedValue","find","c","value","id","newChoices","filter","setState","text","map","choice","usedForResponse","Object","keys","forEach","responseKey","values","alternate","indexOf","newChoicesWithoutTheEmptyOne","focusedEl","oldChoices","length","duplicates","includes","rerenderMath","focusedNodeRef","focus","state","classes","mathMlOptions","maxChoices","toolbarOpts","uploadSoundSupport","imageSupport","pluginProps","maxImageWidth","maxImageHeight","maxLength","visibleChoices","getVisibleChoices","onAddChoice","index","minWidth","zIndex","ref","prompt","language","preventDone","onChoiceChanged","undefined","e","inInInsertCharacter","relatedTarget","closest","onChoiceFocus","onChoiceRemove","React","Component","PropTypes","bool","string","object","isRequired","func","number","Styled"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAEA;;AACA;;;;;;;;;;AAEA,IAAMA,MAAM,GAAG,SAATA,MAAS,CAACC,KAAD;AAAA,SAAY;AACzBC,IAAAA,MAAM,EAAE;AACNC,MAAAA,OAAO,EAAE,MADH;AAENC,MAAAA,aAAa,EAAE,QAFT;AAGNC,MAAAA,YAAY,EAAEJ,KAAK,CAACK,OAAN,CAAcC,IAAd,GAAqB;AAH7B,KADiB;AAMzBC,IAAAA,SAAS,EAAE;AACTC,MAAAA,UAAU,EAAE;AADH,KANc;AASzBC,IAAAA,UAAU,EAAE;AACVC,MAAAA,UAAU,EAAE,YADF;AAEVR,MAAAA,OAAO,EAAE,MAFC;AAGVS,MAAAA,QAAQ,EAAE,MAHA;AAIVC,MAAAA,cAAc,EAAE,cAJN;AAKVC,MAAAA,SAAS,EAAEb,KAAK,CAACK,OAAN,CAAcC,IALf;AAOV,eAAS;AACPQ,QAAAA,MAAM,EAAEd,KAAK,CAACK,OAAN,CAAcC;AADf;AAPC,KATa;AAoBzBS,IAAAA,SAAS,EAAE;AACTC,MAAAA,QAAQ,EAAEhB,KAAK,CAACiB,UAAN,CAAiBD,QAAjB,GAA4B,CAD7B;AAETE,MAAAA,KAAK,EAAElB,KAAK,CAACmB,OAAN,CAAcC,KAAd,CAAoBC,IAFlB;AAGTC,MAAAA,aAAa,EAAEtB,KAAK,CAACK,OAAN,CAAcC,IAAd,GAAqB;AAH3B;AApBc,GAAZ;AAAA,CAAf;;IA2BaiB,O;;;;;;;;;;;;;;;8FAgBH;AAAEC,MAAAA,OAAO,EAAE;AAAEC,QAAAA,IAAI,EAAE;AAAR;AAAX,K;oGACM,K;qGAcC,YAAM;AACnB;AACA,UAAMC,OAAO,GAAGC,qBAASC,WAAT,gDAAhB;;AAEA,qCAAWF,OAAX;AACD,K;wGAEiB,UAACG,SAAD,EAAYC,GAAZ,EAAiBC,GAAjB,EAAyB;AACzC,wBAA4B,MAAKC,KAAjC;AAAA,UAAQC,QAAR,eAAQA,QAAR;AAAA,UAAkBC,KAAlB,eAAkBA,KAAlB;AACA,UAAQC,OAAR,GAAyDD,KAAzD,CAAQC,OAAR;AAAA,UAAiBC,eAAjB,GAAyDF,KAAzD,CAAiBE,eAAjB;AAAA,UAAkCC,kBAAlC,GAAyDH,KAAzD,CAAkCG,kBAAlC;AACA,UAAMC,eAAe,GAAG,CAACH,OAAO,IAAI,EAAZ,EAAgBI,IAAhB,CAAqB,UAACC,CAAD;AAAA,eAAOA,CAAC,CAACC,KAAF,KAAYX,GAAZ,IAAmBU,CAAC,CAACE,EAAF,KAASX,GAAnC;AAAA,OAArB,CAAxB,CAHyC,CAKzC;;AACA,UAAIO,eAAJ,EAAqB;AACnB,YAAIT,SAAS,KAAK,EAAlB,EAAsB;AACpB;AACA,cAAMc,WAAU,GAAG,CAACR,OAAO,IAAI,EAAZ,EAAgBS,MAAhB,CAAuB,UAACJ,CAAD;AAAA,mBAAOA,CAAC,CAACE,EAAF,KAASX,GAAhB;AAAA,WAAvB,CAAnB;;AAEAE,UAAAA,QAAQ,CAACU,WAAD,CAAR;AACD;;AAED,cAAKE,QAAL,CAAc;AACZrB,UAAAA,OAAO,EAAE;AACPC,YAAAA,IAAI,EAAE,IADC;AAEPqB,YAAAA,IAAI,EAAE;AAFC;AADG,SAAd;;AAOA;AACD;;AAED,UAAMH,UAAU,GAAG,CAAAR,OAAO,SAAP,IAAAA,OAAO,WAAP,YAAAA,OAAO,CAAEY,GAAT,CAAa,UAACC,MAAD;AAAA,eAAaA,MAAM,CAACN,EAAP,KAAcX,GAAd,mCAAyBiB,MAAzB;AAAiCP,UAAAA,KAAK,EAAEX;AAAxC,aAAgDkB,MAA7D;AAAA,OAAb,MAAsF,EAAzG;;AAEA,UAAI,CAAC,gCAAc;AAAEP,QAAAA,KAAK,EAAEX;AAAT,OAAd,CAAL,EAAoC;AAClCG,QAAAA,QAAQ,CAACU,UAAD,CAAR;AAEA;AACD,OA9BwC,CAgCzC;;;AACA,UAAIM,eAAe,GAAG,KAAtB;;AAEA,UAAIb,eAAJ,EAAqB;AACnBc,QAAAA,MAAM,CAACC,IAAP,CAAYf,eAAZ,EAA6BgB,OAA7B,CAAqC,UAACC,WAAD,EAAiB;AACpD,cAAIjB,eAAe,CAACiB,WAAD,CAAf,KAAiCtB,GAArC,EAA0C;AACxCkB,YAAAA,eAAe,GAAG,IAAlB;AACD;AACF,SAJD;AAKD;;AAED,UAAIZ,kBAAkB,IAAI,CAACY,eAA3B,EAA4C;AAC1CC,QAAAA,MAAM,CAACI,MAAP,CAAcjB,kBAAd,EAAkCe,OAAlC,CAA0C,UAACG,SAAD,EAAe;AACvD,cAAIA,SAAS,CAACC,OAAV,CAAkBzB,GAAlB,KAA0B,CAA9B,EAAiC;AAC/BkB,YAAAA,eAAe,GAAG,IAAlB;AACD;AACF,SAJD;AAKD;;AAED,UAAIA,eAAJ,EAAqB;AACnB,cAAKJ,QAAL,CAAc;AACZrB,UAAAA,OAAO,EAAE;AACPC,YAAAA,IAAI,EAAE,IADC;AAEPqB,YAAAA,IAAI,EAAE;AAFC;AADG,SAAd;;AAOA;AACD;;AAED,UAAMW,4BAA4B,GAAGd,UAAU,CAACC,MAAX,CAAkB,UAACI,MAAD;AAAA,eAAYA,MAAM,CAACN,EAAP,KAAcX,GAA1B;AAAA,OAAlB,CAArC;AAEAE,MAAAA,QAAQ,CAACwB,4BAAD,CAAR;;AAEA,YAAKZ,QAAL,CAAc;AACZrB,QAAAA,OAAO,EAAE;AACPC,UAAAA,IAAI,EAAE,IADC;AAEPqB,UAAAA,IAAI,EAAE;AAFC;AADG,OAAd;AAMD,K;sGAEe,UAACJ,EAAD;AAAA,aACd,MAAKG,QAAL,CAAc;AACZa,QAAAA,SAAS,EAAEhB;AADC,OAAd,CADc;AAAA,K;oGAKF,YAAM;AAClB,yBAGI,MAAKV,KAHT;AAAA,UACoB2B,UADpB,gBACEzB,KADF,CACWC,OADX;AAAA,UAEEF,QAFF,gBAEEA,QAFF;;AAKA,YAAKY,QAAL,CACE;AACEa,QAAAA,SAAS,YAAKC,UAAU,CAACC,MAAhB;AADX,OADF,EAIE,YAAM;AACJ3B,QAAAA,QAAQ,+CACH0B,UADG,IAEN;AACEjB,UAAAA,EAAE,YAAKiB,UAAU,CAACC,MAAhB,CADJ;AAEEnB,UAAAA,KAAK,EAAE;AAFT,SAFM,GAAR;AAOD,OAZH;AAcD,K;uGAEgB,UAACC,EAAD,EAAQ;AACvB,yBAGI,MAAKV,KAHT;AAAA,UACEC,QADF,gBACEA,QADF;AAAA,UAEWE,OAFX,gBAEED,KAFF,CAEWC,OAFX;AAIA,UAAMQ,UAAU,GAAG,CAACR,OAAO,IAAI,EAAZ,EAAgBS,MAAhB,CAAuB,UAACI,MAAD;AAAA,eAAYA,MAAM,CAACN,EAAP,KAAcA,EAA1B;AAAA,OAAvB,CAAnB;AAEAT,MAAAA,QAAQ,CAACU,UAAD,CAAR;AACD,K;0GAEmB,YAAM;AACxB,yBAGI,MAAKX,KAHT;AAAA,UACE6B,UADF,gBACEA,UADF;AAAA,4CAEE3B,KAFF;AAAA,UAEWC,OAFX,sBAEWA,OAFX;AAAA,UAEoBC,eAFpB,sBAEoBA,eAFpB;;AAKA,UAAI,CAACD,OAAL,EAAc;AACZ,eAAO,EAAP;AACD;;AAED,UAAI0B,UAAJ,EAAgB;AACd,eAAO1B,OAAP;AACD,OAZuB,CAcxB;;;AACA,aAAOA,OAAO,CAACS,MAAR,CAAe,UAACI,MAAD;AAAA,eAAY,EAAEZ,eAAe,IAAIc,MAAM,CAACI,MAAP,CAAclB,eAAd,EAA+B0B,QAA/B,CAAwCd,MAAM,CAACN,EAA/C,CAArB,CAAZ;AAAA,OAAf,CAAP;AACD,K;;;;;;WAlJD,6BAAoB;AAClB,WAAKqB,YAAL;AACD;;;WAED,8BAAqB;AACnB,WAAKA,YAAL;;AAEA,UAAI,KAAKC,cAAT,EAAyB;AACvB,aAAKA,cAAL,CAAoBC,KAApB,CAA0B,KAA1B;AACD;AACF;;;WA0ID,kBAAS;AAAA;;AACP,wBAA+B,KAAKC,KAApC;AAAA,UAAQR,SAAR,eAAQA,SAAR;AAAA,UAAmBlC,OAAnB,eAAmBA,OAAnB;AACA,yBAcI,KAAKQ,KAdT;AAAA,UACEmC,OADF,gBACEA,OADF;AAAA,UAEEN,UAFF,gBAEEA,UAFF;AAAA,UAGEzC,KAHF,gBAGEA,KAHF;AAAA,+CAIEgD,aAJF;AAAA,UAIEA,aAJF,sCAIkB,EAJlB;AAAA,UAKEC,UALF,gBAKEA,UALF;AAAA,UAMWlC,OANX,gBAMED,KANF,CAMWC,OANX;AAAA,UAOEmC,WAPF,gBAOEA,WAPF;AAAA,UAQEC,kBARF,gBAQEA,kBARF;AAAA,+CASEC,YATF;AAAA,UASEA,YATF,sCASiB,EATjB;AAAA,+CAUEC,WAVF;AAAA,UAUEA,WAVF,sCAUgB,EAVhB;AAAA,UAWEC,aAXF,gBAWEA,aAXF;AAAA,UAYEC,cAZF,gBAYEA,cAZF;AAAA,UAaEC,SAbF,gBAaEA,SAbF;AAeA,UAAMC,cAAc,GAAG,KAAKC,iBAAL,MAA4B,EAAnD;AACA,0BACE;AAAK,QAAA,SAAS,EAAEX,OAAO,CAAClE;AAAxB,sBACE,gCAAC,kBAAD;AACE,QAAA,SAAS,EAAEkE,OAAO,CAAC5D,SADrB;AAEE,QAAA,OAAO,EAAC,WAFV;AAGE,QAAA,KAAK,EAAC,SAHR;AAIE,QAAA,OAAO,EAAE,KAAKwE,WAJhB;AAKE,QAAA,QAAQ,EAAEV,UAAU,IAAIlC,OAAd,IAAyBkC,UAAU,KAAKlC,OAAO,CAACyB;AAL5D,sBADF,eAWE;AAAK,QAAA,SAAS,EAAEO,OAAO,CAAC1D;AAAxB,SACGoE,cAAc,CAAC9B,GAAf,CAAmB,UAACC,MAAD,EAASgC,KAAT;AAAA,eAClBtB,SAAS,KAAKV,MAAM,CAACN,EAArB,gBACE;AACE,UAAA,GAAG,EAAEsC,KADP;AAEE,UAAA,KAAK,EAAE;AACLC,YAAAA,QAAQ,EAAE,MADL;AAELC,YAAAA,MAAM,EAAE;AAFH;AAFT,wBAOE,gCAAC,wBAAD;AACE,UAAA,GAAG,EAAE,aAACC,IAAD;AAAA,mBAAU,MAAI,CAACnB,cAAL,GAAsBmB,IAAhC;AAAA,WADP;AAEE,UAAA,SAAS,EAAEhB,OAAO,CAACiB,MAFrB;AAGE,UAAA,YAAY,EAAEZ,YAHhB;AAIE,UAAA,MAAM,EAAExB,MAAM,CAACP,KAJjB;AAKE,UAAA,WAAW,EAAEgC,WALf;AAME,UAAA,uBAAuB,EAAE,CAAC;AAAEY,YAAAA,QAAQ,EAAE;AAAZ,WAAD,EAA0B;AAAEA,YAAAA,QAAQ,EAAE;AAAZ,WAA1B,CAN3B;AAOE,UAAA,QAAQ,EAAE,kBAACvD,GAAD,EAAS;AACjB,gBAAI,MAAI,CAACwD,WAAT,EAAsB;AACpB;AACD;;AAED,YAAA,MAAI,CAACC,eAAL,CAAqBvC,MAAM,CAACP,KAA5B,EAAmCX,GAAnC,EAAwCkB,MAAM,CAACN,EAA/C;AACD,WAbH;AAcE,UAAA,MAAM,EAAE,kBAAM;AACZ,gBAAI,MAAI,CAAC4C,WAAT,EAAsB;AACpB;AACD;;AAED,YAAA,MAAI,CAACzC,QAAL,CAAc;AACZa,cAAAA,SAAS,EAAE8B;AADC,aAAd;AAGD,WAtBH;AAuBE,UAAA,MAAM,EAAE,gBAACC,CAAD,EAAO;AACb,gBAAMC,mBAAmB,GAAGD,CAAC,CAACE,aAAF,IAAmBF,CAAC,CAACE,aAAF,CAAgBC,OAAhB,CAAwB,0BAAxB,CAA/C;AAEA,YAAA,MAAI,CAACN,WAAL,GAAmBI,mBAAnB;AACD,WA3BH;AA4BE,UAAA,gBAAgB,MA5BlB;AA6BE,UAAA,WAAW,EAAEpB,WA7Bf;AA8BE,UAAA,kBAAkB,EAAEC,kBA9BtB;AA+BE,UAAA,aAAa,EAAEH,aA/BjB;AAgCE,UAAA,cAAc,EAAEO,cAhClB;AAiCE,UAAA,aAAa,EAAED,aAjCjB;AAkCE,UAAA,eAAe,EAAEE;AAlCnB,UAPF,CADF,gBA8CE,gCAAC,kBAAD;AACE,UAAA,GAAG,EAAEI,KADP;AAEE,UAAA,UAAU,EAAEnB,UAFd;AAGE,UAAA,QAAQ,EAAC,GAHX;AAIE,UAAA,MAAM,EAAEb,MAJV;AAKE,UAAA,KAAK,EAAE5B,KALT;AAME,UAAA,OAAO,EAAE;AAAA,mBAAM,MAAI,CAACyE,aAAL,CAAmB7C,MAAM,CAACN,EAA1B,CAAN;AAAA,WANX;AAOE,UAAA,cAAc,EAAE;AAAA,mBAAM,MAAI,CAACoD,cAAL,CAAoB9C,MAAM,CAACN,EAA3B,CAAN;AAAA;AAPlB,UA/CgB;AAAA,OAAnB,CADH,CAXF,EAuEGtB,KAAK,iBAAI;AAAK,QAAA,SAAS,EAAE+C,OAAO,CAACpD;AAAxB,SAAoCK,KAApC,CAvEZ,eAyEE,gCAAC,qBAAD;AACE,QAAA,IAAI,EAAEI,OAAO,CAACC,IADhB;AAEE,QAAA,KAAK,EAAC,SAFR;AAGE,QAAA,IAAI,EAAED,OAAO,CAACsB,IAHhB;AAIE,QAAA,SAAS,EAAE;AAAA,iBAAM,MAAI,CAACD,QAAL,CAAc;AAAErB,YAAAA,OAAO,EAAE;AAAEC,cAAAA,IAAI,EAAE;AAAR;AAAX,WAAd,CAAN;AAAA;AAJb,QAzEF,CADF;AAkFD;;;EA3Q0BsE,kBAAMC,S;;;iCAAtBzE,O,eACQ;AACjBsC,EAAAA,UAAU,EAAEoC,sBAAUC,IADL;AAEjB9E,EAAAA,KAAK,EAAE6E,sBAAUE,MAFA;AAGjBjE,EAAAA,KAAK,EAAE+D,sBAAUG,MAAV,CAAiBC,UAHP;AAIjBpE,EAAAA,QAAQ,EAAEgE,sBAAUK,IAAV,CAAeD,UAJR;AAKjBlC,EAAAA,OAAO,EAAE8B,sBAAUG,MAAV,CAAiBC,UALT;AAMjB/B,EAAAA,WAAW,EAAE2B,sBAAUG,MANN;AAOjB3B,EAAAA,WAAW,EAAEwB,sBAAUG,MAPN;AAQjB/B,EAAAA,UAAU,EAAE4B,sBAAUM,MARL;AASjBhC,EAAAA,kBAAkB,EAAE0B,sBAAUG,MATb;AAUjB1B,EAAAA,aAAa,EAAEuB,sBAAUM,MAVR;AAWjB5B,EAAAA,cAAc,EAAEsB,sBAAUM,MAXT;AAYjB3B,EAAAA,SAAS,EAAEqB,sBAAUM;AAZJ,C;AA6QrB,IAAMC,MAAM,GAAG,wBAAWzG,MAAX,EAAmBwB,OAAnB,CAAf;eAEeiF,M","sourcesContent":["import React from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\nimport EditableHtml from '@pie-lib/editable-html';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { AlertDialog } from '@pie-lib/config-ui';\nimport Button from '@material-ui/core/Button';\nimport { withStyles } from '@material-ui/core/styles';\n\nimport Choice from './choice';\nimport { choiceIsEmpty } from './markupUtils';\n\nconst styles = (theme) => ({\n design: {\n display: 'flex',\n flexDirection: 'column',\n marginBottom: theme.spacing.unit * 1.5,\n },\n addButton: {\n marginLeft: 'auto',\n },\n altChoices: {\n alignItems: 'flex-start',\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-evenly',\n marginTop: theme.spacing.unit,\n\n '& > *': {\n margin: theme.spacing.unit,\n },\n },\n errorText: {\n fontSize: theme.typography.fontSize - 2,\n color: theme.palette.error.main,\n paddingBottom: theme.spacing.unit * 2,\n },\n});\n\nexport class Choices extends React.Component {\n static propTypes = {\n duplicates: PropTypes.bool,\n error: PropTypes.string,\n model: PropTypes.object.isRequired,\n onChange: PropTypes.func.isRequired,\n classes: PropTypes.object.isRequired,\n toolbarOpts: PropTypes.object,\n pluginProps: PropTypes.object,\n maxChoices: PropTypes.number,\n uploadSoundSupport: PropTypes.object,\n maxImageWidth: PropTypes.number,\n maxImageHeight: PropTypes.number,\n maxLength: PropTypes.number,\n };\n\n state = { warning: { open: false } };\n preventDone = false;\n\n componentDidMount() {\n this.rerenderMath();\n }\n\n componentDidUpdate() {\n this.rerenderMath();\n\n if (this.focusedNodeRef) {\n this.focusedNodeRef.focus('end');\n }\n }\n\n rerenderMath = () => {\n //eslint-disable-next-line\n const domNode = ReactDOM.findDOMNode(this);\n\n renderMath(domNode);\n };\n\n onChoiceChanged = (prevValue, val, key) => {\n const { onChange, model } = this.props;\n const { choices, correctResponse, alternateResponses } = model;\n const duplicatedValue = (choices || []).find((c) => c.value === val && c.id !== key);\n\n // discard the new added choice or the changes if the choice would be a duplicate to one that already exists\n if (duplicatedValue) {\n if (prevValue === '') {\n // remove the new added choice from choices\n const newChoices = (choices || []).filter((c) => c.id !== key);\n\n onChange(newChoices);\n }\n\n this.setState({\n warning: {\n open: true,\n text: 'Identical answer choices are not allowed and the changes will be discarded.',\n },\n });\n\n return;\n }\n\n const newChoices = choices?.map((choice) => (choice.id === key ? { ...choice, value: val } : choice)) || [];\n\n if (!choiceIsEmpty({ value: val })) {\n onChange(newChoices);\n\n return;\n }\n\n // if the edited content is empty, its usage has to be searched in the correct response definitions\n let usedForResponse = false;\n\n if (correctResponse) {\n Object.keys(correctResponse).forEach((responseKey) => {\n if (correctResponse[responseKey] === key) {\n usedForResponse = true;\n }\n });\n }\n\n if (alternateResponses && !usedForResponse) {\n Object.values(alternateResponses).forEach((alternate) => {\n if (alternate.indexOf(key) >= 0) {\n usedForResponse = true;\n }\n });\n }\n\n if (usedForResponse) {\n this.setState({\n warning: {\n open: true,\n text: 'Answer choices cannot be blank and the changes will be discarded.',\n },\n });\n\n return;\n }\n\n const newChoicesWithoutTheEmptyOne = newChoices.filter((choice) => choice.id !== key);\n\n onChange(newChoicesWithoutTheEmptyOne);\n\n this.setState({\n warning: {\n open: true,\n text: 'Answer choices cannot be blank.',\n },\n });\n };\n\n onChoiceFocus = (id) =>\n this.setState({\n focusedEl: id,\n });\n\n onAddChoice = () => {\n const {\n model: { choices: oldChoices },\n onChange,\n } = this.props;\n\n this.setState(\n {\n focusedEl: `${oldChoices.length}`,\n },\n () => {\n onChange([\n ...oldChoices,\n {\n id: `${oldChoices.length}`,\n value: '',\n },\n ]);\n },\n );\n };\n\n onChoiceRemove = (id) => {\n const {\n onChange,\n model: { choices },\n } = this.props;\n const newChoices = (choices || []).filter((choice) => choice.id !== id);\n\n onChange(newChoices);\n };\n\n getVisibleChoices = () => {\n const {\n duplicates,\n model: { choices, correctResponse },\n } = this.props;\n\n if (!choices) {\n return [];\n }\n\n if (duplicates) {\n return choices;\n }\n\n // if duplicates not allowed, remove the choices that are used to define the correct response\n return choices.filter((choice) => !(correctResponse && Object.values(correctResponse).includes(choice.id)));\n };\n\n render() {\n const { focusedEl, warning } = this.state;\n const {\n classes,\n duplicates,\n error,\n mathMlOptions = {},\n maxChoices,\n model: { choices },\n toolbarOpts,\n uploadSoundSupport,\n imageSupport = {},\n pluginProps = {},\n maxImageWidth,\n maxImageHeight,\n maxLength,\n } = this.props;\n const visibleChoices = this.getVisibleChoices() || [];\n return (\n <div className={classes.design}>\n <Button\n className={classes.addButton}\n variant=\"contained\"\n color=\"primary\"\n onClick={this.onAddChoice}\n disabled={maxChoices && choices && maxChoices === choices.length}\n >\n Add Choice\n </Button>\n\n <div className={classes.altChoices}>\n {visibleChoices.map((choice, index) =>\n focusedEl === choice.id ? (\n <div\n key={index}\n style={{\n minWidth: '100%',\n zIndex: '100',\n }}\n >\n <EditableHtml\n ref={(ref) => (this.focusedNodeRef = ref)}\n className={classes.prompt}\n imageSupport={imageSupport}\n markup={choice.value}\n pluginProps={pluginProps}\n languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}\n onChange={(val) => {\n if (this.preventDone) {\n return;\n }\n\n this.onChoiceChanged(choice.value, val, choice.id);\n }}\n onDone={() => {\n if (this.preventDone) {\n return;\n }\n\n this.setState({\n focusedEl: undefined,\n });\n }}\n onBlur={(e) => {\n const inInInsertCharacter = e.relatedTarget && e.relatedTarget.closest('.insert-character-dialog');\n\n this.preventDone = inInInsertCharacter;\n }}\n disableUnderline\n toolbarOpts={toolbarOpts}\n uploadSoundSupport={uploadSoundSupport}\n mathMlOptions={mathMlOptions}\n maxImageHeight={maxImageHeight}\n maxImageWidth={maxImageWidth}\n charactersLimit={maxLength}\n />\n </div>\n ) : (\n <Choice\n key={index}\n duplicates={duplicates}\n targetId=\"0\"\n choice={choice}\n error={error}\n onClick={() => this.onChoiceFocus(choice.id)}\n onRemoveChoice={() => this.onChoiceRemove(choice.id)}\n />\n ),\n )}\n </div>\n {error && <div className={classes.errorText}>{error}</div>}\n\n <AlertDialog\n open={warning.open}\n title=\"Warning\"\n text={warning.text}\n onConfirm={() => this.setState({ warning: { open: false } })}\n />\n </div>\n );\n }\n}\n\nconst Styled = withStyles(styles)(Choices);\n\nexport default Styled;\n"],"file":"choices.js"}
1
+ {"version":3,"sources":["../src/choices.jsx"],"names":["styles","theme","design","display","flexDirection","marginBottom","spacing","unit","addButton","marginLeft","altChoices","alignItems","flexWrap","justifyContent","marginTop","margin","errorText","fontSize","typography","color","palette","error","main","paddingBottom","Choices","warning","open","domNode","ReactDOM","findDOMNode","prevValue","val","key","props","onChange","model","choices","correctResponse","alternateResponses","duplicatedValue","find","c","value","id","newChoices","filter","setState","text","map","choice","usedForResponse","Object","keys","forEach","responseKey","values","alternate","indexOf","newChoicesWithoutTheEmptyOne","focusedEl","oldChoices","maxId","length","Math","max","parseInt","newId","duplicates","includes","rerenderMath","focusedNodeRef","focus","state","classes","mathMlOptions","maxChoices","toolbarOpts","uploadSoundSupport","imageSupport","pluginProps","maxImageWidth","maxImageHeight","maxLength","visibleChoices","getVisibleChoices","onAddChoice","index","minWidth","zIndex","ref","prompt","language","preventDone","onChoiceChanged","undefined","e","inInInsertCharacter","relatedTarget","closest","onChoiceFocus","onChoiceRemove","React","Component","PropTypes","bool","string","object","isRequired","func","number","Styled"],"mappings":"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","sourcesContent":["import React from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\nimport EditableHtml from '@pie-lib/editable-html';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { AlertDialog } from '@pie-lib/config-ui';\nimport Button from '@material-ui/core/Button';\nimport { withStyles } from '@material-ui/core/styles';\n\nimport Choice from './choice';\nimport { choiceIsEmpty } from './markupUtils';\n\nconst styles = (theme) => ({\n design: {\n display: 'flex',\n flexDirection: 'column',\n marginBottom: theme.spacing.unit * 1.5,\n },\n addButton: {\n marginLeft: 'auto',\n },\n altChoices: {\n alignItems: 'flex-start',\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-evenly',\n marginTop: theme.spacing.unit,\n\n '& > *': {\n margin: theme.spacing.unit,\n },\n },\n errorText: {\n fontSize: theme.typography.fontSize - 2,\n color: theme.palette.error.main,\n paddingBottom: theme.spacing.unit * 2,\n },\n});\n\nexport class Choices extends React.Component {\n static propTypes = {\n duplicates: PropTypes.bool,\n error: PropTypes.string,\n model: PropTypes.object.isRequired,\n onChange: PropTypes.func.isRequired,\n classes: PropTypes.object.isRequired,\n toolbarOpts: PropTypes.object,\n pluginProps: PropTypes.object,\n maxChoices: PropTypes.number,\n uploadSoundSupport: PropTypes.object,\n maxImageWidth: PropTypes.number,\n maxImageHeight: PropTypes.number,\n maxLength: PropTypes.number,\n };\n\n state = { warning: { open: false } };\n preventDone = false;\n\n componentDidMount() {\n this.rerenderMath();\n }\n\n componentDidUpdate() {\n this.rerenderMath();\n\n if (this.focusedNodeRef) {\n this.focusedNodeRef.focus('end');\n }\n }\n\n rerenderMath = () => {\n //eslint-disable-next-line\n const domNode = ReactDOM.findDOMNode(this);\n\n renderMath(domNode);\n };\n\n onChoiceChanged = (prevValue, val, key) => {\n const { onChange, model } = this.props;\n const { choices, correctResponse, alternateResponses } = model;\n const duplicatedValue = (choices || []).find((c) => c.value === val && c.id !== key);\n\n // discard the new added choice or the changes if the choice would be a duplicate to one that already exists\n if (duplicatedValue) {\n if (prevValue === '') {\n // remove the new added choice from choices\n const newChoices = (choices || []).filter((c) => c.id !== key);\n\n onChange(newChoices);\n }\n\n this.setState({\n warning: {\n open: true,\n text: 'Identical answer choices are not allowed and the changes will be discarded.',\n },\n });\n\n return;\n }\n\n const newChoices = choices?.map((choice) => (choice.id === key ? { ...choice, value: val } : choice)) || [];\n\n if (!choiceIsEmpty({ value: val })) {\n onChange(newChoices);\n\n return;\n }\n\n // if the edited content is empty, its usage has to be searched in the correct response definitions\n let usedForResponse = false;\n\n if (correctResponse) {\n Object.keys(correctResponse).forEach((responseKey) => {\n if (correctResponse[responseKey] === key) {\n usedForResponse = true;\n }\n });\n }\n\n if (alternateResponses && !usedForResponse) {\n Object.values(alternateResponses).forEach((alternate) => {\n if (alternate.indexOf(key) >= 0) {\n usedForResponse = true;\n }\n });\n }\n\n if (usedForResponse) {\n this.setState({\n warning: {\n open: true,\n text: 'Answer choices cannot be blank and the changes will be discarded.',\n },\n });\n\n return;\n }\n\n const newChoicesWithoutTheEmptyOne = newChoices.filter((choice) => choice.id !== key);\n\n onChange(newChoicesWithoutTheEmptyOne);\n\n this.setState({\n warning: {\n open: true,\n text: 'Answer choices cannot be blank.',\n },\n });\n };\n\n onChoiceFocus = (id) =>\n this.setState({\n focusedEl: id,\n });\n\n onAddChoice = () => {\n const {\n model: { choices: oldChoices },\n onChange,\n } = this.props;\n\n // find the maximum existing id and add 1 to generate the new id so we avoid duplicates\n const maxId = oldChoices.length > 0 \n ? Math.max(...oldChoices.map(choice => parseInt(choice.id, 10) || 0))\n : -1;\n const newId = `${maxId + 1}`;\n\n this.setState(\n {\n focusedEl: newId,\n },\n () => {\n onChange([\n ...oldChoices,\n {\n id: newId,\n value: '',\n },\n ]);\n },\n );\n };\n\n onChoiceRemove = (id) => {\n const {\n onChange,\n model: { choices },\n } = this.props;\n const newChoices = (choices || []).filter((choice) => choice.id !== id);\n\n onChange(newChoices);\n };\n\n getVisibleChoices = () => {\n const {\n duplicates,\n model: { choices, correctResponse },\n } = this.props;\n\n if (!choices) {\n return [];\n }\n\n if (duplicates) {\n return choices;\n }\n\n // if duplicates not allowed, remove the choices that are used to define the correct response\n return choices.filter((choice) => !(correctResponse && Object.values(correctResponse).includes(choice.id)));\n };\n\n render() {\n const { focusedEl, warning } = this.state;\n const {\n classes,\n duplicates,\n error,\n mathMlOptions = {},\n maxChoices,\n model: { choices },\n toolbarOpts,\n uploadSoundSupport,\n imageSupport = {},\n pluginProps = {},\n maxImageWidth,\n maxImageHeight,\n maxLength,\n } = this.props;\n const visibleChoices = this.getVisibleChoices() || [];\n return (\n <div className={classes.design}>\n <Button\n className={classes.addButton}\n variant=\"contained\"\n color=\"primary\"\n onClick={this.onAddChoice}\n disabled={maxChoices && choices && maxChoices === choices.length}\n >\n Add Choice\n </Button>\n\n <div className={classes.altChoices}>\n {visibleChoices.map((choice, index) =>\n focusedEl === choice.id ? (\n <div\n key={index}\n style={{\n minWidth: '100%',\n zIndex: '100',\n }}\n >\n <EditableHtml\n ref={(ref) => (this.focusedNodeRef = ref)}\n className={classes.prompt}\n imageSupport={imageSupport}\n markup={choice.value}\n pluginProps={pluginProps}\n languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}\n onChange={(val) => {\n if (this.preventDone) {\n return;\n }\n\n this.onChoiceChanged(choice.value, val, choice.id);\n }}\n onDone={() => {\n if (this.preventDone) {\n return;\n }\n\n this.setState({\n focusedEl: undefined,\n });\n }}\n onBlur={(e) => {\n const inInInsertCharacter = e.relatedTarget && e.relatedTarget.closest('.insert-character-dialog');\n\n this.preventDone = inInInsertCharacter;\n }}\n disableUnderline\n toolbarOpts={toolbarOpts}\n uploadSoundSupport={uploadSoundSupport}\n mathMlOptions={mathMlOptions}\n maxImageHeight={maxImageHeight}\n maxImageWidth={maxImageWidth}\n charactersLimit={maxLength}\n />\n </div>\n ) : (\n <Choice\n key={index}\n duplicates={duplicates}\n targetId=\"0\"\n choice={choice}\n error={error}\n onClick={() => this.onChoiceFocus(choice.id)}\n onRemoveChoice={() => this.onChoiceRemove(choice.id)}\n />\n ),\n )}\n </div>\n {error && <div className={classes.errorText}>{error}</div>}\n\n <AlertDialog\n open={warning.open}\n title=\"Warning\"\n text={warning.text}\n onConfirm={() => this.setState({ warning: { open: false } })}\n />\n </div>\n );\n }\n}\n\nconst Styled = withStyles(styles)(Choices);\n\nexport default Styled;\n"],"file":"choices.js"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/drag-in-the-blank-configure",
3
- "version": "7.0.2",
3
+ "version": "7.2.0",
4
4
  "private": true,
5
5
  "main": "lib/index.js",
6
6
  "module": "src/index.js",
@@ -8,10 +8,10 @@
8
8
  "@material-ui/core": "^3.9.2",
9
9
  "@material-ui/icons": "^3.0.1",
10
10
  "@pie-framework/pie-configure-events": "^1.3.0",
11
- "@pie-lib/config-ui": "^11.26.0",
12
- "@pie-lib/drag": "^2.19.0",
13
- "@pie-lib/editable-html": "^11.18.0",
14
- "@pie-lib/math-rendering": "^3.19.0",
11
+ "@pie-lib/config-ui": "^11.25.1",
12
+ "@pie-lib/drag": "^2.18.1",
13
+ "@pie-lib/editable-html": "^11.17.1",
14
+ "@pie-lib/math-rendering": "^3.19.4",
15
15
  "debug": "^3.1.0",
16
16
  "lodash": "^4.17.15",
17
17
  "prop-types": "^15.6.2",
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [7.2.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-controller@7.0.1...@pie-element/drag-in-the-blank-controller@7.2.0) (2025-10-10)
7
+
8
+
9
+ ### Features
10
+
11
+ * update completion rule for categorize, ditb, and image-cloze PD-5179 ([cd03a6e](https://github.com/pie-framework/pie-elements/commit/cd03a6e56e51cc3778749b3679b87f9122405936))
12
+ * update libs PD-5208, PD-5211, PD-5199, PD-5218, PD-5217 ([da327fa](https://github.com/pie-framework/pie-elements/commit/da327fa501f6e9eff1c0b30b5ef092426a91f78b))
13
+
14
+
15
+
16
+
17
+
18
+ # [7.1.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-controller@7.0.0...@pie-element/drag-in-the-blank-controller@7.1.0) (2025-10-07)
19
+
20
+ **Note:** Version bump only for package @pie-element/drag-in-the-blank-controller
21
+
22
+
23
+
24
+
25
+
6
26
  ## [7.0.1](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-controller@6.4.0...@pie-element/drag-in-the-blank-controller@7.0.1) (2025-10-02)
7
27
 
8
28
  **Note:** Version bump only for package @pie-element/drag-in-the-blank-controller
@@ -46,7 +46,7 @@ exports.normalize = normalize;
46
46
  function model(question, session, env, updateSession) {
47
47
  return new Promise( /*#__PURE__*/function () {
48
48
  var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(resolve) {
49
- var normalizedQuestion, feedback, choices, lockChoiceOrder, shouldIncludeCorrectResponse, out;
49
+ var normalizedQuestion, feedback, choices, lockChoiceOrder, responseAreasToBeFilled, shouldIncludeCorrectResponse, out;
50
50
  return _regenerator["default"].wrap(function _callee$(_context) {
51
51
  while (1) {
52
52
  switch (_context.prev = _context.next) {
@@ -109,6 +109,11 @@ function model(question, session, env, updateSession) {
109
109
  choices = _context.sent;
110
110
 
111
111
  case 9:
112
+ // we don't need to check for fewer areas to be filled in the alternateResponses
113
+ // because the alternates are an option in the default correct response (for scoring)
114
+ responseAreasToBeFilled = Object.values(normalizedQuestion.correctResponse || {}).filter(function (value) {
115
+ return !!value;
116
+ }).length;
112
117
  shouldIncludeCorrectResponse = env.mode === 'evaluate';
113
118
  out = _objectSpread(_objectSpread({}, normalizedQuestion), {}, {
114
119
  prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,
@@ -117,7 +122,8 @@ function model(question, session, env, updateSession) {
117
122
  mode: env.mode,
118
123
  disabled: env.mode !== 'gather',
119
124
  responseCorrect: shouldIncludeCorrectResponse ? getScore(normalizedQuestion, session) === 1 : undefined,
120
- correctResponse: shouldIncludeCorrectResponse ? normalizedQuestion.correctResponse : undefined
125
+ correctResponse: shouldIncludeCorrectResponse ? normalizedQuestion.correctResponse : undefined,
126
+ responseAreasToBeFilled: responseAreasToBeFilled
121
127
  });
122
128
 
123
129
  if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
@@ -130,7 +136,7 @@ function model(question, session, env, updateSession) {
130
136
 
131
137
  resolve(out);
132
138
 
133
- case 13:
139
+ case 14:
134
140
  case "end":
135
141
  return _context.stop();
136
142
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["normalize","question","defaults","model","session","env","updateSession","Promise","resolve","normalizedQuestion","feedback","mode","responses","allCorrectResponses","possibleResponses","numberOfPossibleResponses","correctResponses","undefined","value","i","result","Object","keys","reduce","obj","key","choices","answer","filter","choice","lockChoiceOrder","shouldIncludeCorrectResponse","out","prompt","promptEnabled","disabled","responseCorrect","getScore","correctResponse","role","rationale","rationaleEnabled","teacherInstructions","teacherInstructionsEnabled","config","maxScore","length","correctCount","total","str","toFixed","parseFloat","outcome","partialScoringEnabled","partialScoring","enabled","score","empty","createCorrectResponseSession","id","getInnerText","html","replaceAll","getContent","replace","validate","markup","minChoices","maxChoices","maxResponseAreas","errors","forEach","field","required","nbOfResponseAreas","match","nbOfChoices","emptyResponseAreas","values","response","correctResponseError","responseAreasError","choicesError"],"mappings":"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","sourcesContent":["import isEmpty from 'lodash/isEmpty';\nimport { getAllCorrectResponses, choiceIsEmpty } from './utils';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';\nimport defaults from './defaults';\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 function model(question, session, env, updateSession) {\n return new Promise(async (resolve) => {\n const normalizedQuestion = normalize(question);\n let feedback = {};\n\n if (env.mode === 'evaluate') {\n const responses = getAllCorrectResponses(normalizedQuestion) || {};\n const allCorrectResponses = responses.possibleResponses;\n const numberOfPossibleResponses = responses.numberOfPossibleResponses || 0;\n let correctResponses = undefined;\n const { value } = session || {};\n\n for (let i = 0; i < numberOfPossibleResponses; i++) {\n const result = Object.keys(allCorrectResponses).reduce(\n (obj, key) => {\n const choices = allCorrectResponses[key];\n const answer = (value && value[key]) || '';\n\n obj.feedback[key] = choices[i] === answer;\n\n if (obj.feedback[key]) {\n obj.correctResponses += 1;\n }\n\n return obj;\n },\n { correctResponses: 0, feedback: {} },\n );\n\n if (correctResponses === undefined || result.correctResponses > correctResponses) {\n correctResponses = result.correctResponses;\n feedback = result.feedback;\n }\n }\n }\n\n let choices = normalizedQuestion.choices && normalizedQuestion.choices.filter((choice) => !choiceIsEmpty(choice));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'id');\n }\n\n const shouldIncludeCorrectResponse = env.mode === 'evaluate';\n\n const out = {\n ...normalizedQuestion,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choices,\n feedback,\n mode: env.mode,\n disabled: env.mode !== 'gather',\n responseCorrect: shouldIncludeCorrectResponse ? getScore(normalizedQuestion, session) === 1 : undefined,\n correctResponse: shouldIncludeCorrectResponse ? normalizedQuestion.correctResponse : 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\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport const getScore = (config, session) => {\n const responses = getAllCorrectResponses(config);\n const allCorrectResponses = responses.possibleResponses;\n const maxScore = Object.keys(config.correctResponse).length;\n const numberOfPossibleResponses = responses.numberOfPossibleResponses || 0;\n let correctCount = 0;\n const { value } = session || {};\n\n for (let i = 0; i < numberOfPossibleResponses; i++) {\n const result = Object.keys(allCorrectResponses).reduce((total, key) => {\n const choices = allCorrectResponses[key];\n const answer = (value && value[key]) || '';\n\n if (choices[i] === answer) {\n return total;\n }\n\n return total - 1;\n }, maxScore);\n\n if (result > correctCount) {\n correctCount = result;\n }\n\n if (result === maxScore) {\n break;\n }\n }\n\n const str = maxScore ? (correctCount / maxScore).toFixed(2) : 0;\n\n return parseFloat(str);\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring =\n * false. the value in `env` will override the value in `model`.\n * @param {Object} model - the main model\n * @param {boolean} model.partialScoring - is partial scoring enabled (if undefined set to to true)\n * @param {*} session\n * @param {Object} env\n * @param {boolean} env.partialScoring - is partial scoring enabled (if undefined default to true) This overrides\n * `model.partialScoring`.\n */\nexport function outcome(model, session, env = {}) {\n return new Promise((resolve) => {\n const partialScoringEnabled = partialScoring.enabled(model, env);\n const score = getScore(model, session);\n\n resolve({\n score: partialScoringEnabled ? score : score === 1 ? 1 : 0,\n empty: !session || isEmpty(session),\n });\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n resolve({\n value: question.correctResponse,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices, correctResponse, markup } = model;\n const { minChoices = 2, maxChoices, maxResponseAreas } = config;\n const errors = {};\n\n ['teacherInstructions', 'prompt', 'rationale'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n const nbOfResponseAreas = ((markup || '').match(/\\{\\{(\\d+)\\}\\}/g) || []).length;\n const nbOfChoices = (choices || []).length;\n const emptyResponseAreas = Object.values(correctResponse)?.filter((response) => !response);\n\n if (emptyResponseAreas.length) {\n errors.correctResponseError = 'There should be a choice defined for each response area.';\n }\n\n if (nbOfResponseAreas > maxResponseAreas) {\n errors.responseAreasError = `No more than ${maxResponseAreas} response areas should be defined.`;\n } else if (nbOfResponseAreas < 1) {\n errors.responseAreasError = 'There should be at least 1 response area defined.';\n }\n\n if (nbOfChoices < minChoices) {\n errors.choicesError = `There should be at least ${minChoices} tokens defined.`;\n } else if (nbOfChoices > maxChoices) {\n errors.choicesError = `No more than ${maxChoices} tokens should be defined.`;\n }\n\n return errors;\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["normalize","question","defaults","model","session","env","updateSession","Promise","resolve","normalizedQuestion","feedback","mode","responses","allCorrectResponses","possibleResponses","numberOfPossibleResponses","correctResponses","undefined","value","i","result","Object","keys","reduce","obj","key","choices","answer","filter","choice","lockChoiceOrder","responseAreasToBeFilled","values","correctResponse","length","shouldIncludeCorrectResponse","out","prompt","promptEnabled","disabled","responseCorrect","getScore","role","rationale","rationaleEnabled","teacherInstructions","teacherInstructionsEnabled","config","maxScore","correctCount","total","str","toFixed","parseFloat","outcome","partialScoringEnabled","partialScoring","enabled","score","empty","createCorrectResponseSession","id","getInnerText","html","replaceAll","getContent","replace","validate","markup","minChoices","maxChoices","maxResponseAreas","errors","forEach","field","required","nbOfResponseAreas","match","nbOfChoices","emptyResponseAreas","response","correctResponseError","responseAreasError","choicesError"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;;;;;AAEO,IAAMA,SAAS,GAAG,SAAZA,SAAY,CAACC,QAAD;AAAA,yCACpBC,oBADoB,GAEpBD,QAFoB;AAAA,CAAlB;AAKP;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACO,SAASE,KAAT,CAAeF,QAAf,EAAyBG,OAAzB,EAAkCC,GAAlC,EAAuCC,aAAvC,EAAsD;AAC3D,SAAO,IAAIC,OAAJ;AAAA,6FAAY,iBAAOC,OAAP;AAAA;AAAA;AAAA;AAAA;AAAA;AACXC,cAAAA,kBADW,GACUT,SAAS,CAACC,QAAD,CADnB;AAEbS,cAAAA,QAFa,GAEF,EAFE;;AAIjB,kBAAIL,GAAG,CAACM,IAAJ,KAAa,UAAjB,EAA6B;AAAA;AAC3B,sBAAMC,SAAS,GAAG,mCAAuBH,kBAAvB,KAA8C,EAAhE;AACA,sBAAMI,mBAAmB,GAAGD,SAAS,CAACE,iBAAtC;AACA,sBAAMC,yBAAyB,GAAGH,SAAS,CAACG,yBAAV,IAAuC,CAAzE;AACA,sBAAIC,gBAAgB,GAAGC,SAAvB;;AACA,8BAAkBb,OAAO,IAAI,EAA7B;AAAA,sBAAQc,KAAR,SAAQA,KAAR;;AAL2B,6CAOlBC,CAPkB;AAQzB,wBAAMC,MAAM,GAAGC,MAAM,CAACC,IAAP,CAAYT,mBAAZ,EAAiCU,MAAjC,CACb,UAACC,GAAD,EAAMC,GAAN,EAAc;AACZ,0BAAMC,OAAO,GAAGb,mBAAmB,CAACY,GAAD,CAAnC;AACA,0BAAME,MAAM,GAAIT,KAAK,IAAIA,KAAK,CAACO,GAAD,CAAf,IAAyB,EAAxC;AAEAD,sBAAAA,GAAG,CAACd,QAAJ,CAAae,GAAb,IAAoBC,OAAO,CAACP,CAAD,CAAP,KAAeQ,MAAnC;;AAEA,0BAAIH,GAAG,CAACd,QAAJ,CAAae,GAAb,CAAJ,EAAuB;AACrBD,wBAAAA,GAAG,CAACR,gBAAJ,IAAwB,CAAxB;AACD;;AAED,6BAAOQ,GAAP;AACD,qBAZY,EAab;AAAER,sBAAAA,gBAAgB,EAAE,CAApB;AAAuBN,sBAAAA,QAAQ,EAAE;AAAjC,qBAba,CAAf;;AAgBA,wBAAIM,gBAAgB,KAAKC,SAArB,IAAkCG,MAAM,CAACJ,gBAAP,GAA0BA,gBAAhE,EAAkF;AAChFA,sBAAAA,gBAAgB,GAAGI,MAAM,CAACJ,gBAA1B;AACAN,sBAAAA,QAAQ,GAAGU,MAAM,CAACV,QAAlB;AACD;AA3BwB;;AAO3B,uBAAK,IAAIS,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGJ,yBAApB,EAA+CI,CAAC,EAAhD,EAAoD;AAAA,0BAA3CA,CAA2C;AAqBnD;AA5B0B;AA6B5B;;AAEGO,cAAAA,OAnCa,GAmCHjB,kBAAkB,CAACiB,OAAnB,IAA8BjB,kBAAkB,CAACiB,OAAnB,CAA2BE,MAA3B,CAAkC,UAACC,MAAD;AAAA,uBAAY,CAAC,0BAAcA,MAAd,CAAb;AAAA,eAAlC,CAnC3B;AAqCXC,cAAAA,eArCW,GAqCO,kCAAYrB,kBAAZ,EAAgCL,OAAhC,EAAyCC,GAAzC,CArCP;;AAAA,kBAuCZyB,eAvCY;AAAA;AAAA;AAAA;;AAAA;AAAA,qBAwCC,yCAAmBJ,OAAnB,EAA4BtB,OAA5B,EAAqCE,aAArC,EAAoD,IAApD,CAxCD;;AAAA;AAwCfoB,cAAAA,OAxCe;;AAAA;AA2CjB;AACA;AACMK,cAAAA,uBA7CW,GA6CeV,MAAM,CAACW,MAAP,CAAcvB,kBAAkB,CAACwB,eAAnB,IAAsC,EAApD,EAAwDL,MAAxD,CAC9B,UAACV,KAAD;AAAA,uBAAW,CAAC,CAACA,KAAb;AAAA,eAD8B,EAE9BgB,MA/Ce;AAiDXC,cAAAA,4BAjDW,GAiDoB9B,GAAG,CAACM,IAAJ,KAAa,UAjDjC;AAmDXyB,cAAAA,GAnDW,mCAoDZ3B,kBApDY;AAqDf4B,gBAAAA,MAAM,EAAE5B,kBAAkB,CAAC6B,aAAnB,GAAmC7B,kBAAkB,CAAC4B,MAAtD,GAA+D,IArDxD;AAsDfX,gBAAAA,OAAO,EAAPA,OAtDe;AAuDfhB,gBAAAA,QAAQ,EAARA,QAvDe;AAwDfC,gBAAAA,IAAI,EAAEN,GAAG,CAACM,IAxDK;AAyDf4B,gBAAAA,QAAQ,EAAElC,GAAG,CAACM,IAAJ,KAAa,QAzDR;AA0Df6B,gBAAAA,eAAe,EAAEL,4BAA4B,GAAGM,QAAQ,CAAChC,kBAAD,EAAqBL,OAArB,CAAR,KAA0C,CAA7C,GAAiDa,SA1D/E;AA2DfgB,gBAAAA,eAAe,EAAEE,4BAA4B,GAAG1B,kBAAkB,CAACwB,eAAtB,GAAwChB,SA3DtE;AA4Dfc,gBAAAA,uBAAuB,EAAvBA;AA5De;;AA+DjB,kBAAI1B,GAAG,CAACqC,IAAJ,KAAa,YAAb,KAA8BrC,GAAG,CAACM,IAAJ,KAAa,MAAb,IAAuBN,GAAG,CAACM,IAAJ,KAAa,UAAlE,CAAJ,EAAmF;AACjFyB,gBAAAA,GAAG,CAACO,SAAJ,GAAgBlC,kBAAkB,CAACmC,gBAAnB,GAAsCnC,kBAAkB,CAACkC,SAAzD,GAAqE,IAArF;AACAP,gBAAAA,GAAG,CAACS,mBAAJ,GAA0BpC,kBAAkB,CAACqC,0BAAnB,GACtBrC,kBAAkB,CAACoC,mBADG,GAEtB,IAFJ;AAGD,eALD,MAKO;AACLT,gBAAAA,GAAG,CAACO,SAAJ,GAAgB,IAAhB;AACAP,gBAAAA,GAAG,CAACS,mBAAJ,GAA0B,IAA1B;AACD;;AAEDrC,cAAAA,OAAO,CAAC4B,GAAD,CAAP;;AAzEiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAAZ;;AAAA;AAAA;AAAA;AAAA,MAAP;AA2ED;;AAEM,IAAMK,QAAQ,GAAG,SAAXA,QAAW,CAACM,MAAD,EAAS3C,OAAT,EAAqB;AAC3C,MAAMQ,SAAS,GAAG,mCAAuBmC,MAAvB,CAAlB;AACA,MAAMlC,mBAAmB,GAAGD,SAAS,CAACE,iBAAtC;AACA,MAAMkC,QAAQ,GAAG3B,MAAM,CAACC,IAAP,CAAYyB,MAAM,CAACd,eAAnB,EAAoCC,MAArD;AACA,MAAMnB,yBAAyB,GAAGH,SAAS,CAACG,yBAAV,IAAuC,CAAzE;AACA,MAAIkC,YAAY,GAAG,CAAnB;;AACA,cAAkB7C,OAAO,IAAI,EAA7B;AAAA,MAAQc,KAAR,SAAQA,KAAR;;AAN2C,+BAQlCC,CARkC;AASzC,QAAMC,MAAM,GAAGC,MAAM,CAACC,IAAP,CAAYT,mBAAZ,EAAiCU,MAAjC,CAAwC,UAAC2B,KAAD,EAAQzB,GAAR,EAAgB;AACrE,UAAMC,OAAO,GAAGb,mBAAmB,CAACY,GAAD,CAAnC;AACA,UAAME,MAAM,GAAIT,KAAK,IAAIA,KAAK,CAACO,GAAD,CAAf,IAAyB,EAAxC;;AAEA,UAAIC,OAAO,CAACP,CAAD,CAAP,KAAeQ,MAAnB,EAA2B;AACzB,eAAOuB,KAAP;AACD;;AAED,aAAOA,KAAK,GAAG,CAAf;AACD,KATc,EASZF,QATY,CAAf;;AAWA,QAAI5B,MAAM,GAAG6B,YAAb,EAA2B;AACzBA,MAAAA,YAAY,GAAG7B,MAAf;AACD;;AAED,QAAIA,MAAM,KAAK4B,QAAf,EAAyB;AACvB;AACD;AA1BwC;;AAQ3C,OAAK,IAAI7B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGJ,yBAApB,EAA+CI,CAAC,EAAhD,EAAoD;AAAA,sBAA3CA,CAA2C;;AAAA,0BAiBhD;AAEH;;AAED,MAAMgC,GAAG,GAAGH,QAAQ,GAAG,CAACC,YAAY,GAAGD,QAAhB,EAA0BI,OAA1B,CAAkC,CAAlC,CAAH,GAA0C,CAA9D;AAEA,SAAOC,UAAU,CAACF,GAAD,CAAjB;AACD,CAhCM;AAkCP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACO,SAASG,OAAT,CAAiBnD,KAAjB,EAAwBC,OAAxB,EAA2C;AAAA,MAAVC,GAAU,uEAAJ,EAAI;AAChD,SAAO,IAAIE,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9B,QAAM+C,qBAAqB,GAAGC,gCAAeC,OAAf,CAAuBtD,KAAvB,EAA8BE,GAA9B,CAA9B;;AACA,QAAMqD,KAAK,GAAGjB,QAAQ,CAACtC,KAAD,EAAQC,OAAR,CAAtB;AAEAI,IAAAA,OAAO,CAAC;AACNkD,MAAAA,KAAK,EAAEH,qBAAqB,GAAGG,KAAH,GAAWA,KAAK,KAAK,CAAV,GAAc,CAAd,GAAkB,CADnD;AAENC,MAAAA,KAAK,EAAE,CAACvD,OAAD,IAAY,yBAAQA,OAAR;AAFb,KAAD,CAAP;AAID,GARM,CAAP;AASD;;AAEM,IAAMwD,4BAA4B,GAAG,SAA/BA,4BAA+B,CAAC3D,QAAD,EAAWI,GAAX,EAAmB;AAC7D,SAAO,IAAIE,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9B,QAAIH,GAAG,CAACM,IAAJ,KAAa,UAAb,IAA2BN,GAAG,CAACqC,IAAJ,KAAa,YAA5C,EAA0D;AACxDlC,MAAAA,OAAO,CAAC;AACNU,QAAAA,KAAK,EAAEjB,QAAQ,CAACgC,eADV;AAEN4B,QAAAA,EAAE,EAAE;AAFE,OAAD,CAAP;AAID,KALD,MAKO;AACLrD,MAAAA,OAAO,CAAC,IAAD,CAAP;AACD;AACF,GATM,CAAP;AAUD,CAXM,C,CAaP;;;;;AACA,IAAMsD,YAAY,GAAG,SAAfA,YAAe,CAACC,IAAD;AAAA,SAAU,CAACA,IAAI,IAAI,EAAT,EAAaC,UAAb,CAAwB,UAAxB,EAAoC,EAApC,CAAV;AAAA,CAArB,C,CAEA;;;AACA,IAAMC,UAAU,GAAG,SAAbA,UAAa,CAACF,IAAD;AAAA,SAAU,CAACA,IAAI,IAAI,EAAT,EAAaG,OAAb,CAAqB,oCAArB,EAA2D,EAA3D,CAAV;AAAA,CAAnB;;AAEO,IAAMC,QAAQ,GAAG,SAAXA,QAAW,GAA6B;AAAA;;AAAA,MAA5BhE,KAA4B,uEAApB,EAAoB;AAAA,MAAhB4C,MAAgB,uEAAP,EAAO;AACnD,MAAQrB,OAAR,GAA6CvB,KAA7C,CAAQuB,OAAR;AAAA,MAAiBO,eAAjB,GAA6C9B,KAA7C,CAAiB8B,eAAjB;AAAA,MAAkCmC,MAAlC,GAA6CjE,KAA7C,CAAkCiE,MAAlC;AACA,2BAAyDrB,MAAzD,CAAQsB,UAAR;AAAA,MAAQA,UAAR,mCAAqB,CAArB;AAAA,MAAwBC,UAAxB,GAAyDvB,MAAzD,CAAwBuB,UAAxB;AAAA,MAAoCC,gBAApC,GAAyDxB,MAAzD,CAAoCwB,gBAApC;AACA,MAAMC,MAAM,GAAG,EAAf;AAEA,GAAC,qBAAD,EAAwB,QAAxB,EAAkC,WAAlC,EAA+CC,OAA/C,CAAuD,UAACC,KAAD,EAAW;AAAA;;AAChE,QAAI,iBAAA3B,MAAM,CAAC2B,KAAD,CAAN,wDAAeC,QAAf,IAA2B,CAACV,UAAU,CAAC9D,KAAK,CAACuE,KAAD,CAAN,CAA1C,EAA0D;AACxDF,MAAAA,MAAM,CAACE,KAAD,CAAN,GAAgB,yBAAhB;AACD;AACF,GAJD;AAMA,MAAME,iBAAiB,GAAG,CAAC,CAACR,MAAM,IAAI,EAAX,EAAeS,KAAf,CAAqB,gBAArB,KAA0C,EAA3C,EAA+C3C,MAAzE;AACA,MAAM4C,WAAW,GAAG,CAACpD,OAAO,IAAI,EAAZ,EAAgBQ,MAApC;AACA,MAAM6C,kBAAkB,qBAAG1D,MAAM,CAACW,MAAP,CAAcC,eAAd,CAAH,mDAAG,eAAgCL,MAAhC,CAAuC,UAACoD,QAAD;AAAA,WAAc,CAACA,QAAf;AAAA,GAAvC,CAA3B;;AAEA,MAAID,kBAAkB,CAAC7C,MAAvB,EAA+B;AAC7BsC,IAAAA,MAAM,CAACS,oBAAP,GAA8B,0DAA9B;AACD;;AAED,MAAIL,iBAAiB,GAAGL,gBAAxB,EAA0C;AACxCC,IAAAA,MAAM,CAACU,kBAAP,0BAA4CX,gBAA5C;AACD,GAFD,MAEO,IAAIK,iBAAiB,GAAG,CAAxB,EAA2B;AAChCJ,IAAAA,MAAM,CAACU,kBAAP,GAA4B,mDAA5B;AACD;;AAED,MAAIJ,WAAW,GAAGT,UAAlB,EAA8B;AAC5BG,IAAAA,MAAM,CAACW,YAAP,sCAAkDd,UAAlD;AACD,GAFD,MAEO,IAAIS,WAAW,GAAGR,UAAlB,EAA8B;AACnCE,IAAAA,MAAM,CAACW,YAAP,0BAAsCb,UAAtC;AACD;;AAED,SAAOE,MAAP;AACD,CAhCM","sourcesContent":["import isEmpty from 'lodash/isEmpty';\nimport { getAllCorrectResponses, choiceIsEmpty } from './utils';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';\nimport defaults from './defaults';\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 function model(question, session, env, updateSession) {\n return new Promise(async (resolve) => {\n const normalizedQuestion = normalize(question);\n let feedback = {};\n\n if (env.mode === 'evaluate') {\n const responses = getAllCorrectResponses(normalizedQuestion) || {};\n const allCorrectResponses = responses.possibleResponses;\n const numberOfPossibleResponses = responses.numberOfPossibleResponses || 0;\n let correctResponses = undefined;\n const { value } = session || {};\n\n for (let i = 0; i < numberOfPossibleResponses; i++) {\n const result = Object.keys(allCorrectResponses).reduce(\n (obj, key) => {\n const choices = allCorrectResponses[key];\n const answer = (value && value[key]) || '';\n\n obj.feedback[key] = choices[i] === answer;\n\n if (obj.feedback[key]) {\n obj.correctResponses += 1;\n }\n\n return obj;\n },\n { correctResponses: 0, feedback: {} },\n );\n\n if (correctResponses === undefined || result.correctResponses > correctResponses) {\n correctResponses = result.correctResponses;\n feedback = result.feedback;\n }\n }\n }\n\n let choices = normalizedQuestion.choices && normalizedQuestion.choices.filter((choice) => !choiceIsEmpty(choice));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'id');\n }\n\n // we don't need to check for fewer areas to be filled in the alternateResponses\n // because the alternates are an option in the default correct response (for scoring)\n const responseAreasToBeFilled = Object.values(normalizedQuestion.correctResponse || {}).filter(\n (value) => !!value,\n ).length;\n\n const shouldIncludeCorrectResponse = env.mode === 'evaluate';\n\n const out = {\n ...normalizedQuestion,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choices,\n feedback,\n mode: env.mode,\n disabled: env.mode !== 'gather',\n responseCorrect: shouldIncludeCorrectResponse ? getScore(normalizedQuestion, session) === 1 : undefined,\n correctResponse: shouldIncludeCorrectResponse ? normalizedQuestion.correctResponse : undefined,\n responseAreasToBeFilled,\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\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport const getScore = (config, session) => {\n const responses = getAllCorrectResponses(config);\n const allCorrectResponses = responses.possibleResponses;\n const maxScore = Object.keys(config.correctResponse).length;\n const numberOfPossibleResponses = responses.numberOfPossibleResponses || 0;\n let correctCount = 0;\n const { value } = session || {};\n\n for (let i = 0; i < numberOfPossibleResponses; i++) {\n const result = Object.keys(allCorrectResponses).reduce((total, key) => {\n const choices = allCorrectResponses[key];\n const answer = (value && value[key]) || '';\n\n if (choices[i] === answer) {\n return total;\n }\n\n return total - 1;\n }, maxScore);\n\n if (result > correctCount) {\n correctCount = result;\n }\n\n if (result === maxScore) {\n break;\n }\n }\n\n const str = maxScore ? (correctCount / maxScore).toFixed(2) : 0;\n\n return parseFloat(str);\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring =\n * false. the value in `env` will override the value in `model`.\n * @param {Object} model - the main model\n * @param {boolean} model.partialScoring - is partial scoring enabled (if undefined set to to true)\n * @param {*} session\n * @param {Object} env\n * @param {boolean} env.partialScoring - is partial scoring enabled (if undefined default to true) This overrides\n * `model.partialScoring`.\n */\nexport function outcome(model, session, env = {}) {\n return new Promise((resolve) => {\n const partialScoringEnabled = partialScoring.enabled(model, env);\n const score = getScore(model, session);\n\n resolve({\n score: partialScoringEnabled ? score : score === 1 ? 1 : 0,\n empty: !session || isEmpty(session),\n });\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n resolve({\n value: question.correctResponse,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices, correctResponse, markup } = model;\n const { minChoices = 2, maxChoices, maxResponseAreas } = config;\n const errors = {};\n\n ['teacherInstructions', 'prompt', 'rationale'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n const nbOfResponseAreas = ((markup || '').match(/\\{\\{(\\d+)\\}\\}/g) || []).length;\n const nbOfChoices = (choices || []).length;\n const emptyResponseAreas = Object.values(correctResponse)?.filter((response) => !response);\n\n if (emptyResponseAreas.length) {\n errors.correctResponseError = 'There should be a choice defined for each response area.';\n }\n\n if (nbOfResponseAreas > maxResponseAreas) {\n errors.responseAreasError = `No more than ${maxResponseAreas} response areas should be defined.`;\n } else if (nbOfResponseAreas < 1) {\n errors.responseAreasError = 'There should be at least 1 response area defined.';\n }\n\n if (nbOfChoices < minChoices) {\n errors.choicesError = `There should be at least ${minChoices} tokens defined.`;\n } else if (nbOfChoices > maxChoices) {\n errors.choicesError = `No more than ${maxChoices} tokens should be defined.`;\n }\n\n return errors;\n};\n"],"file":"index.js"}
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@pie-element/drag-in-the-blank-controller",
3
3
  "private": true,
4
- "version": "7.0.2",
4
+ "version": "7.2.0",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "module": "src/index.js",
8
8
  "author": "",
9
9
  "license": "ISC",
10
10
  "dependencies": {
11
- "@pie-lib/controller-utils": "^0.19.0",
11
+ "@pie-lib/controller-utils": "^0.19.4",
12
12
  "debug": "^3.1.0",
13
13
  "lodash": "^4.17.15",
14
14
  "type-of": "^2.0.1"
package/lib/index.js CHANGED
@@ -42,7 +42,8 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
42
42
  var isComplete = function isComplete(session, model, audioComplete, elementContext) {
43
43
  var _ref = model || {},
44
44
  autoplayAudioEnabled = _ref.autoplayAudioEnabled,
45
- completeAudioEnabled = _ref.completeAudioEnabled;
45
+ completeAudioEnabled = _ref.completeAudioEnabled,
46
+ responseAreasToBeFilled = _ref.responseAreasToBeFilled;
46
47
 
47
48
  if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {
48
49
  if (elementContext) {
@@ -59,9 +60,10 @@ var isComplete = function isComplete(session, model, audioComplete, elementConte
59
60
  return false;
60
61
  }
61
62
 
62
- return Object.values(session.value || {}).some(function (value) {
63
- return !!value;
64
- });
63
+ var filledResponseAreas = Object.values(session.value || {}).filter(function (val) {
64
+ return !!val;
65
+ }).length;
66
+ return filledResponseAreas >= responseAreasToBeFilled;
65
67
  };
66
68
 
67
69
  exports.isComplete = isComplete;
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["isComplete","session","model","audioComplete","elementContext","autoplayAudioEnabled","completeAudioEnabled","audio","querySelector","isInsidePrompt","closest","value","Object","values","some","DragInTheBlank","_model","_session","elem","React","createElement","Main","onChange","changeSession","ReactDOM","render","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","selector","dispatchChangedEvent","_render","_audioInitialized","m","ModelSetEvent","s","info","document","id","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","observer","MutationObserver","mutationsList","forEach","mutation","type","_createAudioInfoToast","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","audioStartTime","Date","getTime","handleEnded","audioEndTime","waitTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","HTMLElement"],"mappings":"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","sourcesContent":["import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { EnableAudioAutoplayImage } from '@pie-lib/render-ui';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport Main from './main';\n\nexport const isComplete = (session, model, audioComplete, elementContext) => {\n const { autoplayAudioEnabled, completeAudioEnabled } = model || {};\n\n if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {\n if (elementContext) {\n const audio = elementContext.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n // only require audio completion if audio exists and is inside the prompt\n if (audio && isInsidePrompt) {\n return false;\n }\n }\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n return Object.values(session.value || {}).some((value) => !!value);\n};\n\nexport default class DragInTheBlank extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this._audioInitialized = false;\n this.audioComplete = false;\n }\n\n set model(m) {\n this._model = m;\n this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete, this), !!this._model));\n // reset the audioInitialized to false since the model changed, and we might need to reinitialize the audio\n this._audioInitialized = false;\n this._render();\n }\n\n set session(s) {\n this._session = s;\n this._render();\n }\n\n get session() {\n return this._session;\n }\n\n _render = () => {\n if (this._model && this._session) {\n let elem = React.createElement(Main, {\n model: this._model,\n value: this._session.value,\n onChange: this.changeSession,\n });\n\n ReactDOM.render(elem, this, () => {\n renderMath(this);\n });\n }\n };\n\n dispatchChangedEvent = () => {\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete, this)));\n };\n\n changeSession = (value) => {\n this.session.value = value;\n this.session.selector = 'Mouse';\n\n this.dispatchChangedEvent();\n this._render();\n };\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000',\n cursor: 'pointer',\n });\n\n const img = document.createElement('img');\n img.src = EnableAudioAutoplayImage;\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._render();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n if (this._audioInitialized) return;\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n //timestamp when auto-played audio started playing\n this._session.audioStartTime = this._session.audioStartTime || new Date().getTime();\n\n const info = this.querySelector('#play-audio-info');\n if (info) {\n container.removeChild(info);\n }\n\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n //timestamp when auto-played audio completed playing\n this._session.audioEndTime = this._session.audioEndTime || new Date().getTime();\n\n let { audioStartTime, audioEndTime, waitTime } = this._session;\n if (!waitTime && audioStartTime && audioEndTime) {\n // waitTime is elapsed time the user waited for auto-played audio to finish\n this._session.waitTime = audioEndTime - audioStartTime;\n }\n\n this.audioComplete = true;\n this.dispatchChangedEvent();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n // set to true to prevent multiple initializations\n this._audioInitialized = true;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n }\n}\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["isComplete","session","model","audioComplete","elementContext","autoplayAudioEnabled","completeAudioEnabled","responseAreasToBeFilled","audio","querySelector","isInsidePrompt","closest","value","filledResponseAreas","Object","values","filter","val","length","DragInTheBlank","_model","_session","elem","React","createElement","Main","onChange","changeSession","ReactDOM","render","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","selector","dispatchChangedEvent","_render","_audioInitialized","m","ModelSetEvent","s","info","document","id","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","observer","MutationObserver","mutationsList","forEach","mutation","type","_createAudioInfoToast","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","audioStartTime","Date","getTime","handleEnded","audioEndTime","waitTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","HTMLElement"],"mappings":"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","sourcesContent":["import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { EnableAudioAutoplayImage } from '@pie-lib/render-ui';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport Main from './main';\n\nexport const isComplete = (session, model, audioComplete, elementContext) => {\n const { autoplayAudioEnabled, completeAudioEnabled, responseAreasToBeFilled } = model || {};\n\n if (autoplayAudioEnabled && completeAudioEnabled && !audioComplete) {\n if (elementContext) {\n const audio = elementContext.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n // only require audio completion if audio exists and is inside the prompt\n if (audio && isInsidePrompt) {\n return false;\n }\n }\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n const filledResponseAreas = Object.values(session.value || {}).filter((val) => !!val).length;\n\n return filledResponseAreas >= responseAreasToBeFilled;\n};\n\nexport default class DragInTheBlank extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this._audioInitialized = false;\n this.audioComplete = false;\n }\n\n set model(m) {\n this._model = m;\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model, this.audioComplete, this),\n !!this._model,\n ),\n );\n // reset the audioInitialized to false since the model changed, and we might need to reinitialize the audio\n this._audioInitialized = false;\n this._render();\n }\n\n set session(s) {\n this._session = s;\n this._render();\n }\n\n get session() {\n return this._session;\n }\n\n _render = () => {\n if (this._model && this._session) {\n let elem = React.createElement(Main, {\n model: this._model,\n value: this._session.value,\n onChange: this.changeSession,\n });\n\n ReactDOM.render(elem, this, () => {\n renderMath(this);\n });\n }\n };\n\n dispatchChangedEvent = () => {\n this.dispatchEvent(\n new SessionChangedEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model, this.audioComplete, this),\n ),\n );\n };\n\n changeSession = (value) => {\n this.session.value = value;\n this.session.selector = 'Mouse';\n\n this.dispatchChangedEvent();\n this._render();\n };\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000',\n cursor: 'pointer',\n });\n\n const img = document.createElement('img');\n img.src = EnableAudioAutoplayImage;\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._render();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n if (this._audioInitialized) return;\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n //timestamp when auto-played audio started playing\n this._session.audioStartTime = this._session.audioStartTime || new Date().getTime();\n\n const info = this.querySelector('#play-audio-info');\n if (info) {\n container.removeChild(info);\n }\n\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n //timestamp when auto-played audio completed playing\n this._session.audioEndTime = this._session.audioEndTime || new Date().getTime();\n\n let { audioStartTime, audioEndTime, waitTime } = this._session;\n if (!waitTime && audioStartTime && audioEndTime) {\n // waitTime is elapsed time the user waited for auto-played audio to finish\n this._session.waitTime = audioEndTime - audioStartTime;\n }\n\n this.audioComplete = true;\n this.dispatchChangedEvent();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n // set to true to prevent multiple initializations\n this._audioInitialized = true;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n }\n}\n"],"file":"index.js"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "repository": "pie-framework/pie-elements",
7
- "version": "8.0.1",
7
+ "version": "8.2.0",
8
8
  "description": "",
9
9
  "scripts": {
10
10
  "postpublish": "../../scripts/postpublish"
@@ -12,11 +12,11 @@
12
12
  "dependencies": {
13
13
  "@material-ui/core": "^3.9.2",
14
14
  "@pie-framework/pie-player-events": "^0.1.0",
15
- "@pie-lib/correct-answer-toggle": "^2.22.0",
16
- "@pie-lib/drag": "^2.19.0",
17
- "@pie-lib/mask-markup": "^1.30.0",
18
- "@pie-lib/math-rendering": "^3.19.0",
19
- "@pie-lib/render-ui": "^4.32.0",
15
+ "@pie-lib/correct-answer-toggle": "^2.21.1",
16
+ "@pie-lib/drag": "^2.18.1",
17
+ "@pie-lib/mask-markup": "^1.29.1",
18
+ "@pie-lib/math-rendering": "^3.19.4",
19
+ "@pie-lib/render-ui": "^4.31.1",
20
20
  "classnames": "^2.2.5",
21
21
  "lodash": "^4.17.10",
22
22
  "prop-types": "^15.6.1",
@@ -25,24 +25,7 @@
25
25
  },
26
26
  "author": "",
27
27
  "license": "ISC",
28
- "gitHead": "d82bdaf60534197ec8675bb5ebba1ad314075e58",
28
+ "gitHead": "edd2d8fc80a70863b9a71dab5fc2caed85175533",
29
29
  "main": "lib/index.js",
30
- "module": "src/index.js",
31
- "exports": {
32
- ".": {
33
- "import": "./esm/element.js",
34
- "require": "./lib/index.js",
35
- "default": "./esm/element.js"
36
- },
37
- "./configure": {
38
- "import": "./esm/configure.js",
39
- "require": "./configure/lib/index.js",
40
- "default": "./esm/configure.js"
41
- },
42
- "./controller": {
43
- "import": "./esm/controller.js",
44
- "require": "./controller/lib/index.js",
45
- "default": "./esm/controller.js"
46
- }
47
- }
30
+ "module": "src/index.js"
48
31
  }