From 052911f9302d8512cc9126f9b5620f74bedeae4a Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Tue, 21 Apr 2020 15:39:14 -0400 Subject: [PATCH 01/11] Add a construct for sortable columns --- CTFd/themes/admin/assets/css/admin.scss | 8 +++ .../admin/assets/js/pages/scoreboard.js | 53 +++++++++++++++++++ .../admin/assets/js/pages/submissions.js | 31 +++++++++++ CTFd/themes/admin/assets/js/styles.js | 2 + CTFd/themes/admin/static/css/admin.dev.css | 2 +- CTFd/themes/admin/static/js/core.dev.js | 4 +- .../admin/static/js/pages/scoreboard.dev.js | 2 +- .../admin/static/js/pages/submissions.dev.js | 2 +- CTFd/themes/admin/templates/scoreboard.html | 50 +++++++++++------ CTFd/themes/admin/templates/submissions.html | 42 ++++++++++----- CTFd/themes/core/assets/js/utils.js | 35 ++++++++++++ CTFd/themes/core/static/js/core.dev.js | 2 +- 12 files changed, 198 insertions(+), 35 deletions(-) diff --git a/CTFd/themes/admin/assets/css/admin.scss b/CTFd/themes/admin/assets/css/admin.scss index 910bdb91..a30273e0 100644 --- a/CTFd/themes/admin/assets/css/admin.scss +++ b/CTFd/themes/admin/assets/css/admin.scss @@ -66,3 +66,11 @@ tbody tr:hover { tr[data-href] { cursor: pointer; } + +.sort-col { + cursor: pointer; +} + +input[type="checkbox"] { + cursor: pointer; +} diff --git a/CTFd/themes/admin/assets/js/pages/scoreboard.js b/CTFd/themes/admin/assets/js/pages/scoreboard.js index 3eab3284..9ab43414 100644 --- a/CTFd/themes/admin/assets/js/pages/scoreboard.js +++ b/CTFd/themes/admin/assets/js/pages/scoreboard.js @@ -1,6 +1,7 @@ import "./main"; import CTFd from "core/CTFd"; import $ from "jquery"; +import { ezQuery } from "core/ezq"; const api_func = { users: (x, y) => CTFd.api.patch_user_public({ userId: x }, y), @@ -37,6 +38,58 @@ function toggleAccount() { }); } +function toggleSelectedAccounts(accountIDs, action) { + const params = { + hidden: action === "hide" ? true : false + }; + const reqs = []; + for (var accId of accountIDs) { + reqs.push(api_func[CTFd.config.userMode](accId, params)); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); +} + +function hideSelectedAccounts(event) { + let accountIDs = $("input[data-account-id]:checked").map(function() { + return $(this).data("account-id"); + }); + let target = accountIDs.length === 1 ? "account" : "accounts"; + ezQuery({ + title: "Hide Accounts", + body: `Are you sure you want to hide ${accountIDs.length} ${target}?`, + success: function() { + toggleSelectedAccounts(accountIDs, "hide"); + } + }); +} + +function showSelectedAccounts(event) { + let accountIDs = $("input[data-account-id]:checked").map(function() { + return $(this).data("account-id"); + }); + let target = accountIDs.length === 1 ? "account" : "accounts"; + ezQuery({ + title: "Unhide Accounts", + body: `Are you sure you want to unhide ${accountIDs.length} ${target}?`, + success: function() { + toggleSelectedAccounts(accountIDs, "show"); + } + }); +} + +function toggleScoreboardSelect(event) { + const checked = $(this).prop("checked"); + $(this) + .closest("table") + .find("input[data-account-id]") + .prop("checked", checked); +} + $(() => { $(".scoreboard-toggle").click(toggleAccount); + $("#scoreboard-bulk-select").click(toggleScoreboardSelect); + $("#scoreboard-hide-button").click(hideSelectedAccounts); + $("#scoreboard-show-button").click(showSelectedAccounts); }); diff --git a/CTFd/themes/admin/assets/js/pages/submissions.js b/CTFd/themes/admin/assets/js/pages/submissions.js index 3f34ddad..651cd824 100644 --- a/CTFd/themes/admin/assets/js/pages/submissions.js +++ b/CTFd/themes/admin/assets/js/pages/submissions.js @@ -40,6 +40,37 @@ function deleteCorrectSubmission(event) { }); } +function deleteSelectedSubmissions(event) { + let submissionIDs = $("input[data-submission-id]:checked").map(function() { + return $(this).data("submission-id"); + }); + let target = submissionIDs.length === 1 ? "submission" : "submissions"; + + ezQuery({ + title: "Delete Submissions", + body: `Are you sure you want to delete ${submissionIDs.length} ${target}?`, + success: function() { + const reqs = []; + for (var subId of submissionIDs) { + reqs.push(CTFd.api.delete_submission({ submissionId: subId })); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + +function toggleSubmissionSelect(event) { + const checked = $(this).prop("checked"); + $(this) + .closest("table") + .find("input[data-submission-id]") + .prop("checked", checked); +} + $(() => { $(".delete-correct-submission").click(deleteCorrectSubmission); + $("#submissions-bulk-select").change(toggleSubmissionSelect); + $("#submission-delete-button").click(deleteSelectedSubmissions); }); diff --git a/CTFd/themes/admin/assets/js/styles.js b/CTFd/themes/admin/assets/js/styles.js index 7f5e3321..88dd2e16 100644 --- a/CTFd/themes/admin/assets/js/styles.js +++ b/CTFd/themes/admin/assets/js/styles.js @@ -1,4 +1,5 @@ import "bootstrap/dist/js/bootstrap.bundle"; +import { makeSortableTables } from "core/utils"; import $ from "jquery"; export default () => { @@ -52,6 +53,7 @@ export default () => { } }); + makeSortableTables(); $('[data-toggle="tooltip"]').tooltip(); }); }; diff --git a/CTFd/themes/admin/static/css/admin.dev.css b/CTFd/themes/admin/static/css/admin.dev.css index b6e34eaf..9ad61a10 100644 --- a/CTFd/themes/admin/static/css/admin.dev.css +++ b/CTFd/themes/admin/static/css/admin.dev.css @@ -1,4 +1,4 @@ html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal !important;z-index:-20} -#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#keys-pie-graph{height:400px;display:block}#categories-pie-graph{height:400px;display:block}#solve-percentages-graph{height:400px;display:block}.no-decoration{color:inherit !important;text-decoration:none !important}.no-decoration:hover{color:inherit !important;text-decoration:none !important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:"Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,0.1) !important}tr[data-href]{cursor:pointer} +#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#keys-pie-graph{height:400px;display:block}#categories-pie-graph{height:400px;display:block}#solve-percentages-graph{height:400px;display:block}.no-decoration{color:inherit !important;text-decoration:none !important}.no-decoration:hover{color:inherit !important;text-decoration:none !important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:"Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,0.1) !important}tr[data-href]{cursor:pointer}th{cursor:pointer}input[type=checkbox]{cursor:pointer} diff --git a/CTFd/themes/admin/static/js/core.dev.js b/CTFd/themes/admin/static/js/core.dev.js index 516e1cc2..9501d880 100644 --- a/CTFd/themes/admin/static/js/core.dev.js +++ b/CTFd/themes/admin/static/js/core.dev.js @@ -20,7 +20,7 @@ eval("\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd * /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/dist/js/bootstrap.bundle */ \"./node_modules/bootstrap/dist/js/bootstrap.bundle.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = function _default() {\n // TODO: This is kind of a hack to mimic a React-like state construct.\n // It should be removed once we have a real front-end framework in place.\n (0, _jquery.default)(\":input\").each(function () {\n (0, _jquery.default)(this).data(\"initial\", (0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\".form-control\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n },\n blur: function blur() {\n if ((0, _jquery.default)(this).val() === \"\") {\n (0, _jquery.default)(this).removeClass(\"input-filled-valid\");\n }\n }\n });\n (0, _jquery.default)(\".modal\").on(\"show.bs.modal\", function (e) {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n });\n (0, _jquery.default)(function () {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n (0, _jquery.default)(\"tr[data-href]\").click(function () {\n var sel = getSelection().toString();\n\n if (!sel) {\n var href = (0, _jquery.default)(this).attr(\"data-href\");\n\n if (href) {\n window.location = href;\n }\n }\n\n return false;\n });\n (0, _jquery.default)(\"tr[data-href] a, tr[data-href] button\").click(function (e) {\n // TODO: This is a hack to allow modal close buttons to work\n if (!(0, _jquery.default)(this).attr(\"data-dismiss\")) {\n e.stopPropagation();\n }\n });\n (0, _jquery.default)('[data-toggle=\"tooltip\"]').tooltip();\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/styles.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/dist/js/bootstrap.bundle */ \"./node_modules/bootstrap/dist/js/bootstrap.bundle.js\");\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = function _default() {\n // TODO: This is kind of a hack to mimic a React-like state construct.\n // It should be removed once we have a real front-end framework in place.\n (0, _jquery.default)(\":input\").each(function () {\n (0, _jquery.default)(this).data(\"initial\", (0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\".form-control\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n },\n blur: function blur() {\n if ((0, _jquery.default)(this).val() === \"\") {\n (0, _jquery.default)(this).removeClass(\"input-filled-valid\");\n }\n }\n });\n (0, _jquery.default)(\".modal\").on(\"show.bs.modal\", function (e) {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n });\n (0, _jquery.default)(function () {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n (0, _jquery.default)(\"tr[data-href]\").click(function () {\n var sel = getSelection().toString();\n\n if (!sel) {\n var href = (0, _jquery.default)(this).attr(\"data-href\");\n\n if (href) {\n window.location = href;\n }\n }\n\n return false;\n });\n (0, _jquery.default)(\"tr[data-href] a, tr[data-href] button\").click(function (e) {\n // TODO: This is a hack to allow modal close buttons to work\n if (!(0, _jquery.default)(this).attr(\"data-dismiss\")) {\n e.stopPropagation();\n }\n });\n (0, _utils.makeSortableTables)();\n (0, _jquery.default)('[data-toggle=\"tooltip\"]').tooltip();\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/styles.js?"); /***/ }), @@ -128,7 +128,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.WindowController = WindowController;\nexports.colorHash = colorHash;\nexports.htmlEntities = htmlEntities;\nexports.cumulativeSum = cumulativeSum;\nexports.init_notification_counter = init_notification_counter;\nexports.set_notification_counter = set_notification_counter;\nexports.inc_notification_counter = inc_notification_counter;\nexports.dec_notification_counter = dec_notification_counter;\nexports.clear_notification_counter = clear_notification_counter;\nexports.copyToClipboard = copyToClipboard;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n_jquery.default.fn.serializeJSON = function (omit_nulls) {\n var params = {};\n var form = (0, _jquery.default)(this);\n var values = form.serializeArray();\n values = values.concat(form.find(\"input[type=checkbox]:checked\").map(function () {\n return {\n name: this.name,\n value: true\n };\n }).get());\n values = values.concat(form.find(\"input[type=checkbox]:not(:checked)\").map(function () {\n return {\n name: this.name,\n value: false\n };\n }).get());\n values.map(function (x) {\n if (omit_nulls) {\n if (x.value !== null && x.value !== \"\") {\n params[x.name] = x.value;\n } else {\n var input = form.find(\":input[name=\".concat(x.name, \"]\"));\n\n if (input.data(\"initial\") !== input.val()) {\n params[x.name] = x.value;\n }\n }\n } else {\n params[x.name] = x.value;\n }\n });\n return params;\n}; //http://stackoverflow.com/a/2648463 - wizardry!\n\n\nString.prototype.format = String.prototype.f = function () {\n var s = this,\n i = arguments.length;\n\n while (i--) {\n s = s.replace(new RegExp(\"\\\\{\" + i + \"\\\\}\", \"gm\"), arguments[i]);\n }\n\n return s;\n}; //http://stackoverflow.com/a/7616484\n\n\nString.prototype.hashCode = function () {\n var hash = 0,\n i,\n chr,\n len;\n if (this.length == 0) return hash;\n\n for (i = 0, len = this.length; i < len; i++) {\n chr = this.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n\n return hash;\n}; // https://gist.github.com/neilj/4146038\n// https://fastmail.blog/2012/11/26/inter-tab-communication-using-local-storage/\n\n\nfunction WindowController() {\n this.id = Math.random();\n this.isMaster = false;\n this.others = {};\n window.addEventListener(\"storage\", this, false);\n window.addEventListener(\"unload\", this, false);\n this.broadcast(\"hello\");\n var that = this;\n\n var check = function check() {\n that.check();\n that._checkTimeout = setTimeout(check, 9000);\n };\n\n var ping = function ping() {\n that.sendPing();\n that._pingTimeout = setTimeout(ping, 17000);\n };\n\n this._checkTimeout = setTimeout(check, 500);\n this._pingTimeout = setTimeout(ping, 17000);\n}\n\nWindowController.prototype.destroy = function () {\n clearTimeout(this._pingTimeout);\n clearTimeout(this._checkTimeout);\n window.removeEventListener(\"storage\", this, false);\n window.removeEventListener(\"unload\", this, false);\n this.broadcast(\"bye\");\n};\n\nWindowController.prototype.handleEvent = function (event) {\n if (event.type === \"unload\") {\n this.destroy();\n } else if (event.key === \"broadcast\") {\n try {\n var data = JSON.parse(event.newValue);\n\n if (data.id !== this.id) {\n this[data.type](data);\n }\n } catch (error) {}\n }\n};\n\nWindowController.prototype.sendPing = function () {\n this.broadcast(\"ping\");\n};\n\nWindowController.prototype.hello = function (event) {\n this.ping(event);\n\n if (event.id < this.id) {\n this.check();\n } else {\n this.sendPing();\n }\n};\n\nWindowController.prototype.ping = function (event) {\n this.others[event.id] = +new Date();\n};\n\nWindowController.prototype.bye = function (event) {\n delete this.others[event.id];\n this.check();\n};\n\nWindowController.prototype.check = function (event) {\n var now = +new Date(),\n takeMaster = true,\n id;\n\n for (id in this.others) {\n if (this.others[id] + 23000 < now) {\n delete this.others[id];\n } else if (id < this.id) {\n takeMaster = false;\n }\n }\n\n if (this.isMaster !== takeMaster) {\n this.isMaster = takeMaster;\n this.masterDidChange();\n }\n};\n\nWindowController.prototype.masterDidChange = function () {};\n\nWindowController.prototype.broadcast = function (type, data) {\n var event = {\n id: this.id,\n type: type\n };\n\n for (var x in data) {\n event[x] = data[x];\n }\n\n try {\n localStorage.setItem(\"broadcast\", JSON.stringify(event));\n } catch (error) {\n console.log(error);\n }\n};\n\nfunction colorHash(str) {\n var hash = 0;\n\n for (var i = 0; i < str.length; i++) {\n hash = str.charCodeAt(i) + ((hash << 5) - hash);\n }\n\n var colour = \"#\";\n\n for (var _i = 0; _i < 3; _i++) {\n var value = hash >> _i * 8 & 0xff;\n colour += (\"00\" + value.toString(16)).substr(-2);\n }\n\n return colour;\n}\n\nfunction htmlEntities(string) {\n return (0, _jquery.default)(\"
\").text(string).html();\n}\n\nfunction cumulativeSum(arr) {\n var result = arr.concat();\n\n for (var i = 0; i < arr.length; i++) {\n result[i] = arr.slice(0, i + 1).reduce(function (p, i) {\n return p + i;\n });\n }\n\n return result;\n}\n\nvar storage = window.localStorage;\nvar counter_key = \"unread_notifications\";\n\nfunction init_notification_counter() {\n var count = storage.getItem(counter_key);\n\n if (count === null) {\n storage.setItem(counter_key, 0);\n } else {\n if (count > 0) {\n (0, _jquery.default)(\".badge-notification\").text(count);\n }\n }\n}\n\nfunction set_notification_counter(count) {\n storage.setItem(counter_key, count);\n}\n\nfunction inc_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n storage.setItem(counter_key, ++count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n}\n\nfunction dec_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n\n if (count > 0) {\n storage.setItem(counter_key, --count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n } // Always clear if count is 0\n\n\n if (count == 0) {\n clear_notification_counter();\n }\n}\n\nfunction clear_notification_counter() {\n storage.setItem(counter_key, 0);\n (0, _jquery.default)(\".badge-notification\").empty();\n}\n\nfunction copyToClipboard(event, selector) {\n // Select element\n (0, _jquery.default)(selector).select(); // Copy to clipboard\n\n document.execCommand(\"copy\"); // Show tooltip to user\n\n (0, _jquery.default)(event.target).tooltip({\n title: \"Copied!\",\n trigger: \"manual\"\n });\n (0, _jquery.default)(event.target).tooltip(\"show\");\n setTimeout(function () {\n (0, _jquery.default)(event.target).tooltip(\"hide\");\n }, 1500);\n}\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/utils.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.WindowController = WindowController;\nexports.colorHash = colorHash;\nexports.htmlEntities = htmlEntities;\nexports.cumulativeSum = cumulativeSum;\nexports.init_notification_counter = init_notification_counter;\nexports.set_notification_counter = set_notification_counter;\nexports.inc_notification_counter = inc_notification_counter;\nexports.dec_notification_counter = dec_notification_counter;\nexports.clear_notification_counter = clear_notification_counter;\nexports.copyToClipboard = copyToClipboard;\nexports.makeSortableTables = makeSortableTables;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n_jquery.default.fn.serializeJSON = function (omit_nulls) {\n var params = {};\n var form = (0, _jquery.default)(this);\n var values = form.serializeArray();\n values = values.concat(form.find(\"input[type=checkbox]:checked\").map(function () {\n return {\n name: this.name,\n value: true\n };\n }).get());\n values = values.concat(form.find(\"input[type=checkbox]:not(:checked)\").map(function () {\n return {\n name: this.name,\n value: false\n };\n }).get());\n values.map(function (x) {\n if (omit_nulls) {\n if (x.value !== null && x.value !== \"\") {\n params[x.name] = x.value;\n } else {\n var input = form.find(\":input[name=\".concat(x.name, \"]\"));\n\n if (input.data(\"initial\") !== input.val()) {\n params[x.name] = x.value;\n }\n }\n } else {\n params[x.name] = x.value;\n }\n });\n return params;\n}; //http://stackoverflow.com/a/2648463 - wizardry!\n\n\nString.prototype.format = String.prototype.f = function () {\n var s = this,\n i = arguments.length;\n\n while (i--) {\n s = s.replace(new RegExp(\"\\\\{\" + i + \"\\\\}\", \"gm\"), arguments[i]);\n }\n\n return s;\n}; //http://stackoverflow.com/a/7616484\n\n\nString.prototype.hashCode = function () {\n var hash = 0,\n i,\n chr,\n len;\n if (this.length == 0) return hash;\n\n for (i = 0, len = this.length; i < len; i++) {\n chr = this.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n\n return hash;\n}; // https://gist.github.com/neilj/4146038\n// https://fastmail.blog/2012/11/26/inter-tab-communication-using-local-storage/\n\n\nfunction WindowController() {\n this.id = Math.random();\n this.isMaster = false;\n this.others = {};\n window.addEventListener(\"storage\", this, false);\n window.addEventListener(\"unload\", this, false);\n this.broadcast(\"hello\");\n var that = this;\n\n var check = function check() {\n that.check();\n that._checkTimeout = setTimeout(check, 9000);\n };\n\n var ping = function ping() {\n that.sendPing();\n that._pingTimeout = setTimeout(ping, 17000);\n };\n\n this._checkTimeout = setTimeout(check, 500);\n this._pingTimeout = setTimeout(ping, 17000);\n}\n\nWindowController.prototype.destroy = function () {\n clearTimeout(this._pingTimeout);\n clearTimeout(this._checkTimeout);\n window.removeEventListener(\"storage\", this, false);\n window.removeEventListener(\"unload\", this, false);\n this.broadcast(\"bye\");\n};\n\nWindowController.prototype.handleEvent = function (event) {\n if (event.type === \"unload\") {\n this.destroy();\n } else if (event.key === \"broadcast\") {\n try {\n var data = JSON.parse(event.newValue);\n\n if (data.id !== this.id) {\n this[data.type](data);\n }\n } catch (error) {}\n }\n};\n\nWindowController.prototype.sendPing = function () {\n this.broadcast(\"ping\");\n};\n\nWindowController.prototype.hello = function (event) {\n this.ping(event);\n\n if (event.id < this.id) {\n this.check();\n } else {\n this.sendPing();\n }\n};\n\nWindowController.prototype.ping = function (event) {\n this.others[event.id] = +new Date();\n};\n\nWindowController.prototype.bye = function (event) {\n delete this.others[event.id];\n this.check();\n};\n\nWindowController.prototype.check = function (event) {\n var now = +new Date(),\n takeMaster = true,\n id;\n\n for (id in this.others) {\n if (this.others[id] + 23000 < now) {\n delete this.others[id];\n } else if (id < this.id) {\n takeMaster = false;\n }\n }\n\n if (this.isMaster !== takeMaster) {\n this.isMaster = takeMaster;\n this.masterDidChange();\n }\n};\n\nWindowController.prototype.masterDidChange = function () {};\n\nWindowController.prototype.broadcast = function (type, data) {\n var event = {\n id: this.id,\n type: type\n };\n\n for (var x in data) {\n event[x] = data[x];\n }\n\n try {\n localStorage.setItem(\"broadcast\", JSON.stringify(event));\n } catch (error) {\n console.log(error);\n }\n};\n\nfunction colorHash(str) {\n var hash = 0;\n\n for (var i = 0; i < str.length; i++) {\n hash = str.charCodeAt(i) + ((hash << 5) - hash);\n }\n\n var colour = \"#\";\n\n for (var _i = 0; _i < 3; _i++) {\n var value = hash >> _i * 8 & 0xff;\n colour += (\"00\" + value.toString(16)).substr(-2);\n }\n\n return colour;\n}\n\nfunction htmlEntities(string) {\n return (0, _jquery.default)(\"
\").text(string).html();\n}\n\nfunction cumulativeSum(arr) {\n var result = arr.concat();\n\n for (var i = 0; i < arr.length; i++) {\n result[i] = arr.slice(0, i + 1).reduce(function (p, i) {\n return p + i;\n });\n }\n\n return result;\n}\n\nvar storage = window.localStorage;\nvar counter_key = \"unread_notifications\";\n\nfunction init_notification_counter() {\n var count = storage.getItem(counter_key);\n\n if (count === null) {\n storage.setItem(counter_key, 0);\n } else {\n if (count > 0) {\n (0, _jquery.default)(\".badge-notification\").text(count);\n }\n }\n}\n\nfunction set_notification_counter(count) {\n storage.setItem(counter_key, count);\n}\n\nfunction inc_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n storage.setItem(counter_key, ++count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n}\n\nfunction dec_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n\n if (count > 0) {\n storage.setItem(counter_key, --count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n } // Always clear if count is 0\n\n\n if (count == 0) {\n clear_notification_counter();\n }\n}\n\nfunction clear_notification_counter() {\n storage.setItem(counter_key, 0);\n (0, _jquery.default)(\".badge-notification\").empty();\n}\n\nfunction copyToClipboard(event, selector) {\n // Select element\n (0, _jquery.default)(selector).select(); // Copy to clipboard\n\n document.execCommand(\"copy\"); // Show tooltip to user\n\n (0, _jquery.default)(event.target).tooltip({\n title: \"Copied!\",\n trigger: \"manual\"\n });\n (0, _jquery.default)(event.target).tooltip(\"show\");\n setTimeout(function () {\n (0, _jquery.default)(event.target).tooltip(\"hide\");\n }, 1500);\n}\n\nfunction makeSortableTables() {\n (0, _jquery.default)(\"th.sort-col\").append(\" \");\n (0, _jquery.default)(\"th.sort-col\").click(function () {\n var table = (0, _jquery.default)(this).parents(\"table\").eq(0);\n var rows = table.find(\"tr:gt(0)\").toArray().sort(comparer((0, _jquery.default)(this).index()));\n this.asc = !this.asc;\n\n if (!this.asc) {\n rows = rows.reverse();\n }\n\n for (var i = 0; i < rows.length; i++) {\n table.append(rows[i]);\n }\n });\n\n function comparer(index) {\n return function (a, b) {\n var valA = getCellValue(a, index),\n valB = getCellValue(b, index);\n return _jquery.default.isNumeric(valA) && _jquery.default.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB);\n };\n }\n\n function getCellValue(row, index) {\n return (0, _jquery.default)(row).children(\"td\").eq(index).text();\n }\n}\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/utils.js?"); /***/ }), diff --git a/CTFd/themes/admin/static/js/pages/scoreboard.dev.js b/CTFd/themes/admin/static/js/pages/scoreboard.dev.js index b6f11eeb..644965ce 100644 --- a/CTFd/themes/admin/static/js/pages/scoreboard.dev.js +++ b/CTFd/themes/admin/static/js/pages/scoreboard.dev.js @@ -162,7 +162,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar api_func = {\n users: function users(x, y) {\n return _CTFd.default.api.patch_user_public({\n userId: x\n }, y);\n },\n teams: function teams(x, y) {\n return _CTFd.default.api.patch_team_public({\n teamId: x\n }, y);\n }\n};\n\nfunction toggleAccount() {\n var $btn = (0, _jquery.default)(this);\n var id = $btn.data(\"account-id\");\n var state = $btn.data(\"state\");\n var hidden = undefined;\n\n if (state === \"visible\") {\n hidden = true;\n } else if (state === \"hidden\") {\n hidden = false;\n }\n\n var params = {\n hidden: hidden\n };\n\n api_func[_CTFd.default.config.userMode](id, params).then(function (response) {\n if (response.success) {\n if (hidden) {\n $btn.data(\"state\", \"hidden\");\n $btn.addClass(\"btn-danger\").removeClass(\"btn-success\");\n $btn.text(\"Hidden\");\n } else {\n $btn.data(\"state\", \"visible\");\n $btn.addClass(\"btn-success\").removeClass(\"btn-danger\");\n $btn.text(\"Visible\");\n }\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".scoreboard-toggle\").click(toggleAccount);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/scoreboard.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar api_func = {\n users: function users(x, y) {\n return _CTFd.default.api.patch_user_public({\n userId: x\n }, y);\n },\n teams: function teams(x, y) {\n return _CTFd.default.api.patch_team_public({\n teamId: x\n }, y);\n }\n};\n\nfunction toggleAccount() {\n var $btn = (0, _jquery.default)(this);\n var id = $btn.data(\"account-id\");\n var state = $btn.data(\"state\");\n var hidden = undefined;\n\n if (state === \"visible\") {\n hidden = true;\n } else if (state === \"hidden\") {\n hidden = false;\n }\n\n var params = {\n hidden: hidden\n };\n\n api_func[_CTFd.default.config.userMode](id, params).then(function (response) {\n if (response.success) {\n if (hidden) {\n $btn.data(\"state\", \"hidden\");\n $btn.addClass(\"btn-danger\").removeClass(\"btn-success\");\n $btn.text(\"Hidden\");\n } else {\n $btn.data(\"state\", \"visible\");\n $btn.addClass(\"btn-success\").removeClass(\"btn-danger\");\n $btn.text(\"Visible\");\n }\n }\n });\n}\n\nfunction toggleSelectedAccounts(accountIDs, action) {\n var params = {\n hidden: action === \"hide\" ? true : false\n };\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = accountIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var accId = _step.value;\n reqs.push(api_func[_CTFd.default.config.userMode](accId, params));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n}\n\nfunction hideSelectedAccounts(event) {\n var accountIDs = (0, _jquery.default)(\"input[data-account-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"account-id\");\n });\n var target = accountIDs.length === 1 ? \"account\" : \"accounts\";\n (0, _ezq.ezQuery)({\n title: \"Hide Accounts\",\n body: \"Are you sure you want to hide \".concat(accountIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n toggleSelectedAccounts(accountIDs, \"hide\");\n }\n });\n}\n\nfunction showSelectedAccounts(event) {\n var accountIDs = (0, _jquery.default)(\"input[data-account-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"account-id\");\n });\n var target = accountIDs.length === 1 ? \"account\" : \"accounts\";\n (0, _ezq.ezQuery)({\n title: \"Unhide Accounts\",\n body: \"Are you sure you want to unhide \".concat(accountIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n toggleSelectedAccounts(accountIDs, \"show\");\n }\n });\n}\n\nfunction toggleScoreboardSelect(event) {\n var checked = (0, _jquery.default)(this).prop(\"checked\");\n (0, _jquery.default)(this).closest(\"table\").find(\"input[data-account-id]\").prop(\"checked\", checked);\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".scoreboard-toggle\").click(toggleAccount);\n (0, _jquery.default)(\"#scoreboard-bulk-select\").click(toggleScoreboardSelect);\n (0, _jquery.default)(\"#scoreboard-hide-button\").click(hideSelectedAccounts);\n (0, _jquery.default)(\"#scoreboard-show-button\").click(showSelectedAccounts);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/scoreboard.js?"); /***/ }) diff --git a/CTFd/themes/admin/static/js/pages/submissions.dev.js b/CTFd/themes/admin/static/js/pages/submissions.dev.js index ab31c736..771da222 100644 --- a/CTFd/themes/admin/static/js/pages/submissions.dev.js +++ b/CTFd/themes/admin/static/js/pages/submissions.dev.js @@ -162,7 +162,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteCorrectSubmission(event) {\n var key_id = (0, _jquery.default)(this).data(\"submission-id\");\n var $elem = (0, _jquery.default)(this).parent().parent();\n var chal_name = $elem.find(\".chal\").text().trim();\n var team_name = $elem.find(\".team\").text().trim();\n var row = (0, _jquery.default)(this).parent().parent();\n (0, _ezq.ezQuery)({\n title: \"Delete Submission\",\n body: \"Are you sure you want to delete correct submission from {0} for challenge {1}\".format(\"\" + (0, _utils.htmlEntities)(team_name) + \"\", \"\" + (0, _utils.htmlEntities)(chal_name) + \"\"),\n success: function success() {\n _CTFd.default.api.delete_submission({\n submissionId: key_id\n }).then(function (response) {\n if (response.success) {\n row.remove();\n }\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".delete-correct-submission\").click(deleteCorrectSubmission);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/submissions.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteCorrectSubmission(event) {\n var key_id = (0, _jquery.default)(this).data(\"submission-id\");\n var $elem = (0, _jquery.default)(this).parent().parent();\n var chal_name = $elem.find(\".chal\").text().trim();\n var team_name = $elem.find(\".team\").text().trim();\n var row = (0, _jquery.default)(this).parent().parent();\n (0, _ezq.ezQuery)({\n title: \"Delete Submission\",\n body: \"Are you sure you want to delete correct submission from {0} for challenge {1}\".format(\"\" + (0, _utils.htmlEntities)(team_name) + \"\", \"\" + (0, _utils.htmlEntities)(chal_name) + \"\"),\n success: function success() {\n _CTFd.default.api.delete_submission({\n submissionId: key_id\n }).then(function (response) {\n if (response.success) {\n row.remove();\n }\n });\n }\n });\n}\n\nfunction deleteSelectedSubmissions(event) {\n var submissionIDs = (0, _jquery.default)(\"input[data-submission-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"submission-id\");\n });\n var target = submissionIDs.length === 1 ? \"submission\" : \"submissions\";\n (0, _ezq.ezQuery)({\n title: \"Delete Submissions\",\n body: \"Are you sure you want to delete \".concat(submissionIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = submissionIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var subId = _step.value;\n reqs.push(_CTFd.default.api.delete_submission({\n submissionId: subId\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\nfunction toggleSubmissionSelect(event) {\n var checked = (0, _jquery.default)(this).prop(\"checked\");\n (0, _jquery.default)(this).closest(\"table\").find(\"input[data-submission-id]\").prop(\"checked\", checked);\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".delete-correct-submission\").click(deleteCorrectSubmission);\n (0, _jquery.default)(\"#submissions-bulk-select\").change(toggleSubmissionSelect);\n (0, _jquery.default)(\"#submission-delete-button\").click(deleteSelectedSubmissions);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/submissions.js?"); /***/ }) diff --git a/CTFd/themes/admin/templates/scoreboard.html b/CTFd/themes/admin/templates/scoreboard.html index aa855090..a7202afa 100644 --- a/CTFd/themes/admin/templates/scoreboard.html +++ b/CTFd/themes/admin/templates/scoreboard.html @@ -9,19 +9,43 @@
- +
+
+ + +
+
+ + +
+
+
- - - - + + + + + {% for standing in standings %} - + + {% endfor %} diff --git a/CTFd/themes/admin/templates/submissions.html b/CTFd/themes/admin/templates/submissions.html index 458cadef..87e60834 100644 --- a/CTFd/themes/admin/templates/submissions.html +++ b/CTFd/themes/admin/templates/submissions.html @@ -14,21 +14,41 @@
-
PlaceTeamScoreVisibility +
+   +
+
PlaceTeamScoreVisibility
{{ loop.index }} +
+   +
+
{{ loop.index }} {{ standing.name }} @@ -40,15 +64,11 @@ {{ standing.score }} - {% if standing.hidden %} - - {% else %} - - {% endif %} + {% if standing.hidden %} + Hidden + {% else %} + Visible + {% endif %}
+
+
+ +
+
+ + +
+
+
- - - - - - - + + + + + + + {% for sub in submissions %} + @@ -47,12 +67,6 @@ - {% endfor %} diff --git a/CTFd/themes/core/assets/js/utils.js b/CTFd/themes/core/assets/js/utils.js index 4980ffe0..dd778517 100644 --- a/CTFd/themes/core/assets/js/utils.js +++ b/CTFd/themes/core/assets/js/utils.js @@ -256,3 +256,38 @@ export function copyToClipboard(event, selector) { $(event.target).tooltip("hide"); }, 1500); } + +export function makeSortableTables() { + $("th.sort-col").append(` `); + $("th.sort-col").click(function() { + var table = $(this) + .parents("table") + .eq(0); + var rows = table + .find("tr:gt(0)") + .toArray() + .sort(comparer($(this).index())); + this.asc = !this.asc; + if (!this.asc) { + rows = rows.reverse(); + } + for (var i = 0; i < rows.length; i++) { + table.append(rows[i]); + } + }); + function comparer(index) { + return function(a, b) { + var valA = getCellValue(a, index), + valB = getCellValue(b, index); + return $.isNumeric(valA) && $.isNumeric(valB) + ? valA - valB + : valA.toString().localeCompare(valB); + }; + } + function getCellValue(row, index) { + return $(row) + .children("td") + .eq(index) + .text(); + } +} diff --git a/CTFd/themes/core/static/js/core.dev.js b/CTFd/themes/core/static/js/core.dev.js index 271a0942..0a781769 100644 --- a/CTFd/themes/core/static/js/core.dev.js +++ b/CTFd/themes/core/static/js/core.dev.js @@ -128,7 +128,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.WindowController = WindowController;\nexports.colorHash = colorHash;\nexports.htmlEntities = htmlEntities;\nexports.cumulativeSum = cumulativeSum;\nexports.init_notification_counter = init_notification_counter;\nexports.set_notification_counter = set_notification_counter;\nexports.inc_notification_counter = inc_notification_counter;\nexports.dec_notification_counter = dec_notification_counter;\nexports.clear_notification_counter = clear_notification_counter;\nexports.copyToClipboard = copyToClipboard;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n_jquery.default.fn.serializeJSON = function (omit_nulls) {\n var params = {};\n var form = (0, _jquery.default)(this);\n var values = form.serializeArray();\n values = values.concat(form.find(\"input[type=checkbox]:checked\").map(function () {\n return {\n name: this.name,\n value: true\n };\n }).get());\n values = values.concat(form.find(\"input[type=checkbox]:not(:checked)\").map(function () {\n return {\n name: this.name,\n value: false\n };\n }).get());\n values.map(function (x) {\n if (omit_nulls) {\n if (x.value !== null && x.value !== \"\") {\n params[x.name] = x.value;\n } else {\n var input = form.find(\":input[name=\".concat(x.name, \"]\"));\n\n if (input.data(\"initial\") !== input.val()) {\n params[x.name] = x.value;\n }\n }\n } else {\n params[x.name] = x.value;\n }\n });\n return params;\n}; //http://stackoverflow.com/a/2648463 - wizardry!\n\n\nString.prototype.format = String.prototype.f = function () {\n var s = this,\n i = arguments.length;\n\n while (i--) {\n s = s.replace(new RegExp(\"\\\\{\" + i + \"\\\\}\", \"gm\"), arguments[i]);\n }\n\n return s;\n}; //http://stackoverflow.com/a/7616484\n\n\nString.prototype.hashCode = function () {\n var hash = 0,\n i,\n chr,\n len;\n if (this.length == 0) return hash;\n\n for (i = 0, len = this.length; i < len; i++) {\n chr = this.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n\n return hash;\n}; // https://gist.github.com/neilj/4146038\n// https://fastmail.blog/2012/11/26/inter-tab-communication-using-local-storage/\n\n\nfunction WindowController() {\n this.id = Math.random();\n this.isMaster = false;\n this.others = {};\n window.addEventListener(\"storage\", this, false);\n window.addEventListener(\"unload\", this, false);\n this.broadcast(\"hello\");\n var that = this;\n\n var check = function check() {\n that.check();\n that._checkTimeout = setTimeout(check, 9000);\n };\n\n var ping = function ping() {\n that.sendPing();\n that._pingTimeout = setTimeout(ping, 17000);\n };\n\n this._checkTimeout = setTimeout(check, 500);\n this._pingTimeout = setTimeout(ping, 17000);\n}\n\nWindowController.prototype.destroy = function () {\n clearTimeout(this._pingTimeout);\n clearTimeout(this._checkTimeout);\n window.removeEventListener(\"storage\", this, false);\n window.removeEventListener(\"unload\", this, false);\n this.broadcast(\"bye\");\n};\n\nWindowController.prototype.handleEvent = function (event) {\n if (event.type === \"unload\") {\n this.destroy();\n } else if (event.key === \"broadcast\") {\n try {\n var data = JSON.parse(event.newValue);\n\n if (data.id !== this.id) {\n this[data.type](data);\n }\n } catch (error) {}\n }\n};\n\nWindowController.prototype.sendPing = function () {\n this.broadcast(\"ping\");\n};\n\nWindowController.prototype.hello = function (event) {\n this.ping(event);\n\n if (event.id < this.id) {\n this.check();\n } else {\n this.sendPing();\n }\n};\n\nWindowController.prototype.ping = function (event) {\n this.others[event.id] = +new Date();\n};\n\nWindowController.prototype.bye = function (event) {\n delete this.others[event.id];\n this.check();\n};\n\nWindowController.prototype.check = function (event) {\n var now = +new Date(),\n takeMaster = true,\n id;\n\n for (id in this.others) {\n if (this.others[id] + 23000 < now) {\n delete this.others[id];\n } else if (id < this.id) {\n takeMaster = false;\n }\n }\n\n if (this.isMaster !== takeMaster) {\n this.isMaster = takeMaster;\n this.masterDidChange();\n }\n};\n\nWindowController.prototype.masterDidChange = function () {};\n\nWindowController.prototype.broadcast = function (type, data) {\n var event = {\n id: this.id,\n type: type\n };\n\n for (var x in data) {\n event[x] = data[x];\n }\n\n try {\n localStorage.setItem(\"broadcast\", JSON.stringify(event));\n } catch (error) {\n console.log(error);\n }\n};\n\nfunction colorHash(str) {\n var hash = 0;\n\n for (var i = 0; i < str.length; i++) {\n hash = str.charCodeAt(i) + ((hash << 5) - hash);\n }\n\n var colour = \"#\";\n\n for (var _i = 0; _i < 3; _i++) {\n var value = hash >> _i * 8 & 0xff;\n colour += (\"00\" + value.toString(16)).substr(-2);\n }\n\n return colour;\n}\n\nfunction htmlEntities(string) {\n return (0, _jquery.default)(\"
\").text(string).html();\n}\n\nfunction cumulativeSum(arr) {\n var result = arr.concat();\n\n for (var i = 0; i < arr.length; i++) {\n result[i] = arr.slice(0, i + 1).reduce(function (p, i) {\n return p + i;\n });\n }\n\n return result;\n}\n\nvar storage = window.localStorage;\nvar counter_key = \"unread_notifications\";\n\nfunction init_notification_counter() {\n var count = storage.getItem(counter_key);\n\n if (count === null) {\n storage.setItem(counter_key, 0);\n } else {\n if (count > 0) {\n (0, _jquery.default)(\".badge-notification\").text(count);\n }\n }\n}\n\nfunction set_notification_counter(count) {\n storage.setItem(counter_key, count);\n}\n\nfunction inc_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n storage.setItem(counter_key, ++count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n}\n\nfunction dec_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n\n if (count > 0) {\n storage.setItem(counter_key, --count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n } // Always clear if count is 0\n\n\n if (count == 0) {\n clear_notification_counter();\n }\n}\n\nfunction clear_notification_counter() {\n storage.setItem(counter_key, 0);\n (0, _jquery.default)(\".badge-notification\").empty();\n}\n\nfunction copyToClipboard(event, selector) {\n // Select element\n (0, _jquery.default)(selector).select(); // Copy to clipboard\n\n document.execCommand(\"copy\"); // Show tooltip to user\n\n (0, _jquery.default)(event.target).tooltip({\n title: \"Copied!\",\n trigger: \"manual\"\n });\n (0, _jquery.default)(event.target).tooltip(\"show\");\n setTimeout(function () {\n (0, _jquery.default)(event.target).tooltip(\"hide\");\n }, 1500);\n}\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/utils.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.WindowController = WindowController;\nexports.colorHash = colorHash;\nexports.htmlEntities = htmlEntities;\nexports.cumulativeSum = cumulativeSum;\nexports.init_notification_counter = init_notification_counter;\nexports.set_notification_counter = set_notification_counter;\nexports.inc_notification_counter = inc_notification_counter;\nexports.dec_notification_counter = dec_notification_counter;\nexports.clear_notification_counter = clear_notification_counter;\nexports.copyToClipboard = copyToClipboard;\nexports.makeSortableTables = makeSortableTables;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n_jquery.default.fn.serializeJSON = function (omit_nulls) {\n var params = {};\n var form = (0, _jquery.default)(this);\n var values = form.serializeArray();\n values = values.concat(form.find(\"input[type=checkbox]:checked\").map(function () {\n return {\n name: this.name,\n value: true\n };\n }).get());\n values = values.concat(form.find(\"input[type=checkbox]:not(:checked)\").map(function () {\n return {\n name: this.name,\n value: false\n };\n }).get());\n values.map(function (x) {\n if (omit_nulls) {\n if (x.value !== null && x.value !== \"\") {\n params[x.name] = x.value;\n } else {\n var input = form.find(\":input[name=\".concat(x.name, \"]\"));\n\n if (input.data(\"initial\") !== input.val()) {\n params[x.name] = x.value;\n }\n }\n } else {\n params[x.name] = x.value;\n }\n });\n return params;\n}; //http://stackoverflow.com/a/2648463 - wizardry!\n\n\nString.prototype.format = String.prototype.f = function () {\n var s = this,\n i = arguments.length;\n\n while (i--) {\n s = s.replace(new RegExp(\"\\\\{\" + i + \"\\\\}\", \"gm\"), arguments[i]);\n }\n\n return s;\n}; //http://stackoverflow.com/a/7616484\n\n\nString.prototype.hashCode = function () {\n var hash = 0,\n i,\n chr,\n len;\n if (this.length == 0) return hash;\n\n for (i = 0, len = this.length; i < len; i++) {\n chr = this.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n\n return hash;\n}; // https://gist.github.com/neilj/4146038\n// https://fastmail.blog/2012/11/26/inter-tab-communication-using-local-storage/\n\n\nfunction WindowController() {\n this.id = Math.random();\n this.isMaster = false;\n this.others = {};\n window.addEventListener(\"storage\", this, false);\n window.addEventListener(\"unload\", this, false);\n this.broadcast(\"hello\");\n var that = this;\n\n var check = function check() {\n that.check();\n that._checkTimeout = setTimeout(check, 9000);\n };\n\n var ping = function ping() {\n that.sendPing();\n that._pingTimeout = setTimeout(ping, 17000);\n };\n\n this._checkTimeout = setTimeout(check, 500);\n this._pingTimeout = setTimeout(ping, 17000);\n}\n\nWindowController.prototype.destroy = function () {\n clearTimeout(this._pingTimeout);\n clearTimeout(this._checkTimeout);\n window.removeEventListener(\"storage\", this, false);\n window.removeEventListener(\"unload\", this, false);\n this.broadcast(\"bye\");\n};\n\nWindowController.prototype.handleEvent = function (event) {\n if (event.type === \"unload\") {\n this.destroy();\n } else if (event.key === \"broadcast\") {\n try {\n var data = JSON.parse(event.newValue);\n\n if (data.id !== this.id) {\n this[data.type](data);\n }\n } catch (error) {}\n }\n};\n\nWindowController.prototype.sendPing = function () {\n this.broadcast(\"ping\");\n};\n\nWindowController.prototype.hello = function (event) {\n this.ping(event);\n\n if (event.id < this.id) {\n this.check();\n } else {\n this.sendPing();\n }\n};\n\nWindowController.prototype.ping = function (event) {\n this.others[event.id] = +new Date();\n};\n\nWindowController.prototype.bye = function (event) {\n delete this.others[event.id];\n this.check();\n};\n\nWindowController.prototype.check = function (event) {\n var now = +new Date(),\n takeMaster = true,\n id;\n\n for (id in this.others) {\n if (this.others[id] + 23000 < now) {\n delete this.others[id];\n } else if (id < this.id) {\n takeMaster = false;\n }\n }\n\n if (this.isMaster !== takeMaster) {\n this.isMaster = takeMaster;\n this.masterDidChange();\n }\n};\n\nWindowController.prototype.masterDidChange = function () {};\n\nWindowController.prototype.broadcast = function (type, data) {\n var event = {\n id: this.id,\n type: type\n };\n\n for (var x in data) {\n event[x] = data[x];\n }\n\n try {\n localStorage.setItem(\"broadcast\", JSON.stringify(event));\n } catch (error) {\n console.log(error);\n }\n};\n\nfunction colorHash(str) {\n var hash = 0;\n\n for (var i = 0; i < str.length; i++) {\n hash = str.charCodeAt(i) + ((hash << 5) - hash);\n }\n\n var colour = \"#\";\n\n for (var _i = 0; _i < 3; _i++) {\n var value = hash >> _i * 8 & 0xff;\n colour += (\"00\" + value.toString(16)).substr(-2);\n }\n\n return colour;\n}\n\nfunction htmlEntities(string) {\n return (0, _jquery.default)(\"
\").text(string).html();\n}\n\nfunction cumulativeSum(arr) {\n var result = arr.concat();\n\n for (var i = 0; i < arr.length; i++) {\n result[i] = arr.slice(0, i + 1).reduce(function (p, i) {\n return p + i;\n });\n }\n\n return result;\n}\n\nvar storage = window.localStorage;\nvar counter_key = \"unread_notifications\";\n\nfunction init_notification_counter() {\n var count = storage.getItem(counter_key);\n\n if (count === null) {\n storage.setItem(counter_key, 0);\n } else {\n if (count > 0) {\n (0, _jquery.default)(\".badge-notification\").text(count);\n }\n }\n}\n\nfunction set_notification_counter(count) {\n storage.setItem(counter_key, count);\n}\n\nfunction inc_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n storage.setItem(counter_key, ++count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n}\n\nfunction dec_notification_counter() {\n var count = storage.getItem(counter_key) || 0;\n\n if (count > 0) {\n storage.setItem(counter_key, --count);\n (0, _jquery.default)(\".badge-notification\").text(count);\n } // Always clear if count is 0\n\n\n if (count == 0) {\n clear_notification_counter();\n }\n}\n\nfunction clear_notification_counter() {\n storage.setItem(counter_key, 0);\n (0, _jquery.default)(\".badge-notification\").empty();\n}\n\nfunction copyToClipboard(event, selector) {\n // Select element\n (0, _jquery.default)(selector).select(); // Copy to clipboard\n\n document.execCommand(\"copy\"); // Show tooltip to user\n\n (0, _jquery.default)(event.target).tooltip({\n title: \"Copied!\",\n trigger: \"manual\"\n });\n (0, _jquery.default)(event.target).tooltip(\"show\");\n setTimeout(function () {\n (0, _jquery.default)(event.target).tooltip(\"hide\");\n }, 1500);\n}\n\nfunction makeSortableTables() {\n (0, _jquery.default)(\"th.sort-col\").append(\" \");\n (0, _jquery.default)(\"th.sort-col\").click(function () {\n var table = (0, _jquery.default)(this).parents(\"table\").eq(0);\n var rows = table.find(\"tr:gt(0)\").toArray().sort(comparer((0, _jquery.default)(this).index()));\n this.asc = !this.asc;\n\n if (!this.asc) {\n rows = rows.reverse();\n }\n\n for (var i = 0; i < rows.length; i++) {\n table.append(rows[i]);\n }\n });\n\n function comparer(index) {\n return function (a, b) {\n var valA = getCellValue(a, index),\n valB = getCellValue(b, index);\n return _jquery.default.isNumeric(valA) && _jquery.default.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB);\n };\n }\n\n function getCellValue(row, index) {\n return (0, _jquery.default)(row).children(\"td\").eq(index).text();\n }\n}\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/utils.js?"); /***/ }), From 3a15c155c762a8cc5e85f020de76cb6f0ee9ba56 Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Tue, 21 Apr 2020 22:38:46 -0400 Subject: [PATCH 02/11] Make it easier to click checkbox --- .../admin/assets/js/pages/scoreboard.js | 9 --------- .../admin/assets/js/pages/submissions.js | 9 --------- CTFd/themes/admin/assets/js/styles.js | 20 +++++++++++++++++++ CTFd/themes/admin/static/css/admin.dev.css | 2 +- CTFd/themes/admin/static/css/admin.min.css | 2 +- CTFd/themes/admin/static/js/core.dev.js | 2 +- .../admin/static/js/pages/challenge.min.js | 2 +- .../admin/static/js/pages/configs.min.js | 2 +- .../admin/static/js/pages/editor.min.js | 2 +- CTFd/themes/admin/static/js/pages/main.min.js | 2 +- .../static/js/pages/notifications.min.js | 2 +- .../themes/admin/static/js/pages/pages.min.js | 2 +- .../themes/admin/static/js/pages/reset.min.js | 2 +- .../admin/static/js/pages/scoreboard.dev.js | 2 +- .../admin/static/js/pages/scoreboard.min.js | 2 +- .../admin/static/js/pages/statistics.min.js | 2 +- .../admin/static/js/pages/submissions.dev.js | 2 +- .../admin/static/js/pages/submissions.min.js | 2 +- CTFd/themes/admin/static/js/pages/team.min.js | 2 +- CTFd/themes/admin/static/js/pages/user.min.js | 2 +- .../themes/admin/static/js/pages/users.min.js | 2 +- CTFd/themes/admin/templates/scoreboard.html | 6 +++--- CTFd/themes/admin/templates/submissions.html | 6 +++--- .../core/static/js/pages/challenges.min.js | 2 +- CTFd/themes/core/static/js/pages/main.min.js | 2 +- .../core/static/js/pages/notifications.min.js | 2 +- .../core/static/js/pages/scoreboard.min.js | 2 +- .../core/static/js/pages/settings.min.js | 2 +- CTFd/themes/core/static/js/pages/setup.min.js | 2 +- CTFd/themes/core/static/js/pages/stats.min.js | 2 +- .../core/static/js/pages/teams/private.min.js | 2 +- 31 files changed, 52 insertions(+), 50 deletions(-) diff --git a/CTFd/themes/admin/assets/js/pages/scoreboard.js b/CTFd/themes/admin/assets/js/pages/scoreboard.js index 9ab43414..dc9c7e48 100644 --- a/CTFd/themes/admin/assets/js/pages/scoreboard.js +++ b/CTFd/themes/admin/assets/js/pages/scoreboard.js @@ -79,17 +79,8 @@ function showSelectedAccounts(event) { }); } -function toggleScoreboardSelect(event) { - const checked = $(this).prop("checked"); - $(this) - .closest("table") - .find("input[data-account-id]") - .prop("checked", checked); -} - $(() => { $(".scoreboard-toggle").click(toggleAccount); - $("#scoreboard-bulk-select").click(toggleScoreboardSelect); $("#scoreboard-hide-button").click(hideSelectedAccounts); $("#scoreboard-show-button").click(showSelectedAccounts); }); diff --git a/CTFd/themes/admin/assets/js/pages/submissions.js b/CTFd/themes/admin/assets/js/pages/submissions.js index 651cd824..82c6fb3f 100644 --- a/CTFd/themes/admin/assets/js/pages/submissions.js +++ b/CTFd/themes/admin/assets/js/pages/submissions.js @@ -61,16 +61,7 @@ function deleteSelectedSubmissions(event) { }); } -function toggleSubmissionSelect(event) { - const checked = $(this).prop("checked"); - $(this) - .closest("table") - .find("input[data-submission-id]") - .prop("checked", checked); -} - $(() => { $(".delete-correct-submission").click(deleteCorrectSubmission); - $("#submissions-bulk-select").change(toggleSubmissionSelect); $("#submission-delete-button").click(deleteSelectedSubmissions); }); diff --git a/CTFd/themes/admin/assets/js/styles.js b/CTFd/themes/admin/assets/js/styles.js index 88dd2e16..125293b7 100644 --- a/CTFd/themes/admin/assets/js/styles.js +++ b/CTFd/themes/admin/assets/js/styles.js @@ -46,6 +46,26 @@ export default () => { return false; }); + $("[data-checkbox]").click(function(e){ + if ($(e.target).is("input[type=checkbox]")) { + e.stopImmediatePropagation(); + return; + } + let checkbox = $(this).find('input[type=checkbox]'); + // Doing it this way with an event allows data-checkbox-all to work + checkbox.click(); + e.stopImmediatePropagation(); + }); + + $("[data-checkbox-all]").on('click change', function(e){ + const checked = $(this).prop("checked"); + const idx = $(this).index() + 1; + $(this).closest("table") + .find(`tr td:nth-child(${idx}) input[type=checkbox]`) + .prop("checked", checked) + e.stopImmediatePropagation(); + }); + $("tr[data-href] a, tr[data-href] button").click(function(e) { // TODO: This is a hack to allow modal close buttons to work if (!$(this).attr("data-dismiss")) { diff --git a/CTFd/themes/admin/static/css/admin.dev.css b/CTFd/themes/admin/static/css/admin.dev.css index 9ad61a10..e015e2d3 100644 --- a/CTFd/themes/admin/static/css/admin.dev.css +++ b/CTFd/themes/admin/static/css/admin.dev.css @@ -1,4 +1,4 @@ html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal !important;z-index:-20} -#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#keys-pie-graph{height:400px;display:block}#categories-pie-graph{height:400px;display:block}#solve-percentages-graph{height:400px;display:block}.no-decoration{color:inherit !important;text-decoration:none !important}.no-decoration:hover{color:inherit !important;text-decoration:none !important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:"Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,0.1) !important}tr[data-href]{cursor:pointer}th{cursor:pointer}input[type=checkbox]{cursor:pointer} +#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#keys-pie-graph{height:400px;display:block}#categories-pie-graph{height:400px;display:block}#solve-percentages-graph{height:400px;display:block}.no-decoration{color:inherit !important;text-decoration:none !important}.no-decoration:hover{color:inherit !important;text-decoration:none !important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:"Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,0.1) !important}tr[data-href]{cursor:pointer}.sort-col{cursor:pointer}input[type="checkbox"]{cursor:pointer} diff --git a/CTFd/themes/admin/static/css/admin.min.css b/CTFd/themes/admin/static/css/admin.min.css index d207c511..75edc2ee 100644 --- a/CTFd/themes/admin/static/css/admin.min.css +++ b/CTFd/themes/admin/static/css/admin.min.css @@ -1 +1 @@ -html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal!important;z-index:-20}#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#categories-pie-graph,#keys-pie-graph,#solve-percentages-graph{height:400px;display:block}.no-decoration,.no-decoration:hover{color:inherit!important;text-decoration:none!important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:Avenir Next,Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,.1)!important}tr[data-href]{cursor:pointer} \ No newline at end of file +html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal!important;z-index:-20}#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#categories-pie-graph,#keys-pie-graph,#solve-percentages-graph{height:400px;display:block}.no-decoration,.no-decoration:hover{color:inherit!important;text-decoration:none!important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:Avenir Next,Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,.1)!important}.sort-col,input[type=checkbox],tr[data-href]{cursor:pointer} \ No newline at end of file diff --git a/CTFd/themes/admin/static/js/core.dev.js b/CTFd/themes/admin/static/js/core.dev.js index 9501d880..8b5c2806 100644 --- a/CTFd/themes/admin/static/js/core.dev.js +++ b/CTFd/themes/admin/static/js/core.dev.js @@ -20,7 +20,7 @@ eval("\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd * /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/dist/js/bootstrap.bundle */ \"./node_modules/bootstrap/dist/js/bootstrap.bundle.js\");\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = function _default() {\n // TODO: This is kind of a hack to mimic a React-like state construct.\n // It should be removed once we have a real front-end framework in place.\n (0, _jquery.default)(\":input\").each(function () {\n (0, _jquery.default)(this).data(\"initial\", (0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\".form-control\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n },\n blur: function blur() {\n if ((0, _jquery.default)(this).val() === \"\") {\n (0, _jquery.default)(this).removeClass(\"input-filled-valid\");\n }\n }\n });\n (0, _jquery.default)(\".modal\").on(\"show.bs.modal\", function (e) {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n });\n (0, _jquery.default)(function () {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n (0, _jquery.default)(\"tr[data-href]\").click(function () {\n var sel = getSelection().toString();\n\n if (!sel) {\n var href = (0, _jquery.default)(this).attr(\"data-href\");\n\n if (href) {\n window.location = href;\n }\n }\n\n return false;\n });\n (0, _jquery.default)(\"tr[data-href] a, tr[data-href] button\").click(function (e) {\n // TODO: This is a hack to allow modal close buttons to work\n if (!(0, _jquery.default)(this).attr(\"data-dismiss\")) {\n e.stopPropagation();\n }\n });\n (0, _utils.makeSortableTables)();\n (0, _jquery.default)('[data-toggle=\"tooltip\"]').tooltip();\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/styles.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/dist/js/bootstrap.bundle */ \"./node_modules/bootstrap/dist/js/bootstrap.bundle.js\");\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = function _default() {\n // TODO: This is kind of a hack to mimic a React-like state construct.\n // It should be removed once we have a real front-end framework in place.\n (0, _jquery.default)(\":input\").each(function () {\n (0, _jquery.default)(this).data(\"initial\", (0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\".form-control\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n },\n blur: function blur() {\n if ((0, _jquery.default)(this).val() === \"\") {\n (0, _jquery.default)(this).removeClass(\"input-filled-valid\");\n }\n }\n });\n (0, _jquery.default)(\".modal\").on(\"show.bs.modal\", function (e) {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n });\n (0, _jquery.default)(function () {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n (0, _jquery.default)(\"tr[data-href]\").click(function () {\n var sel = getSelection().toString();\n\n if (!sel) {\n var href = (0, _jquery.default)(this).attr(\"data-href\");\n\n if (href) {\n window.location = href;\n }\n }\n\n return false;\n });\n (0, _jquery.default)(\"[data-checkbox]\").click(function (e) {\n if ((0, _jquery.default)(e.target).is(\"input[type=checkbox]\")) {\n e.stopImmediatePropagation();\n return;\n }\n\n var checkbox = (0, _jquery.default)(this).find('input[type=checkbox]'); // Doing it this way with an event allows data-checkbox-all to work\n\n checkbox.click();\n e.stopImmediatePropagation();\n });\n (0, _jquery.default)(\"[data-checkbox-all]\").on('click change', function (e) {\n var checked = (0, _jquery.default)(this).prop(\"checked\");\n var idx = (0, _jquery.default)(this).index() + 1;\n (0, _jquery.default)(this).closest(\"table\").find(\"tr td:nth-child(\".concat(idx, \") input[type=checkbox]\")).prop(\"checked\", checked);\n e.stopImmediatePropagation();\n });\n (0, _jquery.default)(\"tr[data-href] a, tr[data-href] button\").click(function (e) {\n // TODO: This is a hack to allow modal close buttons to work\n if (!(0, _jquery.default)(this).attr(\"data-dismiss\")) {\n e.stopPropagation();\n }\n });\n (0, _utils.makeSortableTables)();\n (0, _jquery.default)('[data-toggle=\"tooltip\"]').tooltip();\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/styles.js?"); /***/ }), diff --git a/CTFd/themes/admin/static/js/pages/challenge.min.js b/CTFd/themes/admin/static/js/pages/challenge.min.js index 17618b66..40592209 100644 --- a/CTFd/themes/admin/static/js/pages/challenge.min.js +++ b/CTFd/themes/admin/static/js/pages/challenge.min.js @@ -1 +1 @@ -!function(d){function e(e){for(var t,o,n=e[0],s=e[1],a=e[2],i=0,l=[];i -- ");for(var s in o.append(n),t)t.hasOwnProperty(s)&&(n=(0,a.default)("".format(s,t[s].name)),o.append(n));(0,a.default)("#flag-edit-modal").modal()}),(0,a.default)("#flag-edit-modal form").submit(function(e){e.preventDefault();var t=(0,a.default)(this).serializeJSON(!0);t.challenge=CHALLENGE_ID,i.default.fetch("/api/v1/flags",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){window.location.reload()})}),(0,a.default)("#flag-edit-modal").modal()},t.editFlagModal=function(e){e.preventDefault();var n=(0,a.default)(this).attr("flag-id"),s=(0,a.default)(this).parent().parent();a.default.get(i.default.config.urlRoot+"/api/v1/flags/"+n,function(e){var o=e.data;a.default.get(i.default.config.urlRoot+o.templates.update,function(e){(0,a.default)("#edit-flags form").empty(),(0,a.default)("#edit-flags form").off();var t=l.default.compile(e);(0,a.default)("#edit-flags form").append(t.render(o)),(0,a.default)("#edit-flags form").submit(function(e){e.preventDefault();var t=(0,a.default)("#edit-flags form").serializeJSON();i.default.fetch("/api/v1/flags/"+n,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){e.success&&((0,a.default)(s).find(".flag-content").text(e.data.content),(0,a.default)("#edit-flags").modal("toggle"))})}),(0,a.default)("#edit-flags").modal()})})},t.flagTypeSelect=function(e){e.preventDefault();var t=(0,a.default)(this).find("option:selected").text();a.default.get(i.default.config.urlRoot+"/api/v1/flags/types/"+t,function(e){var t=e.data;a.default.get(i.default.config.urlRoot+t.templates.create,function(e){var t=l.default.compile(e);(0,a.default)("#create-keys-entry-div").html(t.render()),(0,a.default)("#create-keys-button-div").show()})})};var a=s(o("./node_modules/jquery/dist/jquery.js")),i=s(o("./CTFd/themes/core/assets/js/CTFd.js")),l=s(o("./node_modules/nunjucks/browser/nunjucks.js")),n=o("./CTFd/themes/core/assets/js/ezq.js");function s(e){return e&&e.__esModule?e:{default:e}}},"./CTFd/themes/admin/assets/js/challenges/hints.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.showHintModal=function(e){e.preventDefault(),(0,s.default)("#hint-edit-modal form").find("input, textarea").val(""),(0,s.default)("#new-hint-edit").on("shown.bs.tab",function(e){if("#hint-preview"==e.target.hash){var t=a.default.lib.markdown(),o=(0,s.default)("#hint-write textarea").val();(0,s.default)(e.target.hash).html(t.render(o))}}),(0,s.default)("#hint-edit-modal").modal()},t.showEditHintModal=function(e){e.preventDefault();var t=(0,s.default)(this).attr("hint-id");a.default.fetch("/api/v1/hints/"+t+"?preview=true",{method:"GET",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"}}).then(function(e){return e.json()}).then(function(e){e.success&&((0,s.default)("#hint-edit-form input[name=content],textarea[name=content]").val(e.data.content),(0,s.default)("#hint-edit-form input[name=cost]").val(e.data.cost),(0,s.default)("#hint-edit-form input[name=id]").val(e.data.id),(0,s.default)("#new-hint-edit").on("shown.bs.tab",function(e){if("#hint-preview"==e.target.hash){var t=a.default.lib.markdown(),o=(0,s.default)("#hint-write textarea").val();(0,s.default)(e.target.hash).html(t.render(o))}}),(0,s.default)("#hint-edit-modal").modal())})},t.deleteHint=function(e){e.preventDefault();var t=(0,s.default)(this).attr("hint-id"),o=(0,s.default)(this).parent().parent();(0,n.ezQuery)({title:"Delete Hint",body:"Are you sure you want to delete this hint?",success:function(){a.default.fetch("/api/v1/hints/"+t,{method:"DELETE"}).then(function(e){return e.json()}).then(function(e){e.success&&o.remove()})}})},t.editHint=function(e){e.preventDefault();var t=(0,s.default)(this).serializeJSON(!0);t.challenge=CHALLENGE_ID;var o="POST",n="/api/v1/hints";t.id&&(o="PATCH",n="/api/v1/hints/"+t.id);a.default.fetch(n,{method:o,credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){e.success&&window.location.reload()})};var s=i(o("./node_modules/jquery/dist/jquery.js")),a=i(o("./CTFd/themes/core/assets/js/CTFd.js")),n=o("./CTFd/themes/core/assets/js/ezq.js");function i(e){return e&&e.__esModule?e:{default:e}}},"./CTFd/themes/admin/assets/js/challenges/requirements.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.addRequirement=function(e){e.preventDefault();var t=(0,s.default)("#prerequisite-add-form").serializeJSON();if(!t.prerequisite)return;CHALLENGE_REQUIREMENTS.prerequisites.push(parseInt(t.prerequisite));var o={requirements:CHALLENGE_REQUIREMENTS};a.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(o)}).then(function(e){return e.json()}).then(function(e){e.success&&window.location.reload()})},t.deleteRequirement=function(e){var t=(0,s.default)(this).attr("challenge-id"),o=(0,s.default)(this).parent().parent();CHALLENGE_REQUIREMENTS.prerequisites.pop(t);var n={requirements:CHALLENGE_REQUIREMENTS};a.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(n)}).then(function(e){return e.json()}).then(function(e){e.success&&o.remove()})};var s=n(o("./node_modules/jquery/dist/jquery.js")),a=n(o("./CTFd/themes/core/assets/js/CTFd.js"));function n(e){return e&&e.__esModule?e:{default:e}}},"./CTFd/themes/admin/assets/js/challenges/tags.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.deleteTag=i,t.addTag=function(e){if(13!=e.keyCode)return;var t=(0,n.default)(this),o={value:t.val(),challenge:CHALLENGE_ID};s.default.api.post_tag_list({},o).then(function(e){if(e.success){var t=(0,n.default)("{0}×".format(e.data.value,e.data.id));(0,n.default)("#challenge-tags").append(t),t.click(i)}}),t.val("")};var n=a(o("./node_modules/jquery/dist/jquery.js")),s=a(o("./CTFd/themes/core/assets/js/CTFd.js"));function a(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=(0,n.default)(this),o=t.attr("tag-id");s.default.api.delete_tag({tagId:o}).then(function(e){e.success&&t.parent().remove()})}},"./CTFd/themes/admin/assets/js/pages/challenge.js":function(e,t,o){o("./CTFd/themes/admin/assets/js/pages/main.js");var n=o("./CTFd/themes/core/assets/js/utils.js"),l=f(o("./node_modules/jquery/dist/jquery.js"));o("./node_modules/bootstrap/js/dist/tab.js");var i=f(o("./CTFd/themes/core/assets/js/CTFd.js")),s=o("./CTFd/themes/core/assets/js/ezq.js"),a=f(o("./node_modules/nunjucks/browser/nunjucks.js")),d=f(o("./CTFd/themes/core/assets/js/helpers.js")),r=o("./CTFd/themes/admin/assets/js/challenges/files.js"),c=o("./CTFd/themes/admin/assets/js/challenges/tags.js"),u=o("./CTFd/themes/admin/assets/js/challenges/requirements.js"),m=o("./CTFd/themes/admin/assets/js/challenges/hints.js"),p=o("./CTFd/themes/admin/assets/js/challenges/flags.js");function f(e){return e&&e.__esModule?e:{default:e}}function h(t){i.default.api.get_hint({hintId:t,preview:!0}).then(function(e){e.data.content?function(e){(0,s.ezAlert)({title:"Hint",body:j.render(e.content),button:"Got it!"})}(e.data):displayUnlock(t)})}var j=i.default.lib.markdown();function _(e,t){var o=e.data,n=(0,l.default)("#result-message"),s=(0,l.default)("#result-notification"),a=(0,l.default)("#submission-input");s.removeClass(),n.text(o.message),"authentication_required"!==o.status?("incorrect"===o.status?(s.addClass("alert alert-danger alert-dismissable text-center"),s.slideDown(),a.removeClass("correct"),a.addClass("wrong"),setTimeout(function(){a.removeClass("wrong")},3e3)):"correct"===o.status?(s.addClass("alert alert-success alert-dismissable text-center"),s.slideDown(),(0,l.default)(".challenge-solves").text(parseInt((0,l.default)(".challenge-solves").text().split(" ")[0])+1+" Solves"),a.val(""),a.removeClass("wrong"),a.addClass("correct")):"already_solved"===o.status?(s.addClass("alert alert-info alert-dismissable text-center"),s.slideDown(),a.addClass("correct")):"paused"===o.status?(s.addClass("alert alert-warning alert-dismissable text-center"),s.slideDown()):"ratelimited"===o.status&&(s.addClass("alert alert-warning alert-dismissable text-center"),s.slideDown(),a.addClass("too-fast"),setTimeout(function(){a.removeClass("too-fast")},3e3)),setTimeout(function(){(0,l.default)(".alert").slideUp(),(0,l.default)("#submit-key").removeClass("disabled-button"),(0,l.default)("#submit-key").prop("disabled",!1)},3e3),t&&t(o)):window.location=i.default.config.urlRoot+"/login?next="+i.default.config.urlRoot+window.location.pathname+window.location.hash}function g(o){i.default._internal.challenge={},l.default.getScript(i.default.config.urlRoot+o.scripts.view,function(){l.default.get(i.default.config.urlRoot+o.templates.create,function(e){var t=a.default.compile(e);(0,l.default)("#create-chal-entry-div").html(t.render({nonce:i.default.config.csrfNonce,script_root:i.default.config.urlRoot})),l.default.getScript(i.default.config.urlRoot+o.scripts.create,function(){(0,l.default)("#create-chal-entry-div form").submit(function(e){e.preventDefault();var t=(0,l.default)("#create-chal-entry-div form").serializeJSON();i.default.fetch("/api/v1/challenges",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){e.success&&((0,l.default)("#challenge-create-options #challenge_id").val(e.data.id),(0,l.default)("#challenge-create-options").modal())})})})})})}function v(s){s.preventDefault();var a=(0,l.default)(s.target).serializeJSON(!0),o={challenge_id:a.challenge_id,content:a.flag||"",type:a.flag_type,data:a.flag_data?a.flag_data:""};Promise.all([new Promise(function(t,e){0!=o.content.length?i.default.fetch("/api/v1/flags",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(o)}).then(function(e){t(e.json())}):t()}),new Promise(function(e,t){var o=s.target,n={challenge:a.challenge_id,type:"challenge"};(0,l.default)(o.elements.file).val()&&d.default.files.upload(o,n),e()})]).then(function(e){i.default.fetch("/api/v1/challenges/"+a.challenge_id,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({state:a.state})}).then(function(e){return e.json()}).then(function(e){e.success&&setTimeout(function(){window.location=i.default.config.urlRoot+"/admin/challenges/"+a.challenge_id},700)})})}function y(e){var t=(0,l.default)(this).find("option:selected").data("meta");void 0!==t?g(t):(0,l.default)("#create-chal-entry-div").empty()}(0,l.default)(function(){if((0,l.default)(".preview-challenge").click(function(e){window.challenge=new Object,i.default._internal.challenge={},l.default.get(i.default.config.urlRoot+"/api/v1/challenges/"+CHALLENGE_ID,function(e){var o=i.default._internal.challenge,n=e.data;n.solves=null,l.default.getScript(i.default.config.urlRoot+n.type_data.scripts.view,function(){l.default.get(i.default.config.urlRoot+n.type_data.templates.view,function(e){(0,l.default)("#challenge-window").empty();var t=a.default.compile(e);o.data=n,o.preRender(),n.description=o.render(n.description),n.script_root=i.default.config.urlRoot,(0,l.default)("#challenge-window").append(t.render(n)),(0,l.default)(".challenge-solves").click(function(e){getsolves((0,l.default)("#challenge-id").val())}),(0,l.default)(".nav-tabs a").click(function(e){e.preventDefault(),(0,l.default)(this).tab("show")}),(0,l.default)("#challenge-window").on("hide.bs.modal",function(e){(0,l.default)("#submission-input").removeClass("wrong"),(0,l.default)("#submission-input").removeClass("correct"),(0,l.default)("#incorrect-key").slideUp(),(0,l.default)("#correct-key").slideUp(),(0,l.default)("#already-solved").slideUp(),(0,l.default)("#too-fast").slideUp()}),(0,l.default)(".load-hint").on("click",function(e){h((0,l.default)(this).data("hint-id"))}),(0,l.default)("#submit-key").click(function(e){e.preventDefault(),(0,l.default)("#submit-key").addClass("disabled-button"),(0,l.default)("#submit-key").prop("disabled",!0),i.default._internal.challenge.submit(!0).then(_)}),(0,l.default)("#submission-input").keyup(function(e){13==e.keyCode&&(0,l.default)("#submit-key").click()}),(0,l.default)(".input-field").bind({focus:function(){(0,l.default)(this).parent().addClass("input--filled"),$label=(0,l.default)(this).siblings(".input-label")},blur:function(){""===(0,l.default)(this).val()&&((0,l.default)(this).parent().removeClass("input--filled"),$label=(0,l.default)(this).siblings(".input-label"),$label.removeClass("input--hide"))}}),o.postRender(),window.location.replace(window.location.href.split("#")[0]+"#preview"),(0,l.default)("#challenge-window").modal()})})})}),(0,l.default)(".delete-challenge").click(function(e){(0,s.ezQuery)({title:"Delete Challenge",body:"Are you sure you want to delete {0}".format(""+(0,n.htmlEntities)(CHALLENGE_NAME)+""),success:function(){i.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"DELETE"}).then(function(e){return e.json()}).then(function(e){e.success&&(window.location=i.default.config.urlRoot+"/admin/challenges")})}})}),(0,l.default)("#challenge-update-container > form").submit(function(e){e.preventDefault();var o=(0,l.default)(e.target).serializeJSON(!0);i.default.fetch("/api/v1/challenges/"+CHALLENGE_ID+"/flags",{method:"GET",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"}}).then(function(e){return e.json()}).then(function(e){function t(){i.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(o)}).then(function(e){return e.json()}).then(function(e){if(e.success){switch((0,l.default)(".challenge-state").text(e.data.state),e.data.state){case"visible":(0,l.default)(".challenge-state").removeClass("badge-danger").addClass("badge-success");break;case"hidden":(0,l.default)(".challenge-state").removeClass("badge-success").addClass("badge-danger")}(0,s.ezToast)({title:"Success",body:"Your challenge has been updated!"})}})}0===e.data.length&&"visible"===o.state?(0,s.ezQuery)({title:"Missing Flags",body:"This challenge does not have any flags meaning it is unsolveable. Are you sure you'd like to update this challenge?",success:t}):t()})}),(0,l.default)("#challenge-create-options form").submit(v),(0,l.default)(".nav-tabs a").click(function(e){(0,l.default)(this).tab("show"),window.location.hash=this.hash}),window.location.hash){var e=window.location.hash.replace("<>[]'\"","");(0,l.default)('nav a[href="'+e+'"]').tab("show")}(0,l.default)("#tags-add-input").keyup(c.addTag),(0,l.default)(".delete-tag").click(c.deleteTag),(0,l.default)("#prerequisite-add-form").submit(u.addRequirement),(0,l.default)(".delete-requirement").click(u.deleteRequirement),(0,l.default)("#file-add-form").submit(r.addFile),(0,l.default)(".delete-file").click(r.deleteFile),(0,l.default)("#hint-add-button").click(m.showHintModal),(0,l.default)(".delete-hint").click(m.deleteHint),(0,l.default)(".edit-hint").click(m.showEditHintModal),(0,l.default)("#hint-edit-form").submit(m.editHint),(0,l.default)("#flag-add-button").click(p.addFlagModal),(0,l.default)(".delete-flag").click(p.deleteFlag),(0,l.default)("#flags-create-select").change(p.flagTypeSelect),(0,l.default)(".edit-flag").click(p.editFlagModal),l.default.get(i.default.config.urlRoot+"/api/v1/challenges/types",function(e){(0,l.default)("#create-chals-select").empty();var t=e.data,o=Object.keys(t).length;if(1 -- "),t){var s=t[n],a=(0,l.default)("
- @@ -40,7 +40,7 @@ {% for standing in standings %} -
IDTeamChallengeTypeSubmissionDateDelete +
+   +
+
IDTeamChallengeTypeSubmissionDate
+
+   +
+
{{ sub.id }} - - - -
+
-   +  
Place
+
 
diff --git a/CTFd/themes/admin/templates/submissions.html b/CTFd/themes/admin/templates/submissions.html index 87e60834..f15aeb36 100644 --- a/CTFd/themes/admin/templates/submissions.html +++ b/CTFd/themes/admin/templates/submissions.html @@ -28,9 +28,9 @@ - @@ -44,7 +44,7 @@ {% for sub in submissions %} - '.format(l,s,(0,r.htmlEntities)(a),i))}})}function j(){return l.default.api.get_challenge_list().then(function(e){var t=[],o=(0,_.default)("#challenges-board");v=e.data,o.empty();for(var n=v.length-1;0<=n;n--)if(v[n].solves=0,-1==_.default.inArray(v[n].category,t)){var s=v[n].category;t.push(s);var a=s.replace(/ /g,"-").hashCode(),i=(0,_.default)('
'.format(a)+'
');i.find(".category-header").append((0,_.default)("

"+s+"

")),o.append(i)}for(var l=0;l<=v.length-1;l++){var r=v[l],d=r.name.replace(/ /g,"-").hashCode(),c=r.category.replace(/ /g,"-").hashCode(),u=(0,_.default)("
".format(d)),m=void 0;m=-1==g.indexOf(r.id)?(0,_.default)("".format(r.id)):(0,_.default)("".format(r.id));for(var p=(0,_.default)("

{0}

".format(r.name)),f=(0,_.default)("{0}".format(r.value)),j=0;j .challenges-row").append(u)}(0,_.default)(".challenge-button").click(function(e){y(this.value),b(this.value)})})}function h(){return(0==l.default.user.id?Promise.resolve():c[l.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=t[o].challenge_id;t.push(n)}})).then(j).then(f)}(0,_.default)(function(){h().then(function(){0>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(c.format(e.button));return e.success&&(0,l.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),o.modal("show"),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),o}function f(e){(0,l.default)("#ezq--notifications-toast-container").length||(0,l.default)("body").append((0,l.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=r.format(e.title,e.body),o=(0,l.default)(t);if(e.onclose&&(0,l.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,l.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,l.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(m),s=(0,l.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),(0,l.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,l.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,l.default)(n);return s.find(".modal-body").append((0,l.default)(o)),(0,l.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,l.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/pages/challenges.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js"),o("./node_modules/bootstrap/js/dist/tab.js");var i=a(o("./node_modules/nunjucks/browser/nunjucks.js")),n=o("./CTFd/themes/core/assets/js/ezq.js"),r=o("./CTFd/themes/core/assets/js/utils.js"),d=a(o("./node_modules/moment/moment.js")),_=a(o("./node_modules/jquery/dist/jquery.js")),l=a(o("./CTFd/themes/core/assets/js/CTFd.js")),s=a(o("./CTFd/themes/core/assets/js/config.js"));function a(e){return e&&e.__esModule?e:{default:e}}var c={teams:function(e){return l.default.api.get_team_solves({teamId:e})},users:function(e){return l.default.api.get_user_solves({userId:e})}},u=l.default.lib.markdown();l.default._internal.challenge={};var v=[],g=[],y=function(t){var e=_.default.grep(v,function(e){return e.id==t})[0];"hidden"!==e.type?m(e):(0,n.ezAlert)({title:"Challenge Hidden!",body:"You haven't unlocked this challenge yet!",button:"Got it!"})},m=function(a){return Promise.all([l.default.api.get_challenge({challengeId:a.id}),_.default.getScript(s.default.urlRoot+a.script),_.default.get(s.default.urlRoot+a.template)]).then(function(e){var t=e[0].data,o=e[2],n=l.default._internal.challenge;(0,_.default)("#challenge-window").empty();var s=i.default.compile(o);n.data=t,n.preRender(),t.description=n.render(t.description),t.script_root=l.default.config.urlRoot,(0,_.default)("#challenge-window").append(s.render(t)),(0,_.default)(".challenge-solves").click(function(e){b((0,_.default)("#challenge-id").val())}),(0,_.default)(".nav-tabs a").click(function(e){e.preventDefault(),(0,_.default)(this).tab("show")}),(0,_.default)("#challenge-window").on("hide.bs.modal",function(e){(0,_.default)("#submission-input").removeClass("wrong"),(0,_.default)("#submission-input").removeClass("correct"),(0,_.default)("#incorrect-key").slideUp(),(0,_.default)("#correct-key").slideUp(),(0,_.default)("#already-solved").slideUp(),(0,_.default)("#too-fast").slideUp()}),(0,_.default)(".load-hint").on("click",function(e){w((0,_.default)(this).data("hint-id"))}),(0,_.default)("#submit-key").click(function(e){e.preventDefault(),(0,_.default)("#submit-key").addClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!0),l.default._internal.challenge.submit().then(p).then(j).then(f)}),(0,_.default)("#submission-input").keyup(function(e){13==e.keyCode&&(0,_.default)("#submit-key").click()}),(0,_.default)(".input-field").bind({focus:function(){(0,_.default)(this).parent().addClass("input--filled")},blur:function(){var e=(0,_.default)(this);""===e.val()&&(e.parent().removeClass("input--filled"),e.siblings(".input-label").removeClass("input--hide"))}}),n.postRender(),window.location.replace(window.location.href.split("#")[0]+"#"+a.name),(0,_.default)("#challenge-window").modal()})};function p(e){var t=e.data,o=(0,_.default)("#result-message"),n=(0,_.default)("#result-notification"),s=(0,_.default)("#submission-input");n.removeClass(),o.text(t.message),"authentication_required"!==t.status?("incorrect"===t.status?(n.addClass("alert alert-danger alert-dismissable text-center"),n.slideDown(),s.removeClass("correct"),s.addClass("wrong"),setTimeout(function(){s.removeClass("wrong")},3e3)):"correct"===t.status?(n.addClass("alert alert-success alert-dismissable text-center"),n.slideDown(),(0,_.default)(".challenge-solves").text(parseInt((0,_.default)(".challenge-solves").text().split(" ")[0])+1+" Solves"),s.val(""),s.removeClass("wrong"),s.addClass("correct")):"already_solved"===t.status?(n.addClass("alert alert-info alert-dismissable text-center"),n.slideDown(),s.addClass("correct")):"paused"===t.status?(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown()):"ratelimited"===t.status&&(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown(),s.addClass("too-fast"),setTimeout(function(){s.removeClass("too-fast")},3e3)),setTimeout(function(){(0,_.default)(".alert").slideUp(),(0,_.default)("#submit-key").removeClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!1)},3e3)):window.location=l.default.config.urlRoot+"/login?next="+l.default.config.urlRoot+window.location.pathname+window.location.hash}function f(){return c[l.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=(0,_.default)('button[value="'+t[o].challenge_id+'"]');n.addClass("solved-challenge"),n.prepend("")}})}function b(e){return l.default.api.get_challenge_solves({challengeId:e}).then(function(e){var t=e.data;(0,_.default)(".challenge-solves").text(parseInt(t.length)+" Solves");var o=(0,_.default)("#challenge-solves-names");o.empty();for(var n=0;n
'.format(l,s,(0,r.htmlEntities)(a),i))}})}function j(){return l.default.api.get_challenge_list().then(function(e){var t=[],o=(0,_.default)("#challenges-board");v=e.data,o.empty();for(var n=v.length-1;0<=n;n--)if(v[n].solves=0,-1==_.default.inArray(v[n].category,t)){var s=v[n].category;t.push(s);var a=s.replace(/ /g,"-").hashCode(),i=(0,_.default)('
'.format(a)+'
');i.find(".category-header").append((0,_.default)("

"+s+"

")),o.append(i)}for(var l=0;l<=v.length-1;l++){var r=v[l],d=r.name.replace(/ /g,"-").hashCode(),c=r.category.replace(/ /g,"-").hashCode(),u=(0,_.default)("
".format(d)),m=void 0;m=-1==g.indexOf(r.id)?(0,_.default)("".format(r.id)):(0,_.default)("".format(r.id));for(var p=(0,_.default)("

{0}

".format(r.name)),f=(0,_.default)("{0}".format(r.value)),j=0;j .challenges-row").append(u)}(0,_.default)(".challenge-button").click(function(e){y(this.value),b(this.value)})})}function h(){return(0==l.default.user.id?Promise.resolve():c[l.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=t[o].challenge_id;t.push(n)}})).then(j).then(f)}(0,_.default)(function(){h().then(function(){0>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,i.default)("th.sort-col").click(function(){var e=(0,i.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=a(e,s),n=a(t,s);return i.default.isNumeric(o)&&i.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,i.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):t.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&t.find(".modal-dialog").addClass("modal-lg"),t.find(".modal-footer").append(n),(0,r.default)("main").append(t),t.modal("show"),(0,r.default)(t).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),t}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var o=l.format(e.title,e.body),t=(0,r.default)(o);if(e.onclose&&(0,r.default)(t).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(t).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(t),t.toast({autohide:s,delay:a,animation:i}),t.toast("show"),t}function j(e){var o=i.format(e.title),t=(0,r.default)(o);"string"==typeof e.body?t.find(".modal-body").append("

".concat(e.body,"

")):t.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return t.find(".modal-footer").append(s),t.find(".modal-footer").append(n),(0,r.default)("main").append(t),(0,r.default)(t).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),t.modal("show"),t}function _(e){if(e.target){var o=(0,r.default)(e.target);return o.find(".progress-bar").css("width",e.width+"%"),o}var t=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(t)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var o={success:d,error:s}[e.type].format(e.body);return(0,r.default)(o)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};o.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,o,t){Object.defineProperty(o,"__esModule",{value:!0}),o.default=void 0,t("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=t("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;o.default=function(e,o){return void 0===o&&(o={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===o.headers&&(o.headers={}),o.credentials="same-origin",o.headers.Accept="application/json",o.headers["Content-Type"]="application/json",o.headers["CSRF-Token"]=s.default.csrfNonce,i(e,o)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,o,t){var n=p(t("./CTFd/themes/core/assets/js/CTFd.js")),s=p(t("./node_modules/jquery/dist/jquery.js")),i=p(t("./node_modules/moment/moment.js")),a=p(t("./node_modules/nunjucks/browser/nunjucks.js")),r=t("./node_modules/howler/dist/howler.js"),l=p(t("./CTFd/themes/core/assets/js/events.js")),d=p(t("./CTFd/themes/core/assets/js/config.js")),c=p(t("./CTFd/themes/core/assets/js/styles.js")),m=p(t("./CTFd/themes/core/assets/js/times.js")),u=p(t("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/patch.js":function(e,o,t){var n,r=(n=t("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=t("./CTFd/themes/core/assets/js/api.js");function i(e,o,t){return o in e?Object.defineProperty(e,o,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[o]=t,e}function l(e,o){return function(o){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},o.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},o.cumulativeSum=function(e){for(var o=e.concat(),t=0;t".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),m=p(o("./CTFd/themes/core/assets/js/times.js")),u=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,a.default)("th.sort-col").click(function(){var e=(0,a.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=i(e,s),n=i(t,s);return a.default.isNumeric(o)&&a.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,a.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):t.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&t.find(".modal-dialog").addClass("modal-lg"),t.find(".modal-footer").append(n),(0,r.default)("main").append(t),t.modal("show"),(0,r.default)(t).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),t}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var o=l.format(e.title,e.body),t=(0,r.default)(o);if(e.onclose&&(0,r.default)(t).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(t).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(t),t.toast({autohide:s,delay:a,animation:i}),t.toast("show"),t}function j(e){var o=i.format(e.title),t=(0,r.default)(o);"string"==typeof e.body?t.find(".modal-body").append("

".concat(e.body,"

")):t.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return t.find(".modal-footer").append(s),t.find(".modal-footer").append(n),(0,r.default)("main").append(t),(0,r.default)(t).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),t.modal("show"),t}function _(e){if(e.target){var o=(0,r.default)(e.target);return o.find(".progress-bar").css("width",e.width+"%"),o}var t=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(t)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var o={success:d,error:s}[e.type].format(e.body);return(0,r.default)(o)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};o.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,o,t){Object.defineProperty(o,"__esModule",{value:!0}),o.default=void 0,t("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=t("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;o.default=function(e,o){return void 0===o&&(o={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===o.headers&&(o.headers={}),o.credentials="same-origin",o.headers.Accept="application/json",o.headers["Content-Type"]="application/json",o.headers["CSRF-Token"]=s.default.csrfNonce,i(e,o)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,o,t){var n=p(t("./CTFd/themes/core/assets/js/CTFd.js")),s=p(t("./node_modules/jquery/dist/jquery.js")),i=p(t("./node_modules/moment/moment.js")),a=p(t("./node_modules/nunjucks/browser/nunjucks.js")),r=t("./node_modules/howler/dist/howler.js"),l=p(t("./CTFd/themes/core/assets/js/events.js")),d=p(t("./CTFd/themes/core/assets/js/config.js")),c=p(t("./CTFd/themes/core/assets/js/styles.js")),m=p(t("./CTFd/themes/core/assets/js/times.js")),u=p(t("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/notifications.js":function(e,o,t){t("./CTFd/themes/core/assets/js/pages/main.js");var n=i(t("./node_modules/jquery/dist/jquery.js")),s=(i(t("./CTFd/themes/core/assets/js/CTFd.js")),t("./CTFd/themes/core/assets/js/utils.js"));function i(e){return e&&e.__esModule?e:{default:e}}(0,n.default)(function(){(0,s.clear_notification_counter)()})},"./CTFd/themes/core/assets/js/patch.js":function(e,o,t){var n,r=(n=t("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=t("./CTFd/themes/core/assets/js/api.js");function i(e,o,t){return o in e?Object.defineProperty(e,o,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[o]=t,e}function l(e,o){return function(o){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},o.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},o.cumulativeSum=function(e){for(var o=e.concat(),t=0;t".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),m=p(o("./CTFd/themes/core/assets/js/times.js")),u=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/notifications.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js");var n=i(o("./node_modules/jquery/dist/jquery.js")),s=(i(o("./CTFd/themes/core/assets/js/CTFd.js")),o("./CTFd/themes/core/assets/js/utils.js"));function i(e){return e&&e.__esModule?e:{default:e}}(0,n.default)(function(){(0,s.clear_notification_counter)()})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,a.default)("th.sort-col").click(function(){var e=(0,a.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=i(e,s),n=i(t,s);return a.default.isNumeric(o)&&a.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,a.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):t.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&t.find(".modal-dialog").addClass("modal-lg"),t.find(".modal-footer").append(n),(0,r.default)("main").append(t),t.modal("show"),(0,r.default)(t).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),t}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var o=l.format(e.title,e.body),t=(0,r.default)(o);if(e.onclose&&(0,r.default)(t).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(t).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(t),t.toast({autohide:s,delay:a,animation:i}),t.toast("show"),t}function j(e){var o=i.format(e.title),t=(0,r.default)(o);"string"==typeof e.body?t.find(".modal-body").append("

".concat(e.body,"

")):t.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return t.find(".modal-footer").append(s),t.find(".modal-footer").append(n),(0,r.default)("main").append(t),(0,r.default)(t).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),t.modal("show"),t}function h(e){if(e.target){var o=(0,r.default)(e.target);return o.find(".progress-bar").css("width",e.width+"%"),o}var t=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(t)),(0,r.default)("main").append(s),s.modal("show")}function _(e){var o={success:d,error:s}[e.type].format(e.body);return(0,r.default)(o)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};o.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,o,t){Object.defineProperty(o,"__esModule",{value:!0}),o.default=void 0,t("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=t("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;o.default=function(e,o){return void 0===o&&(o={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===o.headers&&(o.headers={}),o.credentials="same-origin",o.headers.Accept="application/json",o.headers["Content-Type"]="application/json",o.headers["CSRF-Token"]=s.default.csrfNonce,i(e,o)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,o,t){var n=p(t("./CTFd/themes/core/assets/js/CTFd.js")),s=p(t("./node_modules/jquery/dist/jquery.js")),i=p(t("./node_modules/moment/moment.js")),a=p(t("./node_modules/nunjucks/browser/nunjucks.js")),r=t("./node_modules/howler/dist/howler.js"),l=p(t("./CTFd/themes/core/assets/js/events.js")),d=p(t("./CTFd/themes/core/assets/js/config.js")),c=p(t("./CTFd/themes/core/assets/js/styles.js")),m=p(t("./CTFd/themes/core/assets/js/times.js")),u=p(t("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/scoreboard.js":function(e,o,t){t("./CTFd/themes/core/assets/js/pages/main.js");var n=i(t("./node_modules/jquery/dist/jquery.js")),s=i(t("./CTFd/themes/core/assets/js/CTFd.js")),c=i(t("./node_modules/plotly.js-basic-dist/plotly-basic.js")),m=i(t("./node_modules/moment/moment.js")),u=t("./CTFd/themes/core/assets/js/utils.js");function i(e){return e&&e.__esModule?e:{default:e}}function a(){s.default.api.get_scoreboard_detail({count:10}).then(function(e){var o=e.data,t=Object.keys(o),n=[];if(0!==t.length){for(var s=0;s",'
",'","",""].join("");r.append(n)}}),a()}(0,n.default)(function(){setInterval(l,3e5),s.default.api.get_scoreboard_detail({count:10}).then(function(e){var o=e.data,t=Object.keys(o),n=[];if(0!==t.length){for(var s=0;s

No solves yet

')}),a()})},"./CTFd/themes/core/assets/js/patch.js":function(e,o,t){var n,r=(n=t("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=t("./CTFd/themes/core/assets/js/api.js");function i(e,o,t){return o in e?Object.defineProperty(e,o,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[o]=t,e}function l(e,o){return function(o){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},o.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},o.cumulativeSum=function(e){for(var o=e.concat(),t=0;t".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),m=p(o("./CTFd/themes/core/assets/js/times.js")),u=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/scoreboard.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js");var n=i(o("./node_modules/jquery/dist/jquery.js")),s=i(o("./CTFd/themes/core/assets/js/CTFd.js")),c=i(o("./node_modules/plotly.js-basic-dist/plotly-basic.js")),m=i(o("./node_modules/moment/moment.js")),u=o("./CTFd/themes/core/assets/js/utils.js");function i(e){return e&&e.__esModule?e:{default:e}}function a(){s.default.api.get_scoreboard_detail({count:10}).then(function(e){var t=e.data,o=Object.keys(t),n=[];if(0!==o.length){for(var s=0;s",'
",'","",""].join("");r.append(n)}}),a()}(0,n.default)(function(){setInterval(l,3e5),s.default.api.get_scoreboard_detail({count:10}).then(function(e){var t=e.data,o=Object.keys(t),n=[];if(0!==o.length){for(var s=0;s

No solves yet

')}),a()})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,a.default)("th.sort-col").click(function(){var e=(0,a.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=i(e,s),n=i(t,s);return a.default.isNumeric(o)&&a.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,a.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(m),s=(0,r.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),u=p(o("./CTFd/themes/core/assets/js/times.js")),m=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=m.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,u.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/settings.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js");var n=o("./CTFd/themes/core/assets/js/utils.js"),a=r(o("./node_modules/jquery/dist/jquery.js")),s=r(o("./CTFd/themes/core/assets/js/CTFd.js")),i=o("./CTFd/themes/core/assets/js/ezq.js");function r(e){return e&&e.__esModule?e:{default:e}}var l='';function d(e){e.preventDefault(),(0,a.default)("#results").empty();var i=(0,a.default)(this),t=i.serializeJSON(!0);s.default.api.patch_user_private({},t).then(function(s){s.success?(0,a.default)("#results").html(''):"errors"in s&&Object.keys(s.errors).map(function(e){var t=i.find("input[name={0}]".format(e)),o=(0,a.default)(t);o.addClass("input-filled-invalid"),o.removeClass("input-filled-valid");var n=s.errors[e];(0,a.default)("#results").append(l.format(n))})})}function c(e){e.preventDefault();var t=(0,a.default)(this).serializeJSON(!0);s.default.fetch("/api/v1/tokens",{method:"POST",body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){if(e.success){var t=(0,a.default)('\n

Please copy your API Key, it won\'t be shown again!

\n
\n \n
\n \n
\n
\n '));t.find("button").click(function(e){(0,n.copyToClipboard)(e,"#user-token-result")}),(0,i.ezAlert)({title:"API Key Generated",body:t,button:"Got it!",large:!0})}})}function u(e){e.preventDefault();var t=(0,a.default)(this),o=t.data("token-id");(0,i.ezQuery)({title:"Delete Token",body:"Are you sure you want to delete this token?",success:function(){s.default.fetch("/api/v1/tokens/"+o,{method:"DELETE"}).then(function(e){return e.json()}).then(function(e){e.success&&t.parent().parent().remove()})}})}(0,a.default)(function(){(0,a.default)("#user-profile-form").submit(d),(0,a.default)("#user-token-form").submit(c),(0,a.default)(".delete-token").click(u),(0,a.default)(".nav-pills a").click(function(e){window.location.hash=this.hash});var e=window.location.hash;e&&(e=e.replace("<>[]'\"",""),(0,a.default)('.nav-pills a[href="'+e+'"]').tab("show"))})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(m),s=(0,r.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),u=p(o("./CTFd/themes/core/assets/js/times.js")),m=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=m.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,u.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/settings.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js");var n=o("./CTFd/themes/core/assets/js/utils.js"),a=r(o("./node_modules/jquery/dist/jquery.js")),s=r(o("./CTFd/themes/core/assets/js/CTFd.js")),i=o("./CTFd/themes/core/assets/js/ezq.js");function r(e){return e&&e.__esModule?e:{default:e}}var l='';function d(e){e.preventDefault(),(0,a.default)("#results").empty();var i=(0,a.default)(this),t=i.serializeJSON(!0);s.default.api.patch_user_private({},t).then(function(s){s.success?(0,a.default)("#results").html(''):"errors"in s&&Object.keys(s.errors).map(function(e){var t=i.find("input[name={0}]".format(e)),o=(0,a.default)(t);o.addClass("input-filled-invalid"),o.removeClass("input-filled-valid");var n=s.errors[e];(0,a.default)("#results").append(l.format(n))})})}function c(e){e.preventDefault();var t=(0,a.default)(this).serializeJSON(!0);s.default.fetch("/api/v1/tokens",{method:"POST",body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){if(e.success){var t=(0,a.default)('\n

Please copy your API Key, it won\'t be shown again!

\n
\n \n
\n \n
\n
\n '));t.find("button").click(function(e){(0,n.copyToClipboard)(e,"#user-token-result")}),(0,i.ezAlert)({title:"API Key Generated",body:t,button:"Got it!",large:!0})}})}function u(e){e.preventDefault();var t=(0,a.default)(this),o=t.data("token-id");(0,i.ezQuery)({title:"Delete Token",body:"Are you sure you want to delete this token?",success:function(){s.default.fetch("/api/v1/tokens/"+o,{method:"DELETE"}).then(function(e){return e.json()}).then(function(e){e.success&&t.parent().parent().remove()})}})}(0,a.default)(function(){(0,a.default)("#user-profile-form").submit(d),(0,a.default)("#user-token-form").submit(c),(0,a.default)(".delete-token").click(u),(0,a.default)(".nav-pills a").click(function(e){window.location.hash=this.hash});var e=window.location.hash;e&&(e=e.replace("<>[]'\"",""),(0,a.default)('.nav-pills a[href="'+e+'"]').tab("show"))})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,a.default)("th.sort-col").click(function(){var e=(0,a.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=i(e,s),n=i(t,s);return a.default.isNumeric(o)&&a.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,a.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(m),s=(0,r.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),u=p(o("./CTFd/themes/core/assets/js/times.js")),m=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=m.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,u.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/setup.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js");var i=n(o("./node_modules/jquery/dist/jquery.js")),a=n(o("./node_modules/moment-timezone/index.js")),s=n(o("./CTFd/themes/core/assets/js/CTFd.js"));function n(e){return e&&e.__esModule?e:{default:e}}function r(e){e.preventDefault();var o=!0;if((0,i.default)(e.target).closest("[role=tabpanel]").find("input,textarea").each(function(e,t){$e=(0,i.default)(t),!1===t.checkValidity()&&($e.removeClass("input-filled-valid"),$e.addClass("input-filled-invalid"),o=!1)}),0!=o){var t=(0,i.default)(e.target).data("href");(0,i.default)('.nav a[href="'.concat(t,'"]')).tab("show")}}function l(o){var n=(0,i.default)("#".concat(o,"-date")),s=(0,i.default)("#".concat(o,"-time"));return function(e){var t=(0,a.default)("".concat(n.val()," ").concat(s.val()),"YYYY-MM-DD HH:mm").utc().format("X");(0,i.default)("#".concat(o,"-preview")).val(t)}}function d(e){var t={name:(0,i.default)("#ctf_name").val(),type:"jeopardy",description:(0,i.default)("#ctf_description").val(),user_mode:(0,i.default)("#user_mode").val(),event_url:window.location.origin+s.default.config.urlRoot,redirect_url:window.location.origin+s.default.config.urlRoot+"/redirect",integration_setup_url:window.location.origin+s.default.config.urlRoot+"/setup/integrations",start:(0,i.default)("#start-preview").val(),end:(0,i.default)("#end-preview").val(),platform:"CTFd",state:STATE},o=[];for(var n in t)o.push(encodeURIComponent(n)+"="+encodeURIComponent(t[n]));window.open("https://www.majorleaguecyber.org/events/new?"+o.join("&"),"_blank")}(0,i.default)(function(){(0,i.default)(".tab-next").click(r),(0,i.default)("input").on("keypress",function(e){13==e.keyCode&&(e.preventDefault(),(0,i.default)(e.target).closest(".tab-pane").find("button[data-href]").click())}),(0,i.default)("#integration-mlc").click(d),(0,i.default)("#start-date,#start-time").change(l("start")),(0,i.default)("#end-date,#end-time").change(l("end")),(0,i.default)("#config-color-picker").on("input",function(e){(0,i.default)("#config-color-input").val((0,i.default)(this).val())}),(0,i.default)("#config-color-reset").click(function(){(0,i.default)("#config-color-input").val(""),(0,i.default)("#config-color-picker").val("")}),window.addEventListener("storage",function(e){"integrations"==e.key&&e.newValue&&"mlc"==JSON.parse(e.newValue).name&&((0,i.default)("#integration-mlc").text("Already Configured").attr("disabled",!0),window.focus(),localStorage.removeItem("integrations"))}),(0,i.default)("#setup-form").submit(function(e){if((0,i.default)("#newsletter-checkbox").prop("checked")){var t=(0,i.default)(e.target).find("input[name=email]").val();i.default.ajax({type:"POST",url:"https://ctfd.us15.list-manage.com/subscribe/post-json?u=6c7fa6feeced52775aec9d015&id=dd1484208e&c=?",data:{EMAIL:t,subscribe:"Subscribe",b_6c7fa6feeced52775aec9d015_dd1484208e:""},dataType:"jsonp",contentType:"application/json; charset=utf-8"})}})})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(m),s=(0,r.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),u=p(o("./CTFd/themes/core/assets/js/times.js")),m=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=m.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,u.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/setup.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js");var i=n(o("./node_modules/jquery/dist/jquery.js")),a=n(o("./node_modules/moment-timezone/index.js")),s=n(o("./CTFd/themes/core/assets/js/CTFd.js"));function n(e){return e&&e.__esModule?e:{default:e}}function r(e){e.preventDefault();var o=!0;if((0,i.default)(e.target).closest("[role=tabpanel]").find("input,textarea").each(function(e,t){$e=(0,i.default)(t),!1===t.checkValidity()&&($e.removeClass("input-filled-valid"),$e.addClass("input-filled-invalid"),o=!1)}),0!=o){var t=(0,i.default)(e.target).data("href");(0,i.default)('.nav a[href="'.concat(t,'"]')).tab("show")}}function l(o){var n=(0,i.default)("#".concat(o,"-date")),s=(0,i.default)("#".concat(o,"-time"));return function(e){var t=(0,a.default)("".concat(n.val()," ").concat(s.val()),"YYYY-MM-DD HH:mm").utc().format("X");(0,i.default)("#".concat(o,"-preview")).val(t)}}function d(e){var t={name:(0,i.default)("#ctf_name").val(),type:"jeopardy",description:(0,i.default)("#ctf_description").val(),user_mode:(0,i.default)("#user_mode").val(),event_url:window.location.origin+s.default.config.urlRoot,redirect_url:window.location.origin+s.default.config.urlRoot+"/redirect",integration_setup_url:window.location.origin+s.default.config.urlRoot+"/setup/integrations",start:(0,i.default)("#start-preview").val(),end:(0,i.default)("#end-preview").val(),platform:"CTFd",state:STATE},o=[];for(var n in t)o.push(encodeURIComponent(n)+"="+encodeURIComponent(t[n]));window.open("https://www.majorleaguecyber.org/events/new?"+o.join("&"),"_blank")}(0,i.default)(function(){(0,i.default)(".tab-next").click(r),(0,i.default)("input").on("keypress",function(e){13==e.keyCode&&(e.preventDefault(),(0,i.default)(e.target).closest(".tab-pane").find("button[data-href]").click())}),(0,i.default)("#integration-mlc").click(d),(0,i.default)("#start-date,#start-time").change(l("start")),(0,i.default)("#end-date,#end-time").change(l("end")),(0,i.default)("#config-color-picker").on("input",function(e){(0,i.default)("#config-color-input").val((0,i.default)(this).val())}),(0,i.default)("#config-color-reset").click(function(){(0,i.default)("#config-color-input").val(""),(0,i.default)("#config-color-picker").val("")}),window.addEventListener("storage",function(e){"integrations"==e.key&&e.newValue&&"mlc"==JSON.parse(e.newValue).name&&((0,i.default)("#integration-mlc").text("Already Configured").attr("disabled",!0),window.focus(),localStorage.removeItem("integrations"))}),(0,i.default)("#setup-form").submit(function(e){if((0,i.default)("#newsletter-checkbox").prop("checked")){var t=(0,i.default)(e.target).find("input[name=email]").val();i.default.ajax({type:"POST",url:"https://ctfd.us15.list-manage.com/subscribe/post-json?u=6c7fa6feeced52775aec9d015&id=dd1484208e&c=?",data:{EMAIL:t,subscribe:"Subscribe",b_6c7fa6feeced52775aec9d015_dd1484208e:""},dataType:"jsonp",contentType:"application/json; charset=utf-8"})}})})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,a.default)("th.sort-col").click(function(){var e=(0,a.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=i(e,s),n=i(t,s);return a.default.isNumeric(o)&&a.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,a.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(m),s=(0,r.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var g={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=g},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/graphs.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.createGraph=function(e,t,o,n,s,a,i){var r=f[e],l=(0,c.default)(t);if(l.empty(),void 0===l[0])return void console.log("Couldn't find graph target: "+t);l[0].fn=r.fn(n,s,a,i);var d=r.format(n,s,a,i,o);u.default.newPlot(l[0],d,r.layout,j)},t.updateGraph=function(e,t,o,n,s,a,i){var r=f[e],l=(0,c.default)(t),d=r.format(n,s,a,i,o);u.default.update(l[0],d,r.layout,j)};var c=n(o("./node_modules/jquery/dist/jquery.js")),u=n(o("./node_modules/plotly.js-basic-dist/plotly-basic.js")),m=n(o("./node_modules/moment/moment.js")),p=o("./CTFd/themes/core/assets/js/utils.js");function n(e){return e&&e.__esModule?e:{default:e}}var f={score_graph:{layout:{title:"Score over Time",paper_bgcolor:"rgba(0,0,0,0)",plot_bgcolor:"rgba(0,0,0,0)",hovermode:"closest",xaxis:{showgrid:!1,showspikes:!0},yaxis:{showgrid:!1,showspikes:!0},legend:{orientation:"h"}},fn:function(e,t,o,n){return"CTFd_score_".concat(e,"_").concat(o,"_").concat(t,"_").concat((new Date).toISOString().slice(0,19))},format:function(e,t,o,n,s){var a=[],i=[],r=s[0].data,l=s[2].data,d=r.concat(l);d.sort(function(e,t){return new Date(e.date)-new Date(t.date)});for(var c=0;c>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(m),s=(0,r.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var g={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=g},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/graphs.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.createGraph=function(e,t,o,n,s,a,i){var r=f[e],l=(0,c.default)(t);if(l.empty(),void 0===l[0])return void console.log("Couldn't find graph target: "+t);l[0].fn=r.fn(n,s,a,i);var d=r.format(n,s,a,i,o);u.default.newPlot(l[0],d,r.layout,j)},t.updateGraph=function(e,t,o,n,s,a,i){var r=f[e],l=(0,c.default)(t),d=r.format(n,s,a,i,o);u.default.update(l[0],d,r.layout,j)};var c=n(o("./node_modules/jquery/dist/jquery.js")),u=n(o("./node_modules/plotly.js-basic-dist/plotly-basic.js")),m=n(o("./node_modules/moment/moment.js")),p=o("./CTFd/themes/core/assets/js/utils.js");function n(e){return e&&e.__esModule?e:{default:e}}var f={score_graph:{layout:{title:"Score over Time",paper_bgcolor:"rgba(0,0,0,0)",plot_bgcolor:"rgba(0,0,0,0)",hovermode:"closest",xaxis:{showgrid:!1,showspikes:!0},yaxis:{showgrid:!1,showspikes:!0},legend:{orientation:"h"}},fn:function(e,t,o,n){return"CTFd_score_".concat(e,"_").concat(o,"_").concat(t,"_").concat((new Date).toISOString().slice(0,19))},format:function(e,t,o,n,s){var a=[],i=[],r=s[0].data,l=s[2].data,d=r.concat(l);d.sort(function(e,t){return new Date(e.date)-new Date(t.date)});for(var c=0;c>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,i.default)("th.sort-col").click(function(){var e=(0,i.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=a(e,s),n=a(t,s);return i.default.isNumeric(o)&&i.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,i.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),m=p(o("./CTFd/themes/core/assets/js/times.js")),u=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/teams/private.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js"),o("./CTFd/themes/core/assets/js/utils.js");var n=s(o("./CTFd/themes/core/assets/js/CTFd.js"));o("./node_modules/bootstrap/js/dist/modal.js");var r=s(o("./node_modules/jquery/dist/jquery.js"));function s(e){return e&&e.__esModule?e:{default:e}}(0,r.default)(function(){window.team_captain&&((0,r.default)(".edit-team").click(function(){(0,r.default)("#team-edit-modal").modal()}),(0,r.default)(".edit-captain").click(function(){(0,r.default)("#team-captain-modal").modal()}));var a=(0,r.default)("#team-info-form");a.submit(function(e){e.preventDefault(),(0,r.default)("#results").empty();var t=(0,r.default)(this).serializeJSON();n.default.fetch("/api/v1/teams/me",{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){400===e.status?e.json().then(function(i){i.success||Object.keys(i.errors).map(function(e){var t=a.find("input[name={0}]".format(e)),o=(0,r.default)(t);o.addClass("input-filled-invalid"),o.removeClass("input-filled-valid");var n=i.errors[e],s=error_template.format(n);(0,r.default)("#results").append(s)})}):200===e.status&&e.json().then(function(e){e.success&&window.location.reload()})})}),(0,r.default)("#team-captain-form").submit(function(e){e.preventDefault();var t=(0,r.default)("#team-captain-form").serializeJSON(!0);n.default.fetch("/api/v1/teams/me",{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(s){s.success?window.location.reload():((0,r.default)("#team-captain-form > #results").empty(),Object.keys(s.errors).forEach(function(e,t){(0,r.default)("#team-captain-form > #results").append(ezbadge({type:"error",body:s.errors[e]}));var o=(0,r.default)("#team-captain-form").find("select[name={0}]".format(e)),n=(0,r.default)(o);n.addClass("input-filled-invalid"),n.removeClass("input-filled-valid")}))})})})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,i.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(c.format(e.button));return e.success&&(0,r.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),o.modal("show"),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),o}function f(e){(0,r.default)("#ezq--notifications-toast-container").length||(0,r.default)("body").append((0,r.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=l.format(e.title,e.body),o=(0,r.default)(t);if(e.onclose&&(0,r.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,r.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,i=!1!==e.animation,a=e.delay||1e4;return(0,r.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:a,animation:i}),o.toast("show"),o}function j(e){var t=i.format(e.title),o=(0,r.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,r.default)(e.body));var n=(0,r.default)(u),s=(0,r.default)(m);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,r.default)("main").append(o),(0,r.default)(o).on("hidden.bs.modal",function(){(0,r.default)(this).modal("dispose")}),(0,r.default)(n).click(function(){e.success()}),o.modal("show"),o}function _(e){if(e.target){var t=(0,r.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=a.format(e.width),n=i.format(e.title),s=(0,r.default)(n);return s.find(".modal-body").append((0,r.default)(o)),(0,r.default)("main").append(s),s.modal("show")}function h(e){var t={success:d,error:s}[e.type].format(e.body);return(0,r.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:_,ezBadge:h};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var i=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,i(e,t)}},"./CTFd/themes/core/assets/js/pages/main.js":function(e,t,o){var n=p(o("./CTFd/themes/core/assets/js/CTFd.js")),s=p(o("./node_modules/jquery/dist/jquery.js")),i=p(o("./node_modules/moment/moment.js")),a=p(o("./node_modules/nunjucks/browser/nunjucks.js")),r=o("./node_modules/howler/dist/howler.js"),l=p(o("./CTFd/themes/core/assets/js/events.js")),d=p(o("./CTFd/themes/core/assets/js/config.js")),c=p(o("./CTFd/themes/core/assets/js/styles.js")),m=p(o("./CTFd/themes/core/assets/js/times.js")),u=p(o("./CTFd/themes/core/assets/js/helpers.js"));function p(e){return e&&e.__esModule?e:{default:e}}n.default.init(window.init),window.CTFd=n.default,window.helpers=u.default,window.$=s.default,window.Moment=i.default,window.nunjucks=a.default,window.Howl=r.Howl,(0,s.default)(function(){(0,c.default)(),(0,m.default)(),(0,l.default)(d.default.urlRoot)})},"./CTFd/themes/core/assets/js/pages/teams/private.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js"),o("./CTFd/themes/core/assets/js/utils.js");var n=s(o("./CTFd/themes/core/assets/js/CTFd.js"));o("./node_modules/bootstrap/js/dist/modal.js");var r=s(o("./node_modules/jquery/dist/jquery.js"));function s(e){return e&&e.__esModule?e:{default:e}}(0,r.default)(function(){window.team_captain&&((0,r.default)(".edit-team").click(function(){(0,r.default)("#team-edit-modal").modal()}),(0,r.default)(".edit-captain").click(function(){(0,r.default)("#team-captain-modal").modal()}));var a=(0,r.default)("#team-info-form");a.submit(function(e){e.preventDefault(),(0,r.default)("#results").empty();var t=(0,r.default)(this).serializeJSON();n.default.fetch("/api/v1/teams/me",{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){400===e.status?e.json().then(function(i){i.success||Object.keys(i.errors).map(function(e){var t=a.find("input[name={0}]".format(e)),o=(0,r.default)(t);o.addClass("input-filled-invalid"),o.removeClass("input-filled-valid");var n=i.errors[e],s=error_template.format(n);(0,r.default)("#results").append(s)})}):200===e.status&&e.json().then(function(e){e.success&&window.location.reload()})})}),(0,r.default)("#team-captain-form").submit(function(e){e.preventDefault();var t=(0,r.default)("#team-captain-form").serializeJSON(!0);n.default.fetch("/api/v1/teams/me",{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(s){s.success?window.location.reload():((0,r.default)("#team-captain-form > #results").empty(),Object.keys(s.errors).forEach(function(e,t){(0,r.default)("#team-captain-form > #results").append(ezbadge({type:"error",body:s.errors[e]}));var o=(0,r.default)("#team-captain-form").find("select[name={0}]".format(e)),n=(0,r.default)(o);n.addClass("input-filled-invalid"),n.removeClass("input-filled-valid")}))})})})},"./CTFd/themes/core/assets/js/patch.js":function(e,t,o){var n,r=(n=o("./node_modules/q/q.js"))&&n.__esModule?n:{default:n},s=o("./CTFd/themes/core/assets/js/api.js");function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function l(e,t){return function(t){for(var e=1;e>8*s&255).toString(16)).substr(-2)}return n},t.htmlEntities=function(e){return(0,a.default)("
").text(e).html()},t.cumulativeSum=function(e){for(var t=e.concat(),o=0;o'),(0,a.default)("th.sort-col").click(function(){var e=(0,a.default)(this).parents("table").eq(0),t=e.find("tr:gt(0)").toArray().sort(function(s){return function(e,t){var o=i(e,s),n=i(t,s);return a.default.isNumeric(o)&&a.default.isNumeric(n)?o-n:o.toString().localeCompare(n)}}((0,a.default)(this).index()));this.asc=!this.asc,this.asc||(t=t.reverse());for(var o=0;o Date: Wed, 22 Apr 2020 14:57:37 -0400 Subject: [PATCH 03/11] Switch to using outline button --- .../templates/challenges/challenges.html | 42 +++++++-- CTFd/themes/admin/templates/pages.html | 41 ++++++-- CTFd/themes/admin/templates/scoreboard.html | 4 +- CTFd/themes/admin/templates/submissions.html | 6 +- CTFd/themes/admin/templates/teams/teams.html | 82 +++++++++------- CTFd/themes/admin/templates/users/users.html | 93 +++++++++++-------- 6 files changed, 175 insertions(+), 93 deletions(-) diff --git a/CTFd/themes/admin/templates/challenges/challenges.html b/CTFd/themes/admin/templates/challenges/challenges.html index 66bb36a4..baf6df3b 100644 --- a/CTFd/themes/admin/templates/challenges/challenges.html +++ b/CTFd/themes/admin/templates/challenges/challenges.html @@ -18,28 +18,50 @@
+
+
+
+
+ +
+
+
+
+
-
+
-   +  
ID
+
 
diff --git a/CTFd/themes/core/static/js/pages/challenges.min.js b/CTFd/themes/core/static/js/pages/challenges.min.js index 8aad9b5a..a35cda95 100644 --- a/CTFd/themes/core/static/js/pages/challenges.min.js +++ b/CTFd/themes/core/static/js/pages/challenges.min.js @@ -1 +1 @@ -!function(r){function e(e){for(var t,o,n=e[0],s=e[1],a=e[2],i=0,l=[];i".concat(e.body,"

")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(c.format(e.button));return e.success&&(0,l.default)(n).click(function(){e.success()}),e.large&&o.find(".modal-dialog").addClass("modal-lg"),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),o.modal("show"),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),o}function f(e){(0,l.default)("#ezq--notifications-toast-container").length||(0,l.default)("body").append((0,l.default)("
").attr({id:"ezq--notifications-toast-container"}).css({position:"fixed",bottom:"0",right:"0","min-width":"20%"}));var t=r.format(e.title,e.body),o=(0,l.default)(t);if(e.onclose&&(0,l.default)(o).find("button[data-dismiss=toast]").click(function(){e.onclose()}),e.onclick){var n=(0,l.default)(o).find(".toast-body");n.addClass("cursor-pointer"),n.click(function(){e.onclick()})}var s=!1!==e.autohide,a=!1!==e.animation,i=e.delay||1e4;return(0,l.default)("#ezq--notifications-toast-container").prepend(o),o.toast({autohide:s,delay:i,animation:a}),o.toast("show"),o}function j(e){var t=a.format(e.title),o=(0,l.default)(t);"string"==typeof e.body?o.find(".modal-body").append("

".concat(e.body,"

")):o.find(".modal-body").append((0,l.default)(e.body));var n=(0,l.default)(m),s=(0,l.default)(u);return o.find(".modal-footer").append(s),o.find(".modal-footer").append(n),(0,l.default)("main").append(o),(0,l.default)(o).on("hidden.bs.modal",function(){(0,l.default)(this).modal("dispose")}),(0,l.default)(n).click(function(){e.success()}),o.modal("show"),o}function h(e){if(e.target){var t=(0,l.default)(e.target);return t.find(".progress-bar").css("width",e.width+"%"),t}var o=i.format(e.width),n=a.format(e.title),s=(0,l.default)(n);return s.find(".modal-body").append((0,l.default)(o)),(0,l.default)("main").append(s),s.modal("show")}function _(e){var t={success:d,error:s}[e.type].format(e.body);return(0,l.default)(t)}var v={ezAlert:p,ezToast:f,ezQuery:j,ezProgressBar:h,ezBadge:_};t.default=v},"./CTFd/themes/core/assets/js/fetch.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0,o("./node_modules/whatwg-fetch/fetch.js");var n,s=(n=o("./CTFd/themes/core/assets/js/config.js"))&&n.__esModule?n:{default:n};var a=window.fetch;t.default=function(e,t){return void 0===t&&(t={method:"GET",credentials:"same-origin",headers:{}}),e=s.default.urlRoot+e,void 0===t.headers&&(t.headers={}),t.credentials="same-origin",t.headers.Accept="application/json",t.headers["Content-Type"]="application/json",t.headers["CSRF-Token"]=s.default.csrfNonce,a(e,t)}},"./CTFd/themes/core/assets/js/pages/challenges.js":function(e,t,o){o("./CTFd/themes/core/assets/js/pages/main.js"),o("./node_modules/bootstrap/js/dist/tab.js");var i=a(o("./node_modules/nunjucks/browser/nunjucks.js")),n=o("./CTFd/themes/core/assets/js/ezq.js"),r=o("./CTFd/themes/core/assets/js/utils.js"),d=a(o("./node_modules/moment/moment.js")),_=a(o("./node_modules/jquery/dist/jquery.js")),l=a(o("./CTFd/themes/core/assets/js/CTFd.js")),s=a(o("./CTFd/themes/core/assets/js/config.js"));function a(e){return e&&e.__esModule?e:{default:e}}var c={teams:function(e){return l.default.api.get_team_solves({teamId:e})},users:function(e){return l.default.api.get_user_solves({userId:e})}},u=l.default.lib.markdown();l.default._internal.challenge={};var v=[],g=[],y=function(t){var e=_.default.grep(v,function(e){return e.id==t})[0];"hidden"!==e.type?m(e):(0,n.ezAlert)({title:"Challenge Hidden!",body:"You haven't unlocked this challenge yet!",button:"Got it!"})},m=function(a){return Promise.all([l.default.api.get_challenge({challengeId:a.id}),_.default.getScript(s.default.urlRoot+a.script),_.default.get(s.default.urlRoot+a.template)]).then(function(e){var t=e[0].data,o=e[2],n=l.default._internal.challenge;(0,_.default)("#challenge-window").empty();var s=i.default.compile(o);n.data=t,n.preRender(),t.description=n.render(t.description),t.script_root=l.default.config.urlRoot,(0,_.default)("#challenge-window").append(s.render(t)),(0,_.default)(".challenge-solves").click(function(e){b((0,_.default)("#challenge-id").val())}),(0,_.default)(".nav-tabs a").click(function(e){e.preventDefault(),(0,_.default)(this).tab("show")}),(0,_.default)("#challenge-window").on("hide.bs.modal",function(e){(0,_.default)("#submission-input").removeClass("wrong"),(0,_.default)("#submission-input").removeClass("correct"),(0,_.default)("#incorrect-key").slideUp(),(0,_.default)("#correct-key").slideUp(),(0,_.default)("#already-solved").slideUp(),(0,_.default)("#too-fast").slideUp()}),(0,_.default)(".load-hint").on("click",function(e){w((0,_.default)(this).data("hint-id"))}),(0,_.default)("#submit-key").click(function(e){e.preventDefault(),(0,_.default)("#submit-key").addClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!0),l.default._internal.challenge.submit().then(p).then(j).then(f)}),(0,_.default)("#submission-input").keyup(function(e){13==e.keyCode&&(0,_.default)("#submit-key").click()}),(0,_.default)(".input-field").bind({focus:function(){(0,_.default)(this).parent().addClass("input--filled")},blur:function(){var e=(0,_.default)(this);""===e.val()&&(e.parent().removeClass("input--filled"),e.siblings(".input-label").removeClass("input--hide"))}}),n.postRender(),window.location.replace(window.location.href.split("#")[0]+"#"+a.name),(0,_.default)("#challenge-window").modal()})};function p(e){var t=e.data,o=(0,_.default)("#result-message"),n=(0,_.default)("#result-notification"),s=(0,_.default)("#submission-input");n.removeClass(),o.text(t.message),"authentication_required"!==t.status?("incorrect"===t.status?(n.addClass("alert alert-danger alert-dismissable text-center"),n.slideDown(),s.removeClass("correct"),s.addClass("wrong"),setTimeout(function(){s.removeClass("wrong")},3e3)):"correct"===t.status?(n.addClass("alert alert-success alert-dismissable text-center"),n.slideDown(),(0,_.default)(".challenge-solves").text(parseInt((0,_.default)(".challenge-solves").text().split(" ")[0])+1+" Solves"),s.val(""),s.removeClass("wrong"),s.addClass("correct")):"already_solved"===t.status?(n.addClass("alert alert-info alert-dismissable text-center"),n.slideDown(),s.addClass("correct")):"paused"===t.status?(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown()):"ratelimited"===t.status&&(n.addClass("alert alert-warning alert-dismissable text-center"),n.slideDown(),s.addClass("too-fast"),setTimeout(function(){s.removeClass("too-fast")},3e3)),setTimeout(function(){(0,_.default)(".alert").slideUp(),(0,_.default)("#submit-key").removeClass("disabled-button"),(0,_.default)("#submit-key").prop("disabled",!1)},3e3)):window.location=l.default.config.urlRoot+"/login?next="+l.default.config.urlRoot+window.location.pathname+window.location.hash}function f(){return c[l.default.config.userMode]("me").then(function(e){for(var t=e.data,o=t.length-1;0<=o;o--){var n=(0,_.default)('button[value="'+t[o].challenge_id+'"]');n.addClass("solved-challenge"),n.prepend("")}})}function b(e){return l.default.api.get_challenge_solves({challengeId:e}).then(function(e){var t=e.data;(0,_.default)(".challenge-solves").text(parseInt(t.length)+" Solves");var o=(0,_.default)("#challenge-solves-names");o.empty();for(var n=0;n
{2}{3}
{2}{3}
',t+1,"'.format(s.default.config.urlRoot,o[t].account_id),(0,u.htmlEntities)(o[t].name),"",o[t].score,"
',o+1,"'.format(s.default.config.urlRoot,t[o].account_id),(0,u.htmlEntities)(t[o].name),"",t[o].score,"
+
- - - - - - + + + + + + + {% for challenge in challenges %} - + + - - + +
IDNameCategoryValueTypeState +
+   +
+
IDNameCategoryValueTypeState
{{ challenge.id }} +
+   +
+
{{ challenge.id }} {{ challenge.name }} {{ challenge.category }}{{ challenge.value }}{{ challenge.type }}{{ challenge.value }}{{ challenge.type }} {% set badge_state = 'badge-danger' if challenge.state == 'hidden' else 'badge-success' %} {{ challenge.state }} diff --git a/CTFd/themes/admin/templates/pages.html b/CTFd/themes/admin/templates/pages.html index 2562ab91..87a0e7cc 100644 --- a/CTFd/themes/admin/templates/pages.html +++ b/CTFd/themes/admin/templates/pages.html @@ -19,20 +19,41 @@
- +
+
+ +
+
+ + +
+
+
- - - - - - + + + + + + + {% for page in pages %} - + + @@ -60,7 +81,7 @@ Published {% endif %} - {% endfor %} diff --git a/CTFd/themes/admin/templates/scoreboard.html b/CTFd/themes/admin/templates/scoreboard.html index 3a528c9e..80fb24d8 100644 --- a/CTFd/themes/admin/templates/scoreboard.html +++ b/CTFd/themes/admin/templates/scoreboard.html @@ -11,10 +11,10 @@
- -
diff --git a/CTFd/themes/admin/templates/submissions.html b/CTFd/themes/admin/templates/submissions.html index f15aeb36..d92fd4c8 100644 --- a/CTFd/themes/admin/templates/submissions.html +++ b/CTFd/themes/admin/templates/submissions.html @@ -16,7 +16,7 @@
-
@@ -56,7 +56,9 @@ {{ sub.team_name }}
TitleRouteAuthenticationHiddenPublishedSettings +
+   +
+
TitleRouteAuthenticationHiddenPublished
+
+   +
+
{{ page.title }} +
- {{ sub.challenge_name }} + + {{ sub.challenge_name }} + {{ sub.type }} diff --git a/CTFd/themes/admin/templates/teams/teams.html b/CTFd/themes/admin/templates/teams/teams.html index d29f5c94..6fc5d022 100644 --- a/CTFd/themes/admin/templates/teams/teams.html +++ b/CTFd/themes/admin/templates/teams/teams.html @@ -24,48 +24,68 @@ {% endif %}
-
- - -
-
- - -
-
- - -
+
+ + +
+
+ + +
+
+ + +
+ + -
+
- +
+
+
+
+ +
+
+
+
+ +
+
+
- - - - - - + + + + + + {% for team in teams %} - + +
ID - Team - Website - Country - Hidden - Banned + +
+   +
IDTeamWebsiteCountryHiddenBanned
{{ team.id }} +
+   +
+
{{ team.id }} {{ team.name | truncate(32) }} diff --git a/CTFd/themes/admin/templates/users/users.html b/CTFd/themes/admin/templates/users/users.html index 3de7ca9a..ac96e6ef 100644 --- a/CTFd/themes/admin/templates/users/users.html +++ b/CTFd/themes/admin/templates/users/users.html @@ -17,6 +17,7 @@
+
{% if q and field %} @@ -24,55 +25,71 @@ {% endif %}
-
- - -
-
- - -
-
- - -
+
+ + +
+
+ + +
+
+ + +
+
+
-
+
- +
+
+
+
+ +
+
+
+
+
+
+
- - - - - - - - - + + + + + + + + {% for user in users %} - + +
ID - User - Email - Website - Country - Admin - Verified - Hidden - Banned + +
+   +
ID + UserEmailWebsiteCountryAdminVerifiedHiddenBanned
{{ user.id }} +
+   +
+
{{ user.id }} {{ user.name | truncate(32) }} From 7b9cd1df2576e3b668502b8d4b97650c98f7abc5 Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Wed, 22 Apr 2020 15:20:27 -0400 Subject: [PATCH 04/11] Consolidate buttons --- .../admin/templates/challenges/challenges.html | 3 +++ CTFd/themes/admin/templates/scoreboard.html | 5 +---- CTFd/themes/admin/templates/teams/teams.html | 14 +++++++++++--- CTFd/themes/admin/templates/users/users.html | 8 +++++++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CTFd/themes/admin/templates/challenges/challenges.html b/CTFd/themes/admin/templates/challenges/challenges.html index baf6df3b..8ce7e8d4 100644 --- a/CTFd/themes/admin/templates/challenges/challenges.html +++ b/CTFd/themes/admin/templates/challenges/challenges.html @@ -22,6 +22,9 @@
+ diff --git a/CTFd/themes/admin/templates/scoreboard.html b/CTFd/themes/admin/templates/scoreboard.html index 80fb24d8..bea64d2e 100644 --- a/CTFd/themes/admin/templates/scoreboard.html +++ b/CTFd/themes/admin/templates/scoreboard.html @@ -11,10 +11,7 @@
- -
diff --git a/CTFd/themes/admin/templates/teams/teams.html b/CTFd/themes/admin/templates/teams/teams.html index 6fc5d022..37a8116f 100644 --- a/CTFd/themes/admin/templates/teams/teams.html +++ b/CTFd/themes/admin/templates/teams/teams.html @@ -51,9 +51,17 @@
- +
+ + + +
diff --git a/CTFd/themes/admin/templates/users/users.html b/CTFd/themes/admin/templates/users/users.html index ac96e6ef..c28322ca 100644 --- a/CTFd/themes/admin/templates/users/users.html +++ b/CTFd/themes/admin/templates/users/users.html @@ -53,7 +53,13 @@
- + +
From be643dee9003e0b5357e6d403fde6301f0abcabb Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Wed, 22 Apr 2020 15:26:08 -0400 Subject: [PATCH 05/11] Run prettier --- CTFd/themes/admin/assets/js/styles.js | 13 +++++++------ CTFd/themes/admin/static/js/core.dev.js | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CTFd/themes/admin/assets/js/styles.js b/CTFd/themes/admin/assets/js/styles.js index 125293b7..ee3ad6f3 100644 --- a/CTFd/themes/admin/assets/js/styles.js +++ b/CTFd/themes/admin/assets/js/styles.js @@ -46,23 +46,24 @@ export default () => { return false; }); - $("[data-checkbox]").click(function(e){ + $("[data-checkbox]").click(function(e) { if ($(e.target).is("input[type=checkbox]")) { e.stopImmediatePropagation(); return; } - let checkbox = $(this).find('input[type=checkbox]'); + let checkbox = $(this).find("input[type=checkbox]"); // Doing it this way with an event allows data-checkbox-all to work checkbox.click(); e.stopImmediatePropagation(); }); - $("[data-checkbox-all]").on('click change', function(e){ + $("[data-checkbox-all]").on("click change", function(e) { const checked = $(this).prop("checked"); const idx = $(this).index() + 1; - $(this).closest("table") - .find(`tr td:nth-child(${idx}) input[type=checkbox]`) - .prop("checked", checked) + $(this) + .closest("table") + .find(`tr td:nth-child(${idx}) input[type=checkbox]`) + .prop("checked", checked); e.stopImmediatePropagation(); }); diff --git a/CTFd/themes/admin/static/js/core.dev.js b/CTFd/themes/admin/static/js/core.dev.js index 8b5c2806..a58bd972 100644 --- a/CTFd/themes/admin/static/js/core.dev.js +++ b/CTFd/themes/admin/static/js/core.dev.js @@ -20,7 +20,7 @@ eval("\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd * /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/dist/js/bootstrap.bundle */ \"./node_modules/bootstrap/dist/js/bootstrap.bundle.js\");\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = function _default() {\n // TODO: This is kind of a hack to mimic a React-like state construct.\n // It should be removed once we have a real front-end framework in place.\n (0, _jquery.default)(\":input\").each(function () {\n (0, _jquery.default)(this).data(\"initial\", (0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\".form-control\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n },\n blur: function blur() {\n if ((0, _jquery.default)(this).val() === \"\") {\n (0, _jquery.default)(this).removeClass(\"input-filled-valid\");\n }\n }\n });\n (0, _jquery.default)(\".modal\").on(\"show.bs.modal\", function (e) {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n });\n (0, _jquery.default)(function () {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n (0, _jquery.default)(\"tr[data-href]\").click(function () {\n var sel = getSelection().toString();\n\n if (!sel) {\n var href = (0, _jquery.default)(this).attr(\"data-href\");\n\n if (href) {\n window.location = href;\n }\n }\n\n return false;\n });\n (0, _jquery.default)(\"[data-checkbox]\").click(function (e) {\n if ((0, _jquery.default)(e.target).is(\"input[type=checkbox]\")) {\n e.stopImmediatePropagation();\n return;\n }\n\n var checkbox = (0, _jquery.default)(this).find('input[type=checkbox]'); // Doing it this way with an event allows data-checkbox-all to work\n\n checkbox.click();\n e.stopImmediatePropagation();\n });\n (0, _jquery.default)(\"[data-checkbox-all]\").on('click change', function (e) {\n var checked = (0, _jquery.default)(this).prop(\"checked\");\n var idx = (0, _jquery.default)(this).index() + 1;\n (0, _jquery.default)(this).closest(\"table\").find(\"tr td:nth-child(\".concat(idx, \") input[type=checkbox]\")).prop(\"checked\", checked);\n e.stopImmediatePropagation();\n });\n (0, _jquery.default)(\"tr[data-href] a, tr[data-href] button\").click(function (e) {\n // TODO: This is a hack to allow modal close buttons to work\n if (!(0, _jquery.default)(this).attr(\"data-dismiss\")) {\n e.stopPropagation();\n }\n });\n (0, _utils.makeSortableTables)();\n (0, _jquery.default)('[data-toggle=\"tooltip\"]').tooltip();\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/styles.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/dist/js/bootstrap.bundle */ \"./node_modules/bootstrap/dist/js/bootstrap.bundle.js\");\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = function _default() {\n // TODO: This is kind of a hack to mimic a React-like state construct.\n // It should be removed once we have a real front-end framework in place.\n (0, _jquery.default)(\":input\").each(function () {\n (0, _jquery.default)(this).data(\"initial\", (0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\".form-control\").bind({\n focus: function focus() {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n },\n blur: function blur() {\n if ((0, _jquery.default)(this).val() === \"\") {\n (0, _jquery.default)(this).removeClass(\"input-filled-valid\");\n }\n }\n });\n (0, _jquery.default)(\".modal\").on(\"show.bs.modal\", function (e) {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n });\n (0, _jquery.default)(function () {\n (0, _jquery.default)(\".form-control\").each(function () {\n if ((0, _jquery.default)(this).val()) {\n (0, _jquery.default)(this).addClass(\"input-filled-valid\");\n }\n });\n (0, _jquery.default)(\"tr[data-href]\").click(function () {\n var sel = getSelection().toString();\n\n if (!sel) {\n var href = (0, _jquery.default)(this).attr(\"data-href\");\n\n if (href) {\n window.location = href;\n }\n }\n\n return false;\n });\n (0, _jquery.default)(\"[data-checkbox]\").click(function (e) {\n if ((0, _jquery.default)(e.target).is(\"input[type=checkbox]\")) {\n e.stopImmediatePropagation();\n return;\n }\n\n var checkbox = (0, _jquery.default)(this).find(\"input[type=checkbox]\"); // Doing it this way with an event allows data-checkbox-all to work\n\n checkbox.click();\n e.stopImmediatePropagation();\n });\n (0, _jquery.default)(\"[data-checkbox-all]\").on(\"click change\", function (e) {\n var checked = (0, _jquery.default)(this).prop(\"checked\");\n var idx = (0, _jquery.default)(this).index() + 1;\n (0, _jquery.default)(this).closest(\"table\").find(\"tr td:nth-child(\".concat(idx, \") input[type=checkbox]\")).prop(\"checked\", checked);\n e.stopImmediatePropagation();\n });\n (0, _jquery.default)(\"tr[data-href] a, tr[data-href] button\").click(function (e) {\n // TODO: This is a hack to allow modal close buttons to work\n if (!(0, _jquery.default)(this).attr(\"data-dismiss\")) {\n e.stopPropagation();\n }\n });\n (0, _utils.makeSortableTables)();\n (0, _jquery.default)('[data-toggle=\"tooltip\"]').tooltip();\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/styles.js?"); /***/ }), From 5f4af2a3f21fb05d07fdb00af8789f2d61f6974f Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Wed, 22 Apr 2020 17:24:33 -0400 Subject: [PATCH 06/11] Fix tables --- CTFd/themes/admin/templates/pages.html | 10 +++++----- CTFd/themes/admin/templates/scoreboard.html | 8 ++++---- CTFd/themes/admin/templates/submissions.html | 6 +++--- CTFd/themes/admin/templates/teams/teams.html | 8 ++++---- CTFd/themes/admin/templates/users/users.html | 10 +++++----- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/CTFd/themes/admin/templates/pages.html b/CTFd/themes/admin/templates/pages.html index 87a0e7cc..ec45540f 100644 --- a/CTFd/themes/admin/templates/pages.html +++ b/CTFd/themes/admin/templates/pages.html @@ -33,11 +33,11 @@ - @@ -49,8 +49,8 @@ {% for page in pages %} - diff --git a/CTFd/themes/admin/templates/scoreboard.html b/CTFd/themes/admin/templates/scoreboard.html index bea64d2e..f5e25d7f 100644 --- a/CTFd/themes/admin/templates/scoreboard.html +++ b/CTFd/themes/admin/templates/scoreboard.html @@ -23,11 +23,11 @@
-
+
+
 
- +
Title Route Authentication
-
+
+
 
- @@ -37,7 +37,7 @@ {% for standing in standings %} -
-
+
+
 
- +
Place Team Score
+
 
diff --git a/CTFd/themes/admin/templates/submissions.html b/CTFd/themes/admin/templates/submissions.html index d92fd4c8..12272c93 100644 --- a/CTFd/themes/admin/templates/submissions.html +++ b/CTFd/themes/admin/templates/submissions.html @@ -28,11 +28,11 @@ - @@ -44,7 +44,7 @@ {% for sub in submissions %} -
+
 
- +
ID Team Challenge
+
 
diff --git a/CTFd/themes/admin/templates/teams/teams.html b/CTFd/themes/admin/templates/teams/teams.html index 37a8116f..8c835a04 100644 --- a/CTFd/themes/admin/templates/teams/teams.html +++ b/CTFd/themes/admin/templates/teams/teams.html @@ -72,11 +72,11 @@ - @@ -88,7 +88,7 @@ {% for team in teams %} -
-
+
+
 
- +
ID Team Website
+
 
diff --git a/CTFd/themes/admin/templates/users/users.html b/CTFd/themes/admin/templates/users/users.html index c28322ca..d2af1869 100644 --- a/CTFd/themes/admin/templates/users/users.html +++ b/CTFd/themes/admin/templates/users/users.html @@ -71,11 +71,11 @@ - @@ -90,8 +90,8 @@ {% for user in users %} - From d5fd2f8f2a3aa7865a7cfef2317ba84dd76bd2cc Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Wed, 22 Apr 2020 18:49:57 -0400 Subject: [PATCH 07/11] Setup bulk deletion buttons --- .../admin/assets/js/pages/challenges.js | 34 ++++ CTFd/themes/admin/assets/js/pages/pages.js | 46 +++-- CTFd/themes/admin/assets/js/pages/teams.js | 34 ++++ CTFd/themes/admin/assets/js/pages/users.js | 32 ++++ CTFd/themes/admin/static/js/core.dev.js | 2 +- .../admin/static/js/pages/challenge.dev.js | 2 +- .../admin/static/js/pages/challenges.dev.js | 169 ++++++++++++++++++ .../admin/static/js/pages/configs.dev.js | 2 +- .../admin/static/js/pages/editor.dev.js | 2 +- CTFd/themes/admin/static/js/pages/main.dev.js | 2 +- .../static/js/pages/notifications.dev.js | 2 +- .../themes/admin/static/js/pages/pages.dev.js | 4 +- .../themes/admin/static/js/pages/reset.dev.js | 2 +- .../admin/static/js/pages/scoreboard.dev.js | 2 +- .../admin/static/js/pages/statistics.dev.js | 2 +- .../admin/static/js/pages/submissions.dev.js | 2 +- CTFd/themes/admin/static/js/pages/team.dev.js | 2 +- .../themes/admin/static/js/pages/teams.dev.js | 74 +++++++- CTFd/themes/admin/static/js/pages/user.dev.js | 2 +- .../themes/admin/static/js/pages/users.dev.js | 4 +- .../templates/challenges/challenges.html | 6 +- CTFd/themes/admin/templates/pages.html | 4 +- CTFd/themes/admin/templates/teams/teams.html | 26 +-- CTFd/themes/admin/templates/users/users.html | 4 +- webpack.config.js | 1 + 25 files changed, 402 insertions(+), 60 deletions(-) create mode 100644 CTFd/themes/admin/static/js/pages/challenges.dev.js diff --git a/CTFd/themes/admin/assets/js/pages/challenges.js b/CTFd/themes/admin/assets/js/pages/challenges.js index e69de29b..cada9cb5 100644 --- a/CTFd/themes/admin/assets/js/pages/challenges.js +++ b/CTFd/themes/admin/assets/js/pages/challenges.js @@ -0,0 +1,34 @@ +import "./main"; +import CTFd from "core/CTFd"; +import $ from "jquery"; +import { ezQuery } from "core/ezq"; + +function deleteSelectedChallenges(event){ + let challengeIDs = $("input[data-challenge-id]:checked").map(function() { + return $(this).data("challenge-id"); + }); + let target = challengeIDs.length === 1 ? "challenge" : "challenges"; + + ezQuery({ + title: "Delete Challenges", + body: `Are you sure you want to delete ${challengeIDs.length} ${target}?`, + success: function() { + const reqs = []; + for (var chalID of challengeIDs) { + reqs.push( + CTFd.fetch(`/api/v1/challenges/${chalID}`, { + method: "DELETE" + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + +$(() => { + $("#challenges-delete-button").click(deleteSelectedChallenges); +}); + diff --git a/CTFd/themes/admin/assets/js/pages/pages.js b/CTFd/themes/admin/assets/js/pages/pages.js index de5f81c8..7cf3d112 100644 --- a/CTFd/themes/admin/assets/js/pages/pages.js +++ b/CTFd/themes/admin/assets/js/pages/pages.js @@ -1,37 +1,35 @@ import "./main"; import CTFd from "core/CTFd"; import $ from "jquery"; -import { htmlEntities } from "core/utils"; import { ezQuery } from "core/ezq"; -function deletePage(event) { - const elem = $(this); - const name = elem.attr("page-route"); - const page_id = elem.attr("page-id"); + +function deleteSelectedUsers(event) { + let pageIDs = $("input[data-page-id]:checked").map(function() { + return $(this).data("page-id"); + }); + let target = pageIDs.length === 1 ? "page" : "pages"; + ezQuery({ - title: "Delete " + htmlEntities(name), - body: "Are you sure you want to delete {0}?".format( - "" + htmlEntities(name) + "" - ), + title: "Delete Pages", + body: `Are you sure you want to delete ${pageIDs.length} ${target}?`, success: function() { - CTFd.fetch("/api/v1/pages/" + page_id, { - method: "DELETE" - }) - .then(function(response) { - return response.json(); - }) - .then(function(response) { - if (response.success) { - elem - .parent() - .parent() - .remove(); - } - }); + const reqs = []; + for (var pageID of pageIDs) { + reqs.push( + CTFd.fetch(`/api/v1/pages/${pageID}`, { + method: "DELETE" + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); } }); } + $(() => { - $(".delete-page").click(deletePage); + $("#pages-delete-button").click(deleteSelectedUsers); }); diff --git a/CTFd/themes/admin/assets/js/pages/teams.js b/CTFd/themes/admin/assets/js/pages/teams.js index e69de29b..10c123b2 100644 --- a/CTFd/themes/admin/assets/js/pages/teams.js +++ b/CTFd/themes/admin/assets/js/pages/teams.js @@ -0,0 +1,34 @@ +import "./main"; +import CTFd from "core/CTFd"; +import $ from "jquery"; +import { ezQuery } from "core/ezq"; + + +function deleteSelectedTeams(event) { + let teamIDs = $("input[data-team-id]:checked").map(function() { + return $(this).data("team-id"); + }); + let target = teamIDs.length === 1 ? "team" : "teams"; + + ezQuery({ + title: "Delete Teams", + body: `Are you sure you want to delete ${teamIDs.length} ${target}?`, + success: function() { + const reqs = []; + for (var teamID of teamIDs) { + reqs.push( + CTFd.fetch(`/api/v1/teams/${teamID}`, { + method: "DELETE" + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + +$(() => { + $("#teams-delete-button").click(deleteSelectedTeams); +}); \ No newline at end of file diff --git a/CTFd/themes/admin/assets/js/pages/users.js b/CTFd/themes/admin/assets/js/pages/users.js index 09198c2b..90233ee7 100644 --- a/CTFd/themes/admin/assets/js/pages/users.js +++ b/CTFd/themes/admin/assets/js/pages/users.js @@ -1 +1,33 @@ import "./main"; +import CTFd from "core/CTFd"; +import $ from "jquery"; +import { ezQuery } from "core/ezq"; + +function deleteSelectedUsers(event) { + let userIDs = $("input[data-user-id]:checked").map(function() { + return $(this).data("user-id"); + }); + let target = userIDs.length === 1 ? "user" : "users"; + + ezQuery({ + title: "Delete Users", + body: `Are you sure you want to delete ${userIDs.length} ${target}?`, + success: function() { + const reqs = []; + for (var userID of userIDs) { + reqs.push( + CTFd.fetch(`/api/v1/users/${userID}`, { + method: "DELETE" + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + +$(() => { + $("#users-delete-button").click(deleteSelectedUsers); +}); diff --git a/CTFd/themes/admin/static/js/core.dev.js b/CTFd/themes/admin/static/js/core.dev.js index a58bd972..371db0c3 100644 --- a/CTFd/themes/admin/static/js/core.dev.js +++ b/CTFd/themes/admin/static/js/core.dev.js @@ -1,4 +1,4 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"],{ +(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"],{ /***/ "./CTFd/themes/admin/assets/js/pages/main.js": /*!***************************************************!*\ diff --git a/CTFd/themes/admin/static/js/pages/challenge.dev.js b/CTFd/themes/admin/static/js/pages/challenge.dev.js index d84a106f..9c5a418e 100644 --- a/CTFd/themes/admin/static/js/pages/challenge.dev.js +++ b/CTFd/themes/admin/static/js/pages/challenge.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/challenge.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/challenge.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/challenges.dev.js b/CTFd/themes/admin/static/js/pages/challenges.dev.js new file mode 100644 index 00000000..5c77e4d6 --- /dev/null +++ b/CTFd/themes/admin/static/js/pages/challenges.dev.js @@ -0,0 +1,169 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ var executeModules = data[2]; +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ // add entry modules from loaded chunk to deferred list +/******/ deferredModules.push.apply(deferredModules, executeModules || []); +/******/ +/******/ // run deferred modules when all chunks ready +/******/ return checkDeferredModules(); +/******/ }; +/******/ function checkDeferredModules() { +/******/ var result; +/******/ for(var i = 0; i < deferredModules.length; i++) { +/******/ var deferredModule = deferredModules[i]; +/******/ var fulfilled = true; +/******/ for(var j = 1; j < deferredModule.length; j++) { +/******/ var depId = deferredModule[j]; +/******/ if(installedChunks[depId] !== 0) fulfilled = false; +/******/ } +/******/ if(fulfilled) { +/******/ deferredModules.splice(i--, 1); +/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); +/******/ } +/******/ } +/******/ return result; +/******/ } +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "pages/challenges": 0 +/******/ }; +/******/ +/******/ var deferredModules = []; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "/themes/admin/static/js"; +/******/ +/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; +/******/ +/******/ +/******/ // add entry module to deferred list +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/challenges.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); +/******/ // run deferred modules when ready +/******/ return checkDeferredModules(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./CTFd/themes/admin/assets/js/pages/challenges.js": +/*!*********************************************************!*\ + !*** ./CTFd/themes/admin/assets/js/pages/challenges.js ***! + \*********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedChallenges(event) {\n var challengeIDs = (0, _jquery.default)(\"input[data-challenge-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"challenge-id\");\n });\n var target = challengeIDs.length === 1 ? \"challenge\" : \"challenges\";\n (0, _ezq.ezQuery)({\n title: \"Delete Challenges\",\n body: \"Are you sure you want to delete \".concat(challengeIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = challengeIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var chalID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/challenges/\".concat(chalID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#challenges-delete-button\").click(deleteSelectedChallenges);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/challenges.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/CTFd/themes/admin/static/js/pages/configs.dev.js b/CTFd/themes/admin/static/js/pages/configs.dev.js index e2ad88fd..1668f7f9 100644 --- a/CTFd/themes/admin/static/js/pages/configs.dev.js +++ b/CTFd/themes/admin/static/js/pages/configs.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/configs.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/configs.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/editor.dev.js b/CTFd/themes/admin/static/js/pages/editor.dev.js index 96c02339..c9c9ca51 100644 --- a/CTFd/themes/admin/static/js/pages/editor.dev.js +++ b/CTFd/themes/admin/static/js/pages/editor.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/editor.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/editor.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/main.dev.js b/CTFd/themes/admin/static/js/pages/main.dev.js index 67d967b6..6a492084 100644 --- a/CTFd/themes/admin/static/js/pages/main.dev.js +++ b/CTFd/themes/admin/static/js/pages/main.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/main.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/main.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/notifications.dev.js b/CTFd/themes/admin/static/js/pages/notifications.dev.js index 3bc9775c..833e596c 100644 --- a/CTFd/themes/admin/static/js/pages/notifications.dev.js +++ b/CTFd/themes/admin/static/js/pages/notifications.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/notifications.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/notifications.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/pages.dev.js b/CTFd/themes/admin/static/js/pages/pages.dev.js index 80d4a345..038b06c3 100644 --- a/CTFd/themes/admin/static/js/pages/pages.dev.js +++ b/CTFd/themes/admin/static/js/pages/pages.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/pages.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/pages.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) @@ -162,7 +162,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deletePage(event) {\n var elem = (0, _jquery.default)(this);\n var name = elem.attr(\"page-route\");\n var page_id = elem.attr(\"page-id\");\n (0, _ezq.ezQuery)({\n title: \"Delete \" + (0, _utils.htmlEntities)(name),\n body: \"Are you sure you want to delete {0}?\".format(\"\" + (0, _utils.htmlEntities)(name) + \"\"),\n success: function success() {\n _CTFd.default.fetch(\"/api/v1/pages/\" + page_id, {\n method: \"DELETE\"\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n elem.parent().parent().remove();\n }\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".delete-page\").click(deletePage);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/pages.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedUsers(event) {\n var pageIDs = (0, _jquery.default)(\"input[data-page-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"page-id\");\n });\n var target = pageIDs.length === 1 ? \"page\" : \"pages\";\n (0, _ezq.ezQuery)({\n title: \"Delete Pages\",\n body: \"Are you sure you want to delete \".concat(pageIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = pageIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var pageID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/pages/\".concat(pageID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#pages-delete-button\").click(deleteSelectedUsers);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/pages.js?"); /***/ }) diff --git a/CTFd/themes/admin/static/js/pages/reset.dev.js b/CTFd/themes/admin/static/js/pages/reset.dev.js index 043a1c19..d8926f90 100644 --- a/CTFd/themes/admin/static/js/pages/reset.dev.js +++ b/CTFd/themes/admin/static/js/pages/reset.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/reset.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/reset.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/scoreboard.dev.js b/CTFd/themes/admin/static/js/pages/scoreboard.dev.js index f88be9ee..94485ae4 100644 --- a/CTFd/themes/admin/static/js/pages/scoreboard.dev.js +++ b/CTFd/themes/admin/static/js/pages/scoreboard.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/scoreboard.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/scoreboard.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/statistics.dev.js b/CTFd/themes/admin/static/js/pages/statistics.dev.js index aa3730db..f0100406 100644 --- a/CTFd/themes/admin/static/js/pages/statistics.dev.js +++ b/CTFd/themes/admin/static/js/pages/statistics.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/statistics.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/statistics.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/submissions.dev.js b/CTFd/themes/admin/static/js/pages/submissions.dev.js index be2c17e1..25929a2b 100644 --- a/CTFd/themes/admin/static/js/pages/submissions.dev.js +++ b/CTFd/themes/admin/static/js/pages/submissions.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/submissions.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/submissions.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/team.dev.js b/CTFd/themes/admin/static/js/pages/team.dev.js index 25ab2c4f..66fca878 100644 --- a/CTFd/themes/admin/static/js/pages/team.dev.js +++ b/CTFd/themes/admin/static/js/pages/team.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/team.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/team.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/teams.dev.js b/CTFd/themes/admin/static/js/pages/teams.dev.js index 4927e7c9..dbb39fa4 100644 --- a/CTFd/themes/admin/static/js/pages/teams.dev.js +++ b/CTFd/themes/admin/static/js/pages/teams.dev.js @@ -1,7 +1,66 @@ /******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ var executeModules = data[2]; +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ // add entry modules from loaded chunk to deferred list +/******/ deferredModules.push.apply(deferredModules, executeModules || []); +/******/ +/******/ // run deferred modules when all chunks ready +/******/ return checkDeferredModules(); +/******/ }; +/******/ function checkDeferredModules() { +/******/ var result; +/******/ for(var i = 0; i < deferredModules.length; i++) { +/******/ var deferredModule = deferredModules[i]; +/******/ var fulfilled = true; +/******/ for(var j = 1; j < deferredModule.length; j++) { +/******/ var depId = deferredModule[j]; +/******/ if(installedChunks[depId] !== 0) fulfilled = false; +/******/ } +/******/ if(fulfilled) { +/******/ deferredModules.splice(i--, 1); +/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); +/******/ } +/******/ } +/******/ return result; +/******/ } +/******/ /******/ // The module cache /******/ var installedModules = {}; /******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "pages/teams": 0 +/******/ }; +/******/ +/******/ var deferredModules = []; +/******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ @@ -79,9 +138,18 @@ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/themes/admin/static/js"; /******/ +/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; /******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = "./CTFd/themes/admin/assets/js/pages/teams.js"); +/******/ +/******/ // add entry module to deferred list +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/teams.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); +/******/ // run deferred modules when ready +/******/ return checkDeferredModules(); /******/ }) /************************************************************************/ /******/ ({ @@ -94,7 +162,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/teams.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedTeams(event) {\n var teamIDs = (0, _jquery.default)(\"input[data-team-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"team-id\");\n });\n var target = teamIDs.length === 1 ? \"team\" : \"teams\";\n (0, _ezq.ezQuery)({\n title: \"Delete Teams\",\n body: \"Are you sure you want to delete \".concat(teamIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = teamIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var teamID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/teams/\".concat(teamID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#teams-delete-button\").click(deleteSelectedTeams);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/teams.js?"); /***/ }) diff --git a/CTFd/themes/admin/static/js/pages/user.dev.js b/CTFd/themes/admin/static/js/pages/user.dev.js index dca97916..7d5ac5f3 100644 --- a/CTFd/themes/admin/static/js/pages/user.dev.js +++ b/CTFd/themes/admin/static/js/pages/user.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/user.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/user.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) diff --git a/CTFd/themes/admin/static/js/pages/users.dev.js b/CTFd/themes/admin/static/js/pages/users.dev.js index b3e82789..fc1569c7 100644 --- a/CTFd/themes/admin/static/js/pages/users.dev.js +++ b/CTFd/themes/admin/static/js/pages/users.dev.js @@ -147,7 +147,7 @@ /******/ /******/ /******/ // add entry module to deferred list -/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/users.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]); +/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/users.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]); /******/ // run deferred modules when ready /******/ return checkDeferredModules(); /******/ }) @@ -162,7 +162,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/users.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedUsers(event) {\n var userIDs = (0, _jquery.default)(\"input[data-user-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"user-id\");\n });\n var target = userIDs.length === 1 ? \"user\" : \"users\";\n (0, _ezq.ezQuery)({\n title: \"Delete Users\",\n body: \"Are you sure you want to delete \".concat(userIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = userIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var userID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/users/\".concat(userID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#users-delete-button\").click(deleteSelectedUsers);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/users.js?"); /***/ }) diff --git a/CTFd/themes/admin/templates/challenges/challenges.html b/CTFd/themes/admin/templates/challenges/challenges.html index 8ce7e8d4..4d64c096 100644 --- a/CTFd/themes/admin/templates/challenges/challenges.html +++ b/CTFd/themes/admin/templates/challenges/challenges.html @@ -25,7 +25,7 @@ - @@ -81,3 +81,7 @@ {% block scripts %} {% endblock %} + +{% block entrypoint %} + +{% endblock %} \ No newline at end of file diff --git a/CTFd/themes/admin/templates/pages.html b/CTFd/themes/admin/templates/pages.html index ec45540f..9fdfb1e3 100644 --- a/CTFd/themes/admin/templates/pages.html +++ b/CTFd/themes/admin/templates/pages.html @@ -21,7 +21,7 @@
-
@@ -51,7 +51,7 @@
@@ -165,3 +163,7 @@ {% block scripts %} {% endblock %} + +{% block entrypoint %} + +{% endblock %} \ No newline at end of file diff --git a/CTFd/themes/admin/templates/users/users.html b/CTFd/themes/admin/templates/users/users.html index d2af1869..62c4bcc5 100644 --- a/CTFd/themes/admin/templates/users/users.html +++ b/CTFd/themes/admin/templates/users/users.html @@ -59,7 +59,7 @@ - @@ -92,7 +92,7 @@ diff --git a/webpack.config.js b/webpack.config.js index 42aa2671..138504bc 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -36,6 +36,7 @@ const roots = { 'js': { 'pages/main': 'assets/js/pages/main.js', 'pages/challenge': 'assets/js/pages/challenge.js', + 'pages/challenges': 'assets/js/pages/challenges.js', 'pages/configs': 'assets/js/pages/configs.js', 'pages/notifications': 'assets/js/pages/notifications.js', 'pages/editor': 'assets/js/pages/editor.js', From d8e766734aae93a2824bc43ff07ef20ed94361c7 Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Wed, 22 Apr 2020 20:32:10 -0400 Subject: [PATCH 08/11] Add bulk buttons --- .../admin/assets/js/pages/challenges.js | 49 +++++++++++++++- .../admin/assets/js/pages/scoreboard.js | 45 +++++++-------- CTFd/themes/admin/assets/js/pages/teams.js | 49 +++++++++++++++- CTFd/themes/admin/assets/js/pages/users.js | 57 ++++++++++++++++++- .../admin/static/js/pages/challenge.min.js | 2 +- .../admin/static/js/pages/challenges.dev.js | 2 +- .../admin/static/js/pages/challenges.min.js | 1 + .../admin/static/js/pages/configs.min.js | 2 +- .../admin/static/js/pages/editor.min.js | 2 +- CTFd/themes/admin/static/js/pages/main.min.js | 2 +- .../static/js/pages/notifications.min.js | 2 +- .../themes/admin/static/js/pages/pages.min.js | 2 +- .../themes/admin/static/js/pages/reset.min.js | 2 +- .../admin/static/js/pages/scoreboard.dev.js | 2 +- .../admin/static/js/pages/scoreboard.min.js | 2 +- .../admin/static/js/pages/statistics.min.js | 2 +- .../admin/static/js/pages/submissions.min.js | 2 +- CTFd/themes/admin/static/js/pages/team.min.js | 2 +- .../themes/admin/static/js/pages/teams.dev.js | 2 +- .../themes/admin/static/js/pages/teams.min.js | 2 +- CTFd/themes/admin/static/js/pages/user.min.js | 2 +- .../themes/admin/static/js/pages/users.dev.js | 2 +- .../themes/admin/static/js/pages/users.min.js | 2 +- .../templates/challenges/challenges.html | 4 +- CTFd/themes/admin/templates/scoreboard.html | 6 +- CTFd/themes/admin/templates/teams/teams.html | 7 +-- CTFd/themes/admin/templates/users/users.html | 7 +-- 27 files changed, 202 insertions(+), 59 deletions(-) create mode 100644 CTFd/themes/admin/static/js/pages/challenges.min.js diff --git a/CTFd/themes/admin/assets/js/pages/challenges.js b/CTFd/themes/admin/assets/js/pages/challenges.js index cada9cb5..dbed1f9c 100644 --- a/CTFd/themes/admin/assets/js/pages/challenges.js +++ b/CTFd/themes/admin/assets/js/pages/challenges.js @@ -1,7 +1,7 @@ import "./main"; import CTFd from "core/CTFd"; import $ from "jquery"; -import { ezQuery } from "core/ezq"; +import { ezAlert, ezQuery } from "core/ezq"; function deleteSelectedChallenges(event){ let challengeIDs = $("input[data-challenge-id]:checked").map(function() { @@ -28,7 +28,54 @@ function deleteSelectedChallenges(event){ }); } +function bulkEditChallenges(event){ + let challengeIDs = $("input[data-challenge-id]:checked").map(function() { + return $(this).data("challenge-id"); + }); + + ezAlert({ + title: 'Edit Challenges', + body: $(` +
+
+ + +
+
+ + +
+
+ + +
+ + `), + button: "Submit", + success: function() { + let data = $("#challenges-bulk-edit").serializeJSON(true); + const reqs = []; + for (var chalID of challengeIDs) { + reqs.push( + CTFd.fetch(`/api/v1/challenges/${chalID}`, { + method: "PATCH", + body: JSON.stringify(data) + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + $(() => { $("#challenges-delete-button").click(deleteSelectedChallenges); + $("#challenges-edit-button").click(bulkEditChallenges); }); diff --git a/CTFd/themes/admin/assets/js/pages/scoreboard.js b/CTFd/themes/admin/assets/js/pages/scoreboard.js index dc9c7e48..9c0e7175 100644 --- a/CTFd/themes/admin/assets/js/pages/scoreboard.js +++ b/CTFd/themes/admin/assets/js/pages/scoreboard.js @@ -1,7 +1,7 @@ import "./main"; import CTFd from "core/CTFd"; import $ from "jquery"; -import { ezQuery } from "core/ezq"; +import { ezAlert, ezQuery } from "core/ezq"; const api_func = { users: (x, y) => CTFd.api.patch_user_public({ userId: x }, y), @@ -40,7 +40,7 @@ function toggleAccount() { function toggleSelectedAccounts(accountIDs, action) { const params = { - hidden: action === "hide" ? true : false + hidden: action === "hidden" ? true : false }; const reqs = []; for (var accId of accountIDs) { @@ -51,36 +51,35 @@ function toggleSelectedAccounts(accountIDs, action) { }); } -function hideSelectedAccounts(event) { +function bulkToggleAccounts(event){ let accountIDs = $("input[data-account-id]:checked").map(function() { return $(this).data("account-id"); }); - let target = accountIDs.length === 1 ? "account" : "accounts"; - ezQuery({ - title: "Hide Accounts", - body: `Are you sure you want to hide ${accountIDs.length} ${target}?`, - success: function() { - toggleSelectedAccounts(accountIDs, "hide"); - } - }); -} -function showSelectedAccounts(event) { - let accountIDs = $("input[data-account-id]:checked").map(function() { - return $(this).data("account-id"); - }); - let target = accountIDs.length === 1 ? "account" : "accounts"; - ezQuery({ - title: "Unhide Accounts", - body: `Are you sure you want to unhide ${accountIDs.length} ${target}?`, + ezAlert({ + title: 'Toggle Visibility', + body: $(` +
+
+ + +
+ + `), + button: "Submit", success: function() { - toggleSelectedAccounts(accountIDs, "show"); + let data = $("#scoreboard-bulk-edit").serializeJSON(true); + let state = data.visibility; + toggleSelectedAccounts(accountIDs, state); } }); } $(() => { $(".scoreboard-toggle").click(toggleAccount); - $("#scoreboard-hide-button").click(hideSelectedAccounts); - $("#scoreboard-show-button").click(showSelectedAccounts); + $("#scoreboard-edit-button").click(bulkToggleAccounts); }); diff --git a/CTFd/themes/admin/assets/js/pages/teams.js b/CTFd/themes/admin/assets/js/pages/teams.js index 10c123b2..5a726b82 100644 --- a/CTFd/themes/admin/assets/js/pages/teams.js +++ b/CTFd/themes/admin/assets/js/pages/teams.js @@ -1,7 +1,7 @@ import "./main"; import CTFd from "core/CTFd"; import $ from "jquery"; -import { ezQuery } from "core/ezq"; +import { ezAlert, ezQuery } from "core/ezq"; function deleteSelectedTeams(event) { @@ -29,6 +29,53 @@ function deleteSelectedTeams(event) { }); } +function bulkEditTeams(event){ + let teamIDs = $("input[data-team-id]:checked").map(function() { + return $(this).data("team-id"); + }); + + ezAlert({ + title: 'Edit Teams', + body: $(` +
+
+ + +
+
+ + +
+ + `), + button: "Submit", + success: function() { + let data = $("#teams-bulk-edit").serializeJSON(true); + const reqs = []; + for (var teamID of teamIDs) { + reqs.push( + CTFd.fetch(`/api/v1/teams/${teamID}`, { + method: "PATCH", + body: JSON.stringify(data) + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + $(() => { $("#teams-delete-button").click(deleteSelectedTeams); + $("#teams-edit-button").click(bulkEditTeams); }); \ No newline at end of file diff --git a/CTFd/themes/admin/assets/js/pages/users.js b/CTFd/themes/admin/assets/js/pages/users.js index 90233ee7..7dbd77b5 100644 --- a/CTFd/themes/admin/assets/js/pages/users.js +++ b/CTFd/themes/admin/assets/js/pages/users.js @@ -1,7 +1,7 @@ import "./main"; import CTFd from "core/CTFd"; import $ from "jquery"; -import { ezQuery } from "core/ezq"; +import { ezAlert, ezQuery } from "core/ezq"; function deleteSelectedUsers(event) { let userIDs = $("input[data-user-id]:checked").map(function() { @@ -28,6 +28,61 @@ function deleteSelectedUsers(event) { }); } +function bulkEditUsers(event){ + let userIDs = $("input[data-user-id]:checked").map(function() { + return $(this).data("user-id"); + }); + + ezAlert({ + title: 'Edit Users', + body: $(` +
+
+ + +
+
+ + +
+
+ + +
+ + `), + button: "Submit", + success: function() { + let data = $("#users-bulk-edit").serializeJSON(true); + const reqs = []; + for (var userID of userIDs) { + reqs.push( + CTFd.fetch(`/api/v1/users/${userID}`, { + method: "PATCH", + body: JSON.stringify(data) + }) + ); + } + Promise.all(reqs).then(responses => { + window.location.reload(); + }); + } + }); +} + $(() => { $("#users-delete-button").click(deleteSelectedUsers); + $("#users-edit-button").click(bulkEditUsers); }); diff --git a/CTFd/themes/admin/static/js/pages/challenge.min.js b/CTFd/themes/admin/static/js/pages/challenge.min.js index 40592209..b3900ca4 100644 --- a/CTFd/themes/admin/static/js/pages/challenge.min.js +++ b/CTFd/themes/admin/static/js/pages/challenge.min.js @@ -1 +1 @@ -!function(d){function e(e){for(var t,o,n=e[0],s=e[1],a=e[2],i=0,l=[];i -- ");for(var s in o.append(n),t)t.hasOwnProperty(s)&&(n=(0,a.default)("".format(s,t[s].name)),o.append(n));(0,a.default)("#flag-edit-modal").modal()}),(0,a.default)("#flag-edit-modal form").submit(function(e){e.preventDefault();var t=(0,a.default)(this).serializeJSON(!0);t.challenge=CHALLENGE_ID,i.default.fetch("/api/v1/flags",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){window.location.reload()})}),(0,a.default)("#flag-edit-modal").modal()},t.editFlagModal=function(e){e.preventDefault();var n=(0,a.default)(this).attr("flag-id"),s=(0,a.default)(this).parent().parent();a.default.get(i.default.config.urlRoot+"/api/v1/flags/"+n,function(e){var o=e.data;a.default.get(i.default.config.urlRoot+o.templates.update,function(e){(0,a.default)("#edit-flags form").empty(),(0,a.default)("#edit-flags form").off();var t=l.default.compile(e);(0,a.default)("#edit-flags form").append(t.render(o)),(0,a.default)("#edit-flags form").submit(function(e){e.preventDefault();var t=(0,a.default)("#edit-flags form").serializeJSON();i.default.fetch("/api/v1/flags/"+n,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){e.success&&((0,a.default)(s).find(".flag-content").text(e.data.content),(0,a.default)("#edit-flags").modal("toggle"))})}),(0,a.default)("#edit-flags").modal()})})},t.flagTypeSelect=function(e){e.preventDefault();var t=(0,a.default)(this).find("option:selected").text();a.default.get(i.default.config.urlRoot+"/api/v1/flags/types/"+t,function(e){var t=e.data;a.default.get(i.default.config.urlRoot+t.templates.create,function(e){var t=l.default.compile(e);(0,a.default)("#create-keys-entry-div").html(t.render()),(0,a.default)("#create-keys-button-div").show()})})};var a=s(o("./node_modules/jquery/dist/jquery.js")),i=s(o("./CTFd/themes/core/assets/js/CTFd.js")),l=s(o("./node_modules/nunjucks/browser/nunjucks.js")),n=o("./CTFd/themes/core/assets/js/ezq.js");function s(e){return e&&e.__esModule?e:{default:e}}},"./CTFd/themes/admin/assets/js/challenges/hints.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.showHintModal=function(e){e.preventDefault(),(0,s.default)("#hint-edit-modal form").find("input, textarea").val(""),(0,s.default)("#new-hint-edit").on("shown.bs.tab",function(e){if("#hint-preview"==e.target.hash){var t=a.default.lib.markdown(),o=(0,s.default)("#hint-write textarea").val();(0,s.default)(e.target.hash).html(t.render(o))}}),(0,s.default)("#hint-edit-modal").modal()},t.showEditHintModal=function(e){e.preventDefault();var t=(0,s.default)(this).attr("hint-id");a.default.fetch("/api/v1/hints/"+t+"?preview=true",{method:"GET",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"}}).then(function(e){return e.json()}).then(function(e){e.success&&((0,s.default)("#hint-edit-form input[name=content],textarea[name=content]").val(e.data.content),(0,s.default)("#hint-edit-form input[name=cost]").val(e.data.cost),(0,s.default)("#hint-edit-form input[name=id]").val(e.data.id),(0,s.default)("#new-hint-edit").on("shown.bs.tab",function(e){if("#hint-preview"==e.target.hash){var t=a.default.lib.markdown(),o=(0,s.default)("#hint-write textarea").val();(0,s.default)(e.target.hash).html(t.render(o))}}),(0,s.default)("#hint-edit-modal").modal())})},t.deleteHint=function(e){e.preventDefault();var t=(0,s.default)(this).attr("hint-id"),o=(0,s.default)(this).parent().parent();(0,n.ezQuery)({title:"Delete Hint",body:"Are you sure you want to delete this hint?",success:function(){a.default.fetch("/api/v1/hints/"+t,{method:"DELETE"}).then(function(e){return e.json()}).then(function(e){e.success&&o.remove()})}})},t.editHint=function(e){e.preventDefault();var t=(0,s.default)(this).serializeJSON(!0);t.challenge=CHALLENGE_ID;var o="POST",n="/api/v1/hints";t.id&&(o="PATCH",n="/api/v1/hints/"+t.id);a.default.fetch(n,{method:o,credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){e.success&&window.location.reload()})};var s=i(o("./node_modules/jquery/dist/jquery.js")),a=i(o("./CTFd/themes/core/assets/js/CTFd.js")),n=o("./CTFd/themes/core/assets/js/ezq.js");function i(e){return e&&e.__esModule?e:{default:e}}},"./CTFd/themes/admin/assets/js/challenges/requirements.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.addRequirement=function(e){e.preventDefault();var t=(0,s.default)("#prerequisite-add-form").serializeJSON();if(!t.prerequisite)return;CHALLENGE_REQUIREMENTS.prerequisites.push(parseInt(t.prerequisite));var o={requirements:CHALLENGE_REQUIREMENTS};a.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(o)}).then(function(e){return e.json()}).then(function(e){e.success&&window.location.reload()})},t.deleteRequirement=function(e){var t=(0,s.default)(this).attr("challenge-id"),o=(0,s.default)(this).parent().parent();CHALLENGE_REQUIREMENTS.prerequisites.pop(t);var n={requirements:CHALLENGE_REQUIREMENTS};a.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(n)}).then(function(e){return e.json()}).then(function(e){e.success&&o.remove()})};var s=n(o("./node_modules/jquery/dist/jquery.js")),a=n(o("./CTFd/themes/core/assets/js/CTFd.js"));function n(e){return e&&e.__esModule?e:{default:e}}},"./CTFd/themes/admin/assets/js/challenges/tags.js":function(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.deleteTag=i,t.addTag=function(e){if(13!=e.keyCode)return;var t=(0,n.default)(this),o={value:t.val(),challenge:CHALLENGE_ID};s.default.api.post_tag_list({},o).then(function(e){if(e.success){var t=(0,n.default)("{0}×".format(e.data.value,e.data.id));(0,n.default)("#challenge-tags").append(t),t.click(i)}}),t.val("")};var n=a(o("./node_modules/jquery/dist/jquery.js")),s=a(o("./CTFd/themes/core/assets/js/CTFd.js"));function a(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=(0,n.default)(this),o=t.attr("tag-id");s.default.api.delete_tag({tagId:o}).then(function(e){e.success&&t.parent().remove()})}},"./CTFd/themes/admin/assets/js/pages/challenge.js":function(e,t,o){o("./CTFd/themes/admin/assets/js/pages/main.js");var n=o("./CTFd/themes/core/assets/js/utils.js"),l=f(o("./node_modules/jquery/dist/jquery.js"));o("./node_modules/bootstrap/js/dist/tab.js");var i=f(o("./CTFd/themes/core/assets/js/CTFd.js")),s=o("./CTFd/themes/core/assets/js/ezq.js"),a=f(o("./node_modules/nunjucks/browser/nunjucks.js")),d=f(o("./CTFd/themes/core/assets/js/helpers.js")),r=o("./CTFd/themes/admin/assets/js/challenges/files.js"),c=o("./CTFd/themes/admin/assets/js/challenges/tags.js"),u=o("./CTFd/themes/admin/assets/js/challenges/requirements.js"),m=o("./CTFd/themes/admin/assets/js/challenges/hints.js"),p=o("./CTFd/themes/admin/assets/js/challenges/flags.js");function f(e){return e&&e.__esModule?e:{default:e}}function h(t){i.default.api.get_hint({hintId:t,preview:!0}).then(function(e){e.data.content?function(e){(0,s.ezAlert)({title:"Hint",body:j.render(e.content),button:"Got it!"})}(e.data):displayUnlock(t)})}var j=i.default.lib.markdown();function _(e,t){var o=e.data,n=(0,l.default)("#result-message"),s=(0,l.default)("#result-notification"),a=(0,l.default)("#submission-input");s.removeClass(),n.text(o.message),"authentication_required"!==o.status?("incorrect"===o.status?(s.addClass("alert alert-danger alert-dismissable text-center"),s.slideDown(),a.removeClass("correct"),a.addClass("wrong"),setTimeout(function(){a.removeClass("wrong")},3e3)):"correct"===o.status?(s.addClass("alert alert-success alert-dismissable text-center"),s.slideDown(),(0,l.default)(".challenge-solves").text(parseInt((0,l.default)(".challenge-solves").text().split(" ")[0])+1+" Solves"),a.val(""),a.removeClass("wrong"),a.addClass("correct")):"already_solved"===o.status?(s.addClass("alert alert-info alert-dismissable text-center"),s.slideDown(),a.addClass("correct")):"paused"===o.status?(s.addClass("alert alert-warning alert-dismissable text-center"),s.slideDown()):"ratelimited"===o.status&&(s.addClass("alert alert-warning alert-dismissable text-center"),s.slideDown(),a.addClass("too-fast"),setTimeout(function(){a.removeClass("too-fast")},3e3)),setTimeout(function(){(0,l.default)(".alert").slideUp(),(0,l.default)("#submit-key").removeClass("disabled-button"),(0,l.default)("#submit-key").prop("disabled",!1)},3e3),t&&t(o)):window.location=i.default.config.urlRoot+"/login?next="+i.default.config.urlRoot+window.location.pathname+window.location.hash}function g(o){i.default._internal.challenge={},l.default.getScript(i.default.config.urlRoot+o.scripts.view,function(){l.default.get(i.default.config.urlRoot+o.templates.create,function(e){var t=a.default.compile(e);(0,l.default)("#create-chal-entry-div").html(t.render({nonce:i.default.config.csrfNonce,script_root:i.default.config.urlRoot})),l.default.getScript(i.default.config.urlRoot+o.scripts.create,function(){(0,l.default)("#create-chal-entry-div form").submit(function(e){e.preventDefault();var t=(0,l.default)("#create-chal-entry-div form").serializeJSON();i.default.fetch("/api/v1/challenges",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(t)}).then(function(e){return e.json()}).then(function(e){e.success&&((0,l.default)("#challenge-create-options #challenge_id").val(e.data.id),(0,l.default)("#challenge-create-options").modal())})})})})})}function v(s){s.preventDefault();var a=(0,l.default)(s.target).serializeJSON(!0),o={challenge_id:a.challenge_id,content:a.flag||"",type:a.flag_type,data:a.flag_data?a.flag_data:""};Promise.all([new Promise(function(t,e){0!=o.content.length?i.default.fetch("/api/v1/flags",{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(o)}).then(function(e){t(e.json())}):t()}),new Promise(function(e,t){var o=s.target,n={challenge:a.challenge_id,type:"challenge"};(0,l.default)(o.elements.file).val()&&d.default.files.upload(o,n),e()})]).then(function(e){i.default.fetch("/api/v1/challenges/"+a.challenge_id,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({state:a.state})}).then(function(e){return e.json()}).then(function(e){e.success&&setTimeout(function(){window.location=i.default.config.urlRoot+"/admin/challenges/"+a.challenge_id},700)})})}function y(e){var t=(0,l.default)(this).find("option:selected").data("meta");void 0!==t?g(t):(0,l.default)("#create-chal-entry-div").empty()}(0,l.default)(function(){if((0,l.default)(".preview-challenge").click(function(e){window.challenge=new Object,i.default._internal.challenge={},l.default.get(i.default.config.urlRoot+"/api/v1/challenges/"+CHALLENGE_ID,function(e){var o=i.default._internal.challenge,n=e.data;n.solves=null,l.default.getScript(i.default.config.urlRoot+n.type_data.scripts.view,function(){l.default.get(i.default.config.urlRoot+n.type_data.templates.view,function(e){(0,l.default)("#challenge-window").empty();var t=a.default.compile(e);o.data=n,o.preRender(),n.description=o.render(n.description),n.script_root=i.default.config.urlRoot,(0,l.default)("#challenge-window").append(t.render(n)),(0,l.default)(".challenge-solves").click(function(e){getsolves((0,l.default)("#challenge-id").val())}),(0,l.default)(".nav-tabs a").click(function(e){e.preventDefault(),(0,l.default)(this).tab("show")}),(0,l.default)("#challenge-window").on("hide.bs.modal",function(e){(0,l.default)("#submission-input").removeClass("wrong"),(0,l.default)("#submission-input").removeClass("correct"),(0,l.default)("#incorrect-key").slideUp(),(0,l.default)("#correct-key").slideUp(),(0,l.default)("#already-solved").slideUp(),(0,l.default)("#too-fast").slideUp()}),(0,l.default)(".load-hint").on("click",function(e){h((0,l.default)(this).data("hint-id"))}),(0,l.default)("#submit-key").click(function(e){e.preventDefault(),(0,l.default)("#submit-key").addClass("disabled-button"),(0,l.default)("#submit-key").prop("disabled",!0),i.default._internal.challenge.submit(!0).then(_)}),(0,l.default)("#submission-input").keyup(function(e){13==e.keyCode&&(0,l.default)("#submit-key").click()}),(0,l.default)(".input-field").bind({focus:function(){(0,l.default)(this).parent().addClass("input--filled"),$label=(0,l.default)(this).siblings(".input-label")},blur:function(){""===(0,l.default)(this).val()&&((0,l.default)(this).parent().removeClass("input--filled"),$label=(0,l.default)(this).siblings(".input-label"),$label.removeClass("input--hide"))}}),o.postRender(),window.location.replace(window.location.href.split("#")[0]+"#preview"),(0,l.default)("#challenge-window").modal()})})})}),(0,l.default)(".delete-challenge").click(function(e){(0,s.ezQuery)({title:"Delete Challenge",body:"Are you sure you want to delete {0}".format(""+(0,n.htmlEntities)(CHALLENGE_NAME)+""),success:function(){i.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"DELETE"}).then(function(e){return e.json()}).then(function(e){e.success&&(window.location=i.default.config.urlRoot+"/admin/challenges")})}})}),(0,l.default)("#challenge-update-container > form").submit(function(e){e.preventDefault();var o=(0,l.default)(e.target).serializeJSON(!0);i.default.fetch("/api/v1/challenges/"+CHALLENGE_ID+"/flags",{method:"GET",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"}}).then(function(e){return e.json()}).then(function(e){function t(){i.default.fetch("/api/v1/challenges/"+CHALLENGE_ID,{method:"PATCH",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(o)}).then(function(e){return e.json()}).then(function(e){if(e.success){switch((0,l.default)(".challenge-state").text(e.data.state),e.data.state){case"visible":(0,l.default)(".challenge-state").removeClass("badge-danger").addClass("badge-success");break;case"hidden":(0,l.default)(".challenge-state").removeClass("badge-success").addClass("badge-danger")}(0,s.ezToast)({title:"Success",body:"Your challenge has been updated!"})}})}0===e.data.length&&"visible"===o.state?(0,s.ezQuery)({title:"Missing Flags",body:"This challenge does not have any flags meaning it is unsolveable. Are you sure you'd like to update this challenge?",success:t}):t()})}),(0,l.default)("#challenge-create-options form").submit(v),(0,l.default)(".nav-tabs a").click(function(e){(0,l.default)(this).tab("show"),window.location.hash=this.hash}),window.location.hash){var e=window.location.hash.replace("<>[]'\"","");(0,l.default)('nav a[href="'+e+'"]').tab("show")}(0,l.default)("#tags-add-input").keyup(c.addTag),(0,l.default)(".delete-tag").click(c.deleteTag),(0,l.default)("#prerequisite-add-form").submit(u.addRequirement),(0,l.default)(".delete-requirement").click(u.deleteRequirement),(0,l.default)("#file-add-form").submit(r.addFile),(0,l.default)(".delete-file").click(r.deleteFile),(0,l.default)("#hint-add-button").click(m.showHintModal),(0,l.default)(".delete-hint").click(m.deleteHint),(0,l.default)(".edit-hint").click(m.showEditHintModal),(0,l.default)("#hint-edit-form").submit(m.editHint),(0,l.default)("#flag-add-button").click(p.addFlagModal),(0,l.default)(".delete-flag").click(p.deleteFlag),(0,l.default)("#flags-create-select").change(p.flagTypeSelect),(0,l.default)(".edit-flag").click(p.editFlagModal),l.default.get(i.default.config.urlRoot+"/api/v1/challenges/types",function(e){(0,l.default)("#create-chals-select").empty();var t=e.data,o=Object.keys(t).length;if(1 -- "),t){var s=t[n],a=(0,l.default)("
diff --git a/CTFd/themes/admin/templates/teams/teams.html b/CTFd/themes/admin/templates/teams/teams.html index e38d00bb..a1d33e22 100644 --- a/CTFd/themes/admin/templates/teams/teams.html +++ b/CTFd/themes/admin/templates/teams/teams.html @@ -51,11 +51,8 @@
- - -
- @@ -81,17 +80,6 @@ Published {% endif %} - {% endfor %}
-
+
+
 
- +
ID User Email
-
+
+
 
-   +  
diff --git a/CTFd/themes/admin/templates/teams/teams.html b/CTFd/themes/admin/templates/teams/teams.html index 8c835a04..e38d00bb 100644 --- a/CTFd/themes/admin/templates/teams/teams.html +++ b/CTFd/themes/admin/templates/teams/teams.html @@ -51,17 +51,15 @@
-
- - - -
+ + +
@@ -90,7 +88,7 @@
-   +  
{{ team.id }}
-   +  
{{ user.id }}{{ standing.score }} {% if standing.hidden %} - Hidden + hidden {% else %} - Visible + visible {% endif %}
Authentication Hidden Published