{"version":3,"file":"414.js","mappings":"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","sources":["webpack://WebComponents/./runestone/fitb/js/fitb-i18n.en.js","webpack://WebComponents/./runestone/fitb/js/fitb-i18n.pt-br.js","webpack://WebComponents/./runestone/fitb/js/fitb-utils.js","webpack://WebComponents/./runestone/fitb/js/fitb.js","webpack://WebComponents/./runestone/fitb/js/libs/aleaPRNG-1.1.js","webpack://WebComponents/./runestone/fitb/js/timedfitb.js"],"sourcesContent":["$.i18n().load({\n en: {\n msg_no_answer: \"No answer provided.\",\n msg_fitb_check_me: \"Check me\",\n msg_fitb_compare_me: \"Compare me\",\n msg_fitb_randomize: \"Randomize\",\n },\n});\n","$.i18n().load({\n \"pt-br\": {\n msg_no_answer: \"Nenhuma resposta dada.\",\n msg_fitb_check_me: \"Verificar\",\n msg_fitb_compare_me: \"Comparar\"\n },\n});\n","// ********************************************************\n// |docname| - grading-related utilities for FITB questions\n// ********************************************************\n// This code runs both on the server (for server-side grading) and on the client. It's placed here as a set of functions specifically for this purpose.\n\n\"use strict\";\n\nimport { aleaPRNG } from \"./libs/aleaPRNG-1.1.js\";\n\n// Includes\n// ========\n// None.\n//\n//\n// Globals\n// =======\nfunction render_html(html_in, dyn_vars_eval) {\n // Change the replacement tokens in the HTML into tags, so we can replace them using XML. The horrible regex is:\n //\n // Look for the characters ``[%=`` (the opening delimiter)\n /// \\[%=\n // Followed by any amount of whitespace.\n /// \\s*\n // Start a group that will capture the contents (excluding whitespace) of the tokens. For example, given ``[%= foo() %]``, the contents is ``foo()``.\n /// (\n // Don't capture the contents of this group, since it's only a single character. Match any character...\n /// (\n /// ?:.\n /// ...that doesn't end with ``%]`` (the closing delimiter).\n /// (?!%])\n /// )\n // Match this (anything but the closing delimiter) as much as we can.\n /// *)\n // Next, look for any whitespace.\n /// \\s*\n // Finally, look for the closing delimiter ``%]``.\n /// %\\]\n const html_replaced = html_in.replaceAll(\n /\\[%=\\s*((?:.(?!%]))*)\\s*%\\]/g,\n // Replace it with a `` tag. Quote the string, which will automatically escape any double quotes, using JSON.\n (match, group1) =>\n ``\n );\n // Given HTML, turn it into a DOM. Walk the ```` tags, performing the requested evaluation on them.\n //\n // See `DOMParser `_.\n const parser = new DOMParser();\n // See `DOMParser.parseFromString() `_.\n const doc = parser.parseFromString(html_replaced, \"text/html\");\n const script_eval_tags = doc.getElementsByTagName(\"script-eval\");\n while (script_eval_tags.length) {\n // Get the first tag. It will be removed from the collection after it's replaced with its value.\n const script_eval_tag = script_eval_tags[0];\n // See if this ```` tag has as ``@expr`` attribute.\n const expr = script_eval_tag.getAttribute(\"expr\");\n // If so, evaluate it.\n if (expr) {\n const eval_result = window.Function(\n \"v\",\n ...Object.keys(dyn_vars_eval),\n `\"use strict;\"\\nreturn ${expr};`\n )(dyn_vars_eval, ...Object.values(dyn_vars_eval));\n // Replace the tag with the resulting value.\n script_eval_tag.replaceWith(eval_result);\n }\n }\n\n // Return the body contents. Note that the ``DOMParser`` constructs an entire document, not just the document fragment we passed it. Therefore, extract the desired fragment and return that. Note that we need to use `childNodes `_, which includes non-element children like text and comments; using ``children`` omits these non-element children.\n return doc.body.childNodes;\n}\n\n// Functions\n// =========\n// Update the problem's description based on dynamically-generated content.\nexport function renderDynamicContent(\n seed,\n dyn_vars,\n dyn_imports,\n html_in,\n divid,\n prepareCheckAnswers\n) {\n // Initialize RNG with ``seed``.\n const rand = aleaPRNG(seed);\n\n // See `RAND_FUNC `_, which refers to ``rand`` above.\n const dyn_vars_eval = window.Function(\n \"v\",\n \"rand\",\n ...Object.keys(dyn_imports),\n `\"use strict\";\\n${dyn_vars};\\nreturn v;`\n )(\n // We want v.divid = divid and v.prepareCheckAnswers = prepareCheckAnswers. In contrast, the key/values pairs of dyn_imports should be directly assigned to v, hence the Object.assign.\n Object.assign({ divid, prepareCheckAnswers}, dyn_imports),\n rand,\n // In addition to providing this in v, make it available in the function as well, since most problem authors will write ``foo = new BTM()`` (for example, assuming BTM is in dyn_imports) instead of ``foo = new v.BTM()`` (which is unusual syntax).\n ...Object.values(dyn_imports));\n\n let html_out;\n if (typeof dyn_vars_eval.beforeContentRender === \"function\") {\n try {\n dyn_vars_eval.beforeContentRender(dyn_vars_eval);\n } catch (err) {\n console.assert(false,\n `Error in problem ${divid} invoking beforeContentRender`\n );\n throw err;\n }\n }\n try {\n html_out = render_html(html_in, dyn_vars_eval);\n } catch (err) {\n console.assert(false, `Error rendering problem ${divid} text.`);\n throw err;\n }\n\n // the afterContentRender event will be called by the caller of this function (after it updated the HTML based on the contents of html_out).\n return [html_out, dyn_vars_eval];\n}\n\n// Given student answers, grade them and provide feedback.\n//\n// Outputs:\n//\n// - ``displayFeed`` is an array of HTML feedback.\n// - ``isCorrectArray`` is an array of true, false, or null (the question wasn't answered).\n// - ``correct`` is true, false, or null (the question wasn't answered).\n// - ``percent`` is the percentage of correct answers (from 0 to 1, not 0 to 100).\nexport function checkAnswersCore(\n // _`blankNamesDict`: An dict of {blank_name, blank_index} specifying the name for each named blank.\n blankNamesDict,\n // _`given_arr`: An array of strings containing student-provided answers for each blank.\n given_arr,\n // A 2-D array of strings giving feedback for each blank.\n feedbackArray,\n // _`dyn_vars_eval`: A dict produced by evaluating the JavaScript for a dynamic exercise.\n dyn_vars_eval\n) {\n if (\n dyn_vars_eval &&\n typeof dyn_vars_eval.beforeCheckAnswers === \"function\"\n ) {\n const [namedBlankValues, given_arr_converted] = parseAnswers(\n blankNamesDict,\n given_arr,\n dyn_vars_eval\n );\n const dve_blanks = Object.assign({}, dyn_vars_eval, namedBlankValues);\n try {\n dyn_vars_eval.beforeCheckAnswers(dve_blanks, given_arr_converted);\n } catch (err) {\n console.assert(false, \"Error calling beforeCheckAnswers\");\n throw err;\n }\n }\n\n // Keep track if all answers are correct or not.\n let correct = true;\n const isCorrectArray = [];\n const displayFeed = [];\n for (let i = 0; i < given_arr.length; i++) {\n const given = given_arr[i];\n // If this blank is empty, provide no feedback for it.\n if (given === \"\") {\n isCorrectArray.push(null);\n // TODO: was $.i18n(\"msg_no_answer\").\n displayFeed.push(\"No answer provided.\");\n correct = false;\n } else {\n // Look through all feedback for this blank. The last element in the array always matches. If no feedback for this blank exists, use an empty list.\n const fbl = feedbackArray[i] || [];\n let j;\n for (j = 0; j < fbl.length; j++) {\n // The last item of feedback always matches.\n if (j === fbl.length - 1) {\n displayFeed.push(fbl[j][\"feedback\"]);\n break;\n }\n // If this is a regexp...\n if (\"regex\" in fbl[j]) {\n const patt = RegExp(\n fbl[j][\"regex\"],\n fbl[j][\"regexFlags\"]\n );\n if (patt.test(given)) {\n displayFeed.push(fbl[j][\"feedback\"]);\n break;\n }\n } else if (\"number\" in fbl[j]) {\n // This is a number.\n const [min, max] = fbl[j][\"number\"];\n // Convert the given string to a number. While there are `lots of ways `_ to do this; this version supports other bases (hex/binary/octal) as well as floats.\n const actual = +given;\n if (actual >= min && actual <= max) {\n displayFeed.push(fbl[j][\"feedback\"]);\n break;\n }\n // If this is a dynamic solution, they should provide a testing function\n } else if (dyn_vars_eval) {\n const [namedBlankValues, given_arr_converted] =\n parseAnswers(blankNamesDict, given_arr, dyn_vars_eval);\n // If there was a parse error, then it student's answer is incorrect.\n if (given_arr_converted[i] instanceof TypeError) {\n displayFeed.push(given_arr_converted[i].message);\n // Count this as wrong by making j != 0 -- see the code that runs immediately after the executing the break.\n j = 1;\n break;\n }\n // Create a function to wrap the expression to evaluate. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function.\n // Pass the answer, array of all answers, then all entries in ``this.dyn_vars_eval`` dict as function parameters.\n const is_equal = window.Function(\n \"ans\",\n \"ans_array\",\n ...Object.keys(dyn_vars_eval),\n ...Object.keys(namedBlankValues),\n `\"use strict;\"\\nreturn ${fbl[j][\"solution_code\"]};`\n )(\n given_arr_converted[i],\n given_arr_converted,\n ...Object.values(dyn_vars_eval),\n ...Object.values(namedBlankValues)\n );\n // If student's answer is equal to this item, then append this item's feedback.\n if (is_equal) {\n displayFeed.push(\n typeof is_equal === \"string\"\n ? is_equal\n : fbl[j][\"feedback\"]\n );\n break;\n }\n // If this is NOT a dynamic solution, but given a testing function\n } else if (\"solution_code\" in fbl[j]) {\n // Create a function to wrap the expression to evaluate. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function.\n // Pass the answer, array of all answers, then all entries in ``this.dyn_vars_eval`` dict as function parameters.\n const is_equal = window.Function(\n \"ans\",\n \"ans_array\",\n `\"use strict;\"\\nreturn ${fbl[j][\"solution_code\"]};`\n )(given, given_arr);\n // If student's answer is equal to this item, then append this item's feedback.\n if (is_equal) {\n displayFeed.push(\n typeof is_equal === \"string\"\n ? is_equal\n : fbl[j][\"feedback\"]\n );\n break;\n }\n } else {\n // Undefined method of testing.\n console.assert(\"number\" in fbl[j]);\n }\n }\n\n // The answer is correct if it matched the first element in the array. A special case: if only one answer is provided, count it wrong; this is a misformed problem.\n const is_correct = j === 0 && fbl.length > 1;\n isCorrectArray.push(is_correct);\n if (!is_correct) {\n correct = false;\n }\n }\n }\n\n if (\n dyn_vars_eval &&\n typeof dyn_vars_eval.afterCheckAnswers === \"function\"\n ) {\n const [namedBlankValues, given_arr_converted] = parseAnswers(\n blankNamesDict,\n given_arr,\n dyn_vars_eval\n );\n const dve_blanks = Object.assign({}, dyn_vars_eval, namedBlankValues);\n try {\n dyn_vars_eval.afterCheckAnswers(dve_blanks, given_arr_converted);\n } catch (err) {\n console.assert(false, \"Error calling afterCheckAnswers\");\n throw err;\n }\n }\n\n const percent =\n isCorrectArray.filter(Boolean).length / isCorrectArray.length;\n return [displayFeed, correct, isCorrectArray, percent];\n}\n\n// Use the provided parsers to convert a student's answers (as strings) to the type produced by the parser for each blank.\nfunction parseAnswers(\n // See blankNamesDict_.\n blankNamesDict,\n // See given_arr_.\n given_arr,\n // See `dyn_vars_eval`.\n dyn_vars_eval\n) {\n // Provide a dict of {blank_name, converter_answer_value}.\n const namedBlankValues = getNamedBlankValues(\n given_arr,\n blankNamesDict,\n dyn_vars_eval\n );\n // Invert blankNamedDict: compute an array of [blank_0_name, ...]. Note that the array may be sparse: it only contains values for named blanks.\n const given_arr_names = [];\n for (const [k, v] of Object.entries(blankNamesDict)) {\n given_arr_names[v] = k;\n }\n // Compute an array of [converted_blank_0_val, ...]. Note that this re-converts all the values, rather than (possibly deep) copying the values from already-converted named blanks.\n const given_arr_converted = given_arr.map((value, index) =>\n type_convert(given_arr_names[index], value, index, dyn_vars_eval)\n );\n\n return [namedBlankValues, given_arr_converted];\n}\n\n// Render the feedback for a dynamic problem.\nexport function renderDynamicFeedback(\n // See blankNamesDict_.\n blankNamesDict,\n // See given_arr_.\n given_arr,\n // The index of this blank in given_arr_.\n index,\n // The feedback for this blank, containing a template to be rendered.\n displayFeed_i,\n // See dyn_vars_eval_.\n dyn_vars_eval\n) {\n // Use the answer, an array of all answers, the value of all named blanks, and all solution variables for the template.\n const namedBlankValues = getNamedBlankValues(\n given_arr,\n blankNamesDict,\n dyn_vars_eval\n );\n const sol_vars_plus = Object.assign(\n {\n ans: given_arr[index],\n ans_array: given_arr,\n },\n dyn_vars_eval,\n namedBlankValues\n );\n try {\n displayFeed_i = render_html(displayFeed_i, sol_vars_plus);\n } catch (err) {\n console.assert(false, `Error evaluating feedback index ${index}.`);\n throw err;\n }\n\n return displayFeed_i;\n}\n\n// Utilities\n// ---------\n// For each named blank, get the value for the blank: the value of each ``blankName`` gives the index of the blank for that name.\nfunction getNamedBlankValues(given_arr, blankNamesDict, dyn_vars_eval) {\n const namedBlankValues = {};\n for (const [blank_name, blank_index] of Object.entries(blankNamesDict)) {\n namedBlankValues[blank_name] = type_convert(\n blank_name,\n given_arr[blank_index],\n blank_index,\n dyn_vars_eval\n );\n }\n return namedBlankValues;\n}\n\n// Convert a value given its type.\nfunction type_convert(name, value, index, dyn_vars_eval) {\n // The converter can be defined by index, name, or by a single value (which applies to all blanks). If not provided, just pass the data through.\n const types = dyn_vars_eval.types || pass_through;\n const converter = types[name] || types[index] || types;\n // ES5 hack: it doesn't support binary values, and js2py doesn't allow me to override the ``Number`` class. So, define the workaround class ``Number_`` and use it if available.\n if (converter === Number && typeof Number_ !== \"undefined\") {\n converter = Number_;\n }\n\n // Return the converted type. If the converter raises a TypeError, return that; it will be displayed to the user, since we assume type errors are a way for the parser to explain to the user why the parse failed. For all other errors, re-throw it since something went wrong.\n try {\n return converter(value);\n } catch (err) {\n if (err instanceof TypeError) {\n return err;\n } else {\n throw err;\n }\n }\n}\n\n// A pass-through \"converter\".\nfunction pass_through(val) {\n return val;\n}\n","// ***********************************************\n// |docname| -- fill-in-the-blank client-side code\n// ***********************************************\n// This file contains the JS for the Runestone fillintheblank component. It was created By Isaiah Mayerchak and Kirby Olson, 6/4/15 then revised by Brad Miller, 2/7/20.\n//\n// Data storage notes\n// ==================\n//\n// Initial problem restore\n// -----------------------\n// In the constructor, this code (the client) restores the problem by calling ``checkServer``. To do so, either the server sends or local storage has:\n//\n// - seed (used only for dynamic problems)\n// - answer\n// - displayFeed (server-side grading only; otherwise, this is generated locally by client code)\n// - correct (SSG)\n// - isCorrectArray (SSG)\n// - problemHtml (SSG with dynamic problems only)\n//\n// If any of the answers are correct, then the client shows feedback. This is implemented in restoreAnswers_.\n//\n// Grading\n// -------\n// When the user presses the \"Check me\" button, the logCurrentAnswer_ function:\n//\n// - Saves the following to local storage:\n//\n// - seed\n// - answer\n// - timestamp\n// - problemHtml\n//\n// Note that there's no point in saving displayFeed, correct, or isCorrectArray, since these values applied to the previous answer, not the new answer just submitted.\n//\n// - Sends the following to the server; stop after this for client-side grading:\n//\n// - seed (ignored for server-side grading)\n// - answer\n// - correct (ignored for SSG)\n// - percent (ignored for SSG)\n//\n// - Receives the following from the server:\n//\n// - timestamp\n// - displayFeed\n// - correct\n// - isCorrectArray\n//\n// - Saves the following to local storage:\n//\n// - seed\n// - answer\n// - timestamp\n// - displayFeed (SSG only)\n// - correct (SSG only)\n// - isCorrectArray (SSG only)\n// - problemHtml\n//\n// Randomize\n// ---------\n// When the user presses the \"Randomize\" button (which is only available for dynamic problems), the randomize_ function:\n//\n// - For the client-side case, sets the seed to a new, random value. For the server-side case, requests a new seed and problemHtml from the server.\n// - Sets the answer to an array of empty strings.\n// - Saves the usual local data.\n\n\"use strict\";\n\nimport RunestoneBase from \"../../common/js/runestonebase.js\";\nimport {\n renderDynamicContent,\n checkAnswersCore,\n renderDynamicFeedback,\n} from \"./fitb-utils.js\";\nimport \"./fitb-i18n.en.js\";\nimport \"./fitb-i18n.pt-br.js\";\nimport \"../css/fitb.css\";\n\n// Object containing all instances of FITB that aren't a child of a timed assessment.\nexport var FITBList = {};\n\n// FITB constructor\nexport default class FITB extends RunestoneBase {\n constructor(opts) {\n super(opts);\n var orig = opts.orig; // entire

element\n this.useRunestoneServices = opts.useRunestoneServices;\n this.origElem = orig;\n this.divid = orig.id;\n this.correct = null;\n // See comments in fitb.py for the format of ``feedbackArray`` (which is identical in both files).\n //\n // Find the script tag containing JSON and parse it. See `SO `__. If this tag doesn't exist, then no feedback is available; server-side grading will be performed.\n //\n // A destructuring assignment would be perfect, but they don't work with ``this.blah`` and ``with`` statements aren't supported in strict mode.\n const json_element = this.scriptSelector(this.origElem);\n const dict_ = JSON.parse(json_element.html());\n json_element.remove();\n // Check for older versions that have raw html content.\n if (dict_.problemHtml !== undefined) {\n this.problemHtml = dict_.problemHtml;\n this.dyn_vars = dict_.dyn_vars;\n this.blankNames = dict_.blankNames;\n this.feedbackArray = dict_.feedbackArray;\n } else {\n this.problemHtml = this.origElem.innerHTML;\n this.feedbackArray = dict_;\n }\n\n this.createFITBElement();\n this.setupBlanks();\n this.caption = \"Fill in the Blank\";\n this.addCaption(\"runestone\");\n\n // Define a promise which imports any libraries needed by dynamic problems.\n this.dyn_imports = {};\n let imports_promise = Promise.resolve();\n if (dict_.dyn_imports !== undefined) {\n // Collect all import promises.\n let import_promises = [];\n for (const import_ of dict_.dyn_imports) {\n switch (import_) {\n // For imports known at webpack build, bring these in.\n case \"BTM\":\n import_promises.push(\n import(\"btm-expressions/src/BTM_root.js\")\n );\n break;\n // Allow for local imports, usually from problems defined outside the Runestone Components.\n default:\n import_promises.push(\n import(/* webpackIgnore: true */ import_)\n );\n break;\n }\n }\n\n // Combine the resulting module namespace objects when these promises resolve.\n imports_promise = Promise.all(import_promises)\n .then(\n (module_namespace_arr) =>\n (this.dyn_imports = Object.assign(\n {},\n ...module_namespace_arr\n ))\n )\n .catch((err) => {\n throw `Failed dynamic import: ${err}.`;\n });\n }\n\n // Resolve these promises.\n imports_promise.then(() => {\n this.checkServer(\"fillb\", false).then(() => {\n // One option for a dynamic problem is to produce a static problem by providing a fixed seed value. This is typically used when the goal is to render the problem as an image for inclusion in static content (a PDF, etc.). To support this, consider the following cases:\n //\n /// Case Has static seed? Is a client-side, dynamic problem? Has local seed? Result\n /// 0 No No X No action needed.\n /// 1 No Yes No this.randomize().\n /// 2 No Yes Yes No action needed -- problem already restored from local storage.\n /// 3 Yes No X Warning: seed ignored.\n /// 4 Yes Yes No Assign seed; this.renderDynamicContent().\n /// 5 Yes Yes Yes If seeds differ, issue warning. No additional action needed -- problem already restored from local storage.\n\n const has_static_seed = dict_.static_seed !== undefined;\n const is_client_dynamic = typeof this.dyn_vars === \"string\";\n const has_local_seed = this.seed !== undefined;\n\n // Case 1\n if (!has_static_seed && is_client_dynamic && !has_local_seed) {\n this.randomize();\n }\n // Case 3\n else if (has_static_seed && !is_client_dynamic) {\n console.assert(\n false,\n \"Warning: the provided static seed was ignored, because it only affects client-side, dynamic problems.\"\n );\n }\n // Case 4\n else if (\n has_static_seed &&\n is_client_dynamic &&\n !has_local_seed\n ) {\n this.seed = dict_.static_seed;\n this.renderDynamicContent();\n }\n // Case 5\n else if (\n has_static_seed &&\n is_client_dynamic &&\n has_local_seed &&\n this.seed !== dict_.static_seed\n ) {\n console.assert(\n false,\n \"Warning: the provided static seed was overridden by the seed found in local storage.\"\n );\n }\n // Cases 0 and 2\n else {\n // No action needed.\n }\n\n if (typeof Prism !== \"undefined\") {\n Prism.highlightAllUnder(this.containerDiv);\n }\n\n this.indicate_component_ready();\n });\n });\n this.queueMathJax(this.descriptionDiv);\n }\n\n // Find the script tag containing JSON in a given root DOM node.\n scriptSelector(root_node) {\n return $(root_node).find(`script[type=\"application/json\"]`);\n }\n\n /*===========================================\n ==== Functions generating final HTML ====\n ===========================================*/\n createFITBElement() {\n this.renderFITBInput();\n this.renderFITBButtons();\n this.renderFITBFeedbackDiv();\n // replaces the intermediate HTML for this component with the rendered HTML of this component\n $(this.origElem).replaceWith(this.containerDiv);\n }\n renderFITBInput() {\n // The text [input] elements are created by the template.\n this.containerDiv = document.createElement(\"div\");\n this.containerDiv.id = this.divid;\n // Create another container which stores the problem description.\n this.descriptionDiv = document.createElement(\"div\");\n this.containerDiv.appendChild(this.descriptionDiv);\n // Copy the original elements to the container holding what the user will see (client-side grading only).\n if (this.problemHtml) {\n this.descriptionDiv.innerHTML = this.problemHtml;\n // Save original HTML (with templates) used in dynamic problems.\n this.descriptionDiv.origInnerHTML = this.problemHtml;\n }\n }\n\n renderFITBButtons() {\n this.containerDiv.appendChild(document.createElement(\"br\"));\n this.containerDiv.appendChild(document.createElement(\"br\"));\n\n // \"submit\" button\n this.submitButton = document.createElement(\"button\");\n this.submitButton.textContent = $.i18n(\"msg_fitb_check_me\");\n $(this.submitButton).attr({\n class: \"btn btn-success\",\n name: \"do answer\",\n type: \"button\",\n });\n this.submitButton.addEventListener(\n \"click\",\n async function () {\n this.checkCurrentAnswer();\n await this.logCurrentAnswer();\n }.bind(this),\n false\n );\n this.containerDiv.appendChild(this.submitButton);\n\n // \"compare me\" button\n if (this.useRunestoneServices) {\n this.compareButton = document.createElement(\"button\");\n $(this.compareButton).attr({\n class: \"btn btn-default\",\n id: this.origElem.id + \"_bcomp\",\n disabled: \"\",\n name: \"compare\",\n });\n this.compareButton.textContent = $.i18n(\"msg_fitb_compare_me\");\n this.compareButton.addEventListener(\n \"click\",\n function () {\n this.compareFITBAnswers();\n }.bind(this),\n false\n );\n this.containerDiv.appendChild(this.compareButton);\n }\n\n // Randomize button for dynamic problems.\n if (this.dyn_vars) {\n this.randomizeButton = document.createElement(\"button\");\n $(this.randomizeButton).attr({\n class: \"btn btn-default\",\n id: this.origElem.id + \"_bcomp\",\n name: \"randomize\",\n });\n this.randomizeButton.textContent = $.i18n(\"msg_fitb_randomize\");\n this.randomizeButton.addEventListener(\n \"click\",\n function () {\n this.randomize();\n }.bind(this),\n false\n );\n this.containerDiv.appendChild(this.randomizeButton);\n }\n\n this.containerDiv.appendChild(document.createElement(\"div\"));\n }\n renderFITBFeedbackDiv() {\n this.feedBackDiv = document.createElement(\"div\");\n this.feedBackDiv.id = this.divid + \"_feedback\";\n this.containerDiv.appendChild(document.createElement(\"br\"));\n this.containerDiv.appendChild(this.feedBackDiv);\n }\n\n clearFeedbackDiv() {\n // Setting the ``outerHTML`` removes this from the DOM. Use an alternative process -- remove the class (which makes it red/green based on grading) and content.\n this.feedBackDiv.innerHTML = \"\";\n this.feedBackDiv.className = \"\";\n }\n\n // Update the problem's description based on dynamically-generated content.\n renderDynamicContent() {\n // ``this.dyn_vars`` can be true; if so, don't render it, since the server does all the rendering.\n if (typeof this.dyn_vars === \"string\") {\n let html_nodes;\n [html_nodes, this.dyn_vars_eval] = renderDynamicContent(\n this.seed,\n this.dyn_vars,\n this.dyn_imports,\n this.descriptionDiv.origInnerHTML,\n this.divid,\n this.prepareCheckAnswers.bind(this)\n );\n this.descriptionDiv.replaceChildren(...html_nodes);\n\n if (typeof this.dyn_vars_eval.afterContentRender === \"function\") {\n try {\n this.dyn_vars_eval.afterContentRender(this.dyn_vars_eval);\n } catch (err) {\n console.assert(\n false,\n `Error in problem ${this.divid} invoking afterContentRender`\n );\n throw err;\n }\n }\n\n this.setupBlanks();\n }\n }\n\n setupBlanks() {\n // Find and format the blanks. If a dynamic problem just changed the HTML, this will find the newly-created blanks.\n const ba = $(this.descriptionDiv).find(\":input\");\n ba.attr(\"class\", \"form form-control selectwidthauto\");\n ba.attr(\"aria-label\", \"input area\");\n this.blankArray = ba.toArray();\n for (let blank of this.blankArray) {\n $(blank).change(this.recordAnswered.bind(this));\n }\n }\n\n // This tells timed questions that the fitb blanks received some interaction.\n recordAnswered() {\n this.isAnswered = true;\n }\n\n /*===================================\n === Checking/loading from storage ===\n ===================================*/\n restoreAnswers(data) {\n // Restore the seed first, since the dynamic render clears all the blanks.\n this.seed = data.seed;\n this.renderDynamicContent();\n this.queueMathJax(this.descriptionDiv);\n\n var arr;\n // Restore answers from storage retrieval done in RunestoneBase.\n try {\n // The newer format encodes data as a JSON object.\n arr = JSON.parse(data.answer);\n // The result should be an array. If not, try comma parsing instead.\n if (!Array.isArray(arr)) {\n throw new Error();\n }\n } catch (err) {\n // The old format didn't.\n arr = (data.answer || \"\").split(\",\");\n }\n let hasAnswer = false;\n for (var i = 0; i < this.blankArray.length; i++) {\n $(this.blankArray[i]).attr(\"value\", arr[i]);\n if (arr[i]) {\n hasAnswer = true;\n }\n }\n // Is this client-side grading, or server-side grading?\n if (this.feedbackArray) {\n // For client-side grading, re-generate feedback if there's an answer.\n if (hasAnswer) {\n this.checkCurrentAnswer();\n }\n } else {\n // For server-side grading, use the provided feedback from the server or local storage.\n this.displayFeed = data.displayFeed;\n this.correct = data.correct;\n this.isCorrectArray = data.isCorrectArray;\n // Only render if all the data is present; local storage might have old data missing some of these items.\n if (\n typeof this.displayFeed !== \"undefined\" &&\n typeof this.correct !== \"undefined\" &&\n typeof this.isCorrectArray !== \"undefined\"\n ) {\n this.renderFeedback();\n }\n // For server-side dynamic problems, show the rendered problem text.\n this.problemHtml = data.problemHtml;\n if (this.problemHtml) {\n this.descriptionDiv.innerHTML = this.problemHtml;\n this.queueMathJax(this.descriptionDiv);\n this.setupBlanks();\n }\n }\n }\n\n checkLocalStorage() {\n // Loads previous answers from local storage if they exist\n var storedData;\n if (this.graderactive) {\n return;\n }\n var len = localStorage.length;\n if (len > 0) {\n var ex = localStorage.getItem(this.localStorageKey());\n if (ex !== null) {\n try {\n storedData = JSON.parse(ex);\n var arr = storedData.answer;\n } catch (err) {\n // error while parsing; likely due to bad value stored in storage\n console.assert(false, err.message);\n localStorage.removeItem(this.localStorageKey());\n return;\n }\n this.restoreAnswers(storedData);\n }\n }\n }\n\n setLocalStorage(data) {\n let key = this.localStorageKey();\n localStorage.setItem(key, JSON.stringify(data));\n }\n\n checkCurrentAnswer() {\n // Start of the evaluation chain\n this.isCorrectArray = [];\n this.displayFeed = [];\n const pca = this.prepareCheckAnswers();\n\n if (this.useRunestoneServices) {\n if (eBookConfig.enableCompareMe) {\n this.enableCompareButton();\n }\n }\n\n // Grade locally if we can't ask the server to grade.\n if (this.feedbackArray) {\n [\n // An array of HTML feedback.\n this.displayFeed,\n // true, false, or null (the question wasn't answered).\n this.correct,\n // An array of true, false, or null (the question wasn't answered).\n this.isCorrectArray,\n this.percent,\n ] = checkAnswersCore(...pca);\n if (!this.isTimed) {\n this.renderFeedback();\n }\n }\n }\n\n // Inputs:\n //\n // - Strings entered by the student in ``this.blankArray[i].value``.\n // - Feedback in ``this.feedbackArray``.\n prepareCheckAnswers() {\n this.given_arr = [];\n for (var i = 0; i < this.blankArray.length; i++)\n this.given_arr.push(this.blankArray[i].value);\n return [\n this.blankNames,\n this.given_arr,\n this.feedbackArray,\n this.dyn_vars_eval,\n ];\n }\n\n // _`randomize`: This handles a click to the \"Randomize\" button.\n async randomize() {\n // Use the client-side case or the server-side case?\n if (this.feedbackArray) {\n // This is the client-side case.\n //\n this.seed = Math.floor(Math.random() * 2 ** 32);\n this.renderDynamicContent();\n this.queueMathJax(this.descriptionDiv);\n } else {\n // This is the server-side case. Send a request to the `results ` endpoint with ``new_seed`` set to True.\n const request = new Request(\"/assessment/results\", {\n method: \"POST\",\n body: JSON.stringify({\n div_id: this.divid,\n course: eBookConfig.course,\n event: \"fillb\",\n sid: this.sid,\n new_seed: true,\n }),\n headers: this.jsonHeaders,\n });\n const response = await fetch(request);\n if (!response.ok) {\n alert(`HTTP error getting results: ${response.statusText}`);\n return;\n }\n const data = await response.json();\n const res = data.detail;\n this.seed = res.seed;\n this.descriptionDiv.innerHTML = res.problemHtml;\n this.queueMathJax(this.descriptionDiv);\n this.setupBlanks();\n }\n // When getting a new seed, clear all the old answers and feedback.\n this.given_arr = Array(this.blankArray.len).fill(\"\");\n $(this.blankArray).attr(\"value\", \"\");\n this.clearFeedbackDiv();\n this.saveAnswersLocallyOnly();\n }\n\n // Save the answers and associated data locally; don't save feedback provided by the server for this answer. It assumes that ``this.given_arr`` contains the current answers.\n saveAnswersLocallyOnly() {\n this.setLocalStorage({\n // The seed is used for client-side operation, but doesn't matter for server-side.\n seed: this.seed,\n answer: JSON.stringify(this.given_arr),\n timestamp: new Date(),\n // This is only needed for server-side grading with dynamic problems.\n problemHtml: this.descriptionDiv.innerHTML,\n });\n }\n\n // _`logCurrentAnswer`: Save the current state of the problem to local storage and the server; display server feedback.\n async logCurrentAnswer(sid) {\n let answer = JSON.stringify(this.given_arr);\n let feedback = true;\n // Save the answer locally.\n this.saveAnswersLocallyOnly();\n // Save the answer to the server.\n const data = {\n event: \"fillb\",\n div_id: this.divid,\n act: answer || \"\",\n seed: this.seed,\n answer: answer || \"\",\n correct: this.correct ? \"T\" : \"F\",\n percent: this.percent,\n };\n if (typeof sid !== \"undefined\") {\n data.sid = sid;\n feedback = false;\n }\n const server_data = await this.logBookEvent(data);\n if (!feedback) return;\n // Non-server side graded problems are done at this point; likewise, stop here if the server didn't respond.\n if (this.feedbackArray || !server_data) {\n return data;\n }\n // This is the server-side case. On success, update the feedback from the server's grade.\n const res = server_data.detail;\n this.timestamp = res.timestamp;\n this.displayFeed = res.displayFeed;\n this.correct = res.correct;\n this.isCorrectArray = res.isCorrectArray;\n this.setLocalStorage({\n seed: this.seed,\n answer: answer,\n timestamp: this.timestamp,\n problemHtml: this.descriptionDiv.innerHTML,\n displayFeed: this.displayFeed,\n correct: this.correct,\n isCorrectArray: this.isCorrectArray,\n });\n this.renderFeedback();\n return server_data;\n }\n\n /*==============================\n === Evaluation of answer and ===\n === display feedback ===\n ==============================*/\n renderFeedback() {\n if (this.correct) {\n $(this.feedBackDiv).attr(\"class\", \"alert alert-info\");\n for (let j = 0; j < this.blankArray.length; j++) {\n $(this.blankArray[j]).removeClass(\"input-validation-error\");\n }\n } else {\n if (this.displayFeed === null) {\n this.displayFeed = \"\";\n }\n for (let j = 0; j < this.blankArray.length; j++) {\n if (this.isCorrectArray[j] !== true) {\n $(this.blankArray[j]).addClass(\"input-validation-error\");\n } else {\n $(this.blankArray[j]).removeClass(\"input-validation-error\");\n }\n }\n $(this.feedBackDiv).attr(\"class\", \"alert alert-danger\");\n }\n var feedback_html = \"

    \";\n for (var i = 0; i < this.displayFeed.length; i++) {\n let df = this.displayFeed[i];\n let fm = (this.isCorrectArray[i] === true) ? '✔️' : '✖️';\n // Render any dynamic feedback in the provided feedback, for client-side grading of dynamic problems.\n if (typeof this.dyn_vars === \"string\") {\n df = renderDynamicFeedback(\n this.blankNames,\n this.given_arr,\n i,\n df,\n this.dyn_vars_eval\n );\n // Convert the returned NodeList into a string of HTML.\n df = (df?.[0] !== undefined)\n ? df[0].parentElement.innerHTML\n : \"No feedback provided\";\n }\n feedback_html += `
  • ${fm} ${df}
  • `;\n }\n feedback_html += \"
\";\n // Remove the list if it's just one element.\n if (this.displayFeed.length == 1) {\n feedback_html = feedback_html.slice(\n \"
  • \".length,\n -\"
\".length\n );\n }\n this.feedBackDiv.innerHTML = feedback_html;\n if (typeof MathJax !== \"undefined\") {\n this.queueMathJax(this.feedBackDiv);\n }\n }\n\n /*==================================\n === Functions for compare button ===\n ==================================*/\n enableCompareButton() {\n this.compareButton.disabled = false;\n }\n // _`compareFITBAnswers`\n compareFITBAnswers() {\n var data = {};\n data.div_id = this.divid;\n data.course = eBookConfig.course;\n jQuery.get(\n `${eBookConfig.new_server_prefix}/assessment/gettop10Answers`,\n data,\n this.compareFITB\n );\n }\n compareFITB(data, status, whatever) {\n var answers = data.detail.res;\n var misc = data.detail.miscdata;\n var body = \"\";\n body += \"\";\n for (var row in answers) {\n body +=\n \"\";\n }\n body += \"
AnswerCount
\" +\n answers[row].answer +\n \"\" +\n answers[row].count +\n \" times
\";\n var html =\n \"\";\n var el = $(html);\n el.modal();\n }\n\n disableInteraction() {\n for (var i = 0; i < this.blankArray.length; i++) {\n this.blankArray[i].disabled = true;\n }\n }\n}\n\n/*=================================\n== Find the custom HTML tags and ==\n== execute our code on them ==\n=================================*/\n$(document).on(\"runestone:login-complete\", function () {\n $(\"[data-component=fillintheblank]\").each(function (index) {\n var opts = {\n orig: this,\n useRunestoneServices: eBookConfig.useRunestoneServices,\n };\n if ($(this).closest(\"[data-component=timedAssessment]\").length == 0) {\n // If this element exists within a timed component, don't render it here\n try {\n FITBList[this.id] = new FITB(opts);\n window.componentMap[this.id] = FITBList[this.id];\n } catch (err) {\n console.assert(\n false,\n `Error rendering Fill in the Blank Problem ${this.id}\n Details: ${err}`\n );\n }\n }\n });\n});\n","/*////////////////////////////////////////////////////////////////\naleaPRNG 1.1\n//////////////////////////////////////////////////////////////////\nhttps://github.com/macmcmeans/aleaPRNG/blob/master/aleaPRNG-1.1.js\n//////////////////////////////////////////////////////////////////\nOriginal work copyright © 2010 Johannes Baagøe, under MIT license\nThis is a derivative work copyright (c) 2017-2020, W. Mac\" McMeans, under BSD license.\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n////////////////////////////////////////////////////////////////*/\nexport function aleaPRNG() {\n return( function( args ) {\n \"use strict\";\n\n const version = 'aleaPRNG 1.1.0';\n\n var s0\n , s1\n , s2\n , c\n , uinta = new Uint32Array( 3 )\n , initialArgs\n , mashver = ''\n ;\n\n /* private: initializes generator with specified seed */\n function _initState( _internalSeed ) {\n var mash = Mash();\n\n // internal state of generator\n s0 = mash( ' ' );\n s1 = mash( ' ' );\n s2 = mash( ' ' );\n\n c = 1;\n\n for( var i = 0; i < _internalSeed.length; i++ ) {\n s0 -= mash( _internalSeed[ i ] );\n if( s0 < 0 ) { s0 += 1; }\n\n s1 -= mash( _internalSeed[ i ] );\n if( s1 < 0 ) { s1 += 1; }\n\n s2 -= mash( _internalSeed[ i ] );\n if( s2 < 0 ) { s2 += 1; }\n }\n\n mashver = mash.version;\n\n mash = null;\n };\n\n /* private: dependent string hash function */\n function Mash() {\n var n = 4022871197; // 0xefc8249d\n\n var mash = function( data ) {\n data = data.toString();\n\n // cache the length\n for( var i = 0, l = data.length; i < l; i++ ) {\n n += data.charCodeAt( i );\n\n var h = 0.02519603282416938 * n;\n\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 4294967296; // 0x100000000 2^32\n }\n return ( n >>> 0 ) * 2.3283064365386963e-10; // 2^-32\n };\n\n mash.version = 'Mash 0.9';\n return mash;\n };\n\n\n /* private: check if number is integer */\n function _isInteger( _int ) {\n return parseInt( _int, 10 ) === _int;\n };\n\n /* public: return a 32-bit fraction in the range [0, 1]\n This is the main function returned when aleaPRNG is instantiated\n */\n var random = function() {\n var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32\n\n s0 = s1;\n s1 = s2;\n\n return s2 = t - ( c = t | 0 );\n };\n\n /* public: return a 53-bit fraction in the range [0, 1] */\n random.fract53 = function() {\n return random() + ( random() * 0x200000 | 0 ) * 1.1102230246251565e-16; // 2^-53\n };\n\n /* public: return an unsigned integer in the range [0, 2^32] */\n random.int32 = function() {\n return random() * 0x100000000; // 2^32\n };\n\n /* public: advance the generator the specified amount of cycles */\n random.cycle = function( _run ) {\n _run = typeof _run === 'undefined' ? 1 : +_run;\n if( _run < 1 ) { _run = 1; }\n for( var i = 0; i < _run; i++ ) { random(); }\n };\n\n /* public: return inclusive range */\n random.range = function() {\n var loBound\n , hiBound\n ;\n\n if( arguments.length === 1 ) {\n loBound = 0;\n hiBound = arguments[ 0 ];\n\n } else {\n loBound = arguments[ 0 ];\n hiBound = arguments[ 1 ];\n }\n\n if( arguments[ 0 ] > arguments[ 1 ] ) {\n loBound = arguments[ 1 ];\n hiBound = arguments[ 0 ];\n }\n\n // return integer\n if( _isInteger( loBound ) && _isInteger( hiBound ) ) {\n return Math.floor( random() * ( hiBound - loBound + 1 ) ) + loBound;\n\n // return float\n } else {\n return random() * ( hiBound - loBound ) + loBound;\n }\n };\n\n /* public: initialize generator with the seed values used upon instantiation */\n random.restart = function() {\n _initState( initialArgs );\n };\n\n /* public: seeding function */\n random.seed = function() {\n _initState( Array.prototype.slice.call( arguments ) );\n };\n\n /* public: show the version of the RNG */\n random.version = function() {\n return version;\n };\n\n /* public: show the version of the RNG and the Mash string hasher */\n random.versions = function() {\n return version + ', ' + mashver;\n };\n\n // when no seed is specified, create a random one from Windows Crypto (Monte Carlo application)\n if( args.length === 0 ) {\n window.crypto.getRandomValues( uinta );\n args = [ uinta[ 0 ], uinta[ 1 ], uinta[ 2 ] ];\n };\n\n // store the seed used when the RNG was instantiated, if any\n initialArgs = args;\n\n // initialize the RNG\n _initState( args );\n\n return random;\n\n })( Array.prototype.slice.call( arguments ) );\n};","import FITB from \"./fitb.js\";\nexport default class TimedFITB extends FITB {\n constructor(opts) {\n super(opts);\n this.renderTimedIcon(this.inputDiv);\n this.hideButtons();\n this.needsReinitialization = true;\n }\n hideButtons() {\n $(this.submitButton).hide();\n $(this.compareButton).hide();\n }\n renderTimedIcon(component) {\n // renders the clock icon on timed components. The component parameter\n // is the element that the icon should be appended to.\n var timeIconDiv = document.createElement(\"div\");\n var timeIcon = document.createElement(\"img\");\n $(timeIcon).attr({\n src: \"../_static/clock.png\",\n style: \"width:15px;height:15px\",\n });\n timeIconDiv.className = \"timeTip\";\n timeIconDiv.title = \"\";\n timeIconDiv.appendChild(timeIcon);\n $(component).prepend(timeIconDiv);\n }\n checkCorrectTimed() {\n // Returns if the question was correct, incorrect, or skipped (return null in the last case)\n switch (this.correct) {\n case true:\n return \"T\";\n case false:\n return \"F\";\n default:\n return null;\n }\n }\n hideFeedback() {\n for (var i = 0; i < this.blankArray.length; i++) {\n $(this.blankArray[i]).removeClass(\"input-validation-error\");\n }\n this.feedBackDiv.style.display = \"none\";\n }\n\n reinitializeListeners() {\n this.setupBlanks();\n }\n}\n\nif (typeof window.component_factory === \"undefined\") {\n window.component_factory = {};\n}\nwindow.component_factory.fillintheblank = function (opts) {\n if (opts.timed) {\n return new TimedFITB(opts);\n }\n return new FITB(opts);\n};\n"],"names":["$","i18n","load","en","msg_no_answer","msg_fitb_check_me","msg_fitb_compare_me","msg_fitb_randomize","render_html","html_in","dyn_vars_eval","html_replaced","replaceAll","match","group1","JSON","stringify","doc","DOMParser","parseFromString","script_eval_tags","getElementsByTagName","length","script_eval_tag","expr","getAttribute","eval_result","window","Function","Object","keys","values","replaceWith","body","childNodes","parseAnswers","blankNamesDict","given_arr","namedBlankValues","getNamedBlankValues","given_arr_names","k","v","entries","map","value","index","type_convert","renderDynamicFeedback","displayFeed_i","sol_vars_plus","assign","ans","ans_array","err","console","assert","blank_name","blank_index","name","types","pass_through","converter","Number","Number_","TypeError","val","FITBList","FITB","constructor","opts","super","orig","this","useRunestoneServices","origElem","divid","id","correct","json_element","scriptSelector","dict_","parse","html","remove","undefined","problemHtml","dyn_vars","blankNames","feedbackArray","innerHTML","createFITBElement","setupBlanks","caption","addCaption","dyn_imports","imports_promise","Promise","resolve","import_promises","import_","push","import","all","then","module_namespace_arr","catch","checkServer","has_static_seed","static_seed","is_client_dynamic","has_local_seed","seed","renderDynamicContent","randomize","Prism","highlightAllUnder","containerDiv","indicate_component_ready","queueMathJax","descriptionDiv","root_node","find","renderFITBInput","renderFITBButtons","renderFITBFeedbackDiv","document","createElement","appendChild","origInnerHTML","submitButton","textContent","attr","class","type","addEventListener","async","checkCurrentAnswer","logCurrentAnswer","bind","compareButton","disabled","compareFITBAnswers","randomizeButton","feedBackDiv","clearFeedbackDiv","className","html_nodes","prepareCheckAnswers","rand","args","version","s0","s1","s2","c","initialArgs","uinta","Uint32Array","mashver","_initState","_internalSeed","mash","n","data","i","l","toString","h","charCodeAt","Mash","_isInteger","_int","parseInt","random","t","fract53","int32","cycle","_run","range","loBound","hiBound","arguments","Math","floor","restart","Array","prototype","slice","call","versions","crypto","getRandomValues","aleaPRNG","html_out","beforeContentRender","replaceChildren","afterContentRender","ba","blankArray","toArray","blank","change","recordAnswered","isAnswered","restoreAnswers","arr","answer","isArray","Error","split","hasAnswer","displayFeed","isCorrectArray","renderFeedback","checkLocalStorage","storedData","graderactive","localStorage","ex","getItem","localStorageKey","message","removeItem","setLocalStorage","key","setItem","pca","eBookConfig","enableCompareMe","enableCompareButton","percent","beforeCheckAnswers","given_arr_converted","dve_blanks","given","fbl","j","RegExp","test","min","max","actual","is_equal","is_correct","afterCheckAnswers","filter","Boolean","checkAnswersCore","isTimed","request","Request","method","div_id","course","event","sid","new_seed","headers","jsonHeaders","response","fetch","ok","alert","statusText","res","json","detail","len","fill","saveAnswersLocallyOnly","timestamp","Date","feedback","act","server_data","logBookEvent","removeClass","addClass","feedback_html","df","fm","parentElement","MathJax","jQuery","get","new_server_prefix","compareFITB","status","whatever","answers","miscdata","row","count","modal","disableInteraction","on","each","closest","componentMap","TimedFITB","renderTimedIcon","inputDiv","hideButtons","needsReinitialization","hide","component","timeIconDiv","timeIcon","src","style","title","prepend","checkCorrectTimed","hideFeedback","display","reinitializeListeners","component_factory","fillintheblank","timed"],"sourceRoot":""}