@pie-element/drag-in-the-blank 10.1.4 → 10.1.5

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,14 @@
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
+ ## [10.1.5](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank@10.1.4...@pie-element/drag-in-the-blank@10.1.5) (2026-06-22)
7
+
8
+ ### Bug Fixes
9
+
10
+ - bump shared modules and libs PIE-674, PIE-662, PIE-705, PIE-674, PIE-963 ([78a3f64](https://github.com/pie-framework/pie-elements/commit/78a3f64652c9581c61bd4159f3210fc1e32d8bcf))
11
+ - **drag-in-the-blank:** update onChoiceDone to pass latest value from editor PIE-701 ([40b5dc6](https://github.com/pie-framework/pie-elements/commit/40b5dc6dbdf659db2adcfdfb139c4dd4fa06a2f9))
12
+ - handle webcomponent lifecycle on every element that misses it PIE-703 ([9d5923f](https://github.com/pie-framework/pie-elements/commit/9d5923f973f0471e1e8f69ad4309cfc63d980d93))
13
+
6
14
  ## [10.1.4](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank@10.1.3...@pie-element/drag-in-the-blank@10.1.4) (2026-06-17)
7
15
 
8
16
  ### Bug Fixes
@@ -3,6 +3,14 @@
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
+ ## [9.1.5](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-configure@9.1.4...@pie-element/drag-in-the-blank-configure@9.1.5) (2026-06-22)
7
+
8
+ ### Bug Fixes
9
+
10
+ - bump shared modules and libs PIE-674, PIE-662, PIE-705, PIE-674, PIE-963 ([78a3f64](https://github.com/pie-framework/pie-elements/commit/78a3f64652c9581c61bd4159f3210fc1e32d8bcf))
11
+ - **drag-in-the-blank:** update onChoiceDone to pass latest value from editor PIE-701 ([40b5dc6](https://github.com/pie-framework/pie-elements/commit/40b5dc6dbdf659db2adcfdfb139c4dd4fa06a2f9))
12
+ - handle webcomponent lifecycle on every element that misses it PIE-703 ([9d5923f](https://github.com/pie-framework/pie-elements/commit/9d5923f973f0471e1e8f69ad4309cfc63d980d93))
13
+
6
14
  ## [9.1.4](https://github.com/pie-framework/pie-elements/compare/@pie-element/drag-in-the-blank-configure@9.1.3...@pie-element/drag-in-the-blank-configure@9.1.4) (2026-06-17)
7
15
 
8
16
  ### Bug Fixes
@@ -126,7 +126,7 @@ class Choices extends _react.default.Component {
126
126
  }
127
127
  onChange(newChoices);
128
128
  });
129
- (0, _defineProperty2.default)(this, "onChoiceDone", choiceId => {
129
+ (0, _defineProperty2.default)(this, "onChoiceDone", (choiceId, latestValue) => {
130
130
  const {
131
131
  onChange,
132
132
  model
@@ -135,7 +135,20 @@ class Choices extends _react.default.Component {
135
135
  choices
136
136
  } = model;
137
137
  const currentChoice = (choices || []).find(c => c.id === choiceId);
138
- if (!currentChoice || !(0, _markupUtils.choiceIsEmpty)(currentChoice)) {
138
+
139
+ // model.choices[i].value can be stale when the editor's onChange did not fire for the most recent edit
140
+ // (for example, image uploads). In that case, we want to use the latest value from the editor.
141
+ const effectiveValue = latestValue !== undefined ? latestValue : currentChoice && currentChoice.value;
142
+ if (!currentChoice || !(0, _markupUtils.choiceIsEmpty)({
143
+ value: effectiveValue
144
+ })) {
145
+ if (currentChoice && currentChoice.value !== effectiveValue) {
146
+ const newChoices = (choices || []).map(c => c.id === choiceId ? {
147
+ ...c,
148
+ value: effectiveValue
149
+ } : c);
150
+ onChange(newChoices);
151
+ }
139
152
  this.setState({
140
153
  focusedEl: undefined
141
154
  });
@@ -264,11 +277,11 @@ class Choices extends _react.default.Component {
264
277
  }
265
278
  this.onChoiceChanged(choice.value, val, choice.id);
266
279
  },
267
- onDone: () => {
280
+ onDone: val => {
268
281
  if (this.preventDone) {
269
282
  return;
270
283
  }
271
- this.onChoiceDone(choice.id);
284
+ this.onChoiceDone(choice.id, val);
272
285
  },
273
286
  onBlur: e => {
274
287
  const inInInsertCharacter = e.relatedTarget && e.relatedTarget.closest('.insert-character-dialog');
@@ -1 +1 @@
1
- {"version":3,"file":"choices.js","names":["_react","_interopRequireDefault","require","_propTypes","_editableHtmlTipTap","_configUi","_Button","_styles","_choice","_markupUtils","_mathRendering","StyledDesign","styled","theme","display","flexDirection","marginBottom","spacing","StyledAddButton","Button","marginLeft","StyledAltChoices","alignItems","flexWrap","justifyContent","marginTop","margin","ErrorText","fontSize","typography","color","palette","error","main","paddingBottom","Choices","React","Component","constructor","args","_defineProperty2","default","warning","open","createRef","prevValue","val","key","onChange","model","props","choices","correctResponse","alternateResponses","choiceIsEmpty","value","duplicatedValue","find","c","id","newChoices","filter","setState","text","map","choice","usedForResponse","Object","keys","forEach","responseKey","values","alternate","indexOf","choiceId","currentChoice","focusedEl","undefined","oldChoices","maxId","length","Math","max","parseInt","newId","duplicates","includes","componentDidUpdate","focusedNodeRef","focus","renderMath","wrapperRef","current","render","state","mathMlOptions","maxChoices","toolbarOpts","uploadSoundSupport","imageSupport","pluginProps","maxImageWidth","maxImageHeight","maxLength","visibleChoices","getVisibleChoices","createElement","ref","variant","onClick","onAddChoice","disabled","index","style","minWidth","zIndex","autoFocus","markup","languageCharactersProps","language","preventDone","onChoiceChanged","onDone","onChoiceDone","onBlur","e","inInInsertCharacter","relatedTarget","closest","disableUnderline","charactersLimit","onChoiceFocus","onRemoveChoice","onChoiceRemove","AlertDialog","title","onConfirm","exports","PropTypes","bool","string","object","isRequired","func","number","_default"],"sources":["../src/choices.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport EditableHtml from '@pie-lib/editable-html-tip-tap';\nimport { AlertDialog } from '@pie-lib/config-ui';\nimport Button from '@mui/material/Button';\nimport { styled } from '@mui/material/styles';\n\nimport Choice from './choice';\nimport { choiceIsEmpty } from './markupUtils';\nimport { renderMath } from '@pie-lib/math-rendering';\n\nconst StyledDesign = styled('div')(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n marginBottom: theme.spacing(1.5),\n}));\n\nconst StyledAddButton = styled(Button)({\n marginLeft: 'auto',\n});\n\nconst StyledAltChoices = styled('div')(({ theme }) => ({\n alignItems: 'flex-start',\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-evenly',\n marginTop: theme.spacing(1),\n\n '& > *': {\n margin: theme.spacing(1),\n },\n}));\n\nconst ErrorText = styled('div')(({ theme }) => ({\n fontSize: theme.typography.fontSize - 2,\n color: theme.palette.error.main,\n paddingBottom: theme.spacing(2),\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 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 wrapperRef = React.createRef(null);\n\n componentDidUpdate() {\n if (this.focusedNodeRef) {\n this.focusedNodeRef.focus('end');\n }\n\n renderMath(this.wrapperRef.current);\n }\n\n onChoiceChanged = (prevValue, val, key) => {\n const { onChange, model } = this.props;\n const { choices, correctResponse, alternateResponses } = model;\n\n if (choiceIsEmpty({ value: prevValue }) && choiceIsEmpty({ value: val })) {\n return;\n }\n\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 onChange(newChoices);\n };\n\n onChoiceDone = (choiceId) => {\n const { onChange, model } = this.props;\n const { choices } = model;\n const currentChoice = (choices || []).find((c) => c.id === choiceId);\n\n if (!currentChoice || !choiceIsEmpty(currentChoice)) {\n this.setState({ focusedEl: undefined });\n return;\n }\n\n onChange((choices || []).filter((c) => c.id !== choiceId));\n\n this.setState({\n focusedEl: undefined,\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 ? Math.max(...oldChoices.map((choice) => parseInt(choice.id, 10) || 0)) : -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 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 <StyledDesign ref={this.wrapperRef}>\n <StyledAddButton\n variant=\"contained\"\n color=\"primary\"\n onClick={this.onAddChoice}\n disabled={maxChoices && choices && maxChoices === choices.length}\n >\n Add Choice\n </StyledAddButton>\n\n <StyledAltChoices>\n {visibleChoices.map((choice, index) => {\n if (!choice || !choice.id) {\n return null;\n }\n\n return 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 autoFocus\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.onChoiceDone(choice.id);\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 choice={choice}\n error={error}\n onClick={() => this.onChoiceFocus(choice.id)}\n onRemoveChoice={() => this.onChoiceRemove(choice.id)}\n />\n );\n })}\n </StyledAltChoices>\n {error && <ErrorText>{error}</ErrorText>}\n\n <AlertDialog\n open={warning.open}\n title=\"Warning\"\n text={warning.text}\n onConfirm={() => this.setState({ warning: { open: false } })}\n />\n </StyledDesign>\n );\n }\n}\n\nexport default Choices;\n"],"mappings":";;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,mBAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,OAAA,GAAAL,OAAA;AAEA,IAAAM,OAAA,GAAAP,sBAAA,CAAAC,OAAA;AACA,IAAAO,YAAA,GAAAP,OAAA;AACA,IAAAQ,cAAA,GAAAR,OAAA;AAEA,MAAMS,YAAY,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EACjDC,OAAO,EAAE,MAAM;EACfC,aAAa,EAAE,QAAQ;EACvBC,YAAY,EAAEH,KAAK,CAACI,OAAO,CAAC,GAAG;AACjC,CAAC,CAAC,CAAC;AAEH,MAAMC,eAAe,GAAG,IAAAN,cAAM,EAACO,eAAM,CAAC,CAAC;EACrCC,UAAU,EAAE;AACd,CAAC,CAAC;AAEF,MAAMC,gBAAgB,GAAG,IAAAT,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EACrDS,UAAU,EAAE,YAAY;EACxBR,OAAO,EAAE,MAAM;EACfS,QAAQ,EAAE,MAAM;EAChBC,cAAc,EAAE,cAAc;EAC9BC,SAAS,EAAEZ,KAAK,CAACI,OAAO,CAAC,CAAC,CAAC;EAE3B,OAAO,EAAE;IACPS,MAAM,EAAEb,KAAK,CAACI,OAAO,CAAC,CAAC;EACzB;AACF,CAAC,CAAC,CAAC;AAEH,MAAMU,SAAS,GAAG,IAAAf,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EAC9Ce,QAAQ,EAAEf,KAAK,CAACgB,UAAU,CAACD,QAAQ,GAAG,CAAC;EACvCE,KAAK,EAAEjB,KAAK,CAACkB,OAAO,CAACC,KAAK,CAACC,IAAI;EAC/BC,aAAa,EAAErB,KAAK,CAACI,OAAO,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEI,MAAMkB,OAAO,SAASC,cAAK,CAACC,SAAS,CAAC;EAAAC,YAAA,GAAAC,IAAA;IAAA,SAAAA,IAAA;IAAA,IAAAC,gBAAA,CAAAC,OAAA,iBAenC;MAAEC,OAAO,EAAE;QAAEC,IAAI,EAAE;MAAM;IAAE,CAAC;IAAA,IAAAH,gBAAA,CAAAC,OAAA,uBACtB,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,mCACNL,cAAK,CAACQ,SAAS,CAAC,IAAI,CAAC;IAAA,IAAAJ,gBAAA,CAAAC,OAAA,2BAUhB,CAACI,SAAS,EAAEC,GAAG,EAAEC,GAAG,KAAK;MACzC,MAAM;QAAEC,QAAQ;QAAEC;MAAM,CAAC,GAAG,IAAI,CAACC,KAAK;MACtC,MAAM;QAAEC,OAAO;QAAEC,eAAe;QAAEC;MAAmB,CAAC,GAAGJ,KAAK;MAE9D,IAAI,IAAAK,0BAAa,EAAC;QAAEC,KAAK,EAAEV;MAAU,CAAC,CAAC,IAAI,IAAAS,0BAAa,EAAC;QAAEC,KAAK,EAAET;MAAI,CAAC,CAAC,EAAE;QACxE;MACF;MAEA,MAAMU,eAAe,GAAG,CAACL,OAAO,IAAI,EAAE,EAAEM,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACH,KAAK,KAAKT,GAAG,IAAIY,CAAC,CAACC,EAAE,KAAKZ,GAAG,CAAC;;MAEpF;MACA,IAAIS,eAAe,EAAE;QACnB,IAAIX,SAAS,KAAK,EAAE,EAAE;UACpB;UACA,MAAMe,UAAU,GAAG,CAACT,OAAO,IAAI,EAAE,EAAEU,MAAM,CAAEH,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKZ,GAAG,CAAC;UAE9DC,QAAQ,CAACY,UAAU,CAAC;QACtB;QAEA,IAAI,CAACE,QAAQ,CAAC;UACZpB,OAAO,EAAE;YACPC,IAAI,EAAE,IAAI;YACVoB,IAAI,EAAE;UACR;QACF,CAAC,CAAC;QAEF;MACF;MAEA,MAAMH,UAAU,GAAGT,OAAO,EAAEa,GAAG,CAAEC,MAAM,IAAMA,MAAM,CAACN,EAAE,KAAKZ,GAAG,GAAG;QAAE,GAAGkB,MAAM;QAAEV,KAAK,EAAET;MAAI,CAAC,GAAGmB,MAAO,CAAC,IAAI,EAAE;MAE3G,IAAI,CAAC,IAAAX,0BAAa,EAAC;QAAEC,KAAK,EAAET;MAAI,CAAC,CAAC,EAAE;QAClCE,QAAQ,CAACY,UAAU,CAAC;QAEpB;MACF;;MAEA;MACA,IAAIM,eAAe,GAAG,KAAK;MAE3B,IAAId,eAAe,EAAE;QACnBe,MAAM,CAACC,IAAI,CAAChB,eAAe,CAAC,CAACiB,OAAO,CAAEC,WAAW,IAAK;UACpD,IAAIlB,eAAe,CAACkB,WAAW,CAAC,KAAKvB,GAAG,EAAE;YACxCmB,eAAe,GAAG,IAAI;UACxB;QACF,CAAC,CAAC;MACJ;MAEA,IAAIb,kBAAkB,IAAI,CAACa,eAAe,EAAE;QAC1CC,MAAM,CAACI,MAAM,CAAClB,kBAAkB,CAAC,CAACgB,OAAO,CAAEG,SAAS,IAAK;UACvD,IAAIA,SAAS,CAACC,OAAO,CAAC1B,GAAG,CAAC,IAAI,CAAC,EAAE;YAC/BmB,eAAe,GAAG,IAAI;UACxB;QACF,CAAC,CAAC;MACJ;MAEA,IAAIA,eAAe,EAAE;QACnB,IAAI,CAACJ,QAAQ,CAAC;UACZpB,OAAO,EAAE;YACPC,IAAI,EAAE,IAAI;YACVoB,IAAI,EAAE;UACR;QACF,CAAC,CAAC;QAEF;MACF;MAEAf,QAAQ,CAACY,UAAU,CAAC;IACtB,CAAC;IAAA,IAAApB,gBAAA,CAAAC,OAAA,wBAEeiC,QAAQ,IAAK;MAC3B,MAAM;QAAE1B,QAAQ;QAAEC;MAAM,CAAC,GAAG,IAAI,CAACC,KAAK;MACtC,MAAM;QAAEC;MAAQ,CAAC,GAAGF,KAAK;MACzB,MAAM0B,aAAa,GAAG,CAACxB,OAAO,IAAI,EAAE,EAAEM,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKe,QAAQ,CAAC;MAEpE,IAAI,CAACC,aAAa,IAAI,CAAC,IAAArB,0BAAa,EAACqB,aAAa,CAAC,EAAE;QACnD,IAAI,CAACb,QAAQ,CAAC;UAAEc,SAAS,EAAEC;QAAU,CAAC,CAAC;QACvC;MACF;MAEA7B,QAAQ,CAAC,CAACG,OAAO,IAAI,EAAE,EAAEU,MAAM,CAAEH,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKe,QAAQ,CAAC,CAAC;MAE1D,IAAI,CAACZ,QAAQ,CAAC;QACZc,SAAS,EAAEC,SAAS;QACpBnC,OAAO,EAAE;UACPC,IAAI,EAAE,IAAI;UACVoB,IAAI,EAAE;QACR;MACF,CAAC,CAAC;IACJ,CAAC;IAAA,IAAAvB,gBAAA,CAAAC,OAAA,yBAEgBkB,EAAE,IACjB,IAAI,CAACG,QAAQ,CAAC;MACZc,SAAS,EAAEjB;IACb,CAAC,CAAC;IAAA,IAAAnB,gBAAA,CAAAC,OAAA,uBAEU,MAAM;MAClB,MAAM;QACJQ,KAAK,EAAE;UAAEE,OAAO,EAAE2B;QAAW,CAAC;QAC9B9B;MACF,CAAC,GAAG,IAAI,CAACE,KAAK;;MAEd;MACA,MAAM6B,KAAK,GAAGD,UAAU,CAACE,MAAM,GAAG,CAAC,GAAGC,IAAI,CAACC,GAAG,CAAC,GAAGJ,UAAU,CAACd,GAAG,CAAEC,MAAM,IAAKkB,QAAQ,CAAClB,MAAM,CAACN,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;MAChH,MAAMyB,KAAK,GAAG,GAAGL,KAAK,GAAG,CAAC,EAAE;MAE5B,IAAI,CAACjB,QAAQ,CACX;QACEc,SAAS,EAAEQ;MACb,CAAC,EACD,MAAM;QACJpC,QAAQ,CAAC,CACP,GAAG8B,UAAU,EACb;UACEnB,EAAE,EAAEyB,KAAK;UACT7B,KAAK,EAAE;QACT,CAAC,CACF,CAAC;MACJ,CACF,CAAC;IACH,CAAC;IAAA,IAAAf,gBAAA,CAAAC,OAAA,0BAEiBkB,EAAE,IAAK;MACvB,MAAM;QACJX,QAAQ;QACRC,KAAK,EAAE;UAAEE;QAAQ;MACnB,CAAC,GAAG,IAAI,CAACD,KAAK;MACd,MAAMU,UAAU,GAAG,CAACT,OAAO,IAAI,EAAE,EAAEU,MAAM,CAAEI,MAAM,IAAKA,MAAM,CAACN,EAAE,KAAKA,EAAE,CAAC;MAEvEX,QAAQ,CAACY,UAAU,CAAC;IACtB,CAAC;IAAA,IAAApB,gBAAA,CAAAC,OAAA,6BAEmB,MAAM;MACxB,MAAM;QACJ4C,UAAU;QACVpC,KAAK,EAAE;UAAEE,OAAO;UAAEC;QAAgB;MACpC,CAAC,GAAG,IAAI,CAACF,KAAK;MAEd,IAAI,CAACC,OAAO,EAAE;QACZ,OAAO,EAAE;MACX;MAEA,IAAIkC,UAAU,EAAE;QACd,OAAOlC,OAAO;MAChB;;MAEA;MACA,OAAOA,OAAO,CAACU,MAAM,CAAEI,MAAM,IAAK,EAAEb,eAAe,IAAIe,MAAM,CAACI,MAAM,CAACnB,eAAe,CAAC,CAACkC,QAAQ,CAACrB,MAAM,CAACN,EAAE,CAAC,CAAC,CAAC;IAC7G,CAAC;EAAA;EA5JD4B,kBAAkBA,CAAA,EAAG;IACnB,IAAI,IAAI,CAACC,cAAc,EAAE;MACvB,IAAI,CAACA,cAAc,CAACC,KAAK,CAAC,KAAK,CAAC;IAClC;IAEA,IAAAC,yBAAU,EAAC,IAAI,CAACC,UAAU,CAACC,OAAO,CAAC;EACrC;EAwJAC,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEjB,SAAS;MAAElC;IAAQ,CAAC,GAAG,IAAI,CAACoD,KAAK;IACzC,MAAM;MACJT,UAAU;MACVrD,KAAK;MACL+D,aAAa,GAAG,CAAC,CAAC;MAClBC,UAAU;MACV/C,KAAK,EAAE;QAAEE;MAAQ,CAAC;MAClB8C,WAAW;MACXC,kBAAkB;MAClBC,YAAY,GAAG,CAAC,CAAC;MACjBC,WAAW,GAAG,CAAC,CAAC;MAChBC,aAAa;MACbC,cAAc;MACdC;IACF,CAAC,GAAG,IAAI,CAACrD,KAAK;IACd,MAAMsD,cAAc,GAAG,IAAI,CAACC,iBAAiB,CAAC,CAAC,IAAI,EAAE;IACrD,oBACEzG,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAAC/F,YAAY;MAACgG,GAAG,EAAE,IAAI,CAAChB;IAAW,gBACjC3F,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAACxF,eAAe;MACd0F,OAAO,EAAC,WAAW;MACnB9E,KAAK,EAAC,SAAS;MACf+E,OAAO,EAAE,IAAI,CAACC,WAAY;MAC1BC,QAAQ,EAAEf,UAAU,IAAI7C,OAAO,IAAI6C,UAAU,KAAK7C,OAAO,CAAC6B;IAAO,GAClE,YAEgB,CAAC,eAElBhF,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAACrF,gBAAgB,QACdmF,cAAc,CAACxC,GAAG,CAAC,CAACC,MAAM,EAAE+C,KAAK,KAAK;MACrC,IAAI,CAAC/C,MAAM,IAAI,CAACA,MAAM,CAACN,EAAE,EAAE;QACzB,OAAO,IAAI;MACb;MAEA,OAAOiB,SAAS,KAAKX,MAAM,CAACN,EAAE,gBAC5B3D,MAAA,CAAAyC,OAAA,CAAAiE,aAAA;QACE3D,GAAG,EAAEiE,KAAM;QACXC,KAAK,EAAE;UACLC,QAAQ,EAAE,MAAM;UAChBC,MAAM,EAAE;QACV;MAAE,gBAEFnH,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAACtG,mBAAA,CAAAqC,OAAY;QACXkE,GAAG,EAAGA,GAAG,IAAM,IAAI,CAACnB,cAAc,GAAGmB,GAAK;QAC1CS,SAAS;QACTjB,YAAY,EAAEA,YAAa;QAC3BkB,MAAM,EAAEpD,MAAM,CAACV,KAAM;QACrB6C,WAAW,EAAEA,WAAY;QACzBkB,uBAAuB,EAAE,CAAC;UAAEC,QAAQ,EAAE;QAAU,CAAC,EAAE;UAAEA,QAAQ,EAAE;QAAU,CAAC,CAAE;QAC5EvE,QAAQ,EAAGF,GAAG,IAAK;UACjB,IAAI,IAAI,CAAC0E,WAAW,EAAE;YACpB;UACF;UAEA,IAAI,CAACC,eAAe,CAACxD,MAAM,CAACV,KAAK,EAAET,GAAG,EAAEmB,MAAM,CAACN,EAAE,CAAC;QACpD,CAAE;QACF+D,MAAM,EAAEA,CAAA,KAAM;UACZ,IAAI,IAAI,CAACF,WAAW,EAAE;YACpB;UACF;UAEA,IAAI,CAACG,YAAY,CAAC1D,MAAM,CAACN,EAAE,CAAC;QAC9B,CAAE;QACFiE,MAAM,EAAGC,CAAC,IAAK;UACb,MAAMC,mBAAmB,GAAGD,CAAC,CAACE,aAAa,IAAIF,CAAC,CAACE,aAAa,CAACC,OAAO,CAAC,0BAA0B,CAAC;UAElG,IAAI,CAACR,WAAW,GAAGM,mBAAmB;QACxC,CAAE;QACFG,gBAAgB;QAChBhC,WAAW,EAAEA,WAAY;QACzBC,kBAAkB,EAAEA,kBAAmB;QACvCH,aAAa,EAAEA,aAAc;QAC7BO,cAAc,EAAEA,cAAe;QAC/BD,aAAa,EAAEA,aAAc;QAC7B6B,eAAe,EAAE3B;MAAU,CAC5B,CACE,CAAC,gBAENvG,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAAClG,OAAA,CAAAiC,OAAM;QACLM,GAAG,EAAEiE,KAAM;QACX3B,UAAU,EAAEA,UAAW;QACvBpB,MAAM,EAAEA,MAAO;QACfjC,KAAK,EAAEA,KAAM;QACb6E,OAAO,EAAEA,CAAA,KAAM,IAAI,CAACsB,aAAa,CAAClE,MAAM,CAACN,EAAE,CAAE;QAC7CyE,cAAc,EAAEA,CAAA,KAAM,IAAI,CAACC,cAAc,CAACpE,MAAM,CAACN,EAAE;MAAE,CACtD,CACF;IACH,CAAC,CACe,CAAC,EAClB3B,KAAK,iBAAIhC,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAAC/E,SAAS,QAAEK,KAAiB,CAAC,eAExChC,MAAA,CAAAyC,OAAA,CAAAiE,aAAA,CAACrG,SAAA,CAAAiI,WAAW;MACV3F,IAAI,EAAED,OAAO,CAACC,IAAK;MACnB4F,KAAK,EAAC,SAAS;MACfxE,IAAI,EAAErB,OAAO,CAACqB,IAAK;MACnByE,SAAS,EAAEA,CAAA,KAAM,IAAI,CAAC1E,QAAQ,CAAC;QAAEpB,OAAO,EAAE;UAAEC,IAAI,EAAE;QAAM;MAAE,CAAC;IAAE,CAC9D,CACW,CAAC;EAEnB;AACF;AAAC8F,OAAA,CAAAtG,OAAA,GAAAA,OAAA;AAAA,IAAAK,gBAAA,CAAAC,OAAA,EArRYN,OAAO,eACC;EACjBkD,UAAU,EAAEqD,kBAAS,CAACC,IAAI;EAC1B3G,KAAK,EAAE0G,kBAAS,CAACE,MAAM;EACvB3F,KAAK,EAAEyF,kBAAS,CAACG,MAAM,CAACC,UAAU;EAClC9F,QAAQ,EAAE0F,kBAAS,CAACK,IAAI,CAACD,UAAU;EACnC7C,WAAW,EAAEyC,kBAAS,CAACG,MAAM;EAC7BzC,WAAW,EAAEsC,kBAAS,CAACG,MAAM;EAC7B7C,UAAU,EAAE0C,kBAAS,CAACM,MAAM;EAC5B9C,kBAAkB,EAAEwC,kBAAS,CAACG,MAAM;EACpCxC,aAAa,EAAEqC,kBAAS,CAACM,MAAM;EAC/B1C,cAAc,EAAEoC,kBAAS,CAACM,MAAM;EAChCzC,SAAS,EAAEmC,kBAAS,CAACM;AACvB,CAAC;AAAA,IAAAC,QAAA,GAAAR,OAAA,CAAAhG,OAAA,GA0QYN,OAAO","ignoreList":[]}
1
+ {"version":3,"file":"choices.js","names":["_react","_interopRequireDefault","require","_propTypes","_editableHtmlTipTap","_configUi","_Button","_styles","_choice","_markupUtils","_mathRendering","StyledDesign","styled","theme","display","flexDirection","marginBottom","spacing","StyledAddButton","Button","marginLeft","StyledAltChoices","alignItems","flexWrap","justifyContent","marginTop","margin","ErrorText","fontSize","typography","color","palette","error","main","paddingBottom","Choices","React","Component","constructor","args","_defineProperty2","default","warning","open","createRef","prevValue","val","key","onChange","model","props","choices","correctResponse","alternateResponses","choiceIsEmpty","value","duplicatedValue","find","c","id","newChoices","filter","setState","text","map","choice","usedForResponse","Object","keys","forEach","responseKey","values","alternate","indexOf","choiceId","latestValue","currentChoice","effectiveValue","undefined","focusedEl","oldChoices","maxId","length","Math","max","parseInt","newId","duplicates","includes","componentDidUpdate","focusedNodeRef","focus","renderMath","wrapperRef","current","render","state","mathMlOptions","maxChoices","toolbarOpts","uploadSoundSupport","imageSupport","pluginProps","maxImageWidth","maxImageHeight","maxLength","visibleChoices","getVisibleChoices","createElement","ref","variant","onClick","onAddChoice","disabled","index","style","minWidth","zIndex","autoFocus","markup","languageCharactersProps","language","preventDone","onChoiceChanged","onDone","onChoiceDone","onBlur","e","inInInsertCharacter","relatedTarget","closest","disableUnderline","charactersLimit","onChoiceFocus","onRemoveChoice","onChoiceRemove","AlertDialog","title","onConfirm","exports","PropTypes","bool","string","object","isRequired","func","number","_default"],"sources":["../src/choices.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport EditableHtml from '@pie-lib/editable-html-tip-tap';\nimport { AlertDialog } from '@pie-lib/config-ui';\nimport Button from '@mui/material/Button';\nimport { styled } from '@mui/material/styles';\n\nimport Choice from './choice';\nimport { choiceIsEmpty } from './markupUtils';\nimport { renderMath } from '@pie-lib/math-rendering';\n\nconst StyledDesign = styled('div')(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n marginBottom: theme.spacing(1.5),\n}));\n\nconst StyledAddButton = styled(Button)({\n marginLeft: 'auto',\n});\n\nconst StyledAltChoices = styled('div')(({ theme }) => ({\n alignItems: 'flex-start',\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-evenly',\n marginTop: theme.spacing(1),\n\n '& > *': {\n margin: theme.spacing(1),\n },\n}));\n\nconst ErrorText = styled('div')(({ theme }) => ({\n fontSize: theme.typography.fontSize - 2,\n color: theme.palette.error.main,\n paddingBottom: theme.spacing(2),\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 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 wrapperRef = React.createRef(null);\n\n componentDidUpdate() {\n if (this.focusedNodeRef) {\n this.focusedNodeRef.focus('end');\n }\n\n renderMath(this.wrapperRef.current);\n }\n\n onChoiceChanged = (prevValue, val, key) => {\n const { onChange, model } = this.props;\n const { choices, correctResponse, alternateResponses } = model;\n\n if (choiceIsEmpty({ value: prevValue }) && choiceIsEmpty({ value: val })) {\n return;\n }\n\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 onChange(newChoices);\n };\n\n onChoiceDone = (choiceId, latestValue) => {\n const { onChange, model } = this.props;\n const { choices } = model;\n const currentChoice = (choices || []).find((c) => c.id === choiceId);\n\n // model.choices[i].value can be stale when the editor's onChange did not fire for the most recent edit \n // (for example, image uploads). In that case, we want to use the latest value from the editor.\n const effectiveValue = latestValue !== undefined ? latestValue : currentChoice && currentChoice.value;\n\n if (!currentChoice || !choiceIsEmpty({ value: effectiveValue })) {\n if (currentChoice && currentChoice.value !== effectiveValue) {\n const newChoices = (choices || []).map((c) => (c.id === choiceId ? { ...c, value: effectiveValue } : c));\n onChange(newChoices);\n }\n this.setState({ focusedEl: undefined });\n return;\n }\n\n onChange((choices || []).filter((c) => c.id !== choiceId));\n\n this.setState({\n focusedEl: undefined,\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 ? Math.max(...oldChoices.map((choice) => parseInt(choice.id, 10) || 0)) : -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 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 <StyledDesign ref={this.wrapperRef}>\n <StyledAddButton\n variant=\"contained\"\n color=\"primary\"\n onClick={this.onAddChoice}\n disabled={maxChoices && choices && maxChoices === choices.length}\n >\n Add Choice\n </StyledAddButton>\n\n <StyledAltChoices>\n {visibleChoices.map((choice, index) => {\n if (!choice || !choice.id) {\n return null;\n }\n\n return 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 autoFocus\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={(val) => {\n if (this.preventDone) {\n return;\n }\n\n this.onChoiceDone(choice.id, val);\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 choice={choice}\n error={error}\n onClick={() => this.onChoiceFocus(choice.id)}\n onRemoveChoice={() => this.onChoiceRemove(choice.id)}\n />\n );\n })}\n </StyledAltChoices>\n {error && <ErrorText>{error}</ErrorText>}\n\n <AlertDialog\n open={warning.open}\n title=\"Warning\"\n text={warning.text}\n onConfirm={() => this.setState({ warning: { open: false } })}\n />\n </StyledDesign>\n );\n }\n}\n\nexport default Choices;\n"],"mappings":";;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,mBAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,OAAA,GAAAL,OAAA;AAEA,IAAAM,OAAA,GAAAP,sBAAA,CAAAC,OAAA;AACA,IAAAO,YAAA,GAAAP,OAAA;AACA,IAAAQ,cAAA,GAAAR,OAAA;AAEA,MAAMS,YAAY,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EACjDC,OAAO,EAAE,MAAM;EACfC,aAAa,EAAE,QAAQ;EACvBC,YAAY,EAAEH,KAAK,CAACI,OAAO,CAAC,GAAG;AACjC,CAAC,CAAC,CAAC;AAEH,MAAMC,eAAe,GAAG,IAAAN,cAAM,EAACO,eAAM,CAAC,CAAC;EACrCC,UAAU,EAAE;AACd,CAAC,CAAC;AAEF,MAAMC,gBAAgB,GAAG,IAAAT,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EACrDS,UAAU,EAAE,YAAY;EACxBR,OAAO,EAAE,MAAM;EACfS,QAAQ,EAAE,MAAM;EAChBC,cAAc,EAAE,cAAc;EAC9BC,SAAS,EAAEZ,KAAK,CAACI,OAAO,CAAC,CAAC,CAAC;EAE3B,OAAO,EAAE;IACPS,MAAM,EAAEb,KAAK,CAACI,OAAO,CAAC,CAAC;EACzB;AACF,CAAC,CAAC,CAAC;AAEH,MAAMU,SAAS,GAAG,IAAAf,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EAC9Ce,QAAQ,EAAEf,KAAK,CAACgB,UAAU,CAACD,QAAQ,GAAG,CAAC;EACvCE,KAAK,EAAEjB,KAAK,CAACkB,OAAO,CAACC,KAAK,CAACC,IAAI;EAC/BC,aAAa,EAAErB,KAAK,CAACI,OAAO,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEI,MAAMkB,OAAO,SAASC,cAAK,CAACC,SAAS,CAAC;EAAAC,YAAA,GAAAC,IAAA;IAAA,SAAAA,IAAA;IAAA,IAAAC,gBAAA,CAAAC,OAAA,iBAenC;MAAEC,OAAO,EAAE;QAAEC,IAAI,EAAE;MAAM;IAAE,CAAC;IAAA,IAAAH,gBAAA,CAAAC,OAAA,uBACtB,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,mCACNL,cAAK,CAACQ,SAAS,CAAC,IAAI,CAAC;IAAA,IAAAJ,gBAAA,CAAAC,OAAA,2BAUhB,CAACI,SAAS,EAAEC,GAAG,EAAEC,GAAG,KAAK;MACzC,MAAM;QAAEC,QAAQ;QAAEC;MAAM,CAAC,GAAG,IAAI,CAACC,KAAK;MACtC,MAAM;QAAEC,OAAO;QAAEC,eAAe;QAAEC;MAAmB,CAAC,GAAGJ,KAAK;MAE9D,IAAI,IAAAK,0BAAa,EAAC;QAAEC,KAAK,EAAEV;MAAU,CAAC,CAAC,IAAI,IAAAS,0BAAa,EAAC;QAAEC,KAAK,EAAET;MAAI,CAAC,CAAC,EAAE;QACxE;MACF;MAEA,MAAMU,eAAe,GAAG,CAACL,OAAO,IAAI,EAAE,EAAEM,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACH,KAAK,KAAKT,GAAG,IAAIY,CAAC,CAACC,EAAE,KAAKZ,GAAG,CAAC;;MAEpF;MACA,IAAIS,eAAe,EAAE;QACnB,IAAIX,SAAS,KAAK,EAAE,EAAE;UACpB;UACA,MAAMe,UAAU,GAAG,CAACT,OAAO,IAAI,EAAE,EAAEU,MAAM,CAAEH,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKZ,GAAG,CAAC;UAE9DC,QAAQ,CAACY,UAAU,CAAC;QACtB;QAEA,IAAI,CAACE,QAAQ,CAAC;UACZpB,OAAO,EAAE;YACPC,IAAI,EAAE,IAAI;YACVoB,IAAI,EAAE;UACR;QACF,CAAC,CAAC;QAEF;MACF;MAEA,MAAMH,UAAU,GAAGT,OAAO,EAAEa,GAAG,CAAEC,MAAM,IAAMA,MAAM,CAACN,EAAE,KAAKZ,GAAG,GAAG;QAAE,GAAGkB,MAAM;QAAEV,KAAK,EAAET;MAAI,CAAC,GAAGmB,MAAO,CAAC,IAAI,EAAE;MAE3G,IAAI,CAAC,IAAAX,0BAAa,EAAC;QAAEC,KAAK,EAAET;MAAI,CAAC,CAAC,EAAE;QAClCE,QAAQ,CAACY,UAAU,CAAC;QAEpB;MACF;;MAEA;MACA,IAAIM,eAAe,GAAG,KAAK;MAE3B,IAAId,eAAe,EAAE;QACnBe,MAAM,CAACC,IAAI,CAAChB,eAAe,CAAC,CAACiB,OAAO,CAAEC,WAAW,IAAK;UACpD,IAAIlB,eAAe,CAACkB,WAAW,CAAC,KAAKvB,GAAG,EAAE;YACxCmB,eAAe,GAAG,IAAI;UACxB;QACF,CAAC,CAAC;MACJ;MAEA,IAAIb,kBAAkB,IAAI,CAACa,eAAe,EAAE;QAC1CC,MAAM,CAACI,MAAM,CAAClB,kBAAkB,CAAC,CAACgB,OAAO,CAAEG,SAAS,IAAK;UACvD,IAAIA,SAAS,CAACC,OAAO,CAAC1B,GAAG,CAAC,IAAI,CAAC,EAAE;YAC/BmB,eAAe,GAAG,IAAI;UACxB;QACF,CAAC,CAAC;MACJ;MAEA,IAAIA,eAAe,EAAE;QACnB,IAAI,CAACJ,QAAQ,CAAC;UACZpB,OAAO,EAAE;YACPC,IAAI,EAAE,IAAI;YACVoB,IAAI,EAAE;UACR;QACF,CAAC,CAAC;QAEF;MACF;MAEAf,QAAQ,CAACY,UAAU,CAAC;IACtB,CAAC;IAAA,IAAApB,gBAAA,CAAAC,OAAA,wBAEc,CAACiC,QAAQ,EAAEC,WAAW,KAAK;MACxC,MAAM;QAAE3B,QAAQ;QAAEC;MAAM,CAAC,GAAG,IAAI,CAACC,KAAK;MACtC,MAAM;QAAEC;MAAQ,CAAC,GAAGF,KAAK;MACzB,MAAM2B,aAAa,GAAG,CAACzB,OAAO,IAAI,EAAE,EAAEM,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKe,QAAQ,CAAC;;MAEpE;MACA;MACA,MAAMG,cAAc,GAAGF,WAAW,KAAKG,SAAS,GAAGH,WAAW,GAAGC,aAAa,IAAIA,aAAa,CAACrB,KAAK;MAErG,IAAI,CAACqB,aAAa,IAAI,CAAC,IAAAtB,0BAAa,EAAC;QAAEC,KAAK,EAAEsB;MAAe,CAAC,CAAC,EAAE;QAC/D,IAAID,aAAa,IAAIA,aAAa,CAACrB,KAAK,KAAKsB,cAAc,EAAE;UAC3D,MAAMjB,UAAU,GAAG,CAACT,OAAO,IAAI,EAAE,EAAEa,GAAG,CAAEN,CAAC,IAAMA,CAAC,CAACC,EAAE,KAAKe,QAAQ,GAAG;YAAE,GAAGhB,CAAC;YAAEH,KAAK,EAAEsB;UAAe,CAAC,GAAGnB,CAAE,CAAC;UACxGV,QAAQ,CAACY,UAAU,CAAC;QACtB;QACA,IAAI,CAACE,QAAQ,CAAC;UAAEiB,SAAS,EAAED;QAAU,CAAC,CAAC;QACvC;MACF;MAEA9B,QAAQ,CAAC,CAACG,OAAO,IAAI,EAAE,EAAEU,MAAM,CAAEH,CAAC,IAAKA,CAAC,CAACC,EAAE,KAAKe,QAAQ,CAAC,CAAC;MAE1D,IAAI,CAACZ,QAAQ,CAAC;QACZiB,SAAS,EAAED,SAAS;QACpBpC,OAAO,EAAE;UACPC,IAAI,EAAE,IAAI;UACVoB,IAAI,EAAE;QACR;MACF,CAAC,CAAC;IACJ,CAAC;IAAA,IAAAvB,gBAAA,CAAAC,OAAA,yBAEgBkB,EAAE,IACjB,IAAI,CAACG,QAAQ,CAAC;MACZiB,SAAS,EAAEpB;IACb,CAAC,CAAC;IAAA,IAAAnB,gBAAA,CAAAC,OAAA,uBAEU,MAAM;MAClB,MAAM;QACJQ,KAAK,EAAE;UAAEE,OAAO,EAAE6B;QAAW,CAAC;QAC9BhC;MACF,CAAC,GAAG,IAAI,CAACE,KAAK;;MAEd;MACA,MAAM+B,KAAK,GAAGD,UAAU,CAACE,MAAM,GAAG,CAAC,GAAGC,IAAI,CAACC,GAAG,CAAC,GAAGJ,UAAU,CAAChB,GAAG,CAAEC,MAAM,IAAKoB,QAAQ,CAACpB,MAAM,CAACN,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;MAChH,MAAM2B,KAAK,GAAG,GAAGL,KAAK,GAAG,CAAC,EAAE;MAE5B,IAAI,CAACnB,QAAQ,CACX;QACEiB,SAAS,EAAEO;MACb,CAAC,EACD,MAAM;QACJtC,QAAQ,CAAC,CACP,GAAGgC,UAAU,EACb;UACErB,EAAE,EAAE2B,KAAK;UACT/B,KAAK,EAAE;QACT,CAAC,CACF,CAAC;MACJ,CACF,CAAC;IACH,CAAC;IAAA,IAAAf,gBAAA,CAAAC,OAAA,0BAEiBkB,EAAE,IAAK;MACvB,MAAM;QACJX,QAAQ;QACRC,KAAK,EAAE;UAAEE;QAAQ;MACnB,CAAC,GAAG,IAAI,CAACD,KAAK;MACd,MAAMU,UAAU,GAAG,CAACT,OAAO,IAAI,EAAE,EAAEU,MAAM,CAAEI,MAAM,IAAKA,MAAM,CAACN,EAAE,KAAKA,EAAE,CAAC;MAEvEX,QAAQ,CAACY,UAAU,CAAC;IACtB,CAAC;IAAA,IAAApB,gBAAA,CAAAC,OAAA,6BAEmB,MAAM;MACxB,MAAM;QACJ8C,UAAU;QACVtC,KAAK,EAAE;UAAEE,OAAO;UAAEC;QAAgB;MACpC,CAAC,GAAG,IAAI,CAACF,KAAK;MAEd,IAAI,CAACC,OAAO,EAAE;QACZ,OAAO,EAAE;MACX;MAEA,IAAIoC,UAAU,EAAE;QACd,OAAOpC,OAAO;MAChB;;MAEA;MACA,OAAOA,OAAO,CAACU,MAAM,CAAEI,MAAM,IAAK,EAAEb,eAAe,IAAIe,MAAM,CAACI,MAAM,CAACnB,eAAe,CAAC,CAACoC,QAAQ,CAACvB,MAAM,CAACN,EAAE,CAAC,CAAC,CAAC;IAC7G,CAAC;EAAA;EApKD8B,kBAAkBA,CAAA,EAAG;IACnB,IAAI,IAAI,CAACC,cAAc,EAAE;MACvB,IAAI,CAACA,cAAc,CAACC,KAAK,CAAC,KAAK,CAAC;IAClC;IAEA,IAAAC,yBAAU,EAAC,IAAI,CAACC,UAAU,CAACC,OAAO,CAAC;EACrC;EAgKAC,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEhB,SAAS;MAAErC;IAAQ,CAAC,GAAG,IAAI,CAACsD,KAAK;IACzC,MAAM;MACJT,UAAU;MACVvD,KAAK;MACLiE,aAAa,GAAG,CAAC,CAAC;MAClBC,UAAU;MACVjD,KAAK,EAAE;QAAEE;MAAQ,CAAC;MAClBgD,WAAW;MACXC,kBAAkB;MAClBC,YAAY,GAAG,CAAC,CAAC;MACjBC,WAAW,GAAG,CAAC,CAAC;MAChBC,aAAa;MACbC,cAAc;MACdC;IACF,CAAC,GAAG,IAAI,CAACvD,KAAK;IACd,MAAMwD,cAAc,GAAG,IAAI,CAACC,iBAAiB,CAAC,CAAC,IAAI,EAAE;IACrD,oBACE3G,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAACjG,YAAY;MAACkG,GAAG,EAAE,IAAI,CAAChB;IAAW,gBACjC7F,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAAC1F,eAAe;MACd4F,OAAO,EAAC,WAAW;MACnBhF,KAAK,EAAC,SAAS;MACfiF,OAAO,EAAE,IAAI,CAACC,WAAY;MAC1BC,QAAQ,EAAEf,UAAU,IAAI/C,OAAO,IAAI+C,UAAU,KAAK/C,OAAO,CAAC+B;IAAO,GAClE,YAEgB,CAAC,eAElBlF,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAACvF,gBAAgB,QACdqF,cAAc,CAAC1C,GAAG,CAAC,CAACC,MAAM,EAAEiD,KAAK,KAAK;MACrC,IAAI,CAACjD,MAAM,IAAI,CAACA,MAAM,CAACN,EAAE,EAAE;QACzB,OAAO,IAAI;MACb;MAEA,OAAOoB,SAAS,KAAKd,MAAM,CAACN,EAAE,gBAC5B3D,MAAA,CAAAyC,OAAA,CAAAmE,aAAA;QACE7D,GAAG,EAAEmE,KAAM;QACXC,KAAK,EAAE;UACLC,QAAQ,EAAE,MAAM;UAChBC,MAAM,EAAE;QACV;MAAE,gBAEFrH,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAACxG,mBAAA,CAAAqC,OAAY;QACXoE,GAAG,EAAGA,GAAG,IAAM,IAAI,CAACnB,cAAc,GAAGmB,GAAK;QAC1CS,SAAS;QACTjB,YAAY,EAAEA,YAAa;QAC3BkB,MAAM,EAAEtD,MAAM,CAACV,KAAM;QACrB+C,WAAW,EAAEA,WAAY;QACzBkB,uBAAuB,EAAE,CAAC;UAAEC,QAAQ,EAAE;QAAU,CAAC,EAAE;UAAEA,QAAQ,EAAE;QAAU,CAAC,CAAE;QAC5EzE,QAAQ,EAAGF,GAAG,IAAK;UACjB,IAAI,IAAI,CAAC4E,WAAW,EAAE;YACpB;UACF;UAEA,IAAI,CAACC,eAAe,CAAC1D,MAAM,CAACV,KAAK,EAAET,GAAG,EAAEmB,MAAM,CAACN,EAAE,CAAC;QACpD,CAAE;QACFiE,MAAM,EAAG9E,GAAG,IAAK;UACf,IAAI,IAAI,CAAC4E,WAAW,EAAE;YACpB;UACF;UAEA,IAAI,CAACG,YAAY,CAAC5D,MAAM,CAACN,EAAE,EAAEb,GAAG,CAAC;QACnC,CAAE;QACFgF,MAAM,EAAGC,CAAC,IAAK;UACb,MAAMC,mBAAmB,GAAGD,CAAC,CAACE,aAAa,IAAIF,CAAC,CAACE,aAAa,CAACC,OAAO,CAAC,0BAA0B,CAAC;UAElG,IAAI,CAACR,WAAW,GAAGM,mBAAmB;QACxC,CAAE;QACFG,gBAAgB;QAChBhC,WAAW,EAAEA,WAAY;QACzBC,kBAAkB,EAAEA,kBAAmB;QACvCH,aAAa,EAAEA,aAAc;QAC7BO,cAAc,EAAEA,cAAe;QAC/BD,aAAa,EAAEA,aAAc;QAC7B6B,eAAe,EAAE3B;MAAU,CAC5B,CACE,CAAC,gBAENzG,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAACpG,OAAA,CAAAiC,OAAM;QACLM,GAAG,EAAEmE,KAAM;QACX3B,UAAU,EAAEA,UAAW;QACvBtB,MAAM,EAAEA,MAAO;QACfjC,KAAK,EAAEA,KAAM;QACb+E,OAAO,EAAEA,CAAA,KAAM,IAAI,CAACsB,aAAa,CAACpE,MAAM,CAACN,EAAE,CAAE;QAC7C2E,cAAc,EAAEA,CAAA,KAAM,IAAI,CAACC,cAAc,CAACtE,MAAM,CAACN,EAAE;MAAE,CACtD,CACF;IACH,CAAC,CACe,CAAC,EAClB3B,KAAK,iBAAIhC,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAACjF,SAAS,QAAEK,KAAiB,CAAC,eAExChC,MAAA,CAAAyC,OAAA,CAAAmE,aAAA,CAACvG,SAAA,CAAAmI,WAAW;MACV7F,IAAI,EAAED,OAAO,CAACC,IAAK;MACnB8F,KAAK,EAAC,SAAS;MACf1E,IAAI,EAAErB,OAAO,CAACqB,IAAK;MACnB2E,SAAS,EAAEA,CAAA,KAAM,IAAI,CAAC5E,QAAQ,CAAC;QAAEpB,OAAO,EAAE;UAAEC,IAAI,EAAE;QAAM;MAAE,CAAC;IAAE,CAC9D,CACW,CAAC;EAEnB;AACF;AAACgG,OAAA,CAAAxG,OAAA,GAAAA,OAAA;AAAA,IAAAK,gBAAA,CAAAC,OAAA,EA7RYN,OAAO,eACC;EACjBoD,UAAU,EAAEqD,kBAAS,CAACC,IAAI;EAC1B7G,KAAK,EAAE4G,kBAAS,CAACE,MAAM;EACvB7F,KAAK,EAAE2F,kBAAS,CAACG,MAAM,CAACC,UAAU;EAClChG,QAAQ,EAAE4F,kBAAS,CAACK,IAAI,CAACD,UAAU;EACnC7C,WAAW,EAAEyC,kBAAS,CAACG,MAAM;EAC7BzC,WAAW,EAAEsC,kBAAS,CAACG,MAAM;EAC7B7C,UAAU,EAAE0C,kBAAS,CAACM,MAAM;EAC5B9C,kBAAkB,EAAEwC,kBAAS,CAACG,MAAM;EACpCxC,aAAa,EAAEqC,kBAAS,CAACM,MAAM;EAC/B1C,cAAc,EAAEoC,kBAAS,CAACM,MAAM;EAChCzC,SAAS,EAAEmC,kBAAS,CAACM;AACvB,CAAC;AAAA,IAAAC,QAAA,GAAAR,OAAA,CAAAlG,OAAA,GAkRYN,OAAO","ignoreList":[]}
@@ -120,9 +120,13 @@ class DragInTheBlank extends HTMLElement {
120
120
  (0, _mathRendering.renderMath)(this);
121
121
  }, 0);
122
122
  }
123
+ connectedCallback() {
124
+ this._render();
125
+ }
123
126
  disconnectedCallback() {
124
127
  if (this._root) {
125
128
  this._root.unmount();
129
+ this._root = null;
126
130
  }
127
131
  }
128
132
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_pieConfigureEvents","require","_react","_interopRequireDefault","_client","_mathRendering","_main","_debug","_lodashEs","_defaults","_markupUtils","log","debug","DragInTheBlank","HTMLElement","constructor","_root","_model","prepareModel","_configuration","sensibleDefaults","configuration","onModelChanged","bind","onConfigurationChanged","model","m","formModel","markup","_render","c","newConfiguration","defaults","language","enabled","languageChoices","options","length","value","settings","find","option","push","label","disableSidePanel","s","_disableSidePanel","dispatchModelUpdated","reset","resetValue","dispatchEvent","ModelUpdatedEvent","insertImage","handler","InsertImageEvent","onDeleteImage","src","done","DeleteImageEvent","insertSound","InsertSoundEvent","onDeleteSound","DeleteSoundEvent","element","React","createElement","Main","imageSupport","add","delete","uploadSoundSupport","createRoot","render","setTimeout","renderMath","disconnectedCallback","unmount","exports","default","_defineProperty2","joinedObj","slateMarkup","createSlateMarkup","choices","correctResponse","processedMarkup","processMarkup"],"sources":["../src/index.js"],"sourcesContent":["import {\n ModelUpdatedEvent,\n DeleteImageEvent,\n InsertImageEvent,\n InsertSoundEvent,\n DeleteSoundEvent,\n} from '@pie-framework/pie-configure-events';\n\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport Main from './main';\nimport debug from 'debug';\nimport { defaults } from 'lodash-es';\n\nimport sensibleDefaults from './defaults';\nimport { processMarkup, createSlateMarkup } from './markupUtils';\n\nconst log = debug('multiple-choice:configure');\n\nexport default class DragInTheBlank extends HTMLElement {\n static prepareModel = (model = {}) => {\n const joinedObj = {\n ...sensibleDefaults.model,\n ...model,\n };\n const slateMarkup =\n model.slateMarkup || createSlateMarkup(joinedObj.markup, joinedObj.choices, joinedObj.correctResponse);\n const processedMarkup = processMarkup(slateMarkup);\n\n return {\n ...joinedObj,\n slateMarkup,\n markup: processedMarkup.markup,\n correctResponse: processedMarkup.correctResponse,\n };\n };\n\n constructor() {\n super();\n this._root = null;\n this._model = DragInTheBlank.prepareModel();\n this._configuration = sensibleDefaults.configuration;\n this.onModelChanged = this.onModelChanged.bind(this);\n this.onConfigurationChanged = this.onConfigurationChanged.bind(this);\n }\n\n set model(m) {\n const formModel = {\n ...m,\n markup: `<div>${m.markup || sensibleDefaults.model.markup}</div>`,\n };\n\n this._model = DragInTheBlank.prepareModel(formModel);\n this._render();\n }\n\n set configuration(c) {\n const newConfiguration = defaults(c, sensibleDefaults.configuration);\n\n this._configuration = newConfiguration;\n\n // if language:enabled is true, then the corresponding default item model should include a language value;\n // if it is false, then the language field should be omitted from the item model.\n // if a default item model includes a language value (e.g., en_US) and the corresponding authoring view settings have language:settings = true,\n // then (a) language:enabled should also be true, and (b) that default language value should be represented in languageChoices[] (as a key).\n if (newConfiguration?.language?.enabled) {\n if (newConfiguration?.languageChoices?.options?.length) {\n this._model.language = newConfiguration?.languageChoices.options[0].value;\n }\n } else if (newConfiguration.language.settings && this._model.language) {\n this._configuration.language.enabled = true;\n\n if (!this._configuration.languageChoices.options || !this._configuration.languageChoices.options.length) {\n this._configuration.languageChoices.options = [];\n }\n\n // check if the language is already included in the languageChoices.options array\n // and if not, then add it.\n if (!this._configuration.languageChoices.options.find(option => option.value === this._model.language)) {\n this._configuration.languageChoices.options.push({\n value: this._model.language,\n label: this._model.language,\n });\n }\n } else {\n delete this._model.language;\n }\n\n this._render();\n }\n\n set disableSidePanel(s) {\n this._disableSidePanel = s;\n this._render();\n }\n\n dispatchModelUpdated(reset) {\n const resetValue = !!reset;\n\n this.dispatchEvent(new ModelUpdatedEvent(this._model, resetValue));\n }\n\n onModelChanged(m, reset) {\n this._model = DragInTheBlank.prepareModel(m);\n this._render();\n this.dispatchModelUpdated(reset);\n }\n\n onConfigurationChanged(c) {\n this._configuration = c;\n this._render();\n }\n\n /** @param {done, progress, file} handler */\n insertImage(handler) {\n this.dispatchEvent(new InsertImageEvent(handler));\n }\n\n onDeleteImage(src, done) {\n this.dispatchEvent(new DeleteImageEvent(src, done));\n }\n\n insertSound(handler) {\n this.dispatchEvent(new InsertSoundEvent(handler));\n }\n\n onDeleteSound(src, done) {\n this.dispatchEvent(new DeleteSoundEvent(src, done));\n }\n\n _render() {\n log('_render');\n\n let element = React.createElement(Main, {\n model: this._model,\n configuration: this._configuration,\n onModelChanged: this.onModelChanged,\n onConfigurationChanged: this.onConfigurationChanged,\n disableSidePanel: this._disableSidePanel,\n imageSupport: {\n add: this.insertImage.bind(this),\n delete: this.onDeleteImage.bind(this),\n },\n uploadSoundSupport: {\n add: this.insertSound.bind(this),\n delete: this.onDeleteSound.bind(this),\n },\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n\n setTimeout(() => {\n renderMath(this);\n }, 0);\n }\n\n disconnectedCallback() {\n if (this._root) {\n this._root.unmount();\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_pieConfigureEvents","require","_react","_interopRequireDefault","_client","_mathRendering","_main","_debug","_lodashEs","_defaults","_markupUtils","log","debug","DragInTheBlank","HTMLElement","constructor","_root","_model","prepareModel","_configuration","sensibleDefaults","configuration","onModelChanged","bind","onConfigurationChanged","model","m","formModel","markup","_render","c","newConfiguration","defaults","language","enabled","languageChoices","options","length","value","settings","find","option","push","label","disableSidePanel","s","_disableSidePanel","dispatchModelUpdated","reset","resetValue","dispatchEvent","ModelUpdatedEvent","insertImage","handler","InsertImageEvent","onDeleteImage","src","done","DeleteImageEvent","insertSound","InsertSoundEvent","onDeleteSound","DeleteSoundEvent","element","React","createElement","Main","imageSupport","add","delete","uploadSoundSupport","createRoot","render","setTimeout","renderMath","connectedCallback","disconnectedCallback","unmount","exports","default","_defineProperty2","joinedObj","slateMarkup","createSlateMarkup","choices","correctResponse","processedMarkup","processMarkup"],"sources":["../src/index.js"],"sourcesContent":["import {\n ModelUpdatedEvent,\n DeleteImageEvent,\n InsertImageEvent,\n InsertSoundEvent,\n DeleteSoundEvent,\n} from '@pie-framework/pie-configure-events';\n\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport Main from './main';\nimport debug from 'debug';\nimport { defaults } from 'lodash-es';\n\nimport sensibleDefaults from './defaults';\nimport { processMarkup, createSlateMarkup } from './markupUtils';\n\nconst log = debug('multiple-choice:configure');\n\nexport default class DragInTheBlank extends HTMLElement {\n static prepareModel = (model = {}) => {\n const joinedObj = {\n ...sensibleDefaults.model,\n ...model,\n };\n const slateMarkup =\n model.slateMarkup || createSlateMarkup(joinedObj.markup, joinedObj.choices, joinedObj.correctResponse);\n const processedMarkup = processMarkup(slateMarkup);\n\n return {\n ...joinedObj,\n slateMarkup,\n markup: processedMarkup.markup,\n correctResponse: processedMarkup.correctResponse,\n };\n };\n\n constructor() {\n super();\n this._root = null;\n this._model = DragInTheBlank.prepareModel();\n this._configuration = sensibleDefaults.configuration;\n this.onModelChanged = this.onModelChanged.bind(this);\n this.onConfigurationChanged = this.onConfigurationChanged.bind(this);\n }\n\n set model(m) {\n const formModel = {\n ...m,\n markup: `<div>${m.markup || sensibleDefaults.model.markup}</div>`,\n };\n\n this._model = DragInTheBlank.prepareModel(formModel);\n this._render();\n }\n\n set configuration(c) {\n const newConfiguration = defaults(c, sensibleDefaults.configuration);\n\n this._configuration = newConfiguration;\n\n // if language:enabled is true, then the corresponding default item model should include a language value;\n // if it is false, then the language field should be omitted from the item model.\n // if a default item model includes a language value (e.g., en_US) and the corresponding authoring view settings have language:settings = true,\n // then (a) language:enabled should also be true, and (b) that default language value should be represented in languageChoices[] (as a key).\n if (newConfiguration?.language?.enabled) {\n if (newConfiguration?.languageChoices?.options?.length) {\n this._model.language = newConfiguration?.languageChoices.options[0].value;\n }\n } else if (newConfiguration.language.settings && this._model.language) {\n this._configuration.language.enabled = true;\n\n if (!this._configuration.languageChoices.options || !this._configuration.languageChoices.options.length) {\n this._configuration.languageChoices.options = [];\n }\n\n // check if the language is already included in the languageChoices.options array\n // and if not, then add it.\n if (!this._configuration.languageChoices.options.find(option => option.value === this._model.language)) {\n this._configuration.languageChoices.options.push({\n value: this._model.language,\n label: this._model.language,\n });\n }\n } else {\n delete this._model.language;\n }\n\n this._render();\n }\n\n set disableSidePanel(s) {\n this._disableSidePanel = s;\n this._render();\n }\n\n dispatchModelUpdated(reset) {\n const resetValue = !!reset;\n\n this.dispatchEvent(new ModelUpdatedEvent(this._model, resetValue));\n }\n\n onModelChanged(m, reset) {\n this._model = DragInTheBlank.prepareModel(m);\n this._render();\n this.dispatchModelUpdated(reset);\n }\n\n onConfigurationChanged(c) {\n this._configuration = c;\n this._render();\n }\n\n /** @param {done, progress, file} handler */\n insertImage(handler) {\n this.dispatchEvent(new InsertImageEvent(handler));\n }\n\n onDeleteImage(src, done) {\n this.dispatchEvent(new DeleteImageEvent(src, done));\n }\n\n insertSound(handler) {\n this.dispatchEvent(new InsertSoundEvent(handler));\n }\n\n onDeleteSound(src, done) {\n this.dispatchEvent(new DeleteSoundEvent(src, done));\n }\n\n _render() {\n log('_render');\n\n let element = React.createElement(Main, {\n model: this._model,\n configuration: this._configuration,\n onModelChanged: this.onModelChanged,\n onConfigurationChanged: this.onConfigurationChanged,\n disableSidePanel: this._disableSidePanel,\n imageSupport: {\n add: this.insertImage.bind(this),\n delete: this.onDeleteImage.bind(this),\n },\n uploadSoundSupport: {\n add: this.insertSound.bind(this),\n delete: this.onDeleteSound.bind(this),\n },\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n\n setTimeout(() => {\n renderMath(this);\n }, 0);\n }\n\n connectedCallback() {\n this._render();\n }\n\n disconnectedCallback() {\n if (this._root) {\n this._root.unmount();\n this._root = null;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/drag-in-the-blank-configure",
3
- "version": "9.1.4",
3
+ "version": "9.1.5",
4
4
  "private": true,
5
5
  "main": "lib/index.js",
6
6
  "module": "src/index.js",
@@ -12,9 +12,9 @@
12
12
  "@mui/icons-material": "^7.3.4",
13
13
  "@mui/material": "^7.3.4",
14
14
  "@pie-framework/pie-configure-events": "^1.3.0",
15
- "@pie-lib/config-ui": "13.0.8",
15
+ "@pie-lib/config-ui": "13.0.9",
16
16
  "@pie-lib/drag": "4.0.5",
17
- "@pie-lib/editable-html-tip-tap": "2.1.6",
17
+ "@pie-lib/editable-html-tip-tap": "2.1.7",
18
18
  "@pie-lib/math-rendering": "5.0.2",
19
19
  "debug": "^4.1.1",
20
20
  "lodash-es": "^4.17.23",
package/lib/index.js CHANGED
@@ -199,6 +199,7 @@ class DragInTheBlank extends HTMLElement {
199
199
  }
200
200
  if (this._root) {
201
201
  this._root.unmount();
202
+ this._root = null;
202
203
  }
203
204
  }
204
205
  }
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_client","_mathRendering","_renderUi","_piePlayerEvents","_main","isComplete","session","model","audioComplete","elementContext","autoplayAudioEnabled","completeAudioEnabled","responseAreasToBeFilled","audio","querySelector","isInsidePrompt","closest","value","filledResponseAreas","Object","values","filter","val","length","exports","DragInTheBlank","HTMLElement","constructor","_defineProperty2","default","_model","_session","elem","React","createElement","Main","onChange","changeSession","_root","createRoot","render","setTimeout","renderMath","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","selector","dispatchChangedEvent","_render","_audioInitialized","m","ModelSetEvent","s","_createAudioInfoToast","info","document","id","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","connectedCallback","observer","MutationObserver","mutationsList","forEach","mutation","type","container","enableAudio","play","removeChild","removeEventListener","paused","addEventListener","handlePlaying","audioStartTime","Date","getTime","handleEnded","audioEndTime","waitTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","disconnectedCallback","unmount"],"sources":["../src/index.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\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 this._root = null;\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 if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(elem);\n setTimeout(() => renderMath(this), 0);\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 if (this._root) {\n this._root.unmount();\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_client","_mathRendering","_renderUi","_piePlayerEvents","_main","isComplete","session","model","audioComplete","elementContext","autoplayAudioEnabled","completeAudioEnabled","responseAreasToBeFilled","audio","querySelector","isInsidePrompt","closest","value","filledResponseAreas","Object","values","filter","val","length","exports","DragInTheBlank","HTMLElement","constructor","_defineProperty2","default","_model","_session","elem","React","createElement","Main","onChange","changeSession","_root","createRoot","render","setTimeout","renderMath","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","selector","dispatchChangedEvent","_render","_audioInitialized","m","ModelSetEvent","s","_createAudioInfoToast","info","document","id","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","connectedCallback","observer","MutationObserver","mutationsList","forEach","mutation","type","container","enableAudio","play","removeChild","removeEventListener","paused","addEventListener","handlePlaying","audioStartTime","Date","getTime","handleEnded","audioEndTime","waitTime","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","disconnectedCallback","unmount"],"sources":["../src/index.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\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 this._root = null;\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 if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(elem);\n setTimeout(() => renderMath(this), 0);\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 if (this._root) {\n this._root.unmount();\n this._root = null;\n }\n }\n}\n"],"mappings":";;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AACA,IAAAE,cAAA,GAAAF,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,gBAAA,GAAAJ,OAAA;AACA,IAAAK,KAAA,GAAAN,sBAAA,CAAAC,OAAA;AAEO,MAAMM,UAAU,GAAGA,CAACC,OAAO,EAAEC,KAAK,EAAEC,aAAa,EAAEC,cAAc,KAAK;EAC3E,MAAM;IAAEC,oBAAoB;IAAEC,oBAAoB;IAAEC;EAAwB,CAAC,GAAGL,KAAK,IAAI,CAAC,CAAC;EAE3F,IAAIG,oBAAoB,IAAIC,oBAAoB,IAAI,CAACH,aAAa,EAAE;IAClE,IAAIC,cAAc,EAAE;MAClB,MAAMI,KAAK,GAAGJ,cAAc,CAACK,aAAa,CAAC,OAAO,CAAC;MACnD,MAAMC,cAAc,GAAGF,KAAK,IAAIA,KAAK,CAACG,OAAO,CAAC,iBAAiB,CAAC;;MAEhE;MACA,IAAIH,KAAK,IAAIE,cAAc,EAAE;QAC3B,OAAO,KAAK;MACd;IACF;EACF;EAEA,IAAI,CAACT,OAAO,IAAI,CAACA,OAAO,CAACW,KAAK,EAAE;IAC9B,OAAO,KAAK;EACd;EAEA,MAAMC,mBAAmB,GAAGC,MAAM,CAACC,MAAM,CAACd,OAAO,CAACW,KAAK,IAAI,CAAC,CAAC,CAAC,CAACI,MAAM,CAAEC,GAAG,IAAK,CAAC,CAACA,GAAG,CAAC,CAACC,MAAM;EAE5F,OAAOL,mBAAmB,IAAIN,uBAAuB;AACvD,CAAC;AAACY,OAAA,CAAAnB,UAAA,GAAAA,UAAA;AAEa,MAAMoB,cAAc,SAASC,WAAW,CAAC;EACtDC,WAAWA,CAAA,EAAG;IACZ,KAAK,CAAC,CAAC;IAAC,IAAAC,gBAAA,CAAAC,OAAA,mBA+BA,MAAM;MACd,IAAI,IAAI,CAACC,MAAM,IAAI,IAAI,CAACC,QAAQ,EAAE;QAChC,IAAIC,IAAI,gBAAGC,cAAK,CAACC,aAAa,CAACC,aAAI,EAAE;UACnC5B,KAAK,EAAE,IAAI,CAACuB,MAAM;UAClBb,KAAK,EAAE,IAAI,CAACc,QAAQ,CAACd,KAAK;UAC1BmB,QAAQ,EAAE,IAAI,CAACC;QACjB,CAAC,CAAC;QAEF,IAAI,CAAC,IAAI,CAACC,KAAK,EAAE;UACf,IAAI,CAACA,KAAK,GAAG,IAAAC,kBAAU,EAAC,IAAI,CAAC;QAC/B;QACA,IAAI,CAACD,KAAK,CAACE,MAAM,CAACR,IAAI,CAAC;QACvBS,UAAU,CAAC,MAAM,IAAAC,yBAAU,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC;MACvC;IACF,CAAC;IAAA,IAAAd,gBAAA,CAAAC,OAAA,gCAEsB,MAAM;MAC3B,IAAI,CAACc,aAAa,CAChB,IAAIC,oCAAmB,CACrB,IAAI,CAACC,OAAO,CAACC,WAAW,CAAC,CAAC,EAC1BzC,UAAU,CAAC,IAAI,CAAC0B,QAAQ,EAAE,IAAI,CAACD,MAAM,EAAE,IAAI,CAACtB,aAAa,EAAE,IAAI,CACjE,CACF,CAAC;IACH,CAAC;IAAA,IAAAoB,gBAAA,CAAAC,OAAA,yBAEgBZ,KAAK,IAAK;MACzB,IAAI,CAACX,OAAO,CAACW,KAAK,GAAGA,KAAK;MAC1B,IAAI,CAACX,OAAO,CAACyC,QAAQ,GAAG,OAAO;MAE/B,IAAI,CAACC,oBAAoB,CAAC,CAAC;MAC3B,IAAI,CAACC,OAAO,CAAC,CAAC;IAChB,CAAC;IA7DC,IAAI,CAACnB,MAAM,GAAG,IAAI;IAClB,IAAI,CAACC,QAAQ,GAAG,IAAI;IACpB,IAAI,CAACmB,iBAAiB,GAAG,KAAK;IAC9B,IAAI,CAAC1C,aAAa,GAAG,KAAK;IAC1B,IAAI,CAAC8B,KAAK,GAAG,IAAI;EACnB;EAEA,IAAI/B,KAAKA,CAAC4C,CAAC,EAAE;IACX,IAAI,CAACrB,MAAM,GAAGqB,CAAC;IACf,IAAI,CAACR,aAAa,CAChB,IAAIS,8BAAa,CACf,IAAI,CAACP,OAAO,CAACC,WAAW,CAAC,CAAC,EAC1BzC,UAAU,CAAC,IAAI,CAAC0B,QAAQ,EAAE,IAAI,CAACD,MAAM,EAAE,IAAI,CAACtB,aAAa,EAAE,IAAI,CAAC,EAChE,CAAC,CAAC,IAAI,CAACsB,MACT,CACF,CAAC;IACD;IACA,IAAI,CAACoB,iBAAiB,GAAG,KAAK;IAC9B,IAAI,CAACD,OAAO,CAAC,CAAC;EAChB;EAEA,IAAI3C,OAAOA,CAAC+C,CAAC,EAAE;IACb,IAAI,CAACtB,QAAQ,GAAGsB,CAAC;IACjB,IAAI,CAACJ,OAAO,CAAC,CAAC;EAChB;EAEA,IAAI3C,OAAOA,CAAA,EAAG;IACZ,OAAO,IAAI,CAACyB,QAAQ;EACtB;EAmCAuB,qBAAqBA,CAAA,EAAG;IACtB,MAAMC,IAAI,GAAGC,QAAQ,CAACtB,aAAa,CAAC,KAAK,CAAC;IAC1CqB,IAAI,CAACE,EAAE,GAAG,iBAAiB;IAE3BtC,MAAM,CAACuC,MAAM,CAACH,IAAI,CAACI,KAAK,EAAE;MACxBC,QAAQ,EAAE,UAAU;MACpBC,GAAG,EAAE,CAAC;MACNC,KAAK,EAAE,MAAM;MACbC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,MAAM;MACfC,cAAc,EAAE,QAAQ;MACxBC,UAAU,EAAE,QAAQ;MACpBC,UAAU,EAAE,OAAO;MACnBC,MAAM,EAAE,MAAM;MACdC,MAAM,EAAE;IACV,CAAC,CAAC;IAEF,MAAMC,GAAG,GAAGd,QAAQ,CAACtB,aAAa,CAAC,KAAK,CAAC;IACzCoC,GAAG,CAACC,GAAG,GAAGC,kCAAwB;IAClCF,GAAG,CAACG,GAAG,GAAG,yCAAyC;IACnDH,GAAG,CAACR,KAAK,GAAG,GAAG;IACfQ,GAAG,CAACP,MAAM,GAAG,GAAG;IAEhBR,IAAI,CAACmB,WAAW,CAACJ,GAAG,CAAC;IACrB,OAAOf,IAAI;EACb;EAEAoB,iBAAiBA,CAAA,EAAG;IAClB,IAAI,CAAC1B,OAAO,CAAC,CAAC;;IAEd;IACA;IACA;IACA,MAAM2B,QAAQ,GAAG,IAAIC,gBAAgB,CAAC,CAACC,aAAa,EAAEF,QAAQ,KAAK;MACjEE,aAAa,CAACC,OAAO,CAAEC,QAAQ,IAAK;QAClC,IAAIA,QAAQ,CAACC,IAAI,KAAK,WAAW,EAAE;UACjC,IAAI,IAAI,CAAC/B,iBAAiB,EAAE;UAC5B,MAAMrC,KAAK,GAAG,IAAI,CAACC,aAAa,CAAC,OAAO,CAAC;UACzC,MAAMC,cAAc,GAAGF,KAAK,IAAIA,KAAK,CAACG,OAAO,CAAC,iBAAiB,CAAC;UAEhE,IAAI,CAAC,IAAI,CAACc,MAAM,EAAE;UAClB,IAAI,CAAC,IAAI,CAACA,MAAM,CAACpB,oBAAoB,EAAE;UACvC,IAAIG,KAAK,IAAI,CAACE,cAAc,EAAE;UAC9B,IAAI,CAACF,KAAK,EAAE;UAEZ,MAAM0C,IAAI,GAAG,IAAI,CAACD,qBAAqB,CAAC,CAAC;UACzC,MAAM4B,SAAS,GAAG,IAAI,CAACpE,aAAa,CAAC,iBAAiB,CAAC;UACvD,MAAMqE,WAAW,GAAGA,CAAA,KAAM;YACxB,IAAI,IAAI,CAACrE,aAAa,CAAC,kBAAkB,CAAC,EAAE;cAC1CD,KAAK,CAACuE,IAAI,CAAC,CAAC;cACZF,SAAS,CAACG,WAAW,CAAC9B,IAAI,CAAC;YAC7B;YAEAC,QAAQ,CAAC8B,mBAAmB,CAAC,OAAO,EAAEH,WAAW,CAAC;UACpD,CAAC;;UAED;UACA;UACA1C,UAAU,CAAC,MAAM;YACf,IAAI5B,KAAK,CAAC0E,MAAM,IAAI,CAAC,IAAI,CAACzE,aAAa,CAAC,kBAAkB,CAAC,EAAE;cAC3D;cACAoE,SAAS,CAACR,WAAW,CAACnB,IAAI,CAAC;cAC3BC,QAAQ,CAACgC,gBAAgB,CAAC,OAAO,EAAEL,WAAW,CAAC;YACjD,CAAC,MAAM;cACL3B,QAAQ,CAAC8B,mBAAmB,CAAC,OAAO,EAAEH,WAAW,CAAC;YACpD;UACF,CAAC,EAAE,GAAG,CAAC;;UAEP;UACA,MAAMM,aAAa,GAAGA,CAAA,KAAM;YAC1B;YACA,IAAI,CAAC1D,QAAQ,CAAC2D,cAAc,GAAG,IAAI,CAAC3D,QAAQ,CAAC2D,cAAc,IAAI,IAAIC,IAAI,CAAC,CAAC,CAACC,OAAO,CAAC,CAAC;YAEnF,MAAMrC,IAAI,GAAG,IAAI,CAACzC,aAAa,CAAC,kBAAkB,CAAC;YACnD,IAAIyC,IAAI,EAAE;cACR2B,SAAS,CAACG,WAAW,CAAC9B,IAAI,CAAC;YAC7B;YAEA1C,KAAK,CAACyE,mBAAmB,CAAC,SAAS,EAAEG,aAAa,CAAC;UACrD,CAAC;UAED5E,KAAK,CAAC2E,gBAAgB,CAAC,SAAS,EAAEC,aAAa,CAAC;;UAEhD;UACA,MAAMI,WAAW,GAAGA,CAAA,KAAM;YACxB;YACA,IAAI,CAAC9D,QAAQ,CAAC+D,YAAY,GAAG,IAAI,CAAC/D,QAAQ,CAAC+D,YAAY,IAAI,IAAIH,IAAI,CAAC,CAAC,CAACC,OAAO,CAAC,CAAC;YAE/E,IAAI;cAAEF,cAAc;cAAEI,YAAY;cAAEC;YAAS,CAAC,GAAG,IAAI,CAAChE,QAAQ;YAC9D,IAAI,CAACgE,QAAQ,IAAIL,cAAc,IAAII,YAAY,EAAE;cAC/C;cACA,IAAI,CAAC/D,QAAQ,CAACgE,QAAQ,GAAGD,YAAY,GAAGJ,cAAc;YACxD;YAEA,IAAI,CAAClF,aAAa,GAAG,IAAI;YACzB,IAAI,CAACwC,oBAAoB,CAAC,CAAC;YAC3BnC,KAAK,CAACyE,mBAAmB,CAAC,OAAO,EAAEO,WAAW,CAAC;UACjD,CAAC;UAEDhF,KAAK,CAAC2E,gBAAgB,CAAC,OAAO,EAAEK,WAAW,CAAC;;UAE5C;UACA,IAAI,CAACG,MAAM,GAAGnF,KAAK;UACnB,IAAI,CAACoF,cAAc,GAAGR,aAAa;UACnC,IAAI,CAACS,YAAY,GAAGL,WAAW;UAC/B,IAAI,CAACM,YAAY,GAAGhB,WAAW;UAC/B;UACA,IAAI,CAACjC,iBAAiB,GAAG,IAAI;UAE7B0B,QAAQ,CAACwB,UAAU,CAAC,CAAC;QACvB;MACF,CAAC,CAAC;IACJ,CAAC,CAAC;IAEFxB,QAAQ,CAACyB,OAAO,CAAC,IAAI,EAAE;MAAEC,SAAS,EAAE,IAAI;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC;EAC5D;EAEAC,oBAAoBA,CAAA,EAAG;IACrBhD,QAAQ,CAAC8B,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAACa,YAAY,CAAC;IAExD,IAAI,IAAI,CAACH,MAAM,EAAE;MACf,IAAI,CAACA,MAAM,CAACV,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAACW,cAAc,CAAC;MAC/D,IAAI,CAACD,MAAM,CAACV,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAACY,YAAY,CAAC;MAC3D,IAAI,CAACF,MAAM,GAAG,IAAI;IACpB;IAEA,IAAI,IAAI,CAAC1D,KAAK,EAAE;MACd,IAAI,CAACA,KAAK,CAACmE,OAAO,CAAC,CAAC;MACpB,IAAI,CAACnE,KAAK,GAAG,IAAI;IACnB;EACF;AACF;AAACd,OAAA,CAAAK,OAAA,GAAAJ,cAAA","ignoreList":[]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "10.1.4",
7
+ "version": "10.1.5",
8
8
  "description": "",
9
9
  "scripts": {
10
10
  "postpublish": "../../scripts/postpublish"
@@ -17,7 +17,7 @@
17
17
  "@pie-framework/pie-player-events": "^0.1.0",
18
18
  "@pie-lib/correct-answer-toggle": "4.0.4",
19
19
  "@pie-lib/drag": "4.0.5",
20
- "@pie-lib/mask-markup": "3.0.8",
20
+ "@pie-lib/mask-markup": "3.0.9",
21
21
  "@pie-lib/math-rendering": "5.0.2",
22
22
  "@pie-lib/render-ui": "6.1.2",
23
23
  "lodash-es": "^4.17.23",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "author": "",
29
29
  "license": "ISC",
30
- "gitHead": "395c1eeab967e1201bc5904cfe3cc63914ebbb4a",
30
+ "gitHead": "f898c2bf045f66d34e66e8bb201950bfd00b2f0f",
31
31
  "main": "lib/index.js",
32
32
  "module": "src/index.js"
33
33
  }