From b73433e1c97397cb5cf4c4338634b173e5dc6cc8 Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Wed, 12 Aug 2020 19:55:47 -0400 Subject: [PATCH] 321 comments functionality (#1596) * Add a comments functionality for admins to discuss challenges, users, teams, pages * Adds `/api/v1/comments` * Adds a `CommentBox.vue` component for the Admin Panel * Closes #321 --- CTFd/api/__init__.py | 2 + CTFd/api/v1/comments.py | 141 ++++++++++++ CTFd/models/__init__.py | 42 ++++ CTFd/schemas/comments.py | 14 ++ .../js/components/comments/CommentBox.vue | 155 +++++++++++++ .../themes/admin/assets/js/pages/challenge.js | 10 + CTFd/themes/admin/static/js/core.min.js | 217 ++++++++++++++++++ CTFd/themes/admin/static/js/graphs.min.js | 15 ++ CTFd/themes/admin/static/js/helpers.dev.js | 2 +- CTFd/themes/admin/static/js/helpers.min.js | 2 +- .../admin/static/js/pages/challenge.dev.js | 96 +++++++- .../admin/static/js/pages/challenge.min.js | 2 +- .../admin/static/js/vendor.bundle.dev.js | 36 +++ .../admin/static/js/vendor.bundle.min.js | 20 +- .../admin/templates/challenges/challenge.html | 11 +- CTFd/themes/core/assets/js/helpers.js | 55 +++++ CTFd/themes/core/static/js/core.min.js | 146 ++++++++++++ CTFd/themes/core/static/js/helpers.dev.js | 2 +- CTFd/themes/core/static/js/helpers.min.js | 2 +- CTFd/utils/config/pages.py | 4 +- tests/api/v1/test_comments.py | 108 +++++++++ tests/helpers.py | 23 ++ webpack.config.js | 20 +- 23 files changed, 1095 insertions(+), 30 deletions(-) create mode 100644 CTFd/api/v1/comments.py create mode 100644 CTFd/schemas/comments.py create mode 100644 CTFd/themes/admin/assets/js/components/comments/CommentBox.vue create mode 100644 tests/api/v1/test_comments.py diff --git a/CTFd/api/__init__.py b/CTFd/api/__init__.py index e53a0ac0..3c70f839 100644 --- a/CTFd/api/__init__.py +++ b/CTFd/api/__init__.py @@ -3,6 +3,7 @@ from flask_restx import Api from CTFd.api.v1.awards import awards_namespace from CTFd.api.v1.challenges import challenges_namespace +from CTFd.api.v1.comments import comments_namespace from CTFd.api.v1.config import configs_namespace from CTFd.api.v1.files import files_namespace from CTFd.api.v1.flags import flags_namespace @@ -48,3 +49,4 @@ CTFd_API_v1.add_namespace(configs_namespace, "/configs") CTFd_API_v1.add_namespace(pages_namespace, "/pages") CTFd_API_v1.add_namespace(unlocks_namespace, "/unlocks") CTFd_API_v1.add_namespace(tokens_namespace, "/tokens") +CTFd_API_v1.add_namespace(comments_namespace, "/comments") diff --git a/CTFd/api/v1/comments.py b/CTFd/api/v1/comments.py new file mode 100644 index 00000000..24b7db73 --- /dev/null +++ b/CTFd/api/v1/comments.py @@ -0,0 +1,141 @@ +from typing import List + +from flask import request, session +from flask_restx import Namespace, Resource + +from CTFd.api.v1.helpers.models import build_model_filters +from CTFd.api.v1.helpers.request import validate_args +from CTFd.api.v1.helpers.schemas import sqlalchemy_to_pydantic +from CTFd.api.v1.schemas import APIDetailedSuccessResponse, APIListSuccessResponse +from CTFd.constants import RawEnum +from CTFd.models import ( + ChallengeComments, + Comments, + PageComments, + TeamComments, + UserComments, + db, +) +from CTFd.schemas.comments import CommentSchema +from CTFd.utils.decorators import admins_only + +comments_namespace = Namespace("comments", description="Endpoint to retrieve Comments") + + +CommentModel = sqlalchemy_to_pydantic(Comments) + + +class CommentDetailedSuccessResponse(APIDetailedSuccessResponse): + data: CommentModel + + +class CommentListSuccessResponse(APIListSuccessResponse): + data: List[CommentModel] + + +comments_namespace.schema_model( + "CommentDetailedSuccessResponse", CommentDetailedSuccessResponse.apidoc() +) + +comments_namespace.schema_model( + "CommentListSuccessResponse", CommentListSuccessResponse.apidoc() +) + + +def get_comment_model(data): + model = Comments + if "challenge_id" in data: + model = ChallengeComments + elif "user_id" in data: + model = UserComments + elif "team_id" in data: + model = TeamComments + elif "page_id" in data: + model = PageComments + else: + model = Comments + return model + + +@comments_namespace.route("") +class CommentList(Resource): + @admins_only + @comments_namespace.doc( + description="Endpoint to list Comment objects in bulk", + responses={ + 200: ("Success", "CommentListSuccessResponse"), + 400: ( + "An error occured processing the provided or stored data", + "APISimpleErrorResponse", + ), + }, + ) + @validate_args( + { + "challenge_id": (int, None), + "user_id": (int, None), + "team_id": (int, None), + "page_id": (int, None), + "q": (str, None), + "field": (RawEnum("CommentFields", {"content": "content"}), None,), + }, + location="query", + ) + def get(self, query_args): + q = query_args.pop("q", None) + field = str(query_args.pop("field", None)) + CommentModel = get_comment_model(data=query_args) + filters = build_model_filters(model=CommentModel, query=q, field=field) + + comments = CommentModel.query.filter_by(**query_args).filter(*filters).all() + schema = CommentSchema(many=True) + response = schema.dump(comments) + + if response.errors: + return {"success": False, "errors": response.errors}, 400 + + return {"success": True, "data": response.data} + + @admins_only + @comments_namespace.doc( + description="Endpoint to create a Comment object", + responses={ + 200: ("Success", "CommentDetailedSuccessResponse"), + 400: ( + "An error occured processing the provided or stored data", + "APISimpleErrorResponse", + ), + }, + ) + def post(self): + req = request.get_json() + # Always force author IDs to be the actual user + req["author_id"] = session["id"] + CommentModel = get_comment_model(data=req) + + m = CommentModel(**req) + db.session.add(m) + db.session.commit() + + schema = CommentSchema() + + response = schema.dump(m) + db.session.close() + + return {"success": True, "data": response.data} + + +@comments_namespace.route("/") +class Comment(Resource): + @admins_only + @comments_namespace.doc( + description="Endpoint to delete a specific Comment object", + responses={200: ("Success", "APISimpleSuccessResponse")}, + ) + def delete(self, comment_id): + comment = Comments.query.filter_by(id=comment_id).first_or_404() + db.session.delete(comment) + db.session.commit() + db.session.close() + + return {"success": True} diff --git a/CTFd/models/__init__.py b/CTFd/models/__init__.py index b58aa7e0..af9b08bf 100644 --- a/CTFd/models/__init__.py +++ b/CTFd/models/__init__.py @@ -77,6 +77,7 @@ class Challenges(db.Model): tags = db.relationship("Tags", backref="challenge") hints = db.relationship("Hints", backref="challenge") flags = db.relationship("Flags", backref="challenge") + comments = db.relationship("ChallengeComments", backref="challenge") class alt_defaultdict(defaultdict): """ @@ -739,3 +740,44 @@ class Tokens(db.Model): class UserTokens(Tokens): __mapper_args__ = {"polymorphic_identity": "user"} + + +class Comments(db.Model): + __tablename__ = "comments" + id = db.Column(db.Integer, primary_key=True) + type = db.Column(db.String(80), default="standard") + content = db.Column(db.Text) + date = db.Column(db.DateTime, default=datetime.datetime.utcnow) + author_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE")) + author = db.relationship("Users", foreign_keys="Comments.author_id", lazy="select") + + @property + def html(self): + from CTFd.utils.config.pages import build_html + from CTFd.utils.helpers import markup + + return markup(build_html(self.content, sanitize=True)) + + __mapper_args__ = {"polymorphic_identity": "standard", "polymorphic_on": type} + + +class ChallengeComments(Comments): + __mapper_args__ = {"polymorphic_identity": "challenge"} + challenge_id = db.Column( + db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE") + ) + + +class UserComments(Comments): + __mapper_args__ = {"polymorphic_identity": "user"} + user_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE")) + + +class TeamComments(Comments): + __mapper_args__ = {"polymorphic_identity": "team"} + team_id = db.Column(db.Integer, db.ForeignKey("teams.id", ondelete="CASCADE")) + + +class PageComments(Comments): + __mapper_args__ = {"polymorphic_identity": "page"} + page_id = db.Column(db.Integer, db.ForeignKey("pages.id", ondelete="CASCADE")) diff --git a/CTFd/schemas/comments.py b/CTFd/schemas/comments.py new file mode 100644 index 00000000..d5ef43bf --- /dev/null +++ b/CTFd/schemas/comments.py @@ -0,0 +1,14 @@ +from marshmallow import fields + +from CTFd.models import Comments, ma +from CTFd.schemas.users import UserSchema + + +class CommentSchema(ma.ModelSchema): + class Meta: + model = Comments + include_fk = True + dump_only = ("id", "date", "html", "author", "author_id", "type") + + author = fields.Nested(UserSchema(only=("name",))) + html = fields.String() diff --git a/CTFd/themes/admin/assets/js/components/comments/CommentBox.vue b/CTFd/themes/admin/assets/js/components/comments/CommentBox.vue new file mode 100644 index 00000000..ef8ca5ff --- /dev/null +++ b/CTFd/themes/admin/assets/js/components/comments/CommentBox.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/CTFd/themes/admin/assets/js/pages/challenge.js b/CTFd/themes/admin/assets/js/pages/challenge.js index b9791602..20fbc596 100644 --- a/CTFd/themes/admin/assets/js/pages/challenge.js +++ b/CTFd/themes/admin/assets/js/pages/challenge.js @@ -10,6 +10,8 @@ import { addFile, deleteFile } from "../challenges/files"; import { addTag, deleteTag } from "../challenges/tags"; import { addRequirement, deleteRequirement } from "../challenges/requirements"; import { bindMarkdownEditors } from "../styles"; +import Vue from "vue/dist/vue.esm.browser"; +import CommentBox from "../components/comments/CommentBox.vue"; import { showHintModal, editHint, @@ -423,6 +425,14 @@ $(() => { $("#flags-create-select").change(flagTypeSelect); $(".edit-flag").click(editFlagModal); + // Insert CommentBox element + const commentBox = Vue.extend(CommentBox); + let vueContainer = document.createElement("div"); + document.querySelector("#comment-box").appendChild(vueContainer); + new commentBox({ + propsData: { type: "challenge", id: window.CHALLENGE_ID } + }).$mount(vueContainer); + $.get(CTFd.config.urlRoot + "/api/v1/challenges/types", function(response) { const data = response.data; loadChalTemplate(data["standard"]); diff --git a/CTFd/themes/admin/static/js/core.min.js b/CTFd/themes/admin/static/js/core.min.js index e69de29b..3a0dd9f4 100644 --- a/CTFd/themes/admin/static/js/core.min.js +++ b/CTFd/themes/admin/static/js/core.min.js @@ -0,0 +1,217 @@ +(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/components/files/MediaLibrary.vue": +/*!***********************************************************************!*\ + !*** ./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue ***! + \***********************************************************************/ +/*! no static exports found */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _MediaLibrary_vue_vue_type_template_id_50f8d42a___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MediaLibrary.vue?vue&type=template&id=50f8d42a& */ \"./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=template&id=50f8d42a&\");\n/* harmony import */ var _MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MediaLibrary.vue?vue&type=script&lang=js& */ \"./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=script&lang=js&\");\n/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__) if(__WEBPACK_IMPORT_KEY__ !== 'default') (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[key]; }) }(__WEBPACK_IMPORT_KEY__));\n/* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ \"./node_modules/vue-loader/lib/runtime/componentNormalizer.js\");\n\n\n\n\n\n/* normalize component */\n\nvar component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(\n _MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n _MediaLibrary_vue_vue_type_template_id_50f8d42a___WEBPACK_IMPORTED_MODULE_0__[\"render\"],\n _MediaLibrary_vue_vue_type_template_id_50f8d42a___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"],\n false,\n null,\n null,\n null\n \n)\n\n/* hot reload */\nif (false) { var api; }\ncomponent.options.__file = \"CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue\"\n/* harmony default export */ __webpack_exports__[\"default\"] = (component.exports);\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?"); + +/***/ }), + +/***/ "./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=script&lang=js&": +/*!************************************************************************************************!*\ + !*** ./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=script&lang=js& ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_0_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../../../node_modules/babel-loader/lib??ref--0!../../../../../../../node_modules/vue-loader/lib??vue-loader-options!./MediaLibrary.vue?vue&type=script&lang=js& */ \"./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=script&lang=js&\");\n/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_0_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_babel_loader_lib_index_js_ref_0_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__);\n/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _node_modules_babel_loader_lib_index_js_ref_0_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__) if(__WEBPACK_IMPORT_KEY__ !== 'default') (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _node_modules_babel_loader_lib_index_js_ref_0_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));\n /* harmony default export */ __webpack_exports__[\"default\"] = (_node_modules_babel_loader_lib_index_js_ref_0_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0___default.a); \n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?"); + +/***/ }), + +/***/ "./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=template&id=50f8d42a&": +/*!******************************************************************************************************!*\ + !*** ./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=template&id=50f8d42a& ***! + \******************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_template_id_50f8d42a___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../../../../node_modules/vue-loader/lib??vue-loader-options!./MediaLibrary.vue?vue&type=template&id=50f8d42a& */ \"./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=template&id=50f8d42a&\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_template_id_50f8d42a___WEBPACK_IMPORTED_MODULE_0__[\"render\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_MediaLibrary_vue_vue_type_template_id_50f8d42a___WEBPACK_IMPORTED_MODULE_0__[\"staticRenderFns\"]; });\n\n\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?"); + +/***/ }), + +/***/ "./CTFd/themes/admin/assets/js/pages/main.js": +/*!***************************************************!*\ + !*** ./CTFd/themes/admin/assets/js/pages/main.js ***! + \***************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\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 _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\n\nvar _nunjucks = _interopRequireDefault(__webpack_require__(/*! nunjucks */ \"./node_modules/nunjucks/browser/nunjucks.js\"));\n\nvar _howler = __webpack_require__(/*! howler */ \"./node_modules/howler/dist/howler.js\");\n\nvar _events = _interopRequireDefault(__webpack_require__(/*! core/events */ \"./CTFd/themes/core/assets/js/events.js\"));\n\nvar _times = _interopRequireDefault(__webpack_require__(/*! core/times */ \"./CTFd/themes/core/assets/js/times.js\"));\n\nvar _styles = _interopRequireDefault(__webpack_require__(/*! ../styles */ \"./CTFd/themes/admin/assets/js/styles.js\"));\n\nvar _helpers = _interopRequireDefault(__webpack_require__(/*! core/helpers */ \"./CTFd/themes/core/assets/js/helpers.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n_CTFd.default.init(window.init);\n\nwindow.CTFd = _CTFd.default;\nwindow.helpers = _helpers.default;\nwindow.$ = _jquery.default;\nwindow.Moment = _moment.default;\nwindow.nunjucks = _nunjucks.default;\nwindow.Howl = _howler.Howl;\n(0, _jquery.default)(function () {\n (0, _styles.default)();\n (0, _times.default)();\n (0, _events.default)(_CTFd.default.config.urlRoot);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/main.js?"); + +/***/ }), + +/***/ "./CTFd/themes/admin/assets/js/styles.js": +/*!***********************************************!*\ + !*** ./CTFd/themes/admin/assets/js/styles.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.showMediaLibrary = showMediaLibrary;\nexports.bindMarkdownEditors = bindMarkdownEditors;\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\nvar _easymde = _interopRequireDefault(__webpack_require__(/*! easymde */ \"./node_modules/easymde/src/js/easymde.js\"));\n\nvar _vueEsm = _interopRequireDefault(__webpack_require__(/*! vue/dist/vue.esm.browser */ \"./node_modules/vue/dist/vue.esm.browser.js\"));\n\nvar _MediaLibrary = _interopRequireDefault(__webpack_require__(/*! ./components/files/MediaLibrary.vue */ \"./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction showMediaLibrary(editor) {\n var mediaModal = _vueEsm.default.extend(_MediaLibrary.default); // Create an empty div and append it to our
\n\n\n var vueContainer = document.createElement(\"div\");\n document.querySelector(\"main\").appendChild(vueContainer); // Create MediaLibrary component and pass it our editor\n\n var m = new mediaModal({\n propsData: {\n editor: editor // Mount to the empty div\n\n }\n }).$mount(vueContainer); // Destroy the Vue instance and the media modal when closed\n\n (0, _jquery.default)(\"#media-modal\").on(\"hidden.bs.modal\", function (_e) {\n m.$destroy();\n (0, _jquery.default)(\"#media-modal\").remove();\n }); // Pop the Component modal\n\n (0, _jquery.default)(\"#media-modal\").modal();\n}\n\nfunction bindMarkdownEditors() {\n (0, _jquery.default)(\"textarea.markdown\").each(function (_i, e) {\n if (e.hasOwnProperty(\"mde\") === false) {\n var mde = new _easymde.default({\n autoDownloadFontAwesome: false,\n toolbar: [\"bold\", \"italic\", \"heading\", \"|\", \"quote\", \"unordered-list\", \"ordered-list\", \"|\", \"link\", \"image\", {\n name: \"media\",\n action: function action(editor) {\n showMediaLibrary(editor);\n },\n className: \"fas fa-file-upload\",\n title: \"Media Library\"\n }, \"|\", \"preview\", \"guide\"],\n element: this,\n initialValue: (0, _jquery.default)(this).val(),\n forceSync: true,\n minHeight: \"200px\"\n });\n this.mde = mde;\n this.codemirror = mde.codemirror;\n (0, _jquery.default)(this).on(\"change keyup paste\", function () {\n mde.codemirror.getDoc().setValue((0, _jquery.default)(this).val());\n mde.codemirror.refresh();\n });\n }\n });\n}\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)(function () {\n (0, _jquery.default)(\"tr[data-href], td[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, _jquery.default)(\".page-select\").change(function () {\n var url = new URL(window.location);\n url.searchParams.set(\"page\", this.value);\n window.location.href = url.toString();\n });\n (0, _jquery.default)('a[data-toggle=\"tab\"]').on(\"shown.bs.tab\", function (e) {\n sessionStorage.setItem(\"activeTab\", (0, _jquery.default)(e.target).attr(\"href\"));\n });\n var activeTab = sessionStorage.getItem(\"activeTab\");\n\n if (activeTab) {\n var target = (0, _jquery.default)(\".nav-tabs a[href=\\\"\".concat(activeTab, \"\\\"], .nav-pills a[href=\\\"\").concat(activeTab, \"\\\"]\"));\n\n if (target.length) {\n target.tab(\"show\");\n } else {\n sessionStorage.removeItem(\"activeTab\");\n }\n }\n\n bindMarkdownEditors();\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?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/CTFd.js": +/*!********************************************!*\ + !*** ./CTFd/themes/core/assets/js/CTFd.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _fetch = _interopRequireDefault(__webpack_require__(/*! ./fetch */ \"./CTFd/themes/core/assets/js/fetch.js\"));\n\nvar _config = _interopRequireDefault(__webpack_require__(/*! ./config */ \"./CTFd/themes/core/assets/js/config.js\"));\n\nvar _api = __webpack_require__(/*! ./api */ \"./CTFd/themes/core/assets/js/api.js\");\n\n__webpack_require__(/*! ./patch */ \"./CTFd/themes/core/assets/js/patch.js\");\n\nvar _markdownIt = _interopRequireDefault(__webpack_require__(/*! markdown-it */ \"./node_modules/markdown-it/index.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = _interopRequireDefault(__webpack_require__(/*! ./ezq */ \"./CTFd/themes/core/assets/js/ezq.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { if (i % 2) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } else { Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i])); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar api = new _api.API(\"/\");\nvar user = {};\nvar _internal = {};\nvar ui = {\n ezq: _ezq.default\n};\nvar lib = {\n $: _jquery.default,\n markdown: markdown\n};\nvar initialized = false;\n\nvar init = function init(data) {\n if (initialized) {\n return;\n }\n\n initialized = true;\n _config.default.urlRoot = data.urlRoot || _config.default.urlRoot;\n _config.default.csrfNonce = data.csrfNonce || _config.default.csrfNonce;\n _config.default.userMode = data.userMode || _config.default.userMode;\n api.domain = _config.default.urlRoot + \"/api/v1\";\n user.id = data.userId;\n};\n\nvar plugin = {\n run: function run(f) {\n f(CTFd);\n }\n};\n\nfunction markdown(config) {\n // Merge passed config with original. Default to original.\n var md_config = _objectSpread({}, {\n html: true,\n linkify: true\n }, {}, config);\n\n var md = (0, _markdownIt.default)(md_config);\n\n md.renderer.rules.link_open = function (tokens, idx, options, env, self) {\n tokens[idx].attrPush([\"target\", \"_blank\"]);\n return self.renderToken(tokens, idx, options);\n };\n\n return md;\n}\n\nvar CTFd = {\n init: init,\n config: _config.default,\n fetch: _fetch.default,\n user: user,\n ui: ui,\n api: api,\n lib: lib,\n _internal: _internal,\n plugin: plugin\n};\nvar _default = CTFd;\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/CTFd.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/api.js": +/*!*******************************************!*\ + !*** ./CTFd/themes/core/assets/js/api.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nvar _fetch = _interopRequireDefault(__webpack_require__(/*! ./fetch */ \"./CTFd/themes/core/assets/js/fetch.js\"));\n\nvar _q = _interopRequireDefault(__webpack_require__(/*! q */ \"./node_modules/q/q.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/**\n *\n * @class API\n * @param {(string|object)} [domainOrOptions] - The project domain or options object. If object, see the object's optional properties.\n * @param {string} [domainOrOptions.domain] - The project domain\n * @param {object} [domainOrOptions.token] - auth token - object with value property and optional headerOrQueryName and isQuery properties\n */\nvar API = function () {\n \"use strict\";\n\n function API(options) {\n var domain = _typeof(options) === \"object\" ? options.domain : options;\n this.domain = domain ? domain : \"\";\n\n if (this.domain.length === 0) {\n throw new Error(\"Domain parameter must be specified as a string.\");\n }\n }\n\n function serializeQueryParams(parameters) {\n var str = [];\n\n for (var p in parameters) {\n if (parameters.hasOwnProperty(p)) {\n str.push(encodeURIComponent(p) + \"=\" + encodeURIComponent(parameters[p]));\n }\n }\n\n return str.join(\"&\");\n }\n\n function mergeQueryParams(parameters, queryParameters) {\n if (parameters.$queryParameters) {\n Object.keys(parameters.$queryParameters).forEach(function (parameterName) {\n var parameter = parameters.$queryParameters[parameterName];\n queryParameters[parameterName] = parameter;\n });\n }\n\n return queryParameters;\n }\n /**\n * HTTP Request\n * @method\n * @name API#request\n * @param {string} method - http method\n * @param {string} url - url to do request\n * @param {object} parameters\n * @param {object} body - body parameters / object\n * @param {object} headers - header parameters\n * @param {object} queryParameters - querystring parameters\n * @param {object} form - form data object\n * @param {object} deferred - promise object\n */\n\n\n API.prototype.request = function (method, url, parameters, body, headers, queryParameters, form, deferred) {\n var queryParams = queryParameters && Object.keys(queryParameters).length ? serializeQueryParams(queryParameters) : null;\n var urlWithParams = url + (queryParams ? \"?\" + queryParams : \"\");\n\n if (body && !Object.keys(body).length) {\n body = undefined;\n }\n\n (0, _fetch.default)(urlWithParams, {\n method: method,\n headers: headers,\n body: JSON.stringify(body)\n }).then(function (response) {\n return response.json();\n }).then(function (body) {\n deferred.resolve(body);\n }).catch(function (error) {\n deferred.reject(error);\n });\n };\n /**\n *\n * @method\n * @name API#post_award_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_award_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/awards\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_award\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.awardId - An Award ID\n */\n\n\n API.prototype.delete_award = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/awards/{award_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{award_id}\", parameters[\"awardId\"]);\n\n if (parameters[\"awardId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: awardId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_award\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.awardId - An Award ID\n */\n\n\n API.prototype.get_award = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/awards/{award_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{award_id}\", parameters[\"awardId\"]);\n\n if (parameters[\"awardId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: awardId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_challenge_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_challenge_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_challenge_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_challenge_attempt\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_challenge_attempt = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/attempt\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_types\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_challenge_types = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/types\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_challenge\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.challengeId - A Challenge ID\n */\n\n\n API.prototype.patch_challenge = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_challenge\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.challengeId - A Challenge ID\n */\n\n\n API.prototype.delete_challenge = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.challengeId - A Challenge ID\n */\n\n\n API.prototype.get_challenge = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_files\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.id - A Challenge ID\n * @param {string} parameters.challengeId -\n */\n\n\n API.prototype.get_challenge_files = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}/files\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"id\"] !== undefined) {\n queryParameters[\"id\"] = parameters[\"id\"];\n }\n\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_flags\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.id - A Challenge ID\n * @param {string} parameters.challengeId -\n */\n\n\n API.prototype.get_challenge_flags = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}/flags\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"id\"] !== undefined) {\n queryParameters[\"id\"] = parameters[\"id\"];\n }\n\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_hints\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.id - A Challenge ID\n * @param {string} parameters.challengeId -\n */\n\n\n API.prototype.get_challenge_hints = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}/hints\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"id\"] !== undefined) {\n queryParameters[\"id\"] = parameters[\"id\"];\n }\n\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_solves\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.id - A Challenge ID\n * @param {string} parameters.challengeId -\n */\n\n\n API.prototype.get_challenge_solves = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}/solves\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"id\"] !== undefined) {\n queryParameters[\"id\"] = parameters[\"id\"];\n }\n\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_tags\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.id - A Challenge ID\n * @param {string} parameters.challengeId -\n */\n\n\n API.prototype.get_challenge_tags = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/{challenge_id}/tags\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"id\"] !== undefined) {\n queryParameters[\"id\"] = parameters[\"id\"];\n }\n\n path = path.replace(\"{challenge_id}\", parameters[\"challengeId\"]);\n\n if (parameters[\"challengeId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: challengeId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_config_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_config_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_config_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.patch_config_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_config_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_config_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_config\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.configKey -\n */\n\n\n API.prototype.patch_config = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs/{config_key}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{config_key}\", parameters[\"configKey\"]);\n\n if (parameters[\"configKey\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: configKey\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_config\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.configKey -\n */\n\n\n API.prototype.delete_config = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs/{config_key}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{config_key}\", parameters[\"configKey\"]);\n\n if (parameters[\"configKey\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: configKey\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_config\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.configKey -\n */\n\n\n API.prototype.get_config = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs/{config_key}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{config_key}\", parameters[\"configKey\"]);\n\n if (parameters[\"configKey\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: configKey\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_files_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_files_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/files\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_files_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_files_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/files\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_files_detail\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.fileId -\n */\n\n\n API.prototype.delete_files_detail = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/files/{file_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{file_id}\", parameters[\"fileId\"]);\n\n if (parameters[\"fileId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: fileId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_files_detail\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.fileId -\n */\n\n\n API.prototype.get_files_detail = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/files/{file_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{file_id}\", parameters[\"fileId\"]);\n\n if (parameters[\"fileId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: fileId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_flag_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_flag_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_flag_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_flag_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_flag_types\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_flag_types = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags/types\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_flag_types_1\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.typeName -\n */\n\n\n API.prototype.get_flag_types_1 = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags/types/{type_name}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{type_name}\", parameters[\"typeName\"]);\n\n if (parameters[\"typeName\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: typeName\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_flag\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.flagId -\n */\n\n\n API.prototype.patch_flag = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags/{flag_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{flag_id}\", parameters[\"flagId\"]);\n\n if (parameters[\"flagId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: flagId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_flag\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.flagId -\n */\n\n\n API.prototype.delete_flag = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags/{flag_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{flag_id}\", parameters[\"flagId\"]);\n\n if (parameters[\"flagId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: flagId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_flag\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.flagId -\n */\n\n\n API.prototype.get_flag = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/flags/{flag_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{flag_id}\", parameters[\"flagId\"]);\n\n if (parameters[\"flagId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: flagId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_hint_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_hint_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/hints\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_hint_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_hint_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/hints\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_hint\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.hintId -\n */\n\n\n API.prototype.patch_hint = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/hints/{hint_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{hint_id}\", parameters[\"hintId\"]);\n\n if (parameters[\"hintId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: hintId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_hint\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.hintId -\n */\n\n\n API.prototype.delete_hint = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/hints/{hint_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{hint_id}\", parameters[\"hintId\"]);\n\n if (parameters[\"hintId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: hintId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_hint\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.hintId -\n */\n\n\n API.prototype.get_hint = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/hints/{hint_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{hint_id}\", parameters[\"hintId\"]);\n\n if (parameters[\"hintId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: hintId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_notification_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_notification_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/notifications\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_notification_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_notification_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/notifications\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_notification\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.notificationId - A Notification ID\n */\n\n\n API.prototype.delete_notification = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/notifications/{notification_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{notification_id}\", parameters[\"notificationId\"]);\n\n if (parameters[\"notificationId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: notificationId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_notification\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.notificationId - A Notification ID\n */\n\n\n API.prototype.get_notification = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/notifications/{notification_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{notification_id}\", parameters[\"notificationId\"]);\n\n if (parameters[\"notificationId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: notificationId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_page_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_page_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/pages\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_page_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_page_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/pages\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_page_detail\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.pageId -\n */\n\n\n API.prototype.patch_page_detail = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/pages/{page_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{page_id}\", parameters[\"pageId\"]);\n\n if (parameters[\"pageId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: pageId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_page_detail\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.pageId -\n */\n\n\n API.prototype.delete_page_detail = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/pages/{page_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{page_id}\", parameters[\"pageId\"]);\n\n if (parameters[\"pageId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: pageId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_page_detail\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.pageId -\n */\n\n\n API.prototype.get_page_detail = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/pages/{page_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{page_id}\", parameters[\"pageId\"]);\n\n if (parameters[\"pageId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: pageId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_scoreboard_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_scoreboard_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/scoreboard\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_scoreboard_detail\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.count - How many top teams to return\n */\n\n\n API.prototype.get_scoreboard_detail = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/scoreboard/top/{count}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{count}\", parameters[\"count\"]);\n\n if (parameters[\"count\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: count\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_solve_statistics\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_challenge_solve_statistics = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/challenges/solves\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_solve_percentages\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_challenge_solve_percentages = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/challenges/solves/percentages\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_challenge_property_counts\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.column -\n */\n\n\n API.prototype.get_challenge_property_counts = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/challenges/{column}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{column}\", parameters[\"column\"]);\n\n if (parameters[\"column\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: column\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_submission_property_counts\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.column -\n */\n\n\n API.prototype.get_submission_property_counts = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/submissions/{column}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{column}\", parameters[\"column\"]);\n\n if (parameters[\"column\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: column\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_statistics\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_team_statistics = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/teams\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_statistics\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_user_statistics = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/users\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_property_counts\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.column -\n */\n\n\n API.prototype.get_user_property_counts = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/statistics/users/{column}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{column}\", parameters[\"column\"]);\n\n if (parameters[\"column\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: column\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_submissions_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_submissions_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/submissions\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_submissions_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_submissions_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/submissions\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_submission\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.submissionId - A Submission ID\n */\n\n\n API.prototype.delete_submission = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/submissions/{submission_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{submission_id}\", parameters[\"submissionId\"]);\n\n if (parameters[\"submissionId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: submissionId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_submission\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.submissionId - A Submission ID\n */\n\n\n API.prototype.get_submission = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/submissions/{submission_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{submission_id}\", parameters[\"submissionId\"]);\n\n if (parameters[\"submissionId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: submissionId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_tag_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_tag_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/tags\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_tag_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_tag_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/tags\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_tag\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.tagId - A Tag ID\n */\n\n\n API.prototype.patch_tag = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/tags/{tag_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{tag_id}\", parameters[\"tagId\"]);\n\n if (parameters[\"tagId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: tagId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_tag\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.tagId - A Tag ID\n */\n\n\n API.prototype.delete_tag = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/tags/{tag_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{tag_id}\", parameters[\"tagId\"]);\n\n if (parameters[\"tagId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: tagId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_tag\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.tagId - A Tag ID\n */\n\n\n API.prototype.get_tag = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/tags/{tag_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{tag_id}\", parameters[\"tagId\"]);\n\n if (parameters[\"tagId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: tagId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_team_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_team_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_team_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_team_private\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Current Team\n */\n\n\n API.prototype.patch_team_private = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/me\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"teamId\"] !== undefined) {\n queryParameters[\"team_id\"] = parameters[\"teamId\"];\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_private\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Current Team\n */\n\n\n API.prototype.get_team_private = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/me\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n\n if (parameters[\"teamId\"] !== undefined) {\n queryParameters[\"team_id\"] = parameters[\"teamId\"];\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_team_public\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Team ID\n */\n\n\n API.prototype.patch_team_public = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_team_public\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Team ID\n */\n\n\n API.prototype.delete_team_public = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_public\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Team ID\n */\n\n\n API.prototype.get_team_public = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_awards\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Team ID or 'me'\n */\n\n\n API.prototype.get_team_awards = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}/awards\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_fails\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Team ID or 'me'\n */\n\n\n API.prototype.get_team_fails = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}/fails\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_team_solves\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.teamId - Team ID or 'me'\n */\n\n\n API.prototype.get_team_solves = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}/solves\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_unlock_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_unlock_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/unlocks\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_unlock_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_unlock_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/unlocks\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#post_user_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.post_user_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_list\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_user_list = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_user_private\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.patch_user_private = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/me\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_private\n * @param {object} parameters - method options and parameters\n */\n\n\n API.prototype.get_user_private = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/me\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#patch_user_public\n * @param {object} parameters - method options and parameters\n * @param {integer} parameters.userId - User ID\n */\n\n\n API.prototype.patch_user_public = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#delete_user_public\n * @param {object} parameters - method options and parameters\n * @param {integer} parameters.userId - User ID\n */\n\n\n API.prototype.delete_user_public = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"DELETE\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_public\n * @param {object} parameters - method options and parameters\n * @param {integer} parameters.userId - User ID\n */\n\n\n API.prototype.get_user_public = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_awards\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.userId - User ID or 'me'\n */\n\n\n API.prototype.get_user_awards = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}/awards\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_fails\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.userId - User ID or 'me'\n */\n\n\n API.prototype.get_user_fails = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}/fails\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n /**\n *\n * @method\n * @name API#get_user_solves\n * @param {object} parameters - method options and parameters\n * @param {string} parameters.userId - User ID or 'me'\n */\n\n\n API.prototype.get_user_solves = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}/solves\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n };\n\n return API;\n}(); // eslint-disable-next-line no-undef\n\n\nexports.API = API;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/api.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/config.js": +/*!**********************************************!*\ + !*** ./CTFd/themes/core/assets/js/config.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar _default = {\n urlRoot: \"\",\n csrfNonce: \"\",\n userMode: \"\"\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/config.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/events.js": +/*!**********************************************!*\ + !*** ./CTFd/themes/core/assets/js/events.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _howler = __webpack_require__(/*! howler */ \"./node_modules/howler/dist/howler.js\");\n\nvar _eventSourcePolyfill = __webpack_require__(/*! event-source-polyfill */ \"./node_modules/event-source-polyfill/src/eventsource.js\");\n\nvar _ezq = __webpack_require__(/*! ./ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _utils = __webpack_require__(/*! ./utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar EventSource = _eventSourcePolyfill.NativeEventSource || _eventSourcePolyfill.EventSourcePolyfill;\n\nvar _default = function _default(root) {\n var source = new EventSource(root + \"/events\");\n var wc = new _utils.WindowController();\n var howl = new _howler.Howl({\n src: [root + \"/themes/core/static/sounds/notification.webm\", root + \"/themes/core/static/sounds/notification.mp3\"]\n });\n (0, _utils.init_notification_counter)();\n\n function connect() {\n source.addEventListener(\"notification\", function (event) {\n var data = JSON.parse(event.data);\n wc.broadcast(\"notification\", data);\n render(data);\n }, false);\n }\n\n function disconnect() {\n if (source) {\n source.close();\n }\n }\n\n function render(data) {\n switch (data.type) {\n case \"toast\":\n {\n (0, _utils.inc_notification_counter)(); // Trim toast body to length\n\n var length = 50;\n var trimmed_content = data.content.length > length ? data.content.substring(0, length - 3) + \"...\" : data.content;\n var clicked = false;\n (0, _ezq.ezToast)({\n title: data.title,\n body: trimmed_content,\n onclick: function onclick() {\n (0, _ezq.ezAlert)({\n title: data.title,\n body: data.content,\n button: \"Got it!\",\n success: function success() {\n clicked = true;\n (0, _utils.dec_notification_counter)();\n }\n });\n },\n onclose: function onclose() {\n if (!clicked) {\n (0, _utils.dec_notification_counter)();\n }\n }\n });\n break;\n }\n\n case \"alert\":\n {\n (0, _utils.inc_notification_counter)();\n (0, _ezq.ezAlert)({\n title: data.title,\n body: data.content,\n button: \"Got it!\",\n success: function success() {\n (0, _utils.dec_notification_counter)();\n }\n });\n break;\n }\n\n case \"background\":\n {\n (0, _utils.inc_notification_counter)();\n break;\n }\n\n default:\n {\n (0, _utils.inc_notification_counter)();\n break;\n }\n }\n\n if (data.sound) {\n howl.play();\n }\n }\n\n wc.notification = function (data) {\n render(data);\n };\n\n wc.masterDidChange = function () {\n if (this.isMaster) {\n connect();\n } else {\n disconnect();\n }\n };\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/events.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/ezq.js": +/*!*******************************************!*\ + !*** ./CTFd/themes/core/assets/js/ezq.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ezAlert = ezAlert;\nexports.ezToast = ezToast;\nexports.ezQuery = ezQuery;\nexports.ezProgressBar = ezProgressBar;\nexports.ezBadge = ezBadge;\nexports.default = void 0;\n\n__webpack_require__(/*! bootstrap/js/dist/modal */ \"./node_modules/bootstrap/js/dist/modal.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 modalTpl = '
' + '
' + '
' + '
' + '
{0}
' + ' \" + \"
\" + '
' + \"
\" + '
' + \"
\" + \"
\" + \"
\" + \"
\";\nvar toastTpl = '
' + '
' + ' {0}' + ' \" + \"
\" + '
{1}
' + \"
\";\nvar progressTpl = '
' + '
' + \"
\" + \"
\";\nvar errorTpl = '
\\n' + ' Error:\\n' + \" {0}\\n\" + ' \\n' + \"
\";\nvar successTpl = '
\\n' + \" Success!\\n\" + \" {0}\\n\" + ' \\n' + \"
\";\nvar buttonTpl = '';\nvar noTpl = '';\nvar yesTpl = '';\n\nfunction ezAlert(args) {\n var modal = modalTpl.format(args.title);\n var obj = (0, _jquery.default)(modal);\n\n if (typeof args.body === \"string\") {\n obj.find(\".modal-body\").append(\"

\".concat(args.body, \"

\"));\n } else {\n obj.find(\".modal-body\").append((0, _jquery.default)(args.body));\n }\n\n var button = (0, _jquery.default)(buttonTpl.format(args.button));\n\n if (args.success) {\n (0, _jquery.default)(button).click(function () {\n args.success();\n });\n }\n\n if (args.large) {\n obj.find(\".modal-dialog\").addClass(\"modal-lg\");\n }\n\n obj.find(\".modal-footer\").append(button);\n (0, _jquery.default)(\"main\").append(obj);\n obj.modal(\"show\");\n (0, _jquery.default)(obj).on(\"hidden.bs.modal\", function () {\n (0, _jquery.default)(this).modal(\"dispose\");\n });\n return obj;\n}\n\nfunction ezToast(args) {\n var container_available = (0, _jquery.default)(\"#ezq--notifications-toast-container\").length;\n\n if (!container_available) {\n (0, _jquery.default)(\"body\").append((0, _jquery.default)(\"
\").attr({\n id: \"ezq--notifications-toast-container\"\n }).css({\n position: \"fixed\",\n bottom: \"0\",\n right: \"0\",\n \"min-width\": \"20%\"\n }));\n }\n\n var res = toastTpl.format(args.title, args.body);\n var obj = (0, _jquery.default)(res);\n\n if (args.onclose) {\n (0, _jquery.default)(obj).find(\"button[data-dismiss=toast]\").click(function () {\n args.onclose();\n });\n }\n\n if (args.onclick) {\n var body = (0, _jquery.default)(obj).find(\".toast-body\");\n body.addClass(\"cursor-pointer\");\n body.click(function () {\n args.onclick();\n });\n }\n\n var autohide = args.autohide !== false;\n var animation = args.animation !== false;\n var delay = args.delay || 10000; // 10 seconds\n\n (0, _jquery.default)(\"#ezq--notifications-toast-container\").prepend(obj);\n obj.toast({\n autohide: autohide,\n delay: delay,\n animation: animation\n });\n obj.toast(\"show\");\n return obj;\n}\n\nfunction ezQuery(args) {\n var modal = modalTpl.format(args.title);\n var obj = (0, _jquery.default)(modal);\n\n if (typeof args.body === \"string\") {\n obj.find(\".modal-body\").append(\"

\".concat(args.body, \"

\"));\n } else {\n obj.find(\".modal-body\").append((0, _jquery.default)(args.body));\n }\n\n var yes = (0, _jquery.default)(yesTpl);\n var no = (0, _jquery.default)(noTpl);\n obj.find(\".modal-footer\").append(no);\n obj.find(\".modal-footer\").append(yes);\n (0, _jquery.default)(\"main\").append(obj);\n (0, _jquery.default)(obj).on(\"hidden.bs.modal\", function () {\n (0, _jquery.default)(this).modal(\"dispose\");\n });\n (0, _jquery.default)(yes).click(function () {\n args.success();\n });\n obj.modal(\"show\");\n return obj;\n}\n\nfunction ezProgressBar(args) {\n if (args.target) {\n var _obj = (0, _jquery.default)(args.target);\n\n var pbar = _obj.find(\".progress-bar\");\n\n pbar.css(\"width\", args.width + \"%\");\n return _obj;\n }\n\n var progress = progressTpl.format(args.width);\n var modal = modalTpl.format(args.title);\n var obj = (0, _jquery.default)(modal);\n obj.find(\".modal-body\").append((0, _jquery.default)(progress));\n (0, _jquery.default)(\"main\").append(obj);\n return obj.modal(\"show\");\n}\n\nfunction ezBadge(args) {\n var mapping = {\n success: successTpl,\n error: errorTpl\n };\n var tpl = mapping[args.type].format(args.body);\n return (0, _jquery.default)(tpl);\n}\n\nvar ezq = {\n ezAlert: ezAlert,\n ezToast: ezToast,\n ezQuery: ezQuery,\n ezProgressBar: ezProgressBar,\n ezBadge: ezBadge\n};\nvar _default = ezq;\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/ezq.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/fetch.js": +/*!*********************************************!*\ + !*** ./CTFd/themes/core/assets/js/fetch.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n__webpack_require__(/*! whatwg-fetch */ \"./node_modules/whatwg-fetch/fetch.js\");\n\nvar _config = _interopRequireDefault(__webpack_require__(/*! ./config */ \"./CTFd/themes/core/assets/js/config.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar fetch = window.fetch;\n\nvar _default = function _default(url, options) {\n if (options === undefined) {\n options = {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: {}\n };\n }\n\n url = _config.default.urlRoot + url;\n\n if (options.headers === undefined) {\n options.headers = {};\n }\n\n options.credentials = \"same-origin\";\n options.headers[\"Accept\"] = \"application/json\";\n options.headers[\"Content-Type\"] = \"application/json\";\n options.headers[\"CSRF-Token\"] = _config.default.csrfNonce;\n return fetch(url, options);\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/fetch.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/patch.js": +/*!*********************************************!*\ + !*** ./CTFd/themes/core/assets/js/patch.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nvar _q = _interopRequireDefault(__webpack_require__(/*! q */ \"./node_modules/q/q.js\"));\n\nvar _api = __webpack_require__(/*! ./api */ \"./CTFd/themes/core/assets/js/api.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { if (i % 2) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } else { Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i])); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction mergeQueryParams(parameters, queryParameters) {\n return _objectSpread({}, parameters, {}, queryParameters);\n}\n\nfunction serializeQueryParams(parameters) {\n var str = [];\n\n for (var p in parameters) {\n if (parameters.hasOwnProperty(p)) {\n str.push(encodeURIComponent(p) + \"=\" + encodeURIComponent(parameters[p]));\n }\n }\n\n return str.join(\"&\");\n}\n\n_api.API.prototype.requestRaw = function (method, url, parameters, body, headers, queryParameters, form, deferred) {\n var queryParams = queryParameters && Object.keys(queryParameters).length ? serializeQueryParams(queryParameters) : null;\n var urlWithParams = url + (queryParams ? \"?\" + queryParams : \"\");\n\n if (body && !Object.keys(body).length) {\n body = undefined;\n }\n\n fetch(urlWithParams, {\n method: method,\n headers: headers,\n body: body\n }).then(function (response) {\n return response.json();\n }).then(function (body) {\n deferred.resolve(body);\n }).catch(function (error) {\n deferred.reject(error);\n });\n};\n\n_api.API.prototype.patch_user_public = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/{user_id}\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{user_id}\", parameters[\"userId\"]);\n\n if (parameters[\"userId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: userId\"));\n return deferred.promise;\n }\n\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.patch_user_private = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/users/me\";\n var headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n this.request(\"PATCH\", domain + path, parameters, body, headers, {}, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.post_unlock_list = function (parameters, body) {\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/unlocks\";\n var headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n this.request(\"POST\", domain + path, parameters, body, headers, {}, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.post_notification_list = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/notifications\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.post_files_list = function (parameters, body) {\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/files\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n this.requestRaw(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.patch_config = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs/{config_key}\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{config_key}\", parameters[\"configKey\"]);\n\n if (parameters[\"configKey\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: configKey\"));\n return deferred.promise;\n }\n\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.patch_config_list = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/configs\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.post_tag_list = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/tags\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.patch_team_public = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/teams/{team_id}\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{team_id}\", parameters[\"teamId\"]);\n\n if (parameters[\"teamId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: teamId\"));\n return deferred.promise;\n }\n\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"PATCH\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.post_challenge_attempt = function (parameters, body) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/challenges/attempt\";\n var queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"POST\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n_api.API.prototype.get_hint = function (parameters) {\n if (parameters === undefined) {\n parameters = {};\n }\n\n var deferred = _q.default.defer();\n\n var domain = this.domain,\n path = \"/hints/{hint_id}\";\n var body = {},\n queryParameters = {},\n headers = {},\n form = {};\n headers[\"Accept\"] = [\"application/json\"];\n headers[\"Content-Type\"] = [\"application/json\"];\n path = path.replace(\"{hint_id}\", parameters[\"hintId\"]);\n\n if (parameters[\"hintId\"] === undefined) {\n deferred.reject(new Error(\"Missing required parameter: hintId\"));\n return deferred.promise;\n }\n\n delete parameters[\"hintId\"];\n queryParameters = mergeQueryParams(parameters, queryParameters);\n this.request(\"GET\", domain + path, parameters, body, headers, queryParameters, form, deferred);\n return deferred.promise;\n};\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/patch.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/times.js": +/*!*********************************************!*\ + !*** ./CTFd/themes/core/assets/js/times.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.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 (0, _jquery.default)(\"[data-time]\").each(function (i, elem) {\n elem.innerText = (0, _moment.default)((0, _jquery.default)(elem).data(\"time\")).local().format(\"MMMM Do, h:mm:ss A\");\n });\n};\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/times.js?"); + +/***/ }), + +/***/ "./CTFd/themes/core/assets/js/utils.js": +/*!*********************************************!*\ + !*** ./CTFd/themes/core/assets/js/utils.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (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;\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) {// Ignore error\n }\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 // eslint-disable-next-line no-console\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 * 4 & 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?"); + +/***/ }), + +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=script&lang=js&": +/*!******************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--0!./node_modules/vue-loader/lib??vue-loader-options!./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=script&lang=js& ***! + \******************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _helpers = _interopRequireDefault(__webpack_require__(/*! core/helpers */ \"./CTFd/themes/core/assets/js/helpers.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\nfunction get_page_files() {\n return _CTFd.default.fetch(\"/api/v1/files?type=page\", {\n credentials: \"same-origin\"\n }).then(function (response) {\n return response.json();\n });\n}\n\nvar _default = {\n props: {\n editor: Object\n },\n data: function data() {\n return {\n files: [],\n selectedFile: null\n };\n },\n methods: {\n getPageFiles: function getPageFiles() {\n var _this = this;\n\n get_page_files().then(function (response) {\n _this.files = response.data;\n return _this.files;\n });\n },\n uploadChosenFiles: function uploadChosenFiles() {\n var _this2 = this;\n\n // TODO: We should reduce the need to interact with the DOM directly.\n // This looks jank and we should be able to remove it.\n var form = document.querySelector(\"#media-library-upload\");\n\n _helpers.default.files.upload(form, {}, function (_data) {\n _this2.getPageFiles();\n });\n },\n selectFile: function selectFile(file) {\n this.selectedFile = file;\n return this.selectedFile;\n },\n buildSelectedFileUrl: function buildSelectedFileUrl() {\n return _CTFd.default.config.urlRoot + \"/files/\" + this.selectedFile.location;\n },\n deleteSelectedFile: function deleteSelectedFile() {\n var _this3 = this;\n\n var file_id = this.selectedFile.id;\n\n if (confirm(\"Are you sure you want to delete this file?\")) {\n _CTFd.default.fetch(\"/api/v1/files/\" + file_id, {\n method: \"DELETE\"\n }).then(function (response) {\n if (response.status === 200) {\n response.json().then(function (object) {\n if (object.success) {\n _this3.getPageFiles();\n\n _this3.selectedFile = null;\n }\n });\n }\n });\n }\n },\n insertSelectedFile: function insertSelectedFile() {\n var editor = this.$props.editor;\n\n if (editor.hasOwnProperty(\"codemirror\")) {\n editor = editor.codemirror;\n }\n\n var doc = editor.getDoc();\n var cursor = doc.getCursor();\n var url = this.buildSelectedFileUrl();\n var img = this.getIconClass(this.selectedFile.location) === \"far fa-file-image\";\n var filename = url.split(\"/\").pop();\n link = \"[{0}]({1})\".format(filename, url);\n\n if (img) {\n link = \"!\" + link;\n }\n\n doc.replaceRange(link, cursor);\n },\n downloadSelectedFile: function downloadSelectedFile() {\n var link = this.buildSelectedFileUrl();\n window.open(link, \"_blank\");\n },\n getIconClass: function getIconClass(filename) {\n var mapping = {\n // Image Files\n png: \"far fa-file-image\",\n jpg: \"far fa-file-image\",\n jpeg: \"far fa-file-image\",\n gif: \"far fa-file-image\",\n bmp: \"far fa-file-image\",\n svg: \"far fa-file-image\",\n // Text Files\n txt: \"far fa-file-alt\",\n // Video Files\n mov: \"far fa-file-video\",\n mp4: \"far fa-file-video\",\n wmv: \"far fa-file-video\",\n flv: \"far fa-file-video\",\n mkv: \"far fa-file-video\",\n avi: \"far fa-file-video\",\n // PDF Files\n pdf: \"far fa-file-pdf\",\n // Audio Files\n mp3: \"far fa-file-sound\",\n wav: \"far fa-file-sound\",\n aac: \"far fa-file-sound\",\n // Archive Files\n zip: \"far fa-file-archive\",\n gz: \"far fa-file-archive\",\n tar: \"far fa-file-archive\",\n \"7z\": \"far fa-file-archive\",\n rar: \"far fa-file-archive\",\n // Code Files\n py: \"far fa-file-code\",\n c: \"far fa-file-code\",\n cpp: \"far fa-file-code\",\n html: \"far fa-file-code\",\n js: \"far fa-file-code\",\n rb: \"far fa-file-code\",\n go: \"far fa-file-code\"\n };\n var ext = filename.split(\".\").pop();\n return mapping[ext] || \"far fa-file\";\n }\n },\n created: function created() {\n return this.getPageFiles();\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?./node_modules/babel-loader/lib??ref--0!./node_modules/vue-loader/lib??vue-loader-options"); + +/***/ }), + +/***/ "./node_modules/moment/locale sync recursive ^\\.\\/.*$": +/*!**************************************************!*\ + !*** ./node_modules/moment/locale sync ^\.\/.*$ ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var map = {\n\t\"./af\": \"./node_modules/moment/locale/af.js\",\n\t\"./af.js\": \"./node_modules/moment/locale/af.js\",\n\t\"./ar\": \"./node_modules/moment/locale/ar.js\",\n\t\"./ar-dz\": \"./node_modules/moment/locale/ar-dz.js\",\n\t\"./ar-dz.js\": \"./node_modules/moment/locale/ar-dz.js\",\n\t\"./ar-kw\": \"./node_modules/moment/locale/ar-kw.js\",\n\t\"./ar-kw.js\": \"./node_modules/moment/locale/ar-kw.js\",\n\t\"./ar-ly\": \"./node_modules/moment/locale/ar-ly.js\",\n\t\"./ar-ly.js\": \"./node_modules/moment/locale/ar-ly.js\",\n\t\"./ar-ma\": \"./node_modules/moment/locale/ar-ma.js\",\n\t\"./ar-ma.js\": \"./node_modules/moment/locale/ar-ma.js\",\n\t\"./ar-sa\": \"./node_modules/moment/locale/ar-sa.js\",\n\t\"./ar-sa.js\": \"./node_modules/moment/locale/ar-sa.js\",\n\t\"./ar-tn\": \"./node_modules/moment/locale/ar-tn.js\",\n\t\"./ar-tn.js\": \"./node_modules/moment/locale/ar-tn.js\",\n\t\"./ar.js\": \"./node_modules/moment/locale/ar.js\",\n\t\"./az\": \"./node_modules/moment/locale/az.js\",\n\t\"./az.js\": \"./node_modules/moment/locale/az.js\",\n\t\"./be\": \"./node_modules/moment/locale/be.js\",\n\t\"./be.js\": \"./node_modules/moment/locale/be.js\",\n\t\"./bg\": \"./node_modules/moment/locale/bg.js\",\n\t\"./bg.js\": \"./node_modules/moment/locale/bg.js\",\n\t\"./bm\": \"./node_modules/moment/locale/bm.js\",\n\t\"./bm.js\": \"./node_modules/moment/locale/bm.js\",\n\t\"./bn\": \"./node_modules/moment/locale/bn.js\",\n\t\"./bn.js\": \"./node_modules/moment/locale/bn.js\",\n\t\"./bo\": \"./node_modules/moment/locale/bo.js\",\n\t\"./bo.js\": \"./node_modules/moment/locale/bo.js\",\n\t\"./br\": \"./node_modules/moment/locale/br.js\",\n\t\"./br.js\": \"./node_modules/moment/locale/br.js\",\n\t\"./bs\": \"./node_modules/moment/locale/bs.js\",\n\t\"./bs.js\": \"./node_modules/moment/locale/bs.js\",\n\t\"./ca\": \"./node_modules/moment/locale/ca.js\",\n\t\"./ca.js\": \"./node_modules/moment/locale/ca.js\",\n\t\"./cs\": \"./node_modules/moment/locale/cs.js\",\n\t\"./cs.js\": \"./node_modules/moment/locale/cs.js\",\n\t\"./cv\": \"./node_modules/moment/locale/cv.js\",\n\t\"./cv.js\": \"./node_modules/moment/locale/cv.js\",\n\t\"./cy\": \"./node_modules/moment/locale/cy.js\",\n\t\"./cy.js\": \"./node_modules/moment/locale/cy.js\",\n\t\"./da\": \"./node_modules/moment/locale/da.js\",\n\t\"./da.js\": \"./node_modules/moment/locale/da.js\",\n\t\"./de\": \"./node_modules/moment/locale/de.js\",\n\t\"./de-at\": \"./node_modules/moment/locale/de-at.js\",\n\t\"./de-at.js\": \"./node_modules/moment/locale/de-at.js\",\n\t\"./de-ch\": \"./node_modules/moment/locale/de-ch.js\",\n\t\"./de-ch.js\": \"./node_modules/moment/locale/de-ch.js\",\n\t\"./de.js\": \"./node_modules/moment/locale/de.js\",\n\t\"./dv\": \"./node_modules/moment/locale/dv.js\",\n\t\"./dv.js\": \"./node_modules/moment/locale/dv.js\",\n\t\"./el\": \"./node_modules/moment/locale/el.js\",\n\t\"./el.js\": \"./node_modules/moment/locale/el.js\",\n\t\"./en-SG\": \"./node_modules/moment/locale/en-SG.js\",\n\t\"./en-SG.js\": \"./node_modules/moment/locale/en-SG.js\",\n\t\"./en-au\": \"./node_modules/moment/locale/en-au.js\",\n\t\"./en-au.js\": \"./node_modules/moment/locale/en-au.js\",\n\t\"./en-ca\": \"./node_modules/moment/locale/en-ca.js\",\n\t\"./en-ca.js\": \"./node_modules/moment/locale/en-ca.js\",\n\t\"./en-gb\": \"./node_modules/moment/locale/en-gb.js\",\n\t\"./en-gb.js\": \"./node_modules/moment/locale/en-gb.js\",\n\t\"./en-ie\": \"./node_modules/moment/locale/en-ie.js\",\n\t\"./en-ie.js\": \"./node_modules/moment/locale/en-ie.js\",\n\t\"./en-il\": \"./node_modules/moment/locale/en-il.js\",\n\t\"./en-il.js\": \"./node_modules/moment/locale/en-il.js\",\n\t\"./en-nz\": \"./node_modules/moment/locale/en-nz.js\",\n\t\"./en-nz.js\": \"./node_modules/moment/locale/en-nz.js\",\n\t\"./eo\": \"./node_modules/moment/locale/eo.js\",\n\t\"./eo.js\": \"./node_modules/moment/locale/eo.js\",\n\t\"./es\": \"./node_modules/moment/locale/es.js\",\n\t\"./es-do\": \"./node_modules/moment/locale/es-do.js\",\n\t\"./es-do.js\": \"./node_modules/moment/locale/es-do.js\",\n\t\"./es-us\": \"./node_modules/moment/locale/es-us.js\",\n\t\"./es-us.js\": \"./node_modules/moment/locale/es-us.js\",\n\t\"./es.js\": \"./node_modules/moment/locale/es.js\",\n\t\"./et\": \"./node_modules/moment/locale/et.js\",\n\t\"./et.js\": \"./node_modules/moment/locale/et.js\",\n\t\"./eu\": \"./node_modules/moment/locale/eu.js\",\n\t\"./eu.js\": \"./node_modules/moment/locale/eu.js\",\n\t\"./fa\": \"./node_modules/moment/locale/fa.js\",\n\t\"./fa.js\": \"./node_modules/moment/locale/fa.js\",\n\t\"./fi\": \"./node_modules/moment/locale/fi.js\",\n\t\"./fi.js\": \"./node_modules/moment/locale/fi.js\",\n\t\"./fo\": \"./node_modules/moment/locale/fo.js\",\n\t\"./fo.js\": \"./node_modules/moment/locale/fo.js\",\n\t\"./fr\": \"./node_modules/moment/locale/fr.js\",\n\t\"./fr-ca\": \"./node_modules/moment/locale/fr-ca.js\",\n\t\"./fr-ca.js\": \"./node_modules/moment/locale/fr-ca.js\",\n\t\"./fr-ch\": \"./node_modules/moment/locale/fr-ch.js\",\n\t\"./fr-ch.js\": \"./node_modules/moment/locale/fr-ch.js\",\n\t\"./fr.js\": \"./node_modules/moment/locale/fr.js\",\n\t\"./fy\": \"./node_modules/moment/locale/fy.js\",\n\t\"./fy.js\": \"./node_modules/moment/locale/fy.js\",\n\t\"./ga\": \"./node_modules/moment/locale/ga.js\",\n\t\"./ga.js\": \"./node_modules/moment/locale/ga.js\",\n\t\"./gd\": \"./node_modules/moment/locale/gd.js\",\n\t\"./gd.js\": \"./node_modules/moment/locale/gd.js\",\n\t\"./gl\": \"./node_modules/moment/locale/gl.js\",\n\t\"./gl.js\": \"./node_modules/moment/locale/gl.js\",\n\t\"./gom-latn\": \"./node_modules/moment/locale/gom-latn.js\",\n\t\"./gom-latn.js\": \"./node_modules/moment/locale/gom-latn.js\",\n\t\"./gu\": \"./node_modules/moment/locale/gu.js\",\n\t\"./gu.js\": \"./node_modules/moment/locale/gu.js\",\n\t\"./he\": \"./node_modules/moment/locale/he.js\",\n\t\"./he.js\": \"./node_modules/moment/locale/he.js\",\n\t\"./hi\": \"./node_modules/moment/locale/hi.js\",\n\t\"./hi.js\": \"./node_modules/moment/locale/hi.js\",\n\t\"./hr\": \"./node_modules/moment/locale/hr.js\",\n\t\"./hr.js\": \"./node_modules/moment/locale/hr.js\",\n\t\"./hu\": \"./node_modules/moment/locale/hu.js\",\n\t\"./hu.js\": \"./node_modules/moment/locale/hu.js\",\n\t\"./hy-am\": \"./node_modules/moment/locale/hy-am.js\",\n\t\"./hy-am.js\": \"./node_modules/moment/locale/hy-am.js\",\n\t\"./id\": \"./node_modules/moment/locale/id.js\",\n\t\"./id.js\": \"./node_modules/moment/locale/id.js\",\n\t\"./is\": \"./node_modules/moment/locale/is.js\",\n\t\"./is.js\": \"./node_modules/moment/locale/is.js\",\n\t\"./it\": \"./node_modules/moment/locale/it.js\",\n\t\"./it-ch\": \"./node_modules/moment/locale/it-ch.js\",\n\t\"./it-ch.js\": \"./node_modules/moment/locale/it-ch.js\",\n\t\"./it.js\": \"./node_modules/moment/locale/it.js\",\n\t\"./ja\": \"./node_modules/moment/locale/ja.js\",\n\t\"./ja.js\": \"./node_modules/moment/locale/ja.js\",\n\t\"./jv\": \"./node_modules/moment/locale/jv.js\",\n\t\"./jv.js\": \"./node_modules/moment/locale/jv.js\",\n\t\"./ka\": \"./node_modules/moment/locale/ka.js\",\n\t\"./ka.js\": \"./node_modules/moment/locale/ka.js\",\n\t\"./kk\": \"./node_modules/moment/locale/kk.js\",\n\t\"./kk.js\": \"./node_modules/moment/locale/kk.js\",\n\t\"./km\": \"./node_modules/moment/locale/km.js\",\n\t\"./km.js\": \"./node_modules/moment/locale/km.js\",\n\t\"./kn\": \"./node_modules/moment/locale/kn.js\",\n\t\"./kn.js\": \"./node_modules/moment/locale/kn.js\",\n\t\"./ko\": \"./node_modules/moment/locale/ko.js\",\n\t\"./ko.js\": \"./node_modules/moment/locale/ko.js\",\n\t\"./ku\": \"./node_modules/moment/locale/ku.js\",\n\t\"./ku.js\": \"./node_modules/moment/locale/ku.js\",\n\t\"./ky\": \"./node_modules/moment/locale/ky.js\",\n\t\"./ky.js\": \"./node_modules/moment/locale/ky.js\",\n\t\"./lb\": \"./node_modules/moment/locale/lb.js\",\n\t\"./lb.js\": \"./node_modules/moment/locale/lb.js\",\n\t\"./lo\": \"./node_modules/moment/locale/lo.js\",\n\t\"./lo.js\": \"./node_modules/moment/locale/lo.js\",\n\t\"./lt\": \"./node_modules/moment/locale/lt.js\",\n\t\"./lt.js\": \"./node_modules/moment/locale/lt.js\",\n\t\"./lv\": \"./node_modules/moment/locale/lv.js\",\n\t\"./lv.js\": \"./node_modules/moment/locale/lv.js\",\n\t\"./me\": \"./node_modules/moment/locale/me.js\",\n\t\"./me.js\": \"./node_modules/moment/locale/me.js\",\n\t\"./mi\": \"./node_modules/moment/locale/mi.js\",\n\t\"./mi.js\": \"./node_modules/moment/locale/mi.js\",\n\t\"./mk\": \"./node_modules/moment/locale/mk.js\",\n\t\"./mk.js\": \"./node_modules/moment/locale/mk.js\",\n\t\"./ml\": \"./node_modules/moment/locale/ml.js\",\n\t\"./ml.js\": \"./node_modules/moment/locale/ml.js\",\n\t\"./mn\": \"./node_modules/moment/locale/mn.js\",\n\t\"./mn.js\": \"./node_modules/moment/locale/mn.js\",\n\t\"./mr\": \"./node_modules/moment/locale/mr.js\",\n\t\"./mr.js\": \"./node_modules/moment/locale/mr.js\",\n\t\"./ms\": \"./node_modules/moment/locale/ms.js\",\n\t\"./ms-my\": \"./node_modules/moment/locale/ms-my.js\",\n\t\"./ms-my.js\": \"./node_modules/moment/locale/ms-my.js\",\n\t\"./ms.js\": \"./node_modules/moment/locale/ms.js\",\n\t\"./mt\": \"./node_modules/moment/locale/mt.js\",\n\t\"./mt.js\": \"./node_modules/moment/locale/mt.js\",\n\t\"./my\": \"./node_modules/moment/locale/my.js\",\n\t\"./my.js\": \"./node_modules/moment/locale/my.js\",\n\t\"./nb\": \"./node_modules/moment/locale/nb.js\",\n\t\"./nb.js\": \"./node_modules/moment/locale/nb.js\",\n\t\"./ne\": \"./node_modules/moment/locale/ne.js\",\n\t\"./ne.js\": \"./node_modules/moment/locale/ne.js\",\n\t\"./nl\": \"./node_modules/moment/locale/nl.js\",\n\t\"./nl-be\": \"./node_modules/moment/locale/nl-be.js\",\n\t\"./nl-be.js\": \"./node_modules/moment/locale/nl-be.js\",\n\t\"./nl.js\": \"./node_modules/moment/locale/nl.js\",\n\t\"./nn\": \"./node_modules/moment/locale/nn.js\",\n\t\"./nn.js\": \"./node_modules/moment/locale/nn.js\",\n\t\"./pa-in\": \"./node_modules/moment/locale/pa-in.js\",\n\t\"./pa-in.js\": \"./node_modules/moment/locale/pa-in.js\",\n\t\"./pl\": \"./node_modules/moment/locale/pl.js\",\n\t\"./pl.js\": \"./node_modules/moment/locale/pl.js\",\n\t\"./pt\": \"./node_modules/moment/locale/pt.js\",\n\t\"./pt-br\": \"./node_modules/moment/locale/pt-br.js\",\n\t\"./pt-br.js\": \"./node_modules/moment/locale/pt-br.js\",\n\t\"./pt.js\": \"./node_modules/moment/locale/pt.js\",\n\t\"./ro\": \"./node_modules/moment/locale/ro.js\",\n\t\"./ro.js\": \"./node_modules/moment/locale/ro.js\",\n\t\"./ru\": \"./node_modules/moment/locale/ru.js\",\n\t\"./ru.js\": \"./node_modules/moment/locale/ru.js\",\n\t\"./sd\": \"./node_modules/moment/locale/sd.js\",\n\t\"./sd.js\": \"./node_modules/moment/locale/sd.js\",\n\t\"./se\": \"./node_modules/moment/locale/se.js\",\n\t\"./se.js\": \"./node_modules/moment/locale/se.js\",\n\t\"./si\": \"./node_modules/moment/locale/si.js\",\n\t\"./si.js\": \"./node_modules/moment/locale/si.js\",\n\t\"./sk\": \"./node_modules/moment/locale/sk.js\",\n\t\"./sk.js\": \"./node_modules/moment/locale/sk.js\",\n\t\"./sl\": \"./node_modules/moment/locale/sl.js\",\n\t\"./sl.js\": \"./node_modules/moment/locale/sl.js\",\n\t\"./sq\": \"./node_modules/moment/locale/sq.js\",\n\t\"./sq.js\": \"./node_modules/moment/locale/sq.js\",\n\t\"./sr\": \"./node_modules/moment/locale/sr.js\",\n\t\"./sr-cyrl\": \"./node_modules/moment/locale/sr-cyrl.js\",\n\t\"./sr-cyrl.js\": \"./node_modules/moment/locale/sr-cyrl.js\",\n\t\"./sr.js\": \"./node_modules/moment/locale/sr.js\",\n\t\"./ss\": \"./node_modules/moment/locale/ss.js\",\n\t\"./ss.js\": \"./node_modules/moment/locale/ss.js\",\n\t\"./sv\": \"./node_modules/moment/locale/sv.js\",\n\t\"./sv.js\": \"./node_modules/moment/locale/sv.js\",\n\t\"./sw\": \"./node_modules/moment/locale/sw.js\",\n\t\"./sw.js\": \"./node_modules/moment/locale/sw.js\",\n\t\"./ta\": \"./node_modules/moment/locale/ta.js\",\n\t\"./ta.js\": \"./node_modules/moment/locale/ta.js\",\n\t\"./te\": \"./node_modules/moment/locale/te.js\",\n\t\"./te.js\": \"./node_modules/moment/locale/te.js\",\n\t\"./tet\": \"./node_modules/moment/locale/tet.js\",\n\t\"./tet.js\": \"./node_modules/moment/locale/tet.js\",\n\t\"./tg\": \"./node_modules/moment/locale/tg.js\",\n\t\"./tg.js\": \"./node_modules/moment/locale/tg.js\",\n\t\"./th\": \"./node_modules/moment/locale/th.js\",\n\t\"./th.js\": \"./node_modules/moment/locale/th.js\",\n\t\"./tl-ph\": \"./node_modules/moment/locale/tl-ph.js\",\n\t\"./tl-ph.js\": \"./node_modules/moment/locale/tl-ph.js\",\n\t\"./tlh\": \"./node_modules/moment/locale/tlh.js\",\n\t\"./tlh.js\": \"./node_modules/moment/locale/tlh.js\",\n\t\"./tr\": \"./node_modules/moment/locale/tr.js\",\n\t\"./tr.js\": \"./node_modules/moment/locale/tr.js\",\n\t\"./tzl\": \"./node_modules/moment/locale/tzl.js\",\n\t\"./tzl.js\": \"./node_modules/moment/locale/tzl.js\",\n\t\"./tzm\": \"./node_modules/moment/locale/tzm.js\",\n\t\"./tzm-latn\": \"./node_modules/moment/locale/tzm-latn.js\",\n\t\"./tzm-latn.js\": \"./node_modules/moment/locale/tzm-latn.js\",\n\t\"./tzm.js\": \"./node_modules/moment/locale/tzm.js\",\n\t\"./ug-cn\": \"./node_modules/moment/locale/ug-cn.js\",\n\t\"./ug-cn.js\": \"./node_modules/moment/locale/ug-cn.js\",\n\t\"./uk\": \"./node_modules/moment/locale/uk.js\",\n\t\"./uk.js\": \"./node_modules/moment/locale/uk.js\",\n\t\"./ur\": \"./node_modules/moment/locale/ur.js\",\n\t\"./ur.js\": \"./node_modules/moment/locale/ur.js\",\n\t\"./uz\": \"./node_modules/moment/locale/uz.js\",\n\t\"./uz-latn\": \"./node_modules/moment/locale/uz-latn.js\",\n\t\"./uz-latn.js\": \"./node_modules/moment/locale/uz-latn.js\",\n\t\"./uz.js\": \"./node_modules/moment/locale/uz.js\",\n\t\"./vi\": \"./node_modules/moment/locale/vi.js\",\n\t\"./vi.js\": \"./node_modules/moment/locale/vi.js\",\n\t\"./x-pseudo\": \"./node_modules/moment/locale/x-pseudo.js\",\n\t\"./x-pseudo.js\": \"./node_modules/moment/locale/x-pseudo.js\",\n\t\"./yo\": \"./node_modules/moment/locale/yo.js\",\n\t\"./yo.js\": \"./node_modules/moment/locale/yo.js\",\n\t\"./zh-cn\": \"./node_modules/moment/locale/zh-cn.js\",\n\t\"./zh-cn.js\": \"./node_modules/moment/locale/zh-cn.js\",\n\t\"./zh-hk\": \"./node_modules/moment/locale/zh-hk.js\",\n\t\"./zh-hk.js\": \"./node_modules/moment/locale/zh-hk.js\",\n\t\"./zh-tw\": \"./node_modules/moment/locale/zh-tw.js\",\n\t\"./zh-tw.js\": \"./node_modules/moment/locale/zh-tw.js\"\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tvar id = map[req];\n\tif(!(id + 1)) { // check for number or string\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn id;\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = \"./node_modules/moment/locale sync recursive ^\\\\.\\\\/.*$\";\n\n//# sourceURL=webpack:///./node_modules/moment/locale_sync_^\\.\\/.*$?"); + +/***/ }), + +/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=template&id=50f8d42a&": +/*!************************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?vue&type=template&id=50f8d42a& ***! + \************************************************************************************************************************************************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"modal fade\", attrs: { id: \"media-modal\", tabindex: \"-1\" } },\n [\n _c(\"div\", { staticClass: \"modal-dialog modal-lg\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _vm._m(0),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\"div\", { staticClass: \"container\" }, [\n _c(\"div\", { staticClass: \"row mh-100\" }, [\n _c(\n \"div\",\n {\n staticClass: \"col-md-6\",\n attrs: { id: \"media-library-list\" }\n },\n _vm._l(_vm.files, function(file) {\n return _c(\n \"div\",\n { key: file.id, staticClass: \"media-item-wrapper\" },\n [\n _c(\n \"a\",\n {\n attrs: { href: \"javascript:void(0)\" },\n on: {\n click: function($event) {\n _vm.selectFile(file)\n return false\n }\n }\n },\n [\n _c(\"i\", {\n class: _vm.getIconClass(file.location),\n attrs: { \"aria-hidden\": \"true\" }\n }),\n _vm._v(\" \"),\n _c(\"small\", { staticClass: \"media-item-title\" }, [\n _vm._v(_vm._s(file.location.split(\"/\").pop()))\n ])\n ]\n )\n ]\n )\n }),\n 0\n ),\n _vm._v(\" \"),\n _c(\n \"div\",\n {\n staticClass: \"col-md-6\",\n attrs: { id: \"media-library-details\" }\n },\n [\n _c(\"h4\", { staticClass: \"text-center\" }, [\n _vm._v(\"Media Details\")\n ]),\n _vm._v(\" \"),\n _c(\"div\", { attrs: { id: \"media-item\" } }, [\n _c(\n \"div\",\n {\n staticClass: \"text-center\",\n attrs: { id: \"media-icon\" }\n },\n [\n this.selectedFile\n ? _c(\"div\", [\n _vm.getIconClass(\n this.selectedFile.location\n ) === \"far fa-file-image\"\n ? _c(\"div\", [\n _c(\"img\", {\n staticStyle: {\n \"max-width\": \"100%\",\n \"max-height\": \"100%\",\n \"object-fit\": \"contain\"\n },\n attrs: {\n src: _vm.buildSelectedFileUrl()\n }\n })\n ])\n : _c(\"div\", [\n _c(\"i\", {\n class:\n _vm.getIconClass(\n this.selectedFile.location\n ) + \" fa-4x\",\n attrs: { \"aria-hidden\": \"true\" }\n })\n ])\n ])\n : _vm._e()\n ]\n ),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\" \"),\n this.selectedFile\n ? _c(\n \"div\",\n {\n staticClass: \"text-center\",\n attrs: { id: \"media-filename\" }\n },\n [\n _c(\n \"a\",\n {\n attrs: {\n href: _vm.buildSelectedFileUrl(),\n target: \"_blank\"\n }\n },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(\n this.selectedFile.location\n .split(\"/\")\n .pop()\n ) +\n \"\\n \"\n )\n ]\n )\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"br\"),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group\" }, [\n this.selectedFile\n ? _c(\"div\", [\n _vm._v(\n \"\\n Link:\\n \"\n ),\n _c(\"input\", {\n staticClass: \"form-control\",\n attrs: {\n type: \"text\",\n id: \"media-link\",\n readonly: \"\"\n },\n domProps: {\n value: _vm.buildSelectedFileUrl()\n }\n })\n ])\n : _c(\"div\", [\n _vm._v(\n \"\\n Link:\\n \"\n ),\n _c(\"input\", {\n staticClass: \"form-control\",\n attrs: {\n type: \"text\",\n id: \"media-link\",\n readonly: \"\"\n }\n })\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"form-group text-center\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\"div\", { staticClass: \"col-md-6\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn btn-success w-100\",\n attrs: {\n id: \"media-insert\",\n \"data-toggle\": \"tooltip\",\n \"data-placement\": \"top\",\n title: \"Insert link into editor\"\n },\n on: { click: _vm.insertSelectedFile }\n },\n [\n _vm._v(\n \"\\n Insert\\n \"\n )\n ]\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-md-3\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn btn-primary w-100\",\n attrs: {\n id: \"media-download\",\n \"data-toggle\": \"tooltip\",\n \"data-placement\": \"top\",\n title: \"Download file\"\n },\n on: { click: _vm.downloadSelectedFile }\n },\n [_c(\"i\", { staticClass: \"fas fa-download\" })]\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"col-md-3\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn btn-danger w-100\",\n attrs: {\n id: \"media-delete\",\n \"data-toggle\": \"tooltip\",\n \"data-placement\": \"top\",\n title: \"Delete file\"\n },\n on: { click: _vm.deleteSelectedFile }\n },\n [_c(\"i\", { staticClass: \"far fa-trash-alt\" })]\n )\n ])\n ])\n ])\n ])\n ]\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _vm._m(1)\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\"div\", { staticClass: \"float-right\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn btn-primary media-upload-button\",\n attrs: { type: \"submit\" },\n on: { click: _vm.uploadChosenFiles }\n },\n [_vm._v(\"\\n Upload\\n \")]\n )\n ])\n ])\n ])\n ])\n ]\n )\n}\nvar staticRenderFns = [\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\"div\", { staticClass: \"container\" }, [\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\"div\", { staticClass: \"col-md-12\" }, [\n _c(\"h3\", { staticClass: \"text-center\" }, [_vm._v(\"Media Library\")])\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-label\": \"Close\"\n }\n },\n [_c(\"span\", { attrs: { \"aria-hidden\": \"true\" } }, [_vm._v(\"×\")])]\n )\n ])\n },\n function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"form\",\n { attrs: { id: \"media-library-upload\", enctype: \"multipart/form-data\" } },\n [\n _c(\"div\", { staticClass: \"form-group\" }, [\n _c(\"label\", { attrs: { for: \"media-files\" } }, [\n _vm._v(\"\\n Upload Files\\n \")\n ]),\n _vm._v(\" \"),\n _c(\"input\", {\n staticClass: \"form-control-file\",\n attrs: {\n type: \"file\",\n name: \"file\",\n id: \"media-files\",\n multiple: \"\"\n }\n }),\n _vm._v(\" \"),\n _c(\"sub\", { staticClass: \"help-block\" }, [\n _vm._v(\n \"\\n Attach multiple files using Control+Click or Cmd+Click.\\n \"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", value: \"page\", name: \"type\" } })\n ]\n )\n }\n]\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/files/MediaLibrary.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options"); + +/***/ }), + +/***/ 0: +/*!********************!*\ + !*** fs (ignored) ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("/* (ignored) */\n\n//# sourceURL=webpack:///fs_(ignored)?"); + +/***/ }) + +}]); \ No newline at end of file diff --git a/CTFd/themes/admin/static/js/graphs.min.js b/CTFd/themes/admin/static/js/graphs.min.js index e69de29b..afdd65bc 100644 --- a/CTFd/themes/admin/static/js/graphs.min.js +++ b/CTFd/themes/admin/static/js/graphs.min.js @@ -0,0 +1,15 @@ +(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["graphs"],{ + +/***/ "./CTFd/themes/core/assets/js/graphs.js": +/*!**********************************************!*\ + !*** ./CTFd/themes/core/assets/js/graphs.js ***! + \**********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.createGraph = createGraph;\nexports.updateGraph = updateGraph;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _echartsEn = _interopRequireDefault(__webpack_require__(/*! echarts/dist/echarts-en.common */ \"./node_modules/echarts/dist/echarts-en.common.js\"));\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\n\nvar _utils = __webpack_require__(/*! ./utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar graph_configs = {\n score_graph: {\n format: function format(type, id, name, _account_id, responses) {\n var option = {\n title: {\n left: \"center\",\n text: \"Score over Time\"\n },\n tooltip: {\n trigger: \"axis\",\n axisPointer: {\n type: \"cross\"\n }\n },\n legend: {\n type: \"scroll\",\n orient: \"horizontal\",\n align: \"left\",\n bottom: 0,\n data: [name]\n },\n toolbox: {\n feature: {\n saveAsImage: {}\n }\n },\n grid: {\n containLabel: true\n },\n xAxis: [{\n type: \"category\",\n boundaryGap: false,\n data: []\n }],\n yAxis: [{\n type: \"value\"\n }],\n series: []\n };\n var times = [];\n var scores = [];\n var solves = responses[0].data;\n var awards = responses[2].data;\n var total = solves.concat(awards);\n total.sort(function (a, b) {\n return new Date(a.date) - new Date(b.date);\n });\n\n for (var i = 0; i < total.length; i++) {\n var date = (0, _moment.default)(total[i].date);\n times.push(date.toDate());\n\n try {\n scores.push(total[i].challenge.value);\n } catch (e) {\n scores.push(total[i].value);\n }\n }\n\n times.forEach(function (time) {\n option.xAxis[0].data.push(time);\n });\n option.series.push({\n name: window.stats_data.name,\n type: \"line\",\n label: {\n normal: {\n show: true,\n position: \"top\"\n }\n },\n areaStyle: {\n normal: {\n color: (0, _utils.colorHash)(name + id)\n }\n },\n itemStyle: {\n normal: {\n color: (0, _utils.colorHash)(name + id)\n }\n },\n data: (0, _utils.cumulativeSum)(scores)\n });\n return option;\n }\n },\n category_breakdown: {\n format: function format(type, id, name, account_id, responses) {\n var option = {\n title: {\n left: \"center\",\n text: \"Category Breakdown\"\n },\n tooltip: {\n trigger: \"item\"\n },\n toolbox: {\n show: true,\n feature: {\n saveAsImage: {}\n }\n },\n legend: {\n orient: \"horizontal\",\n bottom: 0,\n data: []\n },\n series: [{\n name: \"Category Breakdown\",\n type: \"pie\",\n radius: [\"30%\", \"50%\"],\n avoidLabelOverlap: false,\n label: {\n show: false,\n position: \"center\"\n },\n itemStyle: {\n normal: {\n label: {\n show: true,\n formatter: function formatter(data) {\n return \"\".concat(data.name, \" - \").concat(data.value, \" (\").concat(data.percent, \"%)\");\n }\n },\n labelLine: {\n show: true\n }\n },\n emphasis: {\n label: {\n show: true,\n position: \"center\",\n textStyle: {\n fontSize: \"14\",\n fontWeight: \"normal\"\n }\n }\n }\n },\n emphasis: {\n label: {\n show: true,\n fontSize: \"30\",\n fontWeight: \"bold\"\n }\n },\n labelLine: {\n show: false\n },\n data: []\n }]\n };\n var solves = responses[0].data;\n var categories = [];\n\n for (var i = 0; i < solves.length; i++) {\n categories.push(solves[i].challenge.category);\n }\n\n var keys = categories.filter(function (elem, pos) {\n return categories.indexOf(elem) == pos;\n });\n var counts = [];\n\n for (var _i = 0; _i < keys.length; _i++) {\n var count = 0;\n\n for (var x = 0; x < categories.length; x++) {\n if (categories[x] == keys[_i]) {\n count++;\n }\n }\n\n counts.push(count);\n }\n\n keys.forEach(function (category, index) {\n option.legend.data.push(category);\n option.series[0].data.push({\n value: counts[index],\n name: category,\n itemStyle: {\n color: (0, _utils.colorHash)(category)\n }\n });\n });\n return option;\n }\n },\n solve_percentages: {\n format: function format(type, id, name, account_id, responses) {\n var solves_count = responses[0].data.length;\n var fails_count = responses[1].meta.count;\n var option = {\n title: {\n left: \"center\",\n text: \"Solve Percentages\"\n },\n tooltip: {\n trigger: \"item\"\n },\n toolbox: {\n show: true,\n feature: {\n saveAsImage: {}\n }\n },\n legend: {\n orient: \"horizontal\",\n bottom: 0,\n data: [\"Fails\", \"Solves\"]\n },\n series: [{\n name: \"Solve Percentages\",\n type: \"pie\",\n radius: [\"30%\", \"50%\"],\n avoidLabelOverlap: false,\n label: {\n show: false,\n position: \"center\"\n },\n itemStyle: {\n normal: {\n label: {\n show: true,\n formatter: function formatter(data) {\n return \"\".concat(data.name, \" - \").concat(data.value, \" (\").concat(data.percent, \"%)\");\n }\n },\n labelLine: {\n show: true\n }\n },\n emphasis: {\n label: {\n show: true,\n position: \"center\",\n textStyle: {\n fontSize: \"14\",\n fontWeight: \"normal\"\n }\n }\n }\n },\n emphasis: {\n label: {\n show: true,\n fontSize: \"30\",\n fontWeight: \"bold\"\n }\n },\n labelLine: {\n show: false\n },\n data: [{\n value: fails_count,\n name: \"Fails\",\n itemStyle: {\n color: \"rgb(207, 38, 0)\"\n }\n }, {\n value: solves_count,\n name: \"Solves\",\n itemStyle: {\n color: \"rgb(0, 209, 64)\"\n }\n }]\n }]\n };\n return option;\n }\n }\n};\n\nfunction createGraph(graph_type, target, data, type, id, name, account_id) {\n var cfg = graph_configs[graph_type];\n\n var chart = _echartsEn.default.init(document.querySelector(target));\n\n chart.setOption(cfg.format(type, id, name, account_id, data));\n (0, _jquery.default)(window).on(\"resize\", function () {\n if (chart != null && chart != undefined) {\n chart.resize();\n }\n });\n}\n\nfunction updateGraph(graph_type, target, data, type, id, name, account_id) {\n var cfg = graph_configs[graph_type];\n\n var chart = _echartsEn.default.init(document.querySelector(target));\n\n chart.setOption(cfg.format(type, id, name, account_id, data));\n}\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/graphs.js?"); + +/***/ }) + +}]); \ No newline at end of file diff --git a/CTFd/themes/admin/static/js/helpers.dev.js b/CTFd/themes/admin/static/js/helpers.dev.js index 07b506ef..c0dd333c 100644 --- a/CTFd/themes/admin/static/js/helpers.dev.js +++ b/CTFd/themes/admin/static/js/helpers.dev.js @@ -8,7 +8,7 @@ /***/ (function(module, exports, __webpack_require__) { ; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = _interopRequireDefault(__webpack_require__(/*! ./ezq */ \"./CTFd/themes/core/assets/js/ezq.js\"));\n\nvar _utils = __webpack_require__(/*! ./utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar utils = {\n htmlEntities: _utils.htmlEntities,\n colorHash: _utils.colorHash,\n copyToClipboard: _utils.copyToClipboard\n};\nvar files = {\n upload: function upload(form, extra_data, cb) {\n var CTFd = window.CTFd;\n\n if (form instanceof _jquery.default) {\n form = form[0];\n }\n\n var formData = new FormData(form);\n formData.append(\"nonce\", CTFd.config.csrfNonce);\n\n for (var _i = 0, _Object$entries = Object.entries(extra_data); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),\n key = _Object$entries$_i[0],\n value = _Object$entries$_i[1];\n\n formData.append(key, value);\n }\n\n var pg = _ezq.default.ezProgressBar({\n width: 0,\n title: \"Upload Progress\"\n });\n\n _jquery.default.ajax({\n url: CTFd.config.urlRoot + \"/api/v1/files\",\n data: formData,\n type: \"POST\",\n cache: false,\n contentType: false,\n processData: false,\n xhr: function xhr() {\n var xhr = _jquery.default.ajaxSettings.xhr();\n\n xhr.upload.onprogress = function (e) {\n if (e.lengthComputable) {\n var width = e.loaded / e.total * 100;\n pg = _ezq.default.ezProgressBar({\n target: pg,\n width: width\n });\n }\n };\n\n return xhr;\n },\n success: function success(data) {\n form.reset();\n pg = _ezq.default.ezProgressBar({\n target: pg,\n width: 100\n });\n setTimeout(function () {\n pg.modal(\"hide\");\n }, 500);\n\n if (cb) {\n cb(data);\n }\n }\n });\n }\n};\nvar helpers = {\n files: files,\n utils: utils,\n ezq: _ezq.default\n};\nvar _default = helpers;\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/helpers.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = _interopRequireDefault(__webpack_require__(/*! ./ezq */ \"./CTFd/themes/core/assets/js/ezq.js\"));\n\nvar _utils = __webpack_require__(/*! ./utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { if (i % 2) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } else { Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i])); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar utils = {\n htmlEntities: _utils.htmlEntities,\n colorHash: _utils.colorHash,\n copyToClipboard: _utils.copyToClipboard\n};\nvar files = {\n upload: function upload(form, extra_data, cb) {\n var CTFd = window.CTFd;\n\n if (form instanceof _jquery.default) {\n form = form[0];\n }\n\n var formData = new FormData(form);\n formData.append(\"nonce\", CTFd.config.csrfNonce);\n\n for (var _i = 0, _Object$entries = Object.entries(extra_data); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),\n key = _Object$entries$_i[0],\n value = _Object$entries$_i[1];\n\n formData.append(key, value);\n }\n\n var pg = _ezq.default.ezProgressBar({\n width: 0,\n title: \"Upload Progress\"\n });\n\n _jquery.default.ajax({\n url: CTFd.config.urlRoot + \"/api/v1/files\",\n data: formData,\n type: \"POST\",\n cache: false,\n contentType: false,\n processData: false,\n xhr: function xhr() {\n var xhr = _jquery.default.ajaxSettings.xhr();\n\n xhr.upload.onprogress = function (e) {\n if (e.lengthComputable) {\n var width = e.loaded / e.total * 100;\n pg = _ezq.default.ezProgressBar({\n target: pg,\n width: width\n });\n }\n };\n\n return xhr;\n },\n success: function success(data) {\n form.reset();\n pg = _ezq.default.ezProgressBar({\n target: pg,\n width: 100\n });\n setTimeout(function () {\n pg.modal(\"hide\");\n }, 500);\n\n if (cb) {\n cb(data);\n }\n }\n });\n }\n};\nvar comments = {\n get_comments: function get_comments(extra_args) {\n var CTFd = window.CTFd;\n return CTFd.fetch(\"/api/v1/comments?\" + _jquery.default.param(extra_args), {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n }\n }).then(function (response) {\n return response.json();\n });\n },\n add_comment: function add_comment(comment, type, extra_args, cb) {\n var CTFd = window.CTFd;\n\n var body = _objectSpread({\n content: comment,\n type: type\n }, extra_args);\n\n CTFd.fetch(\"/api/v1/comments\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(body)\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (cb) {\n cb(response);\n }\n });\n },\n delete_comment: function delete_comment(comment_id) {\n var CTFd = window.CTFd;\n return CTFd.fetch(\"/api/v1/comments/\".concat(comment_id), {\n method: \"DELETE\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n }\n }).then(function (response) {\n return response.json();\n });\n }\n};\nvar helpers = {\n files: files,\n comments: comments,\n utils: utils,\n ezq: _ezq.default\n};\nvar _default = helpers;\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/helpers.js?"); /***/ }), diff --git a/CTFd/themes/admin/static/js/helpers.min.js b/CTFd/themes/admin/static/js/helpers.min.js index d58faff4..8d6224f7 100644 --- a/CTFd/themes/admin/static/js/helpers.min.js +++ b/CTFd/themes/admin/static/js/helpers.min.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{"./CTFd/themes/core/assets/js/helpers.js":function(e,r,o){Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var p=n(o("./node_modules/jquery/dist/jquery.js")),c=n(o("./CTFd/themes/core/assets/js/ezq.js")),t=o("./CTFd/themes/core/assets/js/utils.js");function n(e){return e&&e.__esModule?e:{default:e}}function f(e,r){return function(e){if(Array.isArray(e))return e}(e)||function(e,r){var o=[],t=!0,n=!1,s=void 0;try{for(var i,a=e[Symbol.iterator]();!(t=(i=a.next()).done)&&(o.push(i.value),!r||o.length!==r);t=!0);}catch(e){n=!0,s=e}finally{try{t||null==a.return||a.return()}finally{if(n)throw s}}return o}(e,r)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}var s={files:{upload:function(r,e,o){var t=window.CTFd;r instanceof p.default&&(r=r[0]);var n=new FormData(r);n.append("nonce",t.config.csrfNonce);for(var s=0,i=Object.entries(e);s\" + (0, _utils.htmlEntities)(window.CHALLENGE_NAME) + \"\"),\n success: function success() {\n _CTFd.default.fetch(\"/api/v1/challenges/\" + window.CHALLENGE_ID, {\n method: \"DELETE\"\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n window.location = _CTFd.default.config.urlRoot + \"/admin/challenges\";\n }\n });\n }\n });\n });\n (0, _jquery.default)(\"#challenge-update-container > form\").submit(function (e) {\n e.preventDefault();\n var params = (0, _jquery.default)(e.target).serializeJSON(true);\n\n _CTFd.default.fetch(\"/api/v1/challenges/\" + window.CHALLENGE_ID + \"/flags\", {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n }\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n var update_challenge = function update_challenge() {\n _CTFd.default.fetch(\"/api/v1/challenges/\" + window.CHALLENGE_ID, {\n method: \"PATCH\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(params)\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n (0, _jquery.default)(\".challenge-state\").text(response.data.state);\n\n switch (response.data.state) {\n case \"visible\":\n (0, _jquery.default)(\".challenge-state\").removeClass(\"badge-danger\").addClass(\"badge-success\");\n break;\n\n case \"hidden\":\n (0, _jquery.default)(\".challenge-state\").removeClass(\"badge-success\").addClass(\"badge-danger\");\n break;\n\n default:\n break;\n }\n\n (0, _ezq.ezToast)({\n title: \"Success\",\n body: \"Your challenge has been updated!\"\n });\n }\n });\n }; // Check if the challenge doesn't have any flags before marking visible\n\n\n if (response.data.length === 0 && params.state === \"visible\") {\n (0, _ezq.ezQuery)({\n title: \"Missing Flags\",\n body: \"This challenge does not have any flags meaning it may be unsolveable. Are you sure you'd like to update this challenge?\",\n success: update_challenge\n });\n } else {\n update_challenge();\n }\n });\n });\n (0, _jquery.default)(\"#challenge-create-options form\").submit(handleChallengeOptions);\n (0, _jquery.default)(\"#tags-add-input\").keyup(_tags.addTag);\n (0, _jquery.default)(\".delete-tag\").click(_tags.deleteTag);\n (0, _jquery.default)(\"#prerequisite-add-form\").submit(_requirements.addRequirement);\n (0, _jquery.default)(\".delete-requirement\").click(_requirements.deleteRequirement);\n (0, _jquery.default)(\"#file-add-form\").submit(_files.addFile);\n (0, _jquery.default)(\".delete-file\").click(_files.deleteFile);\n (0, _jquery.default)(\"#hint-add-button\").click(_hints.showHintModal);\n (0, _jquery.default)(\".delete-hint\").click(_hints.deleteHint);\n (0, _jquery.default)(\".edit-hint\").click(_hints.showEditHintModal);\n (0, _jquery.default)(\"#hint-edit-form\").submit(_hints.editHint);\n (0, _jquery.default)(\"#flag-add-button\").click(_flags.addFlagModal);\n (0, _jquery.default)(\".delete-flag\").click(_flags.deleteFlag);\n (0, _jquery.default)(\"#flags-create-select\").change(_flags.flagTypeSelect);\n (0, _jquery.default)(\".edit-flag\").click(_flags.editFlagModal);\n\n _jquery.default.get(_CTFd.default.config.urlRoot + \"/api/v1/challenges/types\", function (response) {\n var data = response.data;\n loadChalTemplate(data[\"standard\"]);\n (0, _jquery.default)(\"#create-chals-select input[name=type]\").change(function () {\n var challenge = data[this.value];\n loadChalTemplate(challenge);\n });\n });\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/challenge.js?"); +eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.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\n__webpack_require__(/*! bootstrap/js/dist/tab */ \"./node_modules/bootstrap/js/dist/tab.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nvar _helpers = _interopRequireDefault(__webpack_require__(/*! core/helpers */ \"./CTFd/themes/core/assets/js/helpers.js\"));\n\nvar _files = __webpack_require__(/*! ../challenges/files */ \"./CTFd/themes/admin/assets/js/challenges/files.js\");\n\nvar _tags = __webpack_require__(/*! ../challenges/tags */ \"./CTFd/themes/admin/assets/js/challenges/tags.js\");\n\nvar _requirements = __webpack_require__(/*! ../challenges/requirements */ \"./CTFd/themes/admin/assets/js/challenges/requirements.js\");\n\nvar _styles = __webpack_require__(/*! ../styles */ \"./CTFd/themes/admin/assets/js/styles.js\");\n\nvar _vueEsm = _interopRequireDefault(__webpack_require__(/*! vue/dist/vue.esm.browser */ \"./node_modules/vue/dist/vue.esm.browser.js\"));\n\nvar _CommentBox = _interopRequireDefault(__webpack_require__(/*! ../components/comments/CommentBox.vue */ \"./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue\"));\n\nvar _hints = __webpack_require__(/*! ../challenges/hints */ \"./CTFd/themes/admin/assets/js/challenges/hints.js\");\n\nvar _flags = __webpack_require__(/*! ../challenges/flags */ \"./CTFd/themes/admin/assets/js/challenges/flags.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar displayHint = function displayHint(data) {\n (0, _ezq.ezAlert)({\n title: \"Hint\",\n body: data.html,\n button: \"Got it!\"\n });\n};\n\nvar loadHint = function loadHint(id) {\n _CTFd.default.api.get_hint({\n hintId: id,\n preview: true\n }).then(function (response) {\n if (response.data.content) {\n displayHint(response.data);\n return;\n } // displayUnlock(id);\n\n });\n};\n\nfunction renderSubmissionResponse(response, cb) {\n var result = response.data;\n var result_message = (0, _jquery.default)(\"#result-message\");\n var result_notification = (0, _jquery.default)(\"#result-notification\");\n var answer_input = (0, _jquery.default)(\"#submission-input\");\n result_notification.removeClass();\n result_message.text(result.message);\n\n if (result.status === \"authentication_required\") {\n window.location = _CTFd.default.config.urlRoot + \"/login?next=\" + _CTFd.default.config.urlRoot + window.location.pathname + window.location.hash;\n return;\n } else if (result.status === \"incorrect\") {\n // Incorrect key\n result_notification.addClass(\"alert alert-danger alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.removeClass(\"correct\");\n answer_input.addClass(\"wrong\");\n setTimeout(function () {\n answer_input.removeClass(\"wrong\");\n }, 3000);\n } else if (result.status === \"correct\") {\n // Challenge Solved\n result_notification.addClass(\"alert alert-success alert-dismissable text-center\");\n result_notification.slideDown();\n (0, _jquery.default)(\".challenge-solves\").text(parseInt((0, _jquery.default)(\".challenge-solves\").text().split(\" \")[0]) + 1 + \" Solves\");\n answer_input.val(\"\");\n answer_input.removeClass(\"wrong\");\n answer_input.addClass(\"correct\");\n } else if (result.status === \"already_solved\") {\n // Challenge already solved\n result_notification.addClass(\"alert alert-info alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.addClass(\"correct\");\n } else if (result.status === \"paused\") {\n // CTF is paused\n result_notification.addClass(\"alert alert-warning alert-dismissable text-center\");\n result_notification.slideDown();\n } else if (result.status === \"ratelimited\") {\n // Keys per minute too high\n result_notification.addClass(\"alert alert-warning alert-dismissable text-center\");\n result_notification.slideDown();\n answer_input.addClass(\"too-fast\");\n setTimeout(function () {\n answer_input.removeClass(\"too-fast\");\n }, 3000);\n }\n\n setTimeout(function () {\n (0, _jquery.default)(\".alert\").slideUp();\n (0, _jquery.default)(\"#challenge-submit\").removeClass(\"disabled-button\");\n (0, _jquery.default)(\"#challenge-submit\").prop(\"disabled\", false);\n }, 3000);\n\n if (cb) {\n cb(result);\n }\n}\n\nfunction loadChalTemplate(challenge) {\n _CTFd.default._internal.challenge = {};\n\n _jquery.default.getScript(_CTFd.default.config.urlRoot + challenge.scripts.view, function () {\n var template_data = challenge.create;\n (0, _jquery.default)(\"#create-chal-entry-div\").html(template_data);\n (0, _styles.bindMarkdownEditors)();\n\n _jquery.default.getScript(_CTFd.default.config.urlRoot + challenge.scripts.create, function () {\n (0, _jquery.default)(\"#create-chal-entry-div form\").submit(function (event) {\n event.preventDefault();\n var params = (0, _jquery.default)(\"#create-chal-entry-div form\").serializeJSON();\n\n _CTFd.default.fetch(\"/api/v1/challenges\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(params)\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n (0, _jquery.default)(\"#challenge-create-options #challenge_id\").val(response.data.id);\n (0, _jquery.default)(\"#challenge-create-options\").modal();\n }\n });\n });\n });\n });\n}\n\nfunction handleChallengeOptions(event) {\n event.preventDefault();\n var params = (0, _jquery.default)(event.target).serializeJSON(true);\n var flag_params = {\n challenge_id: params.challenge_id,\n content: params.flag || \"\",\n type: params.flag_type,\n data: params.flag_data ? params.flag_data : \"\"\n }; // Define a save_challenge function\n\n var save_challenge = function save_challenge() {\n _CTFd.default.fetch(\"/api/v1/challenges/\" + params.challenge_id, {\n method: \"PATCH\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n state: params.state\n })\n }).then(function (response) {\n return response.json();\n }).then(function (data) {\n if (data.success) {\n setTimeout(function () {\n window.location = _CTFd.default.config.urlRoot + \"/admin/challenges/\" + params.challenge_id;\n }, 700);\n }\n });\n };\n\n Promise.all([// Save flag\n new Promise(function (resolve, _reject) {\n if (flag_params.content.length == 0) {\n resolve();\n return;\n }\n\n _CTFd.default.fetch(\"/api/v1/flags\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(flag_params)\n }).then(function (response) {\n resolve(response.json());\n });\n }), // Upload files\n new Promise(function (resolve, _reject) {\n var form = event.target;\n var data = {\n challenge: params.challenge_id,\n type: \"challenge\"\n };\n var filepath = (0, _jquery.default)(form.elements[\"file\"]).val();\n\n if (filepath) {\n _helpers.default.files.upload(form, data);\n }\n\n resolve();\n })]).then(function (_responses) {\n save_challenge();\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".preview-challenge\").click(function (_e) {\n _CTFd.default._internal.challenge = {};\n\n _jquery.default.get(_CTFd.default.config.urlRoot + \"/api/v1/challenges/\" + window.CHALLENGE_ID, function (response) {\n // Preview should not show any solves\n var challenge_data = response.data;\n challenge_data[\"solves\"] = null;\n\n _jquery.default.getScript(_CTFd.default.config.urlRoot + challenge_data.type_data.scripts.view, function () {\n var challenge = _CTFd.default._internal.challenge; // Inject challenge data into the plugin\n\n challenge.data = response.data;\n (0, _jquery.default)(\"#challenge-window\").empty(); // Call preRender function in plugin\n\n challenge.preRender();\n (0, _jquery.default)(\"#challenge-window\").append(challenge_data.view);\n (0, _jquery.default)(\"#challenge-window #challenge-input\").addClass(\"form-control\");\n (0, _jquery.default)(\"#challenge-window #challenge-submit\").addClass(\"btn btn-md btn-outline-secondary float-right\");\n (0, _jquery.default)(\".challenge-solves\").hide();\n (0, _jquery.default)(\".nav-tabs a\").click(function (e) {\n e.preventDefault();\n (0, _jquery.default)(this).tab(\"show\");\n }); // Handle modal toggling\n\n (0, _jquery.default)(\"#challenge-window\").on(\"hide.bs.modal\", function (_event) {\n (0, _jquery.default)(\"#challenge-input\").removeClass(\"wrong\");\n (0, _jquery.default)(\"#challenge-input\").removeClass(\"correct\");\n (0, _jquery.default)(\"#incorrect-key\").slideUp();\n (0, _jquery.default)(\"#correct-key\").slideUp();\n (0, _jquery.default)(\"#already-solved\").slideUp();\n (0, _jquery.default)(\"#too-fast\").slideUp();\n });\n (0, _jquery.default)(\".load-hint\").on(\"click\", function (_event) {\n loadHint((0, _jquery.default)(this).data(\"hint-id\"));\n });\n (0, _jquery.default)(\"#challenge-submit\").click(function (e) {\n e.preventDefault();\n (0, _jquery.default)(\"#challenge-submit\").addClass(\"disabled-button\");\n (0, _jquery.default)(\"#challenge-submit\").prop(\"disabled\", true);\n\n _CTFd.default._internal.challenge.submit(true).then(renderSubmissionResponse); // Preview passed as true\n\n });\n (0, _jquery.default)(\"#challenge-input\").keyup(function (event) {\n if (event.keyCode == 13) {\n (0, _jquery.default)(\"#challenge-submit\").click();\n }\n });\n challenge.postRender();\n window.location.replace(window.location.href.split(\"#\")[0] + \"#preview\");\n (0, _jquery.default)(\"#challenge-window\").modal();\n });\n });\n });\n (0, _jquery.default)(\".delete-challenge\").click(function (_e) {\n (0, _ezq.ezQuery)({\n title: \"Delete Challenge\",\n body: \"Are you sure you want to delete {0}\".format(\"\" + (0, _utils.htmlEntities)(window.CHALLENGE_NAME) + \"\"),\n success: function success() {\n _CTFd.default.fetch(\"/api/v1/challenges/\" + window.CHALLENGE_ID, {\n method: \"DELETE\"\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n window.location = _CTFd.default.config.urlRoot + \"/admin/challenges\";\n }\n });\n }\n });\n });\n (0, _jquery.default)(\"#challenge-update-container > form\").submit(function (e) {\n e.preventDefault();\n var params = (0, _jquery.default)(e.target).serializeJSON(true);\n\n _CTFd.default.fetch(\"/api/v1/challenges/\" + window.CHALLENGE_ID + \"/flags\", {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n }\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n var update_challenge = function update_challenge() {\n _CTFd.default.fetch(\"/api/v1/challenges/\" + window.CHALLENGE_ID, {\n method: \"PATCH\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(params)\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n (0, _jquery.default)(\".challenge-state\").text(response.data.state);\n\n switch (response.data.state) {\n case \"visible\":\n (0, _jquery.default)(\".challenge-state\").removeClass(\"badge-danger\").addClass(\"badge-success\");\n break;\n\n case \"hidden\":\n (0, _jquery.default)(\".challenge-state\").removeClass(\"badge-success\").addClass(\"badge-danger\");\n break;\n\n default:\n break;\n }\n\n (0, _ezq.ezToast)({\n title: \"Success\",\n body: \"Your challenge has been updated!\"\n });\n }\n });\n }; // Check if the challenge doesn't have any flags before marking visible\n\n\n if (response.data.length === 0 && params.state === \"visible\") {\n (0, _ezq.ezQuery)({\n title: \"Missing Flags\",\n body: \"This challenge does not have any flags meaning it may be unsolveable. Are you sure you'd like to update this challenge?\",\n success: update_challenge\n });\n } else {\n update_challenge();\n }\n });\n });\n (0, _jquery.default)(\"#challenge-create-options form\").submit(handleChallengeOptions);\n (0, _jquery.default)(\"#tags-add-input\").keyup(_tags.addTag);\n (0, _jquery.default)(\".delete-tag\").click(_tags.deleteTag);\n (0, _jquery.default)(\"#prerequisite-add-form\").submit(_requirements.addRequirement);\n (0, _jquery.default)(\".delete-requirement\").click(_requirements.deleteRequirement);\n (0, _jquery.default)(\"#file-add-form\").submit(_files.addFile);\n (0, _jquery.default)(\".delete-file\").click(_files.deleteFile);\n (0, _jquery.default)(\"#hint-add-button\").click(_hints.showHintModal);\n (0, _jquery.default)(\".delete-hint\").click(_hints.deleteHint);\n (0, _jquery.default)(\".edit-hint\").click(_hints.showEditHintModal);\n (0, _jquery.default)(\"#hint-edit-form\").submit(_hints.editHint);\n (0, _jquery.default)(\"#flag-add-button\").click(_flags.addFlagModal);\n (0, _jquery.default)(\".delete-flag\").click(_flags.deleteFlag);\n (0, _jquery.default)(\"#flags-create-select\").change(_flags.flagTypeSelect);\n (0, _jquery.default)(\".edit-flag\").click(_flags.editFlagModal); // Insert CommentBox element\n\n var commentBox = _vueEsm.default.extend(_CommentBox.default);\n\n var vueContainer = document.createElement(\"div\");\n document.querySelector(\"#comment-box\").appendChild(vueContainer);\n new commentBox({\n propsData: {\n type: \"challenge\",\n id: window.CHALLENGE_ID\n }\n }).$mount(vueContainer);\n\n _jquery.default.get(_CTFd.default.config.urlRoot + \"/api/v1/challenges/types\", function (response) {\n var data = response.data;\n loadChalTemplate(data[\"standard\"]);\n (0, _jquery.default)(\"#create-chals-select input[name=type]\").change(function () {\n var challenge = data[this.value];\n loadChalTemplate(challenge);\n });\n });\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/challenge.js?"); + +/***/ }), + +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=script&lang=js&": +/*!*******************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--0!./node_modules/vue-loader/lib??vue-loader-options!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=script&lang=js& ***! + \*******************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _helpers = _interopRequireDefault(__webpack_require__(/*! core/helpers */ \"./CTFd/themes/core/assets/js/helpers.js\"));\n\nvar _moment = _interopRequireDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\nvar _default = {\n props: {\n // These props are passed to the api via query string.\n // See this.getArgs()\n type: String,\n id: Number\n },\n data: function data() {\n return {\n comment: \"\",\n comments: [],\n urlRoot: _CTFd.default.config.urlRoot\n };\n },\n methods: {\n toLocalTime: function toLocalTime(date) {\n return (0, _moment.default)(date).local().format(\"MMMM Do, h:mm:ss A\");\n },\n getArgs: function getArgs() {\n var args = {};\n args[\"\".concat(this.$props.type, \"_id\")] = this.$props.id;\n return args;\n },\n loadComments: function loadComments() {\n var _this = this;\n\n var apiArgs = this.getArgs();\n\n _helpers.default.comments.get_comments(apiArgs).then(function (response) {\n _this.comments = response.data;\n return _this.comments;\n });\n },\n submitComment: function submitComment() {\n var _this2 = this;\n\n var comment = this.comment.trim();\n\n if (comment.length > 0) {\n _helpers.default.comments.add_comment(comment, \"challenge\", this.getArgs(), function () {\n _this2.loadComments();\n });\n }\n\n this.comment = \"\";\n },\n deleteComment: function deleteComment(commentId) {\n var _this3 = this;\n\n if (confirm(\"Are you sure you'd like to delete this comment?\")) {\n _helpers.default.comments.delete_comment(commentId).then(function (response) {\n if (response.success === true) {\n for (var i = _this3.comments.length - 1; i >= 0; --i) {\n if (_this3.comments[i].id == commentId) {\n _this3.comments.splice(i, 1);\n }\n }\n }\n });\n }\n }\n },\n created: function created() {\n this.loadComments();\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?./node_modules/babel-loader/lib??ref--0!./node_modules/vue-loader/lib??vue-loader-options"); + +/***/ }), + +/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=style&index=0&id=1fd2c08a&scoped=true&lang=css&": +/*!**********************************************************************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib??vue-loader-options!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=style&index=0&id=1fd2c08a&scoped=true&lang=css& ***! + \**********************************************************************************************************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../../../../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \"\\n.card .close[data-v-1fd2c08a] {\\n opacity: 0;\\n transition: 0.2s;\\n}\\n.card:hover .close[data-v-1fd2c08a] {\\n opacity: 0.5;\\n}\\n.close[data-v-1fd2c08a]:hover {\\n opacity: 0.75 !important;\\n}\\n.comment-card-leave[data-v-1fd2c08a] {\\n max-height: 200px;\\n}\\n.comment-card-leave-to[data-v-1fd2c08a] {\\n max-height: 0;\\n}\\n.comment-card-active[data-v-1fd2c08a] {\\n position: absolute;\\n}\\n.comment-card-enter-active[data-v-1fd2c08a],\\n.comment-card-move[data-v-1fd2c08a],\\n.comment-card-leave-active[data-v-1fd2c08a] {\\n transition: all 0.3s;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib??vue-loader-options"); + +/***/ }), + +/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=template&id=1fd2c08a&scoped=true&": +/*!*************************************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=template&id=1fd2c08a&scoped=true& ***! + \*************************************************************************************************************************************************************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", [\n _c(\"div\", { staticClass: \"row mb-3\" }, [\n _c(\"div\", { staticClass: \"col-md-12\" }, [\n _c(\"div\", { staticClass: \"comment\" }, [\n _c(\"textarea\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model.lazy\",\n value: _vm.comment,\n expression: \"comment\",\n modifiers: { lazy: true }\n }\n ],\n staticClass: \"form-control mb-2\",\n attrs: {\n rows: \"2\",\n id: \"comment-input\",\n placeholder: \"Add comment\"\n },\n domProps: { value: _vm.comment },\n on: {\n change: function($event) {\n _vm.comment = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn btn-sm btn-success btn-outlined float-right\",\n attrs: { type: \"submit\" },\n on: {\n click: function($event) {\n return _vm.submitComment()\n }\n }\n },\n [_vm._v(\"\\n Comment\\n \")]\n )\n ])\n ])\n ]),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"comments\" },\n [\n _c(\n \"transition-group\",\n { attrs: { name: \"comment-card\" } },\n _vm._l(_vm.comments.slice().reverse(), function(comment) {\n return _c(\n \"div\",\n { key: comment.id, staticClass: \"comment-card card mb-2\" },\n [\n _c(\"div\", { staticClass: \"card-body pl-0 pb-0 pt-2 pr-2\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close float-right\",\n attrs: { type: \"button\", \"aria-label\": \"Close\" },\n on: {\n click: function($event) {\n return _vm.deleteComment(comment.id)\n }\n }\n },\n [\n _c(\"span\", { attrs: { \"aria-hidden\": \"true\" } }, [\n _vm._v(\"×\")\n ])\n ]\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"card-body\" }, [\n _c(\"div\", {\n staticClass: \"card-text\",\n domProps: { innerHTML: _vm._s(comment.html) }\n }),\n _vm._v(\" \"),\n _c(\"small\", { staticClass: \"text-muted float-left\" }, [\n _c(\"span\", [\n _c(\n \"a\",\n {\n attrs: {\n href:\n _vm.urlRoot + \"/admin/users/\" + comment.author_id\n }\n },\n [_vm._v(_vm._s(comment.author.name))]\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"small\", { staticClass: \"text-muted float-right\" }, [\n _c(\"span\", { staticClass: \"float-right\" }, [\n _vm._v(_vm._s(_vm.toLocalTime(comment.date)))\n ])\n ])\n ])\n ]\n )\n }),\n 0\n )\n ],\n 1\n )\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options"); + +/***/ }), + +/***/ "./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib/index.js?!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=style&index=0&id=1fd2c08a&scoped=true&lang=css&": +/*!******************************************************************************************************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/vue-style-loader!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/vue-loader/lib??vue-loader-options!./CTFd/themes/admin/assets/js/components/comments/CommentBox.vue?vue&type=style&index=0&id=1fd2c08a&scoped=true&lang=css& ***! + \******************************************************************************************************************************************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// style-loader: Adds some css to the DOM by adding a