{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./app/javascript/packs/app.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","kDefaultBoxMsg","kConErrMsg","kDefaultBoxCss","color","ytEmbedEvent","event","tok","nonce","selfInvoke","eventCode","data","$","ajax","url","type","dataType","target","playerInfo","playbackRate","currentTime","duration","success","res","fail","window","cs128SyntaxHighlighterInit","each","block","hljs","highlightBlock","lineNumbersBlock","ytEmbedProcessAll","this","embed_id","embed_tok","embed_nonce","tc","embed_player","YT","Player","attr","events","id","hide","show","e","playerVars","location","origin","err","setInterval","getPlayerState"],"mappings":"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","file":"js/app-de32f364e232cbe1d52c.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/packs/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","if (typeof kDefaultBoxMsg === 'undefined') {\n var kDefaultBoxMsg = \"> Click run program to compile and run your code. Click grade code to submit and grade your code.\";\n}\n\nif (typeof kConErrMsg === 'undefined') {\n var kConErrMsg = 'Sorry, we couldn\\'t connect to the server. Check your internet connection or check our status page.';\n}\n\nif (typeof kDefaultBoxCss === 'undefined') {\n var kDefaultBoxCss = {\n \"min-height\": \"6.1rem\",\n \"max-height\": \"18.5rem\",\n \"background-color\": \"black\",\n color: \"white\",\n \"font-family\": \"'IBM Plex Mono', monospace\"\n };\n}\n\nfunction enableButtons() {\n $('.activity-grade').removeAttr('disabled');\n $('.activity-run').removeAttr('disabled');\n $('.activity-lb').removeAttr('disabled');\n}\n\nfunction disableButtons() {\n $('.activity-grade').attr('disabled', true);\n $('.activity-run').attr('disabled', true);\n $('.activity-lb').attr('disabled', true);\n}\n\nfunction getAttendance(sId) {\n $.ajax({\n url: `https://attendance.cs128.org/api/student/attendance/${sId}`,\n type: 'GET',\n headers: { 'X-Sess-Id': $('meta[name=\"sess-id\"]').attr(\"content\") },\n success: function (res) {\n var attendance_dat = JSON.parse(res);\n if(attendance_dat.attended) {\n let attendance_success_div = $(`#x-attendance-record-${sId}-success`);\n attendance_success_div.find('.attendance-record').html(`${attendance_dat.actor}
${attendance_dat.timestamp}`);\n attendance_success_div.show();\n } else {\n $(`#x-attendance-record-${sId}-fail`).show();\n }\n \n },\n fail: function (res) { }\n });\n}\n\nwindow.cs128SyntaxHighlighterInit = function cs128SyntaxHighlighterInit() {\n $('pre code').each(function(i, block) {\n hljs.highlightBlock(block);\n });\n $('code.hljs').each(function(i, block) {\n hljs.lineNumbersBlock(block);\n });\n}\n\nfunction escapeHtmlCharacters(text) {\n return text.replace(/&/g, \"&\").replace(/>/g, \">\").replace(/')\n}\n\nfunction compileRequestOnReadyState(currentId, btn, readyState, statusCode, response) {\n if (readyState !== 4) return;\n\n enableButtons(); toggleDivBlur(currentId);\n if (readyState === 4 && statusCode === 0) {\n sendAlert(kConErrMsg);\n btnToError(btn);\n return;\n }\n\n if (statusCode >= 300) {\n populateErrMsg(response);\n btnToError(btn);\n return;\n }\n\n var json = JSON.parse(response);\n var currentDiv = $(\"#activity-\" + currentId + \"-output\");\n\n if (json[\"timeout\"]) {\n currentDiv.html(\"Your code TIMED OUT (10s) and was terminated.\");\n btnToSuccess(btn);\n return;\n }\n\n if (json[\"fail\"]) {\n currentDiv.html(\"

Your code FAILED to execute.

\" + escapeHtmlCharacters(json[\"error\"]));\n btnToSuccess(btn);\n return;\n }\n\n if(json[\"output\"].length === 0) {\n currentDiv.html(\"Successful execution with no output.\");\n btnToSuccess(btn);\n return;\n }\n\n currentDiv.html(escapeHtmlCharacters(json[\"output\"]));\n btnToSuccess(btn);\n}\n\nfunction CompileCode(id, req) {\n const btn = stylizeButton($(\"#activity-\" + id + \"-run\"), \"btn-info\", \"btn-warning\", '');\n toggleDivBlur(id);\n disableButtons();\n\n var runRequest = new XMLHttpRequest;\n runRequest.open(\"POST\", \"https://core-apis.cs128.org/compile\", true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"Content-Type\", \"application/json\");\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n compileRequestOnReadyState(id, btn, runRequest.readyState, runRequest.status, runRequest.response);\n }\n runRequest.send(JSON.stringify(req));\n}\n\nfunction GradeCode(id, req) {\n const btn = stylizeButton($(\"#activity-\" + id + \"-grade\"), \"btn-dark\", \"btn-warning\", '');\n toggleDivBlur(id);\n disableButtons();\n\n var runRequest = new XMLHttpRequest;\n runRequest.open(\"POST\", \"https://core-apis.cs128.org/grade\", true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"Content-Type\", \"application/json\");\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n gradeRequestOnReadyState(id, btn, runRequest.readyState, runRequest.status, runRequest.response);\n }\n runRequest.send(JSON.stringify(req));\n}\n\nfunction gradeRequestOnReadyState(currentId, btn, readyState, statusCode, response) {\n if (readyState !== 4) return;\n\n enableButtons(); toggleDivBlur(currentId);\n\n if (readyState === 4 && statusCode === 0) {\n sendAlert(kConErrMsg);\n btnToError(btn);\n return;\n }\n\n if (statusCode >= 300) {\n populateErrMsg(response);\n btnToError(btn);\n return;\n }\n\n var json = JSON.parse(response);\n var currentDiv = $(\"#activity-\" + currentId + \"-output\");\n\n if (json[\"timeout\"] === \"true\") {\n currentDiv.html(\"Your code TIMED OUT (10s) and was terminated. Submission not graded (0%).\");\n btnToSuccess(btn);\n return;\n }\n\n if (json[\"fail\"] === \"true\") {\n currentDiv.html(\"

Your code FAILED to execute. Submission not graded (0%).

\" + escapeHtmlCharacters(json[\"error\"]));\n btnToSuccess(btn);\n return;\n }\n currentDiv.html(\"Graded! Fetching results...\");\n printTestOutput(json, currentDiv, btn);\n}\n\nfunction SaveCode(id, req, notify) {\n const btn = stylizeButton($(\"#activity-\" + id + \"-save\"), \"btn-light\", \"btn-warning\", '');\n disableButtons();\n\n var runRequest = new XMLHttpRequest;\n runRequest.open(\"POST\", \"https://core-apis.cs128.org/save\", true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"Content-Type\", \"application/json\");\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n saveRequestOnReadyState(id, btn, runRequest.readyState, runRequest.status, runRequest.response, notify);\n }\n runRequest.send(JSON.stringify(req));\n}\n\nfunction saveRequestOnReadyState(currentId, btn, readyState, statusCode, response, notify) {\n enableButtons();\n if (readyState !== 4) return;\n\n if (readyState === 4 && statusCode === 0) {\n sendAlert(kConErrMsg);\n btnToError(btn);\n return;\n }\n\n if (statusCode >= 300) {\n populateErrMsg(response);\n btnToError(btn);\n } else if (statusCode === 200) {\n btnToSuccess(btn);\n if(notify) sendSuccess(\"Saved!\")\n } else {\n // unreachable\n }\n}\n\nfunction GetMaxScore(aid, agmax) {\n var runRequest = new XMLHttpRequest;\n runRequest.open(\"GET\", \"https://core-apis.cs128.org/submission_max/\" + aid, true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n getMaxScoreOnReadyState(aid, agmax, runRequest.readyState, runRequest.status, runRequest.response)\n }\n runRequest.send();\n}\n\nfunction getMaxScoreOnReadyState(aid, agmax, readyState, statusCode, response) {\n if (readyState !== 4) return;\n\n function populateDiv(cls, msg) {\n $('#res_display_activity_' + aid).removeClass().addClass(\"alert alert-\" + cls);\n $('#res_display_activity_text_' + aid).html(msg);\n }\n\n if (readyState === 4 && statusCode === 0) {\n populateDiv(\"danger\", \"Couldn't connect to server while fetching your score information.\")\n return;\n }\n\n if (statusCode >= 300) {\n response ? populateDiv(\"danger\", response)\n : populateDiv(\"danger\", \"Something went wrong while fetching your score information.\");\n return;\n }\n\n var json = JSON.parse(response);\n if (json[\"none_graded\"]) {\n populateDiv(\"warning\",\n \"You have not attempted this activity. You currently have 0% for this activity.\");\n } else {\n const timestamp = new Intl.DateTimeFormat('en-US', { dateStyle: 'full', timeStyle: 'long', timeZone: 'US/Central' }).format(new Date(json[\"timestamp\"]))\n const max_sc = json[\"max\"] < 0 ? 0 : json[\"max\"];\n if(json[\"max\"] >= agmax) {\n populateDiv(\"success\",\n \"You received full credit (\" + max_sc + \" of \" + agmax + \" – \" + (max_sc*100/agmax).toFixed(2) + \"%) for this activity from your attempt \" +\n \"on \" + timestamp + \"\");\n } else {\n populateDiv(\"info\",\n \"You received partial credit (\" + max_sc + \" of \" + agmax + \" – \" + (max_sc*100/agmax).toFixed(2) + \"%) for this activity from your attempt \" +\n \"on \" + timestamp + \"\");\n }\n }\n}\n\nfunction invokeSubmissionComprehensive(submissionId, aid, editors, invokeFn) {\n $('#activity-'+aid+'-submission-review-modal-info').html(\"Loading...\")\n $('#activity-'+aid+'-submission-review-modal-feedback').html(\"\").hide()\n $('#activity-'+aid+'-submission-review-modal-diff').html(\"\")\n $('#activity-'+aid+'-submission-review-modal').modal('show');\n bootstrap.Popover.getInstance($('#activity-'+aid+'-history')).hide();\n GetSubmissionComprehensive(submissionId, aid, editors, invokeFn);\n}\n\nfunction GetSubmissionComprehensive(submissionId, aid, editors, invokeFn) {\n var runRequest = new XMLHttpRequest;\n runRequest.open(\"GET\", \"https://core-apis.cs128.org/submission_comprehensive/\" + submissionId, true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n getSubmissionComprehensiveOnReadyState(aid, submissionId, editors, invokeFn, runRequest.readyState, runRequest.status, runRequest.response)\n }\n runRequest.send();\n}\n\nfunction getSubmissionComprehensiveOnReadyState(aid, submissionId, editors, invokeFn, readyState, statusCode, response) {\n if (readyState !== 4) return;\n\n const divSummary = $('#activity-'+aid+'-submission-review-modal-info')\n\n if (readyState === 4 && statusCode === 0) {\n divSummary.html(\"Something went wrong while connecting to server to fetch this submission.\")\n return;\n }\n\n if (statusCode >= 300) {\n response ? divSummary.html(response)\n : divSummary.html(\"Something went wrong while connecting to server to fetch this submission.\")\n return;\n }\n\n var json = JSON.parse(response);\n populateSubmissionComprehensive(aid, submissionId, editors, invokeFn, json)\n}\n\nfunction populateSubmissionComprehensive(aid, submissionId, editors, invokeFn, submission) {\n const divSummary = $('#activity-'+aid+'-submission-review-modal-info')\n const divFeedback = $('#activity-'+aid+'-submission-review-modal-feedback')\n const divDiff = $('#activity-'+aid+'-submission-review-modal-diff')\n\n const curDate = new Date(submission[\"created_at\"]);\n const timestamp = new Intl.DateTimeFormat('en-US', { year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, timeZone: 'US/Central' }).format(curDate)\n\n let summary = `
Submission: ${ timestamp }
Status: `\n let diff = \"\"\n\n function escapeOutput(text) {\n return text.length === 0 ? \"Successful execution with no output.\" : escapeHtmlCharacters(text);\n }\n\n if(submission[\"is_graded\"]) {\n const json = JSON.parse(submission[\"response\"]);\n if(json[\"fail\"] === \"true\") {\n summary += \"Autograder FAILED because of errors
Score: 0
Compiler Output\"\n divFeedback.html(escapeOutput(json[\"error\"])).show()\n } else if(json[\"timeout\"] === \"true\") {\n summary += \"Autograder TIMED OUT
Score: 0\"\n } else {\n summary += `Graded
Score: ${json[\"score\"]}
Autograder Feedback`\n printTestOutput(json, divFeedback)\n divFeedback.show()\n }\n } else {\n if(submission[\"response\"] === \"200\") {\n summary += \"Saved
\"\n } else {\n const json = JSON.parse(submission[\"response\"]);\n if(json[\"fail\"] === \"true\") {\n summary += \"Run request FAILED because of errors
Compiler Output\"\n divFeedback.html(escapeOutput(json[\"error\"])).show()\n } else if(json[\"timeout\"] === \"true\") {\n summary += \"Run request TIMED OUT
\"\n } else {\n summary += \"Compiled and Executed
Program Output\"\n divFeedback.html(escapeOutput(json[\"output\"])).show()\n }\n }\n }\n divSummary.html(summary);\n\n diff = 'Codes'\n\n for(var i = 0; i < submission[\"codes\"].length; i++) {\n const curIndex = submission[\"codes\"][i]['local_file_id'];\n const curFileName = submission[\"codes\"][i]['file_name'];\n const currentCode = editors[curIndex]['editor'].getSession().getValue();\n const fileDiffs = Diff.createTwoFilesPatch(\"(working version) \"+curFileName, \"(this submission) \"+curFileName,\n currentCode, submission[\"codes\"][i]['code']);\n diff += Diff2Html.getPrettyHtml(fileDiffs,\n {inputFormat: 'diff', showFiles: false, matching: 'lines', outputFormat: 'side-by-side'})\n }\n\n divDiff.html(diff);\n $('#activity-' + aid + '-submission-review-modal-diff > .revert-submission-' + aid).click(function() {\n invokeFn(3, $(this).data(\"id\"), aid);\n $('#activity-'+aid+'-submission-review-modal').modal('hide');\n })\n}\n\nfunction populateErrMsg(response) {\n const text = response ? response : \"Our bad! Something's wrong with our server. Please try again.\";\n sendAlert(text);\n}\n\nfunction sendAlert(text) {\n alertify.error(' ' + text);\n}\n\nfunction sendInfo(text) {\n alertify.warning(' ' + text);\n}\n\nfunction sendSuccess(text) {\n alertify.success(' ' + text);\n}\n\nfunction stylizeButton(btn, currentClass, newClass, newHtml) {\n const currentState = { \"classRemoved\": currentClass, \"classAdded\": newClass, \"html\": btn.html(), \"btn\": btn };\n btn.removeClass(currentClass).addClass(newClass).html(newHtml);\n return currentState;\n}\n\nfunction btnToError(btn) {\n stylizeButton(btn[\"btn\"], btn[\"classAdded\"], \"btn-danger\", '')\n setTimeout(function() {\n stylizeButton(btn[\"btn\"], \"btn-danger\", btn[\"classRemoved\"], btn[\"html\"])}, 3000)\n}\n\nfunction btnToSuccess(btn) {\n stylizeButton(btn[\"btn\"], btn[\"classAdded\"], \"btn-success\", '')\n setTimeout(function() {\n stylizeButton(btn[\"btn\"], \"btn-success\", btn[\"classRemoved\"], btn[\"html\"])}, 3000)\n}\n\nfunction toggleDivBlur(id) {\n var currentDiv = $(\"#activity-\" + id + \"-output\");\n currentDiv.toggleClass('blur-div');\n}\n\nfunction printTestOutput(json_data, currentDiv, btn) {\n var json = json_data[\"autograder_feedback\"];\n var outhtml = \"\";\n var totalcorrect = 0;\n var totalcorrectpossible = 0;\n outhtml = outhtml.concat(\"\");\n for(var i = 0; i < json.length; i++) {\n var obj = json[i];\n totalcorrectpossible++;\n\n outhtml = outhtml.concat(\"\");\n\n if(obj[\"pass\"] === \"true\") {\n totalcorrect++;\n outhtml = outhtml.concat(\"\");\n } else {\n outhtml = outhtml.concat(\"\");\n }\n\n outhtml = outhtml.concat(\"\");\n }\n outhtml = outhtml.concat(\"
PASSED (+\");\n outhtml = outhtml.concat(obj[\"points\"]);\n outhtml = outhtml.concat(\")\");\n outhtml = outhtml.concat(escapeHtmlCharacters(obj[\"name\"]));\n outhtml = outhtml.concat(\" FAILED (\");\n if(parseInt(obj[\"points\"]) >= 0) {\n outhtml = outhtml.concat(\"+\");\n }\n outhtml = outhtml.concat(obj[\"points\"]);\n outhtml = outhtml.concat(\")\");\n outhtml = outhtml.concat(escapeHtmlCharacters(obj[\"name\"]));\n outhtml = outhtml.concat(\"
\");\n outhtml = outhtml.concat(escapeHtmlCharacters(obj[\"feedback\"]));\n outhtml = outhtml.concat(\"
\");\n\n if(totalcorrectpossible === totalcorrect) {\n currentDiv.html(\"

Test Summary: ALL \" + totalcorrectpossible + \" test(s) PASSED (\" + json_data[\"score\"] + \" pts). Great job!

\" + outhtml);\n } else {\n currentDiv.html(\"

Test Summary: \" + totalcorrect + \" of \" + totalcorrectpossible + \" test(s) PASSED (\" + json_data[\"score\"] + \"\" + \" pts)

\" + outhtml);\n }\n\n if(btn) btnToSuccess(btn);\n}\n\nfunction invokeSubmissionRevert(submissionId, editors, invokeFn, originalCodes, aid) {\n if(submissionId === -1) {\n if(originalCodes) {\n alertify.confirm(\"Are you sure you want to revert back to the starter version?\",\n function(){ populateCodes(editors, originalCodes, invokeFn, aid) },\n function(){}).set({title:\"Confirm\"}).set({labels:{ok:\"Yes, I'm sure\", cancel: \"Abort\"}});\n }\n } else {\n alertify.confirm(\"Are you sure you want to revert back to this version?\",\n function(){ GetSubmissionCodes(submissionId, editors, invokeFn, aid) },\n function(){}).set({title:\"Confirm\"}).set({labels:{ok:\"Yes, I'm sure\", cancel: \"Abort\"}});\n }\n}\n\nfunction populateCodes(editors, codes, invokeFn, aid) {\n for(var i = 0; i < codes.length; i++) {\n const curIndex = codes[i]['local_file_id'];\n editors[curIndex]['editor'].setValue(codes[i]['code']);\n editors[curIndex]['editor'].clearSelection();\n }\n sendSuccess(\"We reverted your submission back. We will now attempt to save this.\")\n $('#progress_display_activity_'+aid).hide();\n invokeFn(2, true);\n}\n\nfunction GetSubmissionCodes(submissionId, editors, invokeFn, aid) {\n var runRequest = new XMLHttpRequest;\n runRequest.open(\"GET\", \"https://core-apis.cs128.org/submission_files/\" + submissionId, true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n getSubmissionCodesOnReadyState(editors, invokeFn, runRequest.readyState, runRequest.status, runRequest.response, aid)\n }\n runRequest.send();\n sendInfo(\"We are working on retrieving this submission. Hang tight!\")\n}\n\nfunction getSubmissionCodesOnReadyState(editors, invokeFn, readyState, statusCode, response, aid) {\n if (readyState !== 4) return;\n\n if (readyState === 4 && statusCode === 0) {\n sendAlert(\"Something went wrong when retrieving this submission. Try again.\")\n return;\n }\n\n if (statusCode >= 300) {\n response ? sendAlert(response)\n : sendAlert(\"Something went wrong when retrieving this submission. Try again.\");\n return;\n }\n\n var json = JSON.parse(response);\n sendSuccess(\"Got it! Updating the editors...\")\n populateCodes(editors, json, invokeFn, aid)\n}\n\nfunction GetSubmissions(aid, invokeFn, isInitial) {\n var runRequest = new XMLHttpRequest;\n var div = $('#activity-' + aid + '-history-popover-content')\n\n runRequest.open(\"GET\", \"https://core-apis.cs128.org/submissions/\" + aid, true);\n runRequest.withCredentials = true;\n runRequest.setRequestHeader(\"X-Sess-Id\", $('meta[name=\"sess-id\"]').attr('content'));\n runRequest.onreadystatechange = function() {\n if(isInitial) getSubmissionsOnReadyState(aid, div, runRequest.readyState, runRequest.status, runRequest.response, invokeFn, true);\n else getSubmissionsOnReadyState(aid, div, runRequest.readyState, runRequest.status, runRequest.response, invokeFn);\n }\n runRequest.send();\n div.text('Loading...')\n}\n\nfunction getSubmissionsOnReadyState(aid, div, readyState, statusCode, response, invokeFn, isInitial) {\n if (readyState !== 4) return;\n\n if (readyState === 4 && statusCode === 0) {\n div.text(\"Something went wrong when retrieving this submission. Try again.\")\n if(isInitial) bootstrap.Popover.getInstance($('#activity-'+aid+'-history')).hide();\n return;\n }\n\n if (statusCode >= 300) {\n response ? div.text(response)\n : div.text(\"Something went wrong when retrieving this submission. Try again.\");\n if(isInitial) bootstrap.Popover.getInstance($('#activity-'+aid+'-history')).hide();\n return;\n }\n\n var json = JSON.parse(response);\n if(json.length === 0) div.html(\"No history. Click on the load icon () to reload.\")\n else {\n if(isInitial) {\n populateSubmissions(aid, div, json, true);\n\n const curDate = new Date(json[0][\"created_at\"]);\n const timestamp = new Intl.DateTimeFormat('en-US', { dateStyle: 'full', timeStyle: 'long', timeZone: 'US/Central' }).format(curDate)\n $('#progress_display_activity_text_'+aid)\n .html('Welcome back! We found the most recent version you were working on, which was ' +\n 'saved on '+timestamp+'. Want to keep working on this?
' +\n '' +\n '
');\n $('#progress_display_activity_'+aid).show();\n } else {\n populateSubmissions(aid, div, json);\n }\n $('.revert-submission-' + aid).click(function() {\n invokeFn(3, $(this).data(\"id\"), aid);\n })\n $('.detail-submission-' + aid).click(function() {\n invokeFn(4, $(this).data(\"id\"), aid);\n })\n }\n if(isInitial) bootstrap.Popover.getInstance($('#activity-'+aid+'-history')).hide();\n}\n\nfunction populateSubmissions(aid, div, submissions, isInitial) {\n var table = '';\n var max = {\"i\": 0, \"d\": -1}\n for(var i = 0; i < submissions.length; i++) {\n const curDate = new Date(submissions[i][\"created_at\"]);\n const timestamp = new Intl.DateTimeFormat('en-US', { year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, timeZone: 'US/Central' }).format(curDate)\n const score = submissions[i][\"score\"] < 0 ? 0 : submissions[i][\"score\"];\n if(submissions[i][\"is_graded\"] && (max[\"d\"] < score)) {\n max[\"i\"]=i;max[\"d\"]=score;\n }\n table += `` +\n `` +\n `` +\n `` +\n ``;\n }\n table += '' +\n '' +\n ``;\n\n table += '
#TypeScoreTimestamp (CT)
${submissions.length-i}${ submissions[i][\"is_graded\"] ? \"Grade\" : ( submissions[i][\"response\"] === \"200\" ? \"Save\" : \"Run\" )}${ submissions[i][\"is_graded\"] ? submissions[i][\"score\"] : 'N/A' }${ timestamp }` +\n `
0Starter Code
';\n div.html(table);\n if(max[\"d\"]!==-1) {\n if(isInitial) bootstrap.Popover.getInstance($('#activity-'+aid+'-history')).show();\n $('#s-history-'+aid+\"-\"+max[\"i\"]).addClass(\"table-success\");\n }\n if(isInitial) bootstrap.Popover.getInstance($('#activity-'+aid+'-history')).hide();\n}\n\nfunction onYouTubeIframeAPIReady() {\n ytEmbedProcessAll();\n}\nwindow.ytEmbedProcessAll = function ytEmbedProcessAll() {\n$('.cs128-vidembed-yt').each(function() {\n if($(this).data(\"ready\")) return;\n let embed_id = $(this).data(\"block\");\n let embed_tok = $(this).data(\"token\");\n let embed_nonce = $(this).data(\"nonce\");\n let tc = true;\n let embed_player = null;\n try {\n embed_player = new YT.Player($(this).attr('id'), {\n events: {\n 'onReady': () => revealPlayer(embed_id),\n 'onStateChange': (e) => ytEmbedEvent(e, embed_tok, embed_nonce, true)\n },\n playerVars: {\n 'origin': window.location.origin\n }\n });\n } catch (err) { tc = false; }\n if(tc) {\n setInterval(function(){\n let event_g = { \"data\": embed_player.getPlayerState(), \"target\": {\"playerInfo\": embed_player.playerInfo } };\n ytEmbedEvent(event_g, embed_tok, embed_nonce, false);\n }, 30000);\n }\n})\n}\nfunction revealPlayer(id) {\n $(`#cs128-vidspinner-${id}`).hide();\n $(`#cs128-vidembed-${id}`).data(\"ready\", true).show();\n}\nfunction ytEmbedEvent(event, tok, nonce, selfInvoke) {\n var eventCode = event.data;\n if ((!selfInvoke && eventCode == 1) || (selfInvoke && (eventCode == 1 || eventCode == 2 || eventCode == 0))) {\n $.ajax({\n url: `https://analogy.cs128.org/watch_record`,\n type: 'POST',\n dataType: 'json',\n data: {\n \"event_code\": eventCode,\n \"playback_rate\": event.target.playerInfo.playbackRate,\n \"reported_location\": event.target.playerInfo.currentTime,\n \"total_duration\": event.target.playerInfo.duration,\n \"nonce\": nonce,\n \"token\": tok\n },\n success: function (res) { },\n fail: function (res) { }\n });\n }\n}"],"sourceRoot":""}