@pie-element/match 13.0.4-next.20261011174919 → 13.0.4
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/dist/author/configure.d.ts +45 -31
- package/dist/author/configure.js +37 -51
- package/dist/author/defaults.d.ts +59 -57
- package/dist/author/index.d.ts +18 -27
- package/dist/author/index.js +15 -4
- package/dist/author/utils.d.ts +33 -2
- package/dist/browser/author/index.js +24 -29
- package/dist/browser/author/index.js.map +1 -1
- package/dist/browser/controller/index.js.map +1 -1
- package/dist/browser/editor-runtime/author/index.js +24 -29
- package/dist/browser/editor-runtime/author/index.js.map +1 -1
- package/dist/browser/editor-runtime/controller/index.js.map +1 -1
- package/dist/controller/defaults.d.ts +12 -11
- package/dist/controller/index.d.ts +73 -7
- package/dist/index.d.ts +1 -0
- package/dist/schemas/configuration.schema.json +437 -0
- package/dist/schemas/model.schema.json +478 -0
- package/dist/schemas/session.schema.json +36 -0
- package/dist/types.d.ts +183 -0
- package/package.json +21 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../shared/feedback/dist/index.js","../../../../../shared/controller-utils/dist/index.js","../../../src/controller/defaults.ts","../../../src/controller/index.ts"],"sourcesContent":["//#region src/defaults.ts\nvar e = {\n\tcorrect: {\n\t\ttype: \"default\",\n\t\tdefault: \"Correct\",\n\t\tcustom: \"Correct\"\n\t},\n\tincorrect: {\n\t\ttype: \"default\",\n\t\tdefault: \"Incorrect\",\n\t\tcustom: \"Incorrect\"\n\t},\n\tpartial: {\n\t\ttype: \"default\",\n\t\tdefault: \"Nearly\",\n\t\tcustom: \"Nearly\"\n\t},\n\tunanswered: {\n\t\ttype: \"default\",\n\t\tdefault: \"You have not entered a response\",\n\t\tcustom: \"You have not entered a response\"\n\t}\n};\n//#endregion\n//#region src/utils.ts\nfunction t(e) {\n\treturn e === \"partially-correct\" ? \"partial\" : e;\n}\n//#endregion\n//#region src/index.ts\nfunction n(n, r) {\n\tlet i = {\n\t\t...e,\n\t\t...r\n\t}, a = t(n), o = e[a] || {}, s = i[a] || o;\n\treturn {\n\t\tconfig: s,\n\t\tfallback: o[s.type || \"default\"]\n\t};\n}\nfunction r(e, t = {}) {\n\treturn new Promise((r) => {\n\t\tlet { config: a, fallback: o } = n(e, t);\n\t\ti(a, o).then(r);\n\t});\n}\nfunction i(e, t) {\n\treturn new Promise((n) => {\n\t\tif (!e || e.type === \"none\") {\n\t\t\tn(void 0);\n\t\t\treturn;\n\t\t}\n\t\tn(e[e.type] || t);\n\t});\n}\nfunction a(e, t = {}) {\n\tlet { config: r, fallback: i } = n(e, t);\n\treturn o(r, i);\n}\nfunction o(e, t) {\n\tif (!(!e || e.type === \"none\")) return e[e.type] || t;\n}\n//#endregion\nexport { e as defaultFeedback, o as getActualFeedback, a as getActualFeedbackForCorrectness, i as getFeedback, r as getFeedbackForCorrectness, t as normalizeCorrectness };\n","//#region \\0rolldown/runtime.js\nvar e = Object.defineProperty, t = (t, n) => {\n\tlet r = {};\n\tfor (var i in t) e(r, i, {\n\t\tget: t[i],\n\t\tenumerable: !0\n\t});\n\treturn n || e(r, Symbol.toStringTag, { value: \"Module\" }), r;\n};\n//#endregion\n//#region src/persistence.ts\nfunction n(e) {\n\treturn Array.isArray(e) ? e.filter((e) => e != null) : [];\n}\nfunction r(e) {\n\tlet t = [...e];\n\tfor (let e = t.length - 1; e > 0; e--) {\n\t\tlet n = Math.floor(Math.random() * (e + 1));\n\t\t[t[e], t[n]] = [t[n], t[e]];\n\t}\n\treturn t;\n}\nfunction i(e) {\n\treturn e == null ? !0 : Array.isArray(e) ? e.length === 0 : typeof e == \"object\" && Object.keys(e).length === 0;\n}\nasync function a(e, t, a, o = \"value\") {\n\tlet s = n(t?.data?.shuffledValues ?? t?.shuffledValues ?? []);\n\tif (!t) {\n\t\tconsole.warn(\"Unable to save shuffled choices because there's no session.\");\n\t\treturn;\n\t}\n\tif (!i(s)) return n(s.map((t) => e.find((e) => e[o] === t)));\n\tlet c = r(e);\n\tif (a && typeof a == \"function\") try {\n\t\tlet e = n(c.map((e) => e[o]));\n\t\ti(e) ? console.error(`shuffledValues is an empty array - refusing to call updateSession. shuffledChoices: ${JSON.stringify(c)}, key: ${o}`) : await a(t.id, t.element, { shuffledValues: e });\n\t} catch (e) {\n\t\tconsole.warn(\"Unable to save shuffled order for choices\"), console.error(e);\n\t}\n\telse console.warn(\"Unable to save shuffled choices, shuffle will happen every time.\");\n\treturn c;\n}\nfunction o(e, t, n) {\n\treturn !!(e.lockChoiceOrder || n?.[\"@pie-element\"]?.lockChoiceOrder);\n}\n//#endregion\n//#region src/partial-scoring.ts\nvar s = /* @__PURE__ */ t({ enabled: () => c });\nfunction c(e, t, n) {\n\treturn e?.partialScoring === !1 || t?.partialScoring === !1 ? !1 : typeof n != \"boolean\" || n;\n}\n//#endregion\nexport { a as getShuffledChoices, o as lockChoices, s as partialScoring };\n","// @ts-nocheck\n\nexport default {\n choiceMode: 'radio',\n feedbackEnabled: false,\n headers: ['Column 1', 'Column 2', 'Column 3'],\n layout: 3,\n lockChoiceOrder: true,\n partialScoring: false,\n prompt: '',\n promptEnabled: true,\n rationale: '',\n rationaleEnabled: true,\n rows: [],\n scoringType: 'auto',\n studentInstructionsEnabled: true,\n teacherInstructions: '',\n teacherInstructionsEnabled: true,\n toolbarEditorPosition: 'bottom',\n};\n","// @ts-nocheck\n\nimport { cloneDeep, isEmpty, isEqual } from '@pie-element/shared-lodash';\nimport { getFeedbackForCorrectness } from '@pie-element/shared-feedback';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-element/shared-controller-utils';\nimport debug from 'debug';\n\nconst log = debug('@pie-element:match:controller');\n\nimport defaults from './defaults.js';\n\nconst getResponseCorrectness = (model, answers, env = {}) => {\n const isPartialScoring = partialScoring.enabled(model, env);\n const rows = model.rows;\n const checkboxMode = model.choiceMode === 'checkbox';\n\n if (!answers || Object.keys(answers).length === 0) {\n return 'unanswered';\n }\n\n const totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);\n let correctAnswers;\n let incorrectAnswers = 0;\n\n if (checkboxMode) {\n const checkboxes = getCheckboxes(rows, answers);\n\n correctAnswers = checkboxes.correctAnswers;\n incorrectAnswers = checkboxes.incorrectAnswers;\n } else {\n correctAnswers = getCorrectRadios(rows, answers);\n }\n\n if (totalCorrectAnswers === correctAnswers && !incorrectAnswers) {\n return 'correct';\n } else if (correctAnswers === 0) {\n return 'incorrect';\n } else if (isPartialScoring) {\n return 'partial';\n }\n\n return 'incorrect';\n};\n\nconst getCorrectness = (question, env, answers = {}) => {\n if (env.mode === 'evaluate') {\n return getResponseCorrectness(question, answers, env);\n }\n};\n\nconst getCheckboxes = (rows, answers) => {\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n\n rows.forEach((row) => {\n const answer = answers[row.id];\n\n if (answer) {\n row.values.forEach((v, i) => {\n if (answer[i] && answer[i] === v) {\n correctAnswers += 1;\n } else if (answer[i] && answer[i] !== v) {\n incorrectAnswers += 1;\n }\n });\n }\n });\n\n return { correctAnswers, incorrectAnswers };\n};\n\nconst getCorrectRadios = (rows, answers) => {\n let correctAnswers = 0;\n\n rows.forEach((row) => {\n if (isEqual(row.values, answers[row.id])) {\n correctAnswers += 1;\n }\n });\n\n return correctAnswers;\n};\n\nconst getTotalCorrect = (question) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n const matchingTable = checkboxMode ? question.layout - 1 : 1;\n return (question.rows.length || 0) * matchingTable;\n};\n\nconst getTotalCorrectAnswers = (question) => {\n let noOfTotalCorrectAnswers = 0;\n\n question.rows.forEach((row) => {\n row.values.forEach((value) => {\n if (value) {\n noOfTotalCorrectAnswers += 1;\n }\n });\n });\n\n return noOfTotalCorrectAnswers;\n};\n\nconst getPartialScore = (question, answers) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n\n if (checkboxMode) {\n const { correctAnswers, incorrectAnswers } = getCheckboxes(question.rows, answers);\n const totalCorrect = getTotalCorrectAnswers(question);\n\n const total = totalCorrect === 0 ? 1 : totalCorrect;\n\n if (correctAnswers + incorrectAnswers > totalCorrect) {\n const extraAnswers = correctAnswers + incorrectAnswers - totalCorrect;\n const score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));\n\n return score < 0 ? 0 : score;\n } else {\n return parseFloat((correctAnswers / total).toFixed(2));\n }\n } else {\n const correctAnswers = getCorrectRadios(question.rows, answers);\n const totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);\n\n return parseFloat((correctAnswers / totalCorrect).toFixed(2));\n }\n};\n\nconst getOutComeScore = (question, env, answers = {}) => {\n const correctness = getCorrectness(question, env, answers);\n const isPartialScoring = partialScoring.enabled(question, env);\n\n return correctness === 'correct'\n ? 1\n : correctness === 'partial' && isPartialScoring\n ? getPartialScore(question, answers)\n : 0;\n};\n\n/**\n * Generates detailed trace log for match item scoring evaluation\n * @param {Object} question\n * @param {Object} session\n * @param {Object} env\n * @returns {Array<string>} traceLog\n */\nexport const getLogTrace = (question, session, env) => {\n const traceLog = [];\n\n const answers = session?.answers || {};\n const rows = question?.rows || [];\n const checkboxMode = question.choiceMode === 'checkbox';\n\n if (!answers || Object.keys(answers).length === 0) {\n traceLog.push('Student did not provide any answer.');\n return traceLog;\n }\n\n traceLog.push(`Match item contains ${rows.length} row(s).`);\n traceLog.push(`Matching mode: ${checkboxMode ? 'checkbox (multiple matches allowed)' : 'radio (single match per row)'}.`);\n\n let correctCount = 0;\n let incorrectCount = 0;\n let totalCorrect = 0;\n\n rows.forEach((row) => {\n const studentAnswer = answers[row.id];\n const correctValues = row.values || [];\n\n if (checkboxMode) {\n correctValues.forEach((v, idx) => {\n if (v) {\n totalCorrect++;\n }\n\n if (studentAnswer && studentAnswer[idx]) {\n if (studentAnswer[idx] === v) {\n correctCount++;\n } else {\n incorrectCount++;\n }\n }\n });\n } else {\n totalCorrect++;\n if (studentAnswer) {\n if (isEqual(correctValues, studentAnswer)) {\n correctCount++;\n } else {\n incorrectCount++;\n }\n }\n }\n });\n\n if (correctCount > 0) {\n traceLog.push(`${correctCount} correct match(es) selected.`);\n }\n\n if (incorrectCount > 0) {\n traceLog.push(`${incorrectCount} incorrect match(es) selected.`);\n }\n\n if (correctCount === 0 && incorrectCount === 0) {\n traceLog.push('Student provided answers, but none matched the correct responses.');\n }\n\n const partialScoringEnabled = partialScoring.enabled(question, env);\n\n if (partialScoringEnabled) {\n traceLog.push('Score calculated using partial scoring.');\n\n if (checkboxMode) {\n traceLog.push(\n 'Score is based on the number of correct minus extra incorrect matches, divided by the total number of correct matches.',\n );\n\n if (correctCount + incorrectCount > totalCorrect) {\n traceLog.push('Extra selected matches beyond the correct set reduce the score.');\n }\n } else {\n traceLog.push(\n 'Score is based on the number of correctly matched rows divided by the total number of rows.',\n );\n }\n } else {\n traceLog.push('Score calculated using all-or-nothing scoring.');\n traceLog.push('Student must match all rows correctly to receive full credit.');\n }\n\n const rawScore = getOutComeScore(question, env, answers);\n const finalScore = partialScoringEnabled ? rawScore : rawScore === 1 ? 1 : 0;\n\n traceLog.push(`Final score: ${finalScore}.`);\n\n return traceLog;\n};\n\nexport const outcome = (question, session, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined, logTrace: [] });\n } else {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true, logTrace: ['Student did not provide any answer.'] });\n }\n\n const out = {\n score: getOutComeScore(question, env, session.answers),\n empty: false,\n logTrace: getLogTrace(question, session, env),\n };\n\n resolve(out);\n }\n });\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n}\n\nexport const normalize = (question) => ({ ...defaults, ...question });\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 async function model(question, session, env, updateSession) {\n const normalizedQuestion = cloneDeep(normalize(question));\n let correctness, score;\n\n if ((!session || isEmpty(session)) && env.mode === 'evaluate') {\n correctness = 'unanswered';\n score = '0%';\n } else {\n correctness = getCorrectness(normalizedQuestion, env, session && session.answers);\n score = `${getOutComeScore(normalizedQuestion, env, session && session.answers) * 100}%`;\n }\n\n const correctResponse = {};\n const correctInfo = {\n score,\n correctness,\n };\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n normalizedQuestion.rows = await getShuffledChoices(normalizedQuestion.rows, session, updateSession, 'id');\n }\n\n normalizedQuestion.rows.forEach((row) => {\n correctResponse[row.id] = row.values;\n\n if (env.mode !== 'evaluate') {\n delete row.values;\n }\n });\n\n const feedback =\n env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled\n ? await getFeedbackForCorrectness(correctInfo.correctness, normalizedQuestion.feedback)\n : undefined;\n\n const {\n extraCSSRules,\n feedbackEnabled,\n promptEnabled,\n prompt,\n lockChoiceOrder: _,\n ...essentials\n } = normalizedQuestion;\n const out = {\n ...essentials,\n extraCSSRules,\n allowFeedback: feedbackEnabled,\n prompt: promptEnabled ? prompt : null,\n shuffled: !lockChoiceOrder,\n feedback,\n disabled: env.mode !== 'gather',\n view: env.mode === 'view',\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n if (env.mode === 'evaluate') {\n Object.assign(out, {\n correctResponse,\n correctness: correctInfo,\n });\n }\n\n log('out: ', out);\n return out;\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { rows } = question;\n const answers = {};\n\n rows.forEach((r) => {\n answers[r.id] = r.values;\n });\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\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 { rows, choiceMode, headers } = model;\n const {\n minQuestions,\n maxQuestions,\n maxLengthQuestionsHeading,\n maxAnswers,\n maxLengthAnswers,\n maxLengthFirstColumnHeading,\n } = config;\n const rowsErrors = {};\n const columnsErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt', 'rationale'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n if (rows.length < minQuestions) {\n errors.noOfRowsError = `There should be at least ${minQuestions} question rows.`;\n } else if (rows.length > maxQuestions) {\n errors.noOfRowsError = `No more than ${maxQuestions} question rows should be defined.`;\n }\n\n (rows || []).forEach((row, index) => {\n const { id, values = [], title } = row;\n rowsErrors[id] = '';\n\n if (maxLengthQuestionsHeading && getInnerText(title).length > maxLengthQuestionsHeading) {\n rowsErrors[id] += `Content length should be maximum ${maxLengthQuestionsHeading} characters. `;\n }\n\n if (!getContent(title)) {\n rowsErrors[id] += 'Content should not be empty. ';\n } else {\n // check for identical content with the previous answers\n const identicalAnswer = rows.slice(0, index).some((r) => getContent(r.title) === getContent(title));\n\n if (identicalAnswer) {\n rowsErrors[id] += 'Content should be unique. ';\n }\n }\n\n const hasCorrectResponse = values.some((value) => !!value);\n\n if (!hasCorrectResponse) {\n rowsErrors[id] += 'No correct response defined.';\n }\n });\n\n if (maxAnswers && headers.length - 1 > maxAnswers) {\n errors.columnsLengthError = `There should be maximum ${maxAnswers} answers.`;\n }\n\n if (maxLengthFirstColumnHeading && headers[0].length > maxLengthFirstColumnHeading) {\n columnsErrors[0] = `Content length should be maximum ${maxLengthFirstColumnHeading} characters.`;\n }\n\n const headersContent = (headers || []).map((heading) => getContent(heading));\n headersContent.shift(); // remove first column since it does not require validation\n\n headersContent.forEach((heading, index) => {\n const headerIndex = index + 1; // we need to add 1 because we removed first header from validation\n columnsErrors[headerIndex] = '';\n\n if (maxLengthAnswers && getInnerText(heading).length > maxLengthAnswers) {\n columnsErrors[headerIndex] += `Content length should be maximum ${maxLengthAnswers} characters. `;\n }\n\n if (!heading) {\n columnsErrors[headerIndex] += 'Content should not be empty.';\n } else {\n // check for identical content with the previous headers\n const identicalAnswer = headersContent.slice(0, index).some((head) => head === heading);\n\n if (identicalAnswer) {\n columnsErrors[index + 1] += 'Content should be unique.';\n }\n }\n });\n\n const hasRowErrors = Object.values(rowsErrors).some((error) => (error || '').length);\n\n if (hasRowErrors) {\n errors.rowsErrors = rowsErrors;\n\n const noCorrectAnswer = Object.values(rowsErrors).some((error) =>\n (error || '').includes('No correct response defined.'),\n );\n\n if (noCorrectAnswer) {\n errors.correctResponseError =\n choiceMode === 'radio'\n ? 'There should be a correct response defined for every row.'\n : 'There should be at least one correct response defined for every row.';\n }\n }\n\n const hasColumnErrors = Object.values(columnsErrors).some((error) => (error || '').length);\n\n if (hasColumnErrors) {\n errors.columnsErrors = columnsErrors;\n }\n\n return errors;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../shared/feedback/dist/index.js","../../../../../shared/controller-utils/dist/index.js","../../../src/controller/defaults.ts","../../../src/controller/index.ts"],"sourcesContent":["//#region src/defaults.ts\nvar e = {\n\tcorrect: {\n\t\ttype: \"default\",\n\t\tdefault: \"Correct\",\n\t\tcustom: \"Correct\"\n\t},\n\tincorrect: {\n\t\ttype: \"default\",\n\t\tdefault: \"Incorrect\",\n\t\tcustom: \"Incorrect\"\n\t},\n\tpartial: {\n\t\ttype: \"default\",\n\t\tdefault: \"Nearly\",\n\t\tcustom: \"Nearly\"\n\t},\n\tunanswered: {\n\t\ttype: \"default\",\n\t\tdefault: \"You have not entered a response\",\n\t\tcustom: \"You have not entered a response\"\n\t}\n};\n//#endregion\n//#region src/utils.ts\nfunction t(e) {\n\treturn e === \"partially-correct\" ? \"partial\" : e;\n}\n//#endregion\n//#region src/index.ts\nfunction n(n, r) {\n\tlet i = {\n\t\t...e,\n\t\t...r\n\t}, a = t(n), o = e[a] || {}, s = i[a] || o;\n\treturn {\n\t\tconfig: s,\n\t\tfallback: o[s.type || \"default\"]\n\t};\n}\nfunction r(e, t = {}) {\n\treturn new Promise((r) => {\n\t\tlet { config: a, fallback: o } = n(e, t);\n\t\ti(a, o).then(r);\n\t});\n}\nfunction i(e, t) {\n\treturn new Promise((n) => {\n\t\tif (!e || e.type === \"none\") {\n\t\t\tn(void 0);\n\t\t\treturn;\n\t\t}\n\t\tn(e[e.type] || t);\n\t});\n}\nfunction a(e, t = {}) {\n\tlet { config: r, fallback: i } = n(e, t);\n\treturn o(r, i);\n}\nfunction o(e, t) {\n\tif (!(!e || e.type === \"none\")) return e[e.type] || t;\n}\n//#endregion\nexport { e as defaultFeedback, o as getActualFeedback, a as getActualFeedbackForCorrectness, i as getFeedback, r as getFeedbackForCorrectness, t as normalizeCorrectness };\n","//#region \\0rolldown/runtime.js\nvar e = Object.defineProperty, t = (t, n) => {\n\tlet r = {};\n\tfor (var i in t) e(r, i, {\n\t\tget: t[i],\n\t\tenumerable: !0\n\t});\n\treturn n || e(r, Symbol.toStringTag, { value: \"Module\" }), r;\n};\n//#endregion\n//#region src/persistence.ts\nfunction n(e) {\n\treturn Array.isArray(e) ? e.filter((e) => e != null) : [];\n}\nfunction r(e) {\n\tlet t = [...e];\n\tfor (let e = t.length - 1; e > 0; e--) {\n\t\tlet n = Math.floor(Math.random() * (e + 1));\n\t\t[t[e], t[n]] = [t[n], t[e]];\n\t}\n\treturn t;\n}\nfunction i(e) {\n\treturn e == null ? !0 : Array.isArray(e) ? e.length === 0 : typeof e == \"object\" && Object.keys(e).length === 0;\n}\nasync function a(e, t, a, o = \"value\") {\n\tlet s = n(t?.data?.shuffledValues ?? t?.shuffledValues ?? []);\n\tif (!t) {\n\t\tconsole.warn(\"Unable to save shuffled choices because there's no session.\");\n\t\treturn;\n\t}\n\tif (!i(s)) return n(s.map((t) => e.find((e) => e[o] === t)));\n\tlet c = r(e);\n\tif (a && typeof a == \"function\") try {\n\t\tlet e = n(c.map((e) => e[o]));\n\t\ti(e) ? console.error(`shuffledValues is an empty array - refusing to call updateSession. shuffledChoices: ${JSON.stringify(c)}, key: ${o}`) : await a(t.id, t.element, { shuffledValues: e });\n\t} catch (e) {\n\t\tconsole.warn(\"Unable to save shuffled order for choices\"), console.error(e);\n\t}\n\telse console.warn(\"Unable to save shuffled choices, shuffle will happen every time.\");\n\treturn c;\n}\nfunction o(e, t, n) {\n\treturn !!(e.lockChoiceOrder || n?.[\"@pie-element\"]?.lockChoiceOrder);\n}\n//#endregion\n//#region src/partial-scoring.ts\nvar s = /* @__PURE__ */ t({ enabled: () => c });\nfunction c(e, t, n) {\n\treturn e?.partialScoring === !1 || t?.partialScoring === !1 ? !1 : typeof n != \"boolean\" || n;\n}\n//#endregion\nexport { a as getShuffledChoices, o as lockChoices, s as partialScoring };\n","import type { MatchModel, MatchRow } from '../types.js';\n\nexport default {\n choiceMode: 'radio',\n feedbackEnabled: false,\n headers: ['Column 1', 'Column 2', 'Column 3'],\n layout: 3,\n lockChoiceOrder: true,\n partialScoring: false,\n prompt: '',\n promptEnabled: true,\n rationale: '',\n rationaleEnabled: true,\n rows: [] as MatchRow[],\n scoringType: 'auto',\n studentInstructionsEnabled: true,\n teacherInstructions: '',\n teacherInstructionsEnabled: true,\n toolbarEditorPosition: 'bottom',\n} satisfies Omit<MatchModel, 'id' | 'element'>;\n","import { cloneDeep, isEmpty, isEqual } from '@pie-element/shared-lodash';\nimport { getFeedbackForCorrectness, type Correctness, type Feedback } from '@pie-element/shared-feedback';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-element/shared-controller-utils';\nimport type { PieEnvironment, PieUpdateSession } from '@pie-element/shared-types';\nimport debug from 'debug';\nimport type { MatchConfiguration, MatchModel, MatchRow, MatchSession } from '../types.js';\n\nconst log = debug('@pie-element:match:controller');\n\nimport defaults from './defaults.js';\n\n/** The learner's selections: for each row id, one flag per answer column. */\ntype Answers = Record<string, boolean[]>;\n\n/** The session shape the shared choice utilities take; ours may carry numeric row ids. */\ntype SharedSession = Parameters<typeof getShuffledChoices>[1];\n\n/** Errors `validate()` reports; `rowsErrors` is keyed by row id, `columnsErrors` by column index. */\nexport type MatchValidationErrors = {\n teacherInstructions?: string;\n prompt?: string;\n rationale?: string;\n noOfRowsError?: string;\n rowsErrors?: Record<string, string>;\n correctResponseError?: string;\n columnsLengthError?: string;\n columnsErrors?: Record<number, string>;\n};\n\n/** The model `model()` hands the delivery. */\ntype MatchViewModel = Omit<\n MatchModel,\n 'feedback' | 'feedbackEnabled' | 'prompt' | 'promptEnabled' | 'lockChoiceOrder' | 'rationale' | 'teacherInstructions'\n> & {\n allowFeedback?: boolean;\n prompt: string | null;\n shuffled: boolean;\n feedback?: string;\n disabled: boolean;\n view: boolean;\n rationale?: string | null;\n teacherInstructions?: string | null;\n correctResponse?: Answers;\n correctness?: { score: string; correctness?: Correctness };\n};\n\nconst getResponseCorrectness = (\n model: MatchModel,\n answers: Answers | undefined,\n env: Partial<PieEnvironment> = {},\n): Correctness => {\n const isPartialScoring = partialScoring.enabled(model, env);\n const rows = model.rows;\n const checkboxMode = model.choiceMode === 'checkbox';\n\n if (!answers || Object.keys(answers).length === 0) {\n return 'unanswered';\n }\n\n const totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);\n let correctAnswers: number;\n let incorrectAnswers = 0;\n\n if (checkboxMode) {\n const checkboxes = getCheckboxes(rows, answers);\n\n correctAnswers = checkboxes.correctAnswers;\n incorrectAnswers = checkboxes.incorrectAnswers;\n } else {\n correctAnswers = getCorrectRadios(rows, answers);\n }\n\n if (totalCorrectAnswers === correctAnswers && !incorrectAnswers) {\n return 'correct';\n } else if (correctAnswers === 0) {\n return 'incorrect';\n } else if (isPartialScoring) {\n return 'partial';\n }\n\n return 'incorrect';\n};\n\nconst getCorrectness = (\n question: MatchModel,\n env: Partial<PieEnvironment>,\n answers: Answers = {},\n): Correctness | undefined => {\n if (env.mode === 'evaluate') {\n return getResponseCorrectness(question, answers, env);\n }\n};\n\nconst getCheckboxes = (rows: MatchRow[], answers: Answers) => {\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n\n rows.forEach((row) => {\n const answer = answers[row.id];\n\n if (answer) {\n row.values.forEach((v, i) => {\n if (answer[i] && answer[i] === v) {\n correctAnswers += 1;\n } else if (answer[i] && answer[i] !== v) {\n incorrectAnswers += 1;\n }\n });\n }\n });\n\n return { correctAnswers, incorrectAnswers };\n};\n\nconst getCorrectRadios = (rows: MatchRow[], answers: Answers) => {\n let correctAnswers = 0;\n\n rows.forEach((row) => {\n if (isEqual(row.values, answers[row.id])) {\n correctAnswers += 1;\n }\n });\n\n return correctAnswers;\n};\n\nconst getTotalCorrect = (question: MatchModel) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n const matchingTable = checkboxMode ? (question.layout as number) - 1 : 1;\n return (question.rows.length || 0) * matchingTable;\n};\n\nconst getTotalCorrectAnswers = (question: MatchModel) => {\n let noOfTotalCorrectAnswers = 0;\n\n question.rows.forEach((row) => {\n row.values.forEach((value) => {\n if (value) {\n noOfTotalCorrectAnswers += 1;\n }\n });\n });\n\n return noOfTotalCorrectAnswers;\n};\n\nconst getPartialScore = (question: MatchModel, answers: Answers) => {\n const checkboxMode = question.choiceMode === 'checkbox';\n\n if (checkboxMode) {\n const { correctAnswers, incorrectAnswers } = getCheckboxes(question.rows, answers);\n const totalCorrect = getTotalCorrectAnswers(question);\n\n const total = totalCorrect === 0 ? 1 : totalCorrect;\n\n if (correctAnswers + incorrectAnswers > totalCorrect) {\n const extraAnswers = correctAnswers + incorrectAnswers - totalCorrect;\n const score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));\n\n return score < 0 ? 0 : score;\n } else {\n return parseFloat((correctAnswers / total).toFixed(2));\n }\n } else {\n const correctAnswers = getCorrectRadios(question.rows, answers);\n const totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);\n\n return parseFloat((correctAnswers / totalCorrect).toFixed(2));\n }\n};\n\nconst getOutComeScore = (question: MatchModel, env: Partial<PieEnvironment>, answers: Answers = {}) => {\n const correctness = getCorrectness(question, env, answers);\n const isPartialScoring = partialScoring.enabled(question, env);\n\n return correctness === 'correct'\n ? 1\n : correctness === 'partial' && isPartialScoring\n ? getPartialScore(question, answers)\n : 0;\n};\n\n/**\n * Generates detailed trace log for match item scoring evaluation\n * @param {Object} question\n * @param {Object} session\n * @param {Object} env\n * @returns {Array<string>} traceLog\n */\nexport const getLogTrace = (\n question: MatchModel,\n session: MatchSession | undefined,\n env: Partial<PieEnvironment>,\n) => {\n const traceLog: string[] = [];\n\n const answers = session?.answers || {};\n const rows = question?.rows || [];\n const checkboxMode = question.choiceMode === 'checkbox';\n\n if (!answers || Object.keys(answers).length === 0) {\n traceLog.push('Student did not provide any answer.');\n return traceLog;\n }\n\n traceLog.push(`Match item contains ${rows.length} row(s).`);\n traceLog.push(`Matching mode: ${checkboxMode ? 'checkbox (multiple matches allowed)' : 'radio (single match per row)'}.`);\n\n let correctCount = 0;\n let incorrectCount = 0;\n let totalCorrect = 0;\n\n rows.forEach((row) => {\n const studentAnswer = answers[row.id];\n const correctValues = row.values || [];\n\n if (checkboxMode) {\n correctValues.forEach((v, idx) => {\n if (v) {\n totalCorrect++;\n }\n\n if (studentAnswer && studentAnswer[idx]) {\n if (studentAnswer[idx] === v) {\n correctCount++;\n } else {\n incorrectCount++;\n }\n }\n });\n } else {\n totalCorrect++;\n if (studentAnswer) {\n if (isEqual(correctValues, studentAnswer)) {\n correctCount++;\n } else {\n incorrectCount++;\n }\n }\n }\n });\n\n if (correctCount > 0) {\n traceLog.push(`${correctCount} correct match(es) selected.`);\n }\n\n if (incorrectCount > 0) {\n traceLog.push(`${incorrectCount} incorrect match(es) selected.`);\n }\n\n if (correctCount === 0 && incorrectCount === 0) {\n traceLog.push('Student provided answers, but none matched the correct responses.');\n }\n\n const partialScoringEnabled = partialScoring.enabled(question, env);\n\n if (partialScoringEnabled) {\n traceLog.push('Score calculated using partial scoring.');\n\n if (checkboxMode) {\n traceLog.push(\n 'Score is based on the number of correct minus extra incorrect matches, divided by the total number of correct matches.',\n );\n\n if (correctCount + incorrectCount > totalCorrect) {\n traceLog.push('Extra selected matches beyond the correct set reduce the score.');\n }\n } else {\n traceLog.push(\n 'Score is based on the number of correctly matched rows divided by the total number of rows.',\n );\n }\n } else {\n traceLog.push('Score calculated using all-or-nothing scoring.');\n traceLog.push('Student must match all rows correctly to receive full credit.');\n }\n\n const rawScore = getOutComeScore(question, env, answers);\n const finalScore = partialScoringEnabled ? rawScore : rawScore === 1 ? 1 : 0;\n\n traceLog.push(`Final score: ${finalScore}.`);\n\n return traceLog;\n};\n\nexport const outcome = (question: MatchModel, session: MatchSession | undefined, env: PieEnvironment) => {\n return new Promise<{ score?: number; completed?: boolean; empty?: boolean; logTrace: string[] }>((resolve) => {\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined, logTrace: [] });\n } else {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true, logTrace: ['Student did not provide any answer.'] });\n }\n\n const out = {\n score: getOutComeScore(question, env, (session as MatchSession).answers),\n empty: false,\n logTrace: getLogTrace(question, session, env),\n };\n\n resolve(out);\n }\n });\n};\n\nexport function createDefaultModel(model: Partial<MatchModel> = {}) {\n return new Promise<Partial<MatchModel>>((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n}\n\nexport const normalize = (question: MatchModel) => ({ ...defaults, ...question });\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 async function model(\n question: MatchModel,\n session: MatchSession | undefined,\n env: PieEnvironment,\n updateSession?: PieUpdateSession,\n) {\n const normalizedQuestion = cloneDeep(normalize(question));\n let correctness: Correctness | undefined, score: string;\n\n if ((!session || isEmpty(session)) && env.mode === 'evaluate') {\n correctness = 'unanswered';\n score = '0%';\n } else {\n correctness = getCorrectness(normalizedQuestion, env, session && session.answers);\n score = `${getOutComeScore(normalizedQuestion, env, session && session.answers) * 100}%`;\n }\n\n const correctResponse: Answers = {};\n const correctInfo = {\n score,\n correctness,\n };\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session as SharedSession, env);\n\n if (!lockChoiceOrder) {\n // `undefined` without a session, which the `forEach` below then throws on\n normalizedQuestion.rows = (await getShuffledChoices(\n normalizedQuestion.rows,\n session as SharedSession,\n updateSession,\n 'id',\n )) as MatchRow[];\n }\n\n normalizedQuestion.rows.forEach((row) => {\n correctResponse[row.id] = row.values;\n\n if (env.mode !== 'evaluate') {\n delete (row as Partial<MatchRow>).values;\n }\n });\n\n const feedback =\n env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled\n ? await getFeedbackForCorrectness(\n correctInfo.correctness as Correctness,\n normalizedQuestion.feedback as Partial<Feedback> | undefined,\n )\n : undefined;\n\n const {\n extraCSSRules,\n feedbackEnabled,\n promptEnabled,\n prompt,\n lockChoiceOrder: _,\n ...essentials\n } = normalizedQuestion;\n const out: MatchViewModel = {\n ...essentials,\n extraCSSRules,\n allowFeedback: feedbackEnabled,\n prompt: promptEnabled ? prompt : null,\n shuffled: !lockChoiceOrder,\n feedback,\n disabled: env.mode !== 'gather',\n view: env.mode === 'view',\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n if (env.mode === 'evaluate') {\n Object.assign(out, {\n correctResponse,\n correctness: correctInfo,\n });\n }\n\n log('out: ', out);\n return out;\n}\n\nexport const createCorrectResponseSession = (question: MatchModel, env: PieEnvironment) => {\n return new Promise<MatchSession | null>((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { rows } = question;\n const answers: Answers = {};\n\n rows.forEach((r) => {\n answers[r.id] = r.values;\n });\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html: string | undefined) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html: string | undefined) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (\n model: Partial<MatchModel> = {},\n config: MatchConfiguration = {},\n): MatchValidationErrors => {\n const { rows, choiceMode, headers } = model;\n const {\n minQuestions,\n maxQuestions,\n maxLengthQuestionsHeading,\n maxAnswers,\n maxLengthAnswers,\n maxLengthFirstColumnHeading,\n } = config;\n const rowsErrors: Record<string, string> = {};\n const columnsErrors: Record<number, string> = {};\n const errors: MatchValidationErrors = {};\n\n (['teacherInstructions', 'prompt', 'rationale'] as const).forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n // without `rows` this throws; a missing bound compares false\n if ((rows as MatchRow[]).length < (minQuestions as number)) {\n errors.noOfRowsError = `There should be at least ${minQuestions} question rows.`;\n } else if ((rows as MatchRow[]).length > (maxQuestions as number)) {\n errors.noOfRowsError = `No more than ${maxQuestions} question rows should be defined.`;\n }\n\n (rows || []).forEach((row, index) => {\n const { id, values = [], title } = row;\n rowsErrors[id] = '';\n\n if (maxLengthQuestionsHeading && getInnerText(title).length > maxLengthQuestionsHeading) {\n rowsErrors[id] += `Content length should be maximum ${maxLengthQuestionsHeading} characters. `;\n }\n\n if (!getContent(title)) {\n rowsErrors[id] += 'Content should not be empty. ';\n } else {\n // check for identical content with the previous answers\n const identicalAnswer = (rows as MatchRow[])\n .slice(0, index)\n .some((r) => getContent(r.title) === getContent(title));\n\n if (identicalAnswer) {\n rowsErrors[id] += 'Content should be unique. ';\n }\n }\n\n const hasCorrectResponse = values.some((value) => !!value);\n\n if (!hasCorrectResponse) {\n rowsErrors[id] += 'No correct response defined.';\n }\n });\n\n if (maxAnswers && (headers as string[]).length - 1 > maxAnswers) {\n errors.columnsLengthError = `There should be maximum ${maxAnswers} answers.`;\n }\n\n if (maxLengthFirstColumnHeading && (headers as string[])[0].length > maxLengthFirstColumnHeading) {\n columnsErrors[0] = `Content length should be maximum ${maxLengthFirstColumnHeading} characters.`;\n }\n\n const headersContent = (headers || []).map((heading) => getContent(heading));\n headersContent.shift(); // remove first column since it does not require validation\n\n headersContent.forEach((heading, index) => {\n const headerIndex = index + 1; // we need to add 1 because we removed first header from validation\n columnsErrors[headerIndex] = '';\n\n if (maxLengthAnswers && getInnerText(heading).length > maxLengthAnswers) {\n columnsErrors[headerIndex] += `Content length should be maximum ${maxLengthAnswers} characters. `;\n }\n\n if (!heading) {\n columnsErrors[headerIndex] += 'Content should not be empty.';\n } else {\n // check for identical content with the previous headers\n const identicalAnswer = headersContent.slice(0, index).some((head) => head === heading);\n\n if (identicalAnswer) {\n columnsErrors[index + 1] += 'Content should be unique.';\n }\n }\n });\n\n const hasRowErrors = Object.values(rowsErrors).some((error) => (error || '').length);\n\n if (hasRowErrors) {\n errors.rowsErrors = rowsErrors;\n\n const noCorrectAnswer = Object.values(rowsErrors).some((error) =>\n (error || '').includes('No correct response defined.'),\n );\n\n if (noCorrectAnswer) {\n errors.correctResponseError =\n choiceMode === 'radio'\n ? 'There should be a correct response defined for every row.'\n : 'There should be at least one correct response defined for every row.';\n }\n }\n\n const hasColumnErrors = Object.values(columnsErrors).some((error) => (error || '').length);\n\n if (hasColumnErrors) {\n errors.columnsErrors = columnsErrors;\n }\n\n return errors;\n};\n"],"mappings":"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"}
|
|
@@ -19970,15 +19970,12 @@ var DT = class extends I.Component {
|
|
|
19970
19970
|
}), jT = (e) => typeof e == "string" ? {
|
|
19971
19971
|
label: e,
|
|
19972
19972
|
value: e
|
|
19973
|
-
} : e, MT =
|
|
19974
|
-
|
|
19975
|
-
|
|
19976
|
-
|
|
19977
|
-
|
|
19978
|
-
|
|
19979
|
-
isConfigProperty: n
|
|
19980
|
-
};
|
|
19981
|
-
}, NT = (e, t, n = !1) => ({
|
|
19973
|
+
} : e, MT = (e, t, n = !1) => ({
|
|
19974
|
+
type: "radio",
|
|
19975
|
+
label: e,
|
|
19976
|
+
choices: t && t.map((e) => jT(e)),
|
|
19977
|
+
isConfigProperty: n
|
|
19978
|
+
}), NT = (e, t, n = !1) => ({
|
|
19982
19979
|
type: "dropdown",
|
|
19983
19980
|
label: e,
|
|
19984
19981
|
choices: t,
|
|
@@ -20509,21 +20506,7 @@ var mE = (0, Uc.default)("pie-elements:match:configure"), hE = A("div")(({ theme
|
|
|
20509
20506
|
color: e.palette.error.main,
|
|
20510
20507
|
paddingTop: e.spacing(1)
|
|
20511
20508
|
})), ME = class extends I.Component {
|
|
20512
|
-
|
|
20513
|
-
onModelChanged: V.default.func,
|
|
20514
|
-
onConfigurationChanged: V.default.func,
|
|
20515
|
-
model: V.default.object.isRequired,
|
|
20516
|
-
configuration: V.default.object.isRequired,
|
|
20517
|
-
imageSupport: V.default.shape({
|
|
20518
|
-
add: V.default.func.isRequired,
|
|
20519
|
-
delete: V.default.func.isRequired
|
|
20520
|
-
}),
|
|
20521
|
-
uploadSoundSupport: V.default.shape({
|
|
20522
|
-
add: V.default.func.isRequired,
|
|
20523
|
-
delete: V.default.func.isRequired
|
|
20524
|
-
})
|
|
20525
|
-
};
|
|
20526
|
-
static defaultProps = {};
|
|
20509
|
+
rowIdCounter;
|
|
20527
20510
|
constructor(e) {
|
|
20528
20511
|
super(e);
|
|
20529
20512
|
let t = 0;
|
|
@@ -20602,7 +20585,8 @@ var mE = (0, Uc.default)("pie-elements:match:configure"), hE = A("div")(({ theme
|
|
|
20602
20585
|
onResponseTypeChange = (e) => {
|
|
20603
20586
|
let { model: t } = this.props, n = { ...t };
|
|
20604
20587
|
e === "radio" && n.rows.forEach((e) => {
|
|
20605
|
-
e.values.reduce((e, t) => t === !0 ? e + 1 : e)
|
|
20588
|
+
let n = e.values.reduce((e, t) => t === !0 ? Number(e) + 1 : e);
|
|
20589
|
+
Number(n) > 1 && (e.values = Array(t.layout - 1).fill(!1));
|
|
20606
20590
|
}), n.choiceMode = e, this.onChange(n);
|
|
20607
20591
|
};
|
|
20608
20592
|
onPartialScoringChange = (e) => {
|
|
@@ -20952,6 +20936,11 @@ var mE = (0, Uc.default)("pie-elements:match:configure"), hE = A("div")(({ theme
|
|
|
20952
20936
|
}
|
|
20953
20937
|
}
|
|
20954
20938
|
}, zE = (0, Uc.default)("pie-elements:match:configure"), BE = class e extends HTMLElement {
|
|
20939
|
+
_root;
|
|
20940
|
+
_model;
|
|
20941
|
+
_modelCopy;
|
|
20942
|
+
_configuration;
|
|
20943
|
+
hasPlayerAsParent;
|
|
20955
20944
|
static createDefaultModel = (e = {}) => ({
|
|
20956
20945
|
...RE.model,
|
|
20957
20946
|
...e
|
|
@@ -20971,10 +20960,16 @@ var mE = (0, Uc.default)("pie-elements:match:configure"), hE = A("div")(({ theme
|
|
|
20971
20960
|
...RE.configuration,
|
|
20972
20961
|
...e
|
|
20973
20962
|
};
|
|
20974
|
-
this._configuration = t, this.resetModelAfterConfigurationIsSet(), t?.language?.enabled
|
|
20975
|
-
|
|
20976
|
-
|
|
20977
|
-
|
|
20963
|
+
if (this._configuration = t, this.resetModelAfterConfigurationIsSet(), t?.language?.enabled) t?.languageChoices?.options?.length && (this._model.language = t?.languageChoices.options[0].value);
|
|
20964
|
+
else if (t.language.settings && this._model.language) {
|
|
20965
|
+
t.language.enabled = !0, (!t.languageChoices.options || !t.languageChoices.options.length) && (t.languageChoices.options = []);
|
|
20966
|
+
let e = this._model.language;
|
|
20967
|
+
t.languageChoices.options.find((t) => t.value === e) || t.languageChoices.options.push({
|
|
20968
|
+
value: e,
|
|
20969
|
+
label: e
|
|
20970
|
+
});
|
|
20971
|
+
} else delete this._model.language;
|
|
20972
|
+
dt(e?.rows?.inputConfiguration) && (at(t.rows, "inputConfiguration.image.disabled", !this._model?.enableImages), at(t.rows, "inputConfiguration.video.disabled", !0), at(t.rows, "inputConfiguration.audio.disabled", !0)), this._render();
|
|
20978
20973
|
}
|
|
20979
20974
|
onModelChanged(e) {
|
|
20980
20975
|
this._model = e, zE("[onModelChanged]: ", this._model), this._render(), this.dispatchEvent(new NE(this._model));
|