Repository: CTFd/CTFd
Pull request #287 (2017-06-17 23:14:50)

Moving themes into a themes folder
This moves themes into a dedicated themes folder. This allows themes to be unified under a single folder but stay separated.

This lets us simplify the logic for uploading themes and potentially automatically downloading themes. 


Patch:
diff --git a/CTFd/__init__.py b/CTFd/__init__.py
index 63fd3473..d1b32c9b 100644
--- a/CTFd/__init__.py
+++ b/CTFd/__init__.py
@@ -23,9 +23,11 @@ __version__ = '1.0.2'
 class ThemeLoader(FileSystemLoader):
     def get_source(self, environment, template):
         if template.startswith('admin/'):
+            template = template.lstrip('admin/')
+            template = "/".join(['admin', 'templates', template])
             return super(ThemeLoader, self).get_source(environment, template)
         theme = utils.get_config('ctf_theme')
-        template = "/".join([theme, template])
+        template = "/".join([theme, 'templates', template])
         return super(ThemeLoader, self).get_source(environment, template)
 
 
@@ -33,7 +35,7 @@ def create_app(config='CTFd.config.Config'):
     app = Flask(__name__)
     with app.app_context():
         app.config.from_object(config)
-        app.jinja_loader = ThemeLoader(os.path.join(app.root_path, app.template_folder), followlinks=True)
+        app.jinja_loader = ThemeLoader(os.path.join(app.root_path, 'themes'), followlinks=True)
 
         from CTFd.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking
 
diff --git a/CTFd/static/admin/css/style.css b/CTFd/themes/admin/static/css/style.css
similarity index 100%
rename from CTFd/static/admin/css/style.css
rename to CTFd/themes/admin/static/css/style.css
diff --git a/CTFd/static/admin/css/vendor/bootstrap.min.css b/CTFd/themes/admin/static/css/vendor/bootstrap.min.css
similarity index 100%
rename from CTFd/static/admin/css/vendor/bootstrap.min.css
rename to CTFd/themes/admin/static/css/vendor/bootstrap.min.css
diff --git a/CTFd/static/admin/css/vendor/codemirror.min.css b/CTFd/themes/admin/static/css/vendor/codemirror.min.css
similarity index 100%
rename from CTFd/static/admin/css/vendor/codemirror.min.css
rename to CTFd/themes/admin/static/css/vendor/codemirror.min.css
diff --git a/CTFd/static/admin/css/vendor/font-awesome/HELP-US-OUT.txt b/CTFd/themes/admin/static/css/vendor/font-awesome/HELP-US-OUT.txt
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/HELP-US-OUT.txt
rename to CTFd/themes/admin/static/css/vendor/font-awesome/HELP-US-OUT.txt
diff --git a/CTFd/static/admin/css/vendor/font-awesome/css/font-awesome.css b/CTFd/themes/admin/static/css/vendor/font-awesome/css/font-awesome.css
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/css/font-awesome.css
rename to CTFd/themes/admin/static/css/vendor/font-awesome/css/font-awesome.css
diff --git a/CTFd/static/admin/css/vendor/font-awesome/css/font-awesome.min.css b/CTFd/themes/admin/static/css/vendor/font-awesome/css/font-awesome.min.css
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/css/font-awesome.min.css
rename to CTFd/themes/admin/static/css/vendor/font-awesome/css/font-awesome.min.css
diff --git a/CTFd/static/admin/css/vendor/font-awesome/fonts/FontAwesome.otf b/CTFd/themes/admin/static/css/vendor/font-awesome/fonts/FontAwesome.otf
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/fonts/FontAwesome.otf
rename to CTFd/themes/admin/static/css/vendor/font-awesome/fonts/FontAwesome.otf
diff --git a/CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.eot b/CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.eot
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.eot
rename to CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.eot
diff --git a/CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.svg b/CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.svg
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.svg
rename to CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.svg
diff --git a/CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf b/CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf
rename to CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf
diff --git a/CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.woff b/CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.woff
rename to CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff
diff --git a/CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2 b/CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2
rename to CTFd/themes/admin/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/animated.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/animated.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/animated.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/animated.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/bordered-pulled.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/bordered-pulled.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/bordered-pulled.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/bordered-pulled.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/core.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/core.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/core.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/core.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/fixed-width.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/fixed-width.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/fixed-width.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/fixed-width.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/font-awesome.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/font-awesome.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/font-awesome.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/font-awesome.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/icons.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/icons.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/icons.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/icons.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/larger.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/larger.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/larger.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/larger.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/list.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/list.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/list.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/list.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/mixins.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/mixins.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/mixins.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/mixins.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/path.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/path.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/path.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/path.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/rotated-flipped.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/rotated-flipped.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/rotated-flipped.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/rotated-flipped.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/stacked.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/stacked.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/stacked.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/stacked.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/less/variables.less b/CTFd/themes/admin/static/css/vendor/font-awesome/less/variables.less
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/less/variables.less
rename to CTFd/themes/admin/static/css/vendor/font-awesome/less/variables.less
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_animated.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_animated.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_animated.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_animated.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_bordered-pulled.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_bordered-pulled.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_bordered-pulled.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_bordered-pulled.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_core.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_core.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_core.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_core.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_fixed-width.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_fixed-width.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_fixed-width.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_fixed-width.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_icons.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_icons.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_icons.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_icons.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_larger.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_larger.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_larger.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_larger.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_list.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_list.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_list.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_list.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_mixins.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_mixins.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_mixins.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_mixins.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_path.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_path.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_path.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_path.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_rotated-flipped.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_rotated-flipped.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_rotated-flipped.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_rotated-flipped.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_stacked.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_stacked.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_stacked.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_stacked.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/_variables.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/_variables.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/_variables.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/_variables.scss
diff --git a/CTFd/static/admin/css/vendor/font-awesome/scss/font-awesome.scss b/CTFd/themes/admin/static/css/vendor/font-awesome/scss/font-awesome.scss
similarity index 100%
rename from CTFd/static/admin/css/vendor/font-awesome/scss/font-awesome.scss
rename to CTFd/themes/admin/static/css/vendor/font-awesome/scss/font-awesome.scss
diff --git a/CTFd/static/admin/css/vendor/lato.css b/CTFd/themes/admin/static/css/vendor/lato.css
similarity index 100%
rename from CTFd/static/admin/css/vendor/lato.css
rename to CTFd/themes/admin/static/css/vendor/lato.css
diff --git a/CTFd/static/admin/css/vendor/raleway.css b/CTFd/themes/admin/static/css/vendor/raleway.css
similarity index 100%
rename from CTFd/static/admin/css/vendor/raleway.css
rename to CTFd/themes/admin/static/css/vendor/raleway.css
diff --git a/CTFd/static/admin/fonts/lato/lato-v11-latin-regular.eot b/CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.eot
similarity index 100%
rename from CTFd/static/admin/fonts/lato/lato-v11-latin-regular.eot
rename to CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.eot
diff --git a/CTFd/static/admin/fonts/lato/lato-v11-latin-regular.svg b/CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.svg
similarity index 100%
rename from CTFd/static/admin/fonts/lato/lato-v11-latin-regular.svg
rename to CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.svg
diff --git a/CTFd/static/admin/fonts/lato/lato-v11-latin-regular.ttf b/CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.ttf
similarity index 100%
rename from CTFd/static/admin/fonts/lato/lato-v11-latin-regular.ttf
rename to CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.ttf
diff --git a/CTFd/static/admin/fonts/lato/lato-v11-latin-regular.woff b/CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.woff
similarity index 100%
rename from CTFd/static/admin/fonts/lato/lato-v11-latin-regular.woff
rename to CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.woff
diff --git a/CTFd/static/admin/fonts/lato/lato-v11-latin-regular.woff2 b/CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.woff2
similarity index 100%
rename from CTFd/static/admin/fonts/lato/lato-v11-latin-regular.woff2
rename to CTFd/themes/admin/static/fonts/lato/lato-v11-latin-regular.woff2
diff --git a/CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.eot b/CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.eot
similarity index 100%
rename from CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.eot
rename to CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.eot
diff --git a/CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.svg b/CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.svg
similarity index 100%
rename from CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.svg
rename to CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.svg
diff --git a/CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.ttf b/CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.ttf
similarity index 100%
rename from CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.ttf
rename to CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.ttf
diff --git a/CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.woff b/CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.woff
similarity index 100%
rename from CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.woff
rename to CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.woff
diff --git a/CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.woff2 b/CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.woff2
similarity index 100%
rename from CTFd/static/admin/fonts/raleway/raleway-v10-latin-500.woff2
rename to CTFd/themes/admin/static/fonts/raleway/raleway-v10-latin-500.woff2
diff --git a/CTFd/static/admin/js/chal-new.js b/CTFd/themes/admin/static/js/chal-new.js
similarity index 77%
rename from CTFd/static/admin/js/chal-new.js
rename to CTFd/themes/admin/static/js/chal-new.js
index b56b1bf1..65990bb4 100644
--- a/CTFd/static/admin/js/chal-new.js
+++ b/CTFd/themes/admin/static/js/chal-new.js
@@ -1,8 +1,8 @@
 function load_chal_template(chal_type_name){
-    $.get(script_root + '/static/admin/js/templates/challenges/'+ chal_type_name +'/' + chal_type_name + '-challenge-create.hbs', function(template_data){
+    $.get(script_root + '/themes/admin/static/js/templates/challenges/'+ chal_type_name +'/' + chal_type_name + '-challenge-create.hbs', function(template_data){
         var template = Handlebars.compile(template_data);
         $("#create-chal-entry-div").html(template({'nonce':nonce, 'script_root':script_root}));
-        $.getScript(script_root + '/static/admin/js/templates/challenges/'+chal_type_name+'/'+chal_type_name+'-challenge-create.js', function(){
+        $.getScript(script_root + '/themes/admin/static/js/templates/challenges/'+chal_type_name+'/'+chal_type_name+'-challenge-create.js', function(){
             console.log('loaded');
         });
     });
diff --git a/CTFd/static/admin/js/chalboard.js b/CTFd/themes/admin/static/js/chalboard.js
similarity index 88%
rename from CTFd/static/admin/js/chalboard.js
rename to CTFd/themes/admin/static/js/chalboard.js
index 31fb2a16..e3615060 100644
--- a/CTFd/static/admin/js/chalboard.js
+++ b/CTFd/themes/admin/static/js/chalboard.js
@@ -22,7 +22,7 @@ String.prototype.hashCode = function() {
 };
 
 function load_edit_key_modal(key_id, key_type_name) {
-    $.get(script_root + '/static/admin/js/templates/keys/'+key_type_name+'/edit-'+key_type_name+'-modal.hbs', function(template_data){
+    $.get(script_root + '/themes/admin/static/js/templates/keys/'+key_type_name+'/edit-'+key_type_name+'-modal.hbs', function(template_data){
         $.get(script_root + '/admin/keys/' + key_id, function(key_data){
             $('#edit-keys').empty();
             var template = Handlebars.compile(template_data);
@@ -43,11 +43,11 @@ function load_chal_template(id, success_cb){
     obj = $.grep(challenges['game'], function (e) {
         return e.id == id;
     })[0]
-    $.get(script_root + '/static/admin/js/templates/challenges/'+ obj['type_name'] +'/' + obj['type_name'] + '-challenge-update.hbs', function(template_data){
+    $.get(script_root + '/themes/admin/static/js/templates/challenges/'+ obj['type_name'] +'/' + obj['type_name'] + '-challenge-update.hbs', function(template_data){
         var template = Handlebars.compile(template_data);
         $("#update-modals-entry-div").html(template({'nonce':$('#nonce').val(), 'script_root':script_root}));
         $.ajax({
-          url: script_root + '/static/admin/js/templates/challenges/'+obj['type_name']+'/'+obj['type_name']+'-challenge-update.js',
+          url: script_root + '/themes/admin/static/js/templates/challenges/'+obj['type_name']+'/'+obj['type_name']+'-challenge-update.js',
           dataType: "script",
           success: success_cb,
           cache: true,
diff --git a/CTFd/static/admin/js/main.js b/CTFd/themes/admin/static/js/main.js
similarity index 100%
rename from CTFd/static/admin/js/main.js
rename to CTFd/themes/admin/static/js/main.js
diff --git a/CTFd/static/admin/js/multi-modal.js b/CTFd/themes/admin/static/js/multi-modal.js
similarity index 100%
rename from CTFd/static/admin/js/multi-modal.js
rename to CTFd/themes/admin/static/js/multi-modal.js
diff --git a/CTFd/static/admin/js/team.js b/CTFd/themes/admin/static/js/team.js
similarity index 100%
rename from CTFd/static/admin/js/team.js
rename to CTFd/themes/admin/static/js/team.js
diff --git a/CTFd/static/admin/js/templates/admin-keys-table.hbs b/CTFd/themes/admin/static/js/templates/admin-keys-table.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/admin-keys-table.hbs
rename to CTFd/themes/admin/static/js/templates/admin-keys-table.hbs
diff --git a/CTFd/static/admin/js/templates/challenges/standard/standard-challenge-create.hbs b/CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-create.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/challenges/standard/standard-challenge-create.hbs
rename to CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-create.hbs
diff --git a/CTFd/static/admin/js/templates/challenges/standard/standard-challenge-create.js b/CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-create.js
similarity index 100%
rename from CTFd/static/admin/js/templates/challenges/standard/standard-challenge-create.js
rename to CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-create.js
diff --git a/CTFd/static/admin/js/templates/challenges/standard/standard-challenge-update.hbs b/CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-update.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/challenges/standard/standard-challenge-update.hbs
rename to CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-update.hbs
diff --git a/CTFd/static/admin/js/templates/challenges/standard/standard-challenge-update.js b/CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-update.js
similarity index 98%
rename from CTFd/static/admin/js/templates/challenges/standard/standard-challenge-update.js
rename to CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-update.js
index 0160ab9d..ebf5dad0 100644
--- a/CTFd/static/admin/js/templates/challenges/standard/standard-challenge-update.js
+++ b/CTFd/themes/admin/static/js/templates/challenges/standard/standard-challenge-update.js
@@ -57,7 +57,7 @@ function loadkeys(chal){
         keys = $.parseJSON(JSON.stringify(data));
         keys = keys['keys'];
         $('#current-keys').empty();
-        $.get(script_root + "/static/admin/js/templates/admin-keys-table.hbs", function(data){
+        $.get(script_root + "/themes/admin/static/js/templates/admin-keys-table.hbs", function(data){
             var template = Handlebars.compile(data);
             var wrapper  = {keys: keys, script_root: script_root};
             $('#current-keys').append(template(wrapper));
@@ -317,7 +317,7 @@ $('#create-key').click(function(e){
 $('#create-keys-select').change(function(){
     var key_type_name = $(this).find("option:selected").text();
 
-    $.get(script_root + '/static/admin/js/templates/keys/'+key_type_name +'/'+key_type_name+'.hbs', function(template_data){
+    $.get(script_root + '/themes/admin/static/js/templates/keys/'+key_type_name +'/'+key_type_name+'.hbs', function(template_data){
         var template = Handlebars.compile(template_data);
         $("#create-keys-entry-div").html(template());
         $("#create-keys-button-div").show();
diff --git a/CTFd/static/admin/js/templates/keys/regex/edit-regex-modal.hbs b/CTFd/themes/admin/static/js/templates/keys/regex/edit-regex-modal.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/keys/regex/edit-regex-modal.hbs
rename to CTFd/themes/admin/static/js/templates/keys/regex/edit-regex-modal.hbs
diff --git a/CTFd/static/admin/js/templates/keys/regex/regex.hbs b/CTFd/themes/admin/static/js/templates/keys/regex/regex.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/keys/regex/regex.hbs
rename to CTFd/themes/admin/static/js/templates/keys/regex/regex.hbs
diff --git a/CTFd/static/admin/js/templates/keys/static/edit-static-modal.hbs b/CTFd/themes/admin/static/js/templates/keys/static/edit-static-modal.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/keys/static/edit-static-modal.hbs
rename to CTFd/themes/admin/static/js/templates/keys/static/edit-static-modal.hbs
diff --git a/CTFd/static/admin/js/templates/keys/static/static.hbs b/CTFd/themes/admin/static/js/templates/keys/static/static.hbs
similarity index 100%
rename from CTFd/static/admin/js/templates/keys/static/static.hbs
rename to CTFd/themes/admin/static/js/templates/keys/static/static.hbs
diff --git a/CTFd/static/admin/js/utils.js b/CTFd/themes/admin/static/js/utils.js
similarity index 100%
rename from CTFd/static/admin/js/utils.js
rename to CTFd/themes/admin/static/js/utils.js
diff --git a/CTFd/static/admin/js/vendor/bootstrap.min.js b/CTFd/themes/admin/static/js/vendor/bootstrap.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/bootstrap.min.js
rename to CTFd/themes/admin/static/js/vendor/bootstrap.min.js
diff --git a/CTFd/static/admin/js/vendor/codemirror.min.js b/CTFd/themes/admin/static/js/vendor/codemirror.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/codemirror.min.js
rename to CTFd/themes/admin/static/js/vendor/codemirror.min.js
diff --git a/CTFd/static/admin/js/vendor/handlebars.min.js b/CTFd/themes/admin/static/js/vendor/handlebars.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/handlebars.min.js
rename to CTFd/themes/admin/static/js/vendor/handlebars.min.js
diff --git a/CTFd/static/admin/js/vendor/jquery.min.js b/CTFd/themes/admin/static/js/vendor/jquery.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/jquery.min.js
rename to CTFd/themes/admin/static/js/vendor/jquery.min.js
diff --git a/CTFd/static/admin/js/vendor/marked.min.js b/CTFd/themes/admin/static/js/vendor/marked.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/marked.min.js
rename to CTFd/themes/admin/static/js/vendor/marked.min.js
diff --git a/CTFd/static/admin/js/vendor/moment-timezone-with-data.min.js b/CTFd/themes/admin/static/js/vendor/moment-timezone-with-data.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/moment-timezone-with-data.min.js
rename to CTFd/themes/admin/static/js/vendor/moment-timezone-with-data.min.js
diff --git a/CTFd/static/admin/js/vendor/moment.min.js b/CTFd/themes/admin/static/js/vendor/moment.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/moment.min.js
rename to CTFd/themes/admin/static/js/vendor/moment.min.js
diff --git a/CTFd/static/admin/js/vendor/plotly.min.js b/CTFd/themes/admin/static/js/vendor/plotly.min.js
similarity index 100%
rename from CTFd/static/admin/js/vendor/plotly.min.js
rename to CTFd/themes/admin/static/js/vendor/plotly.min.js
diff --git a/CTFd/templates/admin/base.html b/CTFd/themes/admin/templates/base.html
similarity index 63%
rename from CTFd/templates/admin/base.html
rename to CTFd/themes/admin/templates/base.html
index 0ba60a01..21faea6b 100644
--- a/CTFd/templates/admin/base.html
+++ b/CTFd/themes/admin/templates/base.html
@@ -5,17 +5,17 @@
 		<title>Admin Panel</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0">
-		<link rel="shortcut icon" href="{{ request.script_root }}/static/original/img/favicon.ico" type="image/x-icon">
-		<link rel="icon" href="{{ request.script_root }}/static/original/img/favicon.ico" type="image/x-icon">
-		<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/vendor/bootstrap.min.css">
-		<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/vendor/font-awesome/css/font-awesome.min.css" />
-		<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/style.css">
-		<link href='{{ request.script_root }}/static/admin/css/vendor/lato.css' rel='stylesheet' type='text/css'>
-		<link href='{{ request.script_root }}/static/admin/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
-		<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/style.css">
-		<script src="{{ request.script_root }}/static/admin/js/vendor/moment.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/moment-timezone-with-data.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/handlebars.min.js"></script>
+		<link rel="shortcut icon" href="{{ request.script_root }}/themes/original/static/img/favicon.ico" type="image/x-icon">
+		<link rel="icon" href="{{ request.script_root }}/themes/original/static/img/favicon.ico" type="image/x-icon">
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/admin/static/css/vendor/bootstrap.min.css">
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/admin/static/css/vendor/font-awesome/css/font-awesome.min.css" />
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/admin/static/css/style.css">
+		<link href='{{ request.script_root }}/themes/admin/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
+		<link href='{{ request.script_root }}/themes/admin/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
+		<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/themes/admin/static/css/style.css">
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/moment.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/moment-timezone-with-data.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/handlebars.min.js"></script>
 		<script type="text/javascript">
 				var script_root = "{{ request.script_root }}";
 		</script>
@@ -74,11 +74,11 @@
 				</div>
 		</div>
 	</div>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/jquery.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/marked.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/bootstrap.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/main.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/jquery.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/marked.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/bootstrap.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/main.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
 		{% block scripts %} {% endblock %}
 </body>
 
diff --git a/CTFd/templates/admin/chals.html b/CTFd/themes/admin/templates/chals.html
similarity index 83%
rename from CTFd/templates/admin/chals.html
rename to CTFd/themes/admin/templates/chals.html
index 98063f40..f1dba254 100644
--- a/CTFd/templates/admin/chals.html
+++ b/CTFd/themes/admin/templates/chals.html
@@ -50,7 +50,7 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
-	<script src="{{ request.script_root }}/static/admin/js/chalboard.js"></script>
-	<script src="{{ request.script_root }}/static/admin/js/multi-modal.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/chalboard.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/multi-modal.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/admin/chals/create.html b/CTFd/themes/admin/templates/chals/create.html
similarity index 79%
rename from CTFd/templates/admin/chals/create.html
rename to CTFd/themes/admin/templates/chals/create.html
index 1f594514..8028cb7d 100644
--- a/CTFd/templates/admin/chals/create.html
+++ b/CTFd/themes/admin/templates/chals/create.html
@@ -31,15 +31,15 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
-	<script src="{{ request.script_root }}/static/admin/js/vendor/codemirror.min.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/vendor/codemirror.min.js"></script>
 	<script>
 
 	function load_chal_template(chal_type_name){
-		$.get(script_root + '/static/admin/js/templates/challenges/'+ chal_type_name +'/' + chal_type_name + '-challenge-create.hbs', function(template_data){
+		$.get(script_root + '/themes/admin/static/js/templates/challenges/'+ chal_type_name +'/' + chal_type_name + '-challenge-create.hbs', function(template_data){
 			var template = Handlebars.compile(template_data);
 			$("#create-chal-entry-div").html(template({'nonce':nonce, 'script_root':script_root}));
-			$.getScript(script_root + '/static/admin/js/templates/challenges/'+chal_type_name+'/'+chal_type_name+'-challenge-create.js', function(){
+			$.getScript(script_root + '/themes/admin/static/js/templates/challenges/'+chal_type_name+'/'+chal_type_name+'-challenge-create.js', function(){
 				console.log('loaded');
 			});
 		});
diff --git a/CTFd/templates/admin/config.html b/CTFd/themes/admin/templates/config.html
similarity index 100%
rename from CTFd/templates/admin/config.html
rename to CTFd/themes/admin/templates/config.html
diff --git a/CTFd/templates/admin/containers.html b/CTFd/themes/admin/templates/containers.html
similarity index 100%
rename from CTFd/templates/admin/containers.html
rename to CTFd/themes/admin/templates/containers.html
diff --git a/CTFd/templates/admin/correct_keys.html b/CTFd/themes/admin/templates/correct_keys.html
similarity index 97%
rename from CTFd/templates/admin/correct_keys.html
rename to CTFd/themes/admin/templates/correct_keys.html
index 4f8c8c55..78522f60 100644
--- a/CTFd/templates/admin/correct_keys.html
+++ b/CTFd/themes/admin/templates/correct_keys.html
@@ -77,7 +77,7 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
 	<script>
 	$('#delete-solve').click(function(e){
 		e.preventDefault();
diff --git a/CTFd/templates/admin/editor.html b/CTFd/themes/admin/templates/editor.html
similarity index 97%
rename from CTFd/templates/admin/editor.html
rename to CTFd/themes/admin/templates/editor.html
index f000bbc1..bd3d7d6f 100644
--- a/CTFd/templates/admin/editor.html
+++ b/CTFd/themes/admin/templates/editor.html
@@ -1,7 +1,7 @@
 {% extends "admin/base.html" %}
 
 {% block stylesheets %}
-	<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/vendor/codemirror.min.css">
+	<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/themes/admin/static/css/vendor/codemirror.min.css">
 	<style>
 	.row-fluid { margin: 25px; padding-bottom: 25px; }
 	.media-item-wrapper { height: 120px; margin: 5px;
@@ -129,8 +129,8 @@
 {% endblock %}
 
 {% block scripts %}
-<script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
-<script src="{{ request.script_root }}/static/admin/js/vendor/codemirror.min.js"></script>
+<script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
+<script src="{{ request.script_root }}/themes/admin/static/js/vendor/codemirror.min.js"></script>
 <script>
 	function uploadfiles(){
 		var form = $('#media-library-upload')[0];
diff --git a/CTFd/templates/admin/graphs.html b/CTFd/themes/admin/templates/graphs.html
similarity index 97%
rename from CTFd/templates/admin/graphs.html
rename to CTFd/themes/admin/templates/graphs.html
index 91ecfd68..e805403d 100644
--- a/CTFd/templates/admin/graphs.html
+++ b/CTFd/themes/admin/templates/graphs.html
@@ -29,7 +29,7 @@
 			display: block;
 		}
 	</style>
-	<script src="{{ request.script_root }}/static/admin/js/vendor/plotly.min.js"></script>
+	<script src="{{ request.script_root }}/themes/admin/static/js/vendor/plotly.min.js"></script>
 	<script type="text/javascript">
 		// $.distint(array)
 		// Unique elements in array
diff --git a/CTFd/templates/admin/page.html b/CTFd/themes/admin/templates/page.html
similarity index 63%
rename from CTFd/templates/admin/page.html
rename to CTFd/themes/admin/templates/page.html
index f763f731..5fb171b6 100644
--- a/CTFd/templates/admin/page.html
+++ b/CTFd/themes/admin/templates/page.html
@@ -5,17 +5,17 @@
 		<title>Admin Panel</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0">
-		<link rel="shortcut icon" href="{{ request.script_root }}/static/original/img/favicon.ico" type="image/x-icon">
-		<link rel="icon" href="{{ request.script_root }}/static/original/img/favicon.ico" type="image/x-icon">
-		<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/vendor/bootstrap.min.css">
-		<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/vendor/font-awesome/css/font-awesome.min.css" />
-		<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/style.css">
-		<link href='{{ request.script_root }}/static/admin/css/vendor/lato.css' rel='stylesheet' type='text/css'>
-		<link href='{{ request.script_root }}/static/admin/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
-		<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/style.css">
-		<script src="{{ request.script_root }}/static/admin/js/vendor/moment.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/moment-timezone-with-data.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/handlebars.min.js"></script>
+		<link rel="shortcut icon" href="{{ request.script_root }}/themes/original/static/img/favicon.ico" type="image/x-icon">
+		<link rel="icon" href="{{ request.script_root }}/themes/original/static/img/favicon.ico" type="image/x-icon">
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/admin/static/css/vendor/bootstrap.min.css">
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/admin/static/css/vendor/font-awesome/css/font-awesome.min.css" />
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/admin/static/css/style.css">
+		<link href='{{ request.script_root }}/themes/admin/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
+		<link href='{{ request.script_root }}/themes/admin/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
+		<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/themes/admin/static/css/style.css">
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/moment.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/moment-timezone-with-data.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/handlebars.min.js"></script>
 		<script type="text/javascript">
 				var script_root = "{{ request.script_root }}";
 		</script>
@@ -70,9 +70,9 @@
 				{{ content | safe }}
 		</div>
 </div>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/jquery.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/marked.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/bootstrap.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/jquery.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/marked.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/bootstrap.min.js"></script>
 		{% block scripts %} {% endblock %}
 </body>
 
diff --git a/CTFd/templates/admin/pages.html b/CTFd/themes/admin/templates/pages.html
similarity index 95%
rename from CTFd/templates/admin/pages.html
rename to CTFd/themes/admin/templates/pages.html
index 7c3746da..63ec892e 100644
--- a/CTFd/templates/admin/pages.html
+++ b/CTFd/themes/admin/templates/pages.html
@@ -1,7 +1,7 @@
 {% extends "admin/base.html" %}
 
 {% block stylesheets %}
-	<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/vendor/codemirror.min.css">
+	<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/themes/admin/static/css/vendor/codemirror.min.css">
 	<style>
 		.CodeMirror {
 			padding-left: 15px;
@@ -78,7 +78,7 @@
 {% endblock %}
 
 {% block scripts %}
-<script src="{{ request.script_root }}/static/admin/js/vendor/codemirror.min.js"></script>
+<script src="{{ request.script_root }}/themes/admin/static/js/vendor/codemirror.min.js"></script>
 <script>
 var editor = CodeMirror.fromTextArea(document.getElementById("pages-editor"), {
 	lineNumbers: true,
diff --git a/CTFd/templates/admin/scoreboard.html b/CTFd/themes/admin/templates/scoreboard.html
similarity index 100%
rename from CTFd/templates/admin/scoreboard.html
rename to CTFd/themes/admin/templates/scoreboard.html
diff --git a/CTFd/templates/admin/statistics.html b/CTFd/themes/admin/templates/statistics.html
similarity index 100%
rename from CTFd/templates/admin/statistics.html
rename to CTFd/themes/admin/templates/statistics.html
diff --git a/CTFd/templates/admin/team.html b/CTFd/themes/admin/templates/team.html
similarity index 97%
rename from CTFd/templates/admin/team.html
rename to CTFd/themes/admin/templates/team.html
index 31b1401a..21951459 100644
--- a/CTFd/templates/admin/team.html
+++ b/CTFd/themes/admin/templates/team.html
@@ -221,10 +221,10 @@
 {% endblock %}
 
 {% block scripts %}
-		<script src="{{ request.script_root }}/static/admin/js/vendor/moment.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/vendor/plotly.min.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
-		<script src="{{ request.script_root }}/static/admin/js/team.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/moment.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/vendor/plotly.min.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
+		<script src="{{ request.script_root }}/themes/admin/static/js/team.js"></script>
 		<script>
 				$('#delete-solve').click(function (e) {
 						e.preventDefault();
diff --git a/CTFd/templates/admin/teams.html b/CTFd/themes/admin/templates/teams.html
similarity index 100%
rename from CTFd/templates/admin/teams.html
rename to CTFd/themes/admin/templates/teams.html
diff --git a/CTFd/templates/admin/wrong_keys.html b/CTFd/themes/admin/templates/wrong_keys.html
similarity index 98%
rename from CTFd/templates/admin/wrong_keys.html
rename to CTFd/themes/admin/templates/wrong_keys.html
index 71492400..3660f36b 100644
--- a/CTFd/templates/admin/wrong_keys.html
+++ b/CTFd/themes/admin/templates/wrong_keys.html
@@ -84,7 +84,7 @@
 {% endblock %}
 
 {% block scripts %}
-    <script src="{{ request.script_root }}/static/admin/js/utils.js"></script>
+    <script src="{{ request.script_root }}/themes/admin/static/js/utils.js"></script>
     <script>
         $('#delete-solve').click(function (e) {
             e.preventDefault();
diff --git a/CTFd/static/original/css/style.css b/CTFd/themes/original/static/css/style.css
similarity index 100%
rename from CTFd/static/original/css/style.css
rename to CTFd/themes/original/static/css/style.css
diff --git a/CTFd/static/original/css/vendor/bootstrap.min.css b/CTFd/themes/original/static/css/vendor/bootstrap.min.css
similarity index 100%
rename from CTFd/static/original/css/vendor/bootstrap.min.css
rename to CTFd/themes/original/static/css/vendor/bootstrap.min.css
diff --git a/CTFd/static/original/css/vendor/codemirror.min.css b/CTFd/themes/original/static/css/vendor/codemirror.min.css
similarity index 100%
rename from CTFd/static/original/css/vendor/codemirror.min.css
rename to CTFd/themes/original/static/css/vendor/codemirror.min.css
diff --git a/CTFd/static/original/css/vendor/font-awesome/HELP-US-OUT.txt b/CTFd/themes/original/static/css/vendor/font-awesome/HELP-US-OUT.txt
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/HELP-US-OUT.txt
rename to CTFd/themes/original/static/css/vendor/font-awesome/HELP-US-OUT.txt
diff --git a/CTFd/static/original/css/vendor/font-awesome/css/font-awesome.css b/CTFd/themes/original/static/css/vendor/font-awesome/css/font-awesome.css
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/css/font-awesome.css
rename to CTFd/themes/original/static/css/vendor/font-awesome/css/font-awesome.css
diff --git a/CTFd/static/original/css/vendor/font-awesome/css/font-awesome.min.css b/CTFd/themes/original/static/css/vendor/font-awesome/css/font-awesome.min.css
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/css/font-awesome.min.css
rename to CTFd/themes/original/static/css/vendor/font-awesome/css/font-awesome.min.css
diff --git a/CTFd/static/original/css/vendor/font-awesome/fonts/FontAwesome.otf b/CTFd/themes/original/static/css/vendor/font-awesome/fonts/FontAwesome.otf
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/fonts/FontAwesome.otf
rename to CTFd/themes/original/static/css/vendor/font-awesome/fonts/FontAwesome.otf
diff --git a/CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.eot b/CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.eot
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.eot
rename to CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.eot
diff --git a/CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.svg b/CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.svg
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.svg
rename to CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.svg
diff --git a/CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf b/CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf
rename to CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.ttf
diff --git a/CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.woff b/CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.woff
rename to CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff
diff --git a/CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2 b/CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2
rename to CTFd/themes/original/static/css/vendor/font-awesome/fonts/fontawesome-webfont.woff2
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/animated.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/animated.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/animated.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/animated.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/bordered-pulled.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/bordered-pulled.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/bordered-pulled.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/bordered-pulled.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/core.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/core.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/core.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/core.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/fixed-width.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/fixed-width.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/fixed-width.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/fixed-width.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/font-awesome.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/font-awesome.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/font-awesome.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/font-awesome.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/icons.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/icons.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/icons.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/icons.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/larger.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/larger.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/larger.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/larger.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/list.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/list.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/list.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/list.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/mixins.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/mixins.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/mixins.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/mixins.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/path.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/path.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/path.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/path.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/rotated-flipped.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/rotated-flipped.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/rotated-flipped.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/rotated-flipped.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/stacked.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/stacked.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/stacked.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/stacked.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/less/variables.less b/CTFd/themes/original/static/css/vendor/font-awesome/less/variables.less
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/less/variables.less
rename to CTFd/themes/original/static/css/vendor/font-awesome/less/variables.less
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_animated.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_animated.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_animated.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_animated.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_bordered-pulled.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_bordered-pulled.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_bordered-pulled.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_bordered-pulled.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_core.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_core.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_core.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_core.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_fixed-width.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_fixed-width.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_fixed-width.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_fixed-width.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_icons.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_icons.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_icons.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_icons.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_larger.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_larger.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_larger.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_larger.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_list.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_list.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_list.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_list.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_mixins.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_mixins.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_mixins.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_mixins.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_path.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_path.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_path.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_path.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_rotated-flipped.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_rotated-flipped.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_rotated-flipped.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_rotated-flipped.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_stacked.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_stacked.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_stacked.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_stacked.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/_variables.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/_variables.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/_variables.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/_variables.scss
diff --git a/CTFd/static/original/css/vendor/font-awesome/scss/font-awesome.scss b/CTFd/themes/original/static/css/vendor/font-awesome/scss/font-awesome.scss
similarity index 100%
rename from CTFd/static/original/css/vendor/font-awesome/scss/font-awesome.scss
rename to CTFd/themes/original/static/css/vendor/font-awesome/scss/font-awesome.scss
diff --git a/CTFd/static/original/css/vendor/lato.css b/CTFd/themes/original/static/css/vendor/lato.css
similarity index 100%
rename from CTFd/static/original/css/vendor/lato.css
rename to CTFd/themes/original/static/css/vendor/lato.css
diff --git a/CTFd/static/original/css/vendor/raleway.css b/CTFd/themes/original/static/css/vendor/raleway.css
similarity index 100%
rename from CTFd/static/original/css/vendor/raleway.css
rename to CTFd/themes/original/static/css/vendor/raleway.css
diff --git a/CTFd/static/original/fonts/lato/lato-v11-latin-regular.eot b/CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.eot
similarity index 100%
rename from CTFd/static/original/fonts/lato/lato-v11-latin-regular.eot
rename to CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.eot
diff --git a/CTFd/static/original/fonts/lato/lato-v11-latin-regular.svg b/CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.svg
similarity index 100%
rename from CTFd/static/original/fonts/lato/lato-v11-latin-regular.svg
rename to CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.svg
diff --git a/CTFd/static/original/fonts/lato/lato-v11-latin-regular.ttf b/CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.ttf
similarity index 100%
rename from CTFd/static/original/fonts/lato/lato-v11-latin-regular.ttf
rename to CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.ttf
diff --git a/CTFd/static/original/fonts/lato/lato-v11-latin-regular.woff b/CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.woff
similarity index 100%
rename from CTFd/static/original/fonts/lato/lato-v11-latin-regular.woff
rename to CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.woff
diff --git a/CTFd/static/original/fonts/lato/lato-v11-latin-regular.woff2 b/CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.woff2
similarity index 100%
rename from CTFd/static/original/fonts/lato/lato-v11-latin-regular.woff2
rename to CTFd/themes/original/static/fonts/lato/lato-v11-latin-regular.woff2
diff --git a/CTFd/static/original/fonts/raleway/raleway-v10-latin-500.eot b/CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.eot
similarity index 100%
rename from CTFd/static/original/fonts/raleway/raleway-v10-latin-500.eot
rename to CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.eot
diff --git a/CTFd/static/original/fonts/raleway/raleway-v10-latin-500.svg b/CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.svg
similarity index 100%
rename from CTFd/static/original/fonts/raleway/raleway-v10-latin-500.svg
rename to CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.svg
diff --git a/CTFd/static/original/fonts/raleway/raleway-v10-latin-500.ttf b/CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.ttf
similarity index 100%
rename from CTFd/static/original/fonts/raleway/raleway-v10-latin-500.ttf
rename to CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.ttf
diff --git a/CTFd/static/original/fonts/raleway/raleway-v10-latin-500.woff b/CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.woff
similarity index 100%
rename from CTFd/static/original/fonts/raleway/raleway-v10-latin-500.woff
rename to CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.woff
diff --git a/CTFd/static/original/fonts/raleway/raleway-v10-latin-500.woff2 b/CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.woff2
similarity index 100%
rename from CTFd/static/original/fonts/raleway/raleway-v10-latin-500.woff2
rename to CTFd/themes/original/static/fonts/raleway/raleway-v10-latin-500.woff2
diff --git a/CTFd/static/original/img/ctfd.ai b/CTFd/themes/original/static/img/ctfd.ai
similarity index 100%
rename from CTFd/static/original/img/ctfd.ai
rename to CTFd/themes/original/static/img/ctfd.ai
diff --git a/CTFd/static/original/img/ctfd.svg b/CTFd/themes/original/static/img/ctfd.svg
similarity index 100%
rename from CTFd/static/original/img/ctfd.svg
rename to CTFd/themes/original/static/img/ctfd.svg
diff --git a/CTFd/static/original/img/ctfd_transfer.svg b/CTFd/themes/original/static/img/ctfd_transfer.svg
similarity index 100%
rename from CTFd/static/original/img/ctfd_transfer.svg
rename to CTFd/themes/original/static/img/ctfd_transfer.svg
diff --git a/CTFd/static/original/img/favicon.ico b/CTFd/themes/original/static/img/favicon.ico
similarity index 100%
rename from CTFd/static/original/img/favicon.ico
rename to CTFd/themes/original/static/img/favicon.ico
diff --git a/CTFd/static/original/img/logo.png b/CTFd/themes/original/static/img/logo.png
similarity index 100%
rename from CTFd/static/original/img/logo.png
rename to CTFd/themes/original/static/img/logo.png
diff --git a/CTFd/static/original/img/logo_old.png b/CTFd/themes/original/static/img/logo_old.png
similarity index 100%
rename from CTFd/static/original/img/logo_old.png
rename to CTFd/themes/original/static/img/logo_old.png
diff --git a/CTFd/static/original/img/scoreboard.png b/CTFd/themes/original/static/img/scoreboard.png
similarity index 100%
rename from CTFd/static/original/img/scoreboard.png
rename to CTFd/themes/original/static/img/scoreboard.png
diff --git a/CTFd/static/original/js/chalboard.js b/CTFd/themes/original/static/js/chalboard.js
similarity index 97%
rename from CTFd/static/original/js/chalboard.js
rename to CTFd/themes/original/static/js/chalboard.js
index 156e3aec..7e09feae 100644
--- a/CTFd/static/original/js/chalboard.js
+++ b/CTFd/themes/original/static/js/chalboard.js
@@ -24,7 +24,7 @@ function loadchalbyname(chalname) {
 }
 
 function updateChalWindow(obj) {
-    $.get(script_root + '/static/original/js/templates/challenges/'+obj.type+'/'+obj.type+'-challenge-modal.hbs', function(template_data){
+    $.get(script_root + '/themes/original/static/js/templates/challenges/'+obj.type+'/'+obj.type+'-challenge-modal.hbs', function(template_data){
         $('#chal-window').empty();
         templates[obj.type] = template_data;
         var template_data = templates[obj.type];
@@ -46,7 +46,7 @@ function updateChalWindow(obj) {
         };
 
         $('#chal-window').append(template(wrapper));
-        $.getScript(script_root + '/static/original/js/templates/challenges/'+obj.type+'/'+obj.type+'-challenge-script.js',
+        $.getScript(script_root + '/themes/original/static/js/templates/challenges/'+obj.type+'/'+obj.type+'-challenge-script.js',
             function() {
                 // Handle Solves tab
                 $('.chal-solves').click(function (e) {
diff --git a/CTFd/static/original/js/multi-modal.js b/CTFd/themes/original/static/js/multi-modal.js
similarity index 100%
rename from CTFd/static/original/js/multi-modal.js
rename to CTFd/themes/original/static/js/multi-modal.js
diff --git a/CTFd/static/original/js/scoreboard.js b/CTFd/themes/original/static/js/scoreboard.js
similarity index 100%
rename from CTFd/static/original/js/scoreboard.js
rename to CTFd/themes/original/static/js/scoreboard.js
diff --git a/CTFd/static/original/js/style.js b/CTFd/themes/original/static/js/style.js
similarity index 100%
rename from CTFd/static/original/js/style.js
rename to CTFd/themes/original/static/js/style.js
diff --git a/CTFd/static/original/js/team.js b/CTFd/themes/original/static/js/team.js
similarity index 100%
rename from CTFd/static/original/js/team.js
rename to CTFd/themes/original/static/js/team.js
diff --git a/CTFd/static/original/js/templates/challenges/standard/standard-challenge-modal.hbs b/CTFd/themes/original/static/js/templates/challenges/standard/standard-challenge-modal.hbs
similarity index 100%
rename from CTFd/static/original/js/templates/challenges/standard/standard-challenge-modal.hbs
rename to CTFd/themes/original/static/js/templates/challenges/standard/standard-challenge-modal.hbs
diff --git a/CTFd/static/original/js/templates/challenges/standard/standard-challenge-script.js b/CTFd/themes/original/static/js/templates/challenges/standard/standard-challenge-script.js
similarity index 100%
rename from CTFd/static/original/js/templates/challenges/standard/standard-challenge-script.js
rename to CTFd/themes/original/static/js/templates/challenges/standard/standard-challenge-script.js
diff --git a/CTFd/static/original/js/utils.js b/CTFd/themes/original/static/js/utils.js
similarity index 100%
rename from CTFd/static/original/js/utils.js
rename to CTFd/themes/original/static/js/utils.js
diff --git a/CTFd/static/original/js/vendor/bootstrap.min.js b/CTFd/themes/original/static/js/vendor/bootstrap.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/bootstrap.min.js
rename to CTFd/themes/original/static/js/vendor/bootstrap.min.js
diff --git a/CTFd/static/original/js/vendor/codemirror.min.js b/CTFd/themes/original/static/js/vendor/codemirror.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/codemirror.min.js
rename to CTFd/themes/original/static/js/vendor/codemirror.min.js
diff --git a/CTFd/static/original/js/vendor/handlebars.min.js b/CTFd/themes/original/static/js/vendor/handlebars.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/handlebars.min.js
rename to CTFd/themes/original/static/js/vendor/handlebars.min.js
diff --git a/CTFd/static/original/js/vendor/jquery.min.js b/CTFd/themes/original/static/js/vendor/jquery.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/jquery.min.js
rename to CTFd/themes/original/static/js/vendor/jquery.min.js
diff --git a/CTFd/static/original/js/vendor/marked.min.js b/CTFd/themes/original/static/js/vendor/marked.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/marked.min.js
rename to CTFd/themes/original/static/js/vendor/marked.min.js
diff --git a/CTFd/static/original/js/vendor/moment-timezone-with-data.min.js b/CTFd/themes/original/static/js/vendor/moment-timezone-with-data.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/moment-timezone-with-data.min.js
rename to CTFd/themes/original/static/js/vendor/moment-timezone-with-data.min.js
diff --git a/CTFd/static/original/js/vendor/moment.min.js b/CTFd/themes/original/static/js/vendor/moment.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/moment.min.js
rename to CTFd/themes/original/static/js/vendor/moment.min.js
diff --git a/CTFd/static/original/js/vendor/plotly.min.js b/CTFd/themes/original/static/js/vendor/plotly.min.js
similarity index 100%
rename from CTFd/static/original/js/vendor/plotly.min.js
rename to CTFd/themes/original/static/js/vendor/plotly.min.js
diff --git a/CTFd/templates/original/base.html b/CTFd/themes/original/templates/base.html
similarity index 63%
rename from CTFd/templates/original/base.html
rename to CTFd/themes/original/templates/base.html
index 0a27986c..ae9d3aab 100644
--- a/CTFd/templates/original/base.html
+++ b/CTFd/themes/original/templates/base.html
@@ -4,17 +4,17 @@
 		<title>{{ ctf_name() }}</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0">
-		<link rel="shortcut icon" href="{{ request.script_root }}/static/{{ ctf_theme() }}/img/favicon.ico" type="image/x-icon">
-		<link rel="icon" href="{{ request.script_root }}/static/{{ ctf_theme() }}/img/favicon.ico" type="image/x-icon">
-		<link rel="stylesheet" href="{{ request.script_root }}/static/{{ ctf_theme() }}/css/vendor/bootstrap.min.css">
-		<link rel="stylesheet" href="{{ request.script_root }}/static/{{ ctf_theme() }}/css/vendor/font-awesome/css/font-awesome.min.css" />
-		<link href='{{ request.script_root }}/static/{{ ctf_theme() }}/css/vendor/lato.css' rel='stylesheet' type='text/css'>
-		<link href='{{ request.script_root }}/static/{{ ctf_theme() }}/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
-		<link rel="stylesheet" href="{{ request.script_root }}/static/{{ ctf_theme() }}/css/style.css">
+		<link rel="shortcut icon" href="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/img/favicon.ico" type="image/x-icon">
+		<link rel="icon" href="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/img/favicon.ico" type="image/x-icon">
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/css/vendor/bootstrap.min.css">
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/css/vendor/font-awesome/css/font-awesome.min.css" />
+		<link href='{{ request.script_root }}/themes/{{ ctf_theme() }}/static/css/vendor/lato.css' rel='stylesheet' type='text/css'>
+		<link href='{{ request.script_root }}/themes/{{ ctf_theme() }}/static/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
+		<link rel="stylesheet" href="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/css/style.css">
 		<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/user.css">
 		{% block stylesheets %}{% endblock %}
-		<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/vendor/moment.min.js"></script>
-		<script src="{{ request.script_root }}/static/original/js/vendor/handlebars.min.js"></script>
+		<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/vendor/moment.min.js"></script>
+		<script src="{{ request.script_root }}/themes/original/static/js/vendor/handlebars.min.js"></script>
 		<script type="text/javascript">
 				var script_root = "{{ request.script_root }}";
 		</script>
@@ -69,9 +69,9 @@
 				<p class="text-muted text-center"><a style="text-decoration:none;" href="https://ctfd.io"><sub>Powered by CTFd</sub></p>
 		</div>
 	</div>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/vendor/jquery.min.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/vendor/marked.min.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/vendor/bootstrap.min.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/vendor/jquery.min.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/vendor/marked.min.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/vendor/bootstrap.min.js"></script>
 	{% block scripts %}
 	{% endblock %}
 </body>
diff --git a/CTFd/templates/original/chals.html b/CTFd/themes/original/templates/chals.html
similarity index 86%
rename from CTFd/templates/original/chals.html
rename to CTFd/themes/original/templates/chals.html
index 917ad660..dde75e7e 100644
--- a/CTFd/templates/original/chals.html
+++ b/CTFd/themes/original/templates/chals.html
@@ -8,6 +8,7 @@
 	.category-header {text-align: center}
 	.challenge-wrapper {padding: 5px;}
 	.challenge-button {width: 100%; height:100px;}
+	.challenge-button:hover {opacity: 0.9;}
 	.submit-row {padding-top: 0px; padding-right: 0px; padding-left: 0px;}
 	.disabled-button {background-color: #EEEEEE}
 
@@ -122,8 +123,8 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/utils.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/multi-modal.js"></script>
-	{% if not errors %}<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/chalboard.js"></script>{% endif %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/utils.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/multi-modal.js"></script>
+	{% if not errors %}<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/chalboard.js"></script>{% endif %}
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/original/confirm.html b/CTFd/themes/original/templates/confirm.html
similarity index 91%
rename from CTFd/templates/original/confirm.html
rename to CTFd/themes/original/templates/confirm.html
index 291cfd10..37281d5d 100644
--- a/CTFd/templates/original/confirm.html
+++ b/CTFd/themes/original/templates/confirm.html
@@ -44,6 +44,6 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 {% endblock %}
 
diff --git a/CTFd/templates/original/errors/403.html b/CTFd/themes/original/templates/errors/403.html
similarity index 100%
rename from CTFd/templates/original/errors/403.html
rename to CTFd/themes/original/templates/errors/403.html
diff --git a/CTFd/templates/original/errors/404.html b/CTFd/themes/original/templates/errors/404.html
similarity index 100%
rename from CTFd/templates/original/errors/404.html
rename to CTFd/themes/original/templates/errors/404.html
diff --git a/CTFd/templates/original/errors/500.html b/CTFd/themes/original/templates/errors/500.html
similarity index 100%
rename from CTFd/templates/original/errors/500.html
rename to CTFd/themes/original/templates/errors/500.html
diff --git a/CTFd/templates/original/errors/502.html b/CTFd/themes/original/templates/errors/502.html
similarity index 100%
rename from CTFd/templates/original/errors/502.html
rename to CTFd/themes/original/templates/errors/502.html
diff --git a/CTFd/templates/original/login.html b/CTFd/themes/original/templates/login.html
similarity index 95%
rename from CTFd/templates/original/login.html
rename to CTFd/themes/original/templates/login.html
index e44e3fcf..2f276cb4 100644
--- a/CTFd/templates/original/login.html
+++ b/CTFd/themes/original/templates/login.html
@@ -67,6 +67,6 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 {% endblock %}
 
diff --git a/CTFd/templates/original/page.html b/CTFd/themes/original/templates/page.html
similarity index 100%
rename from CTFd/templates/original/page.html
rename to CTFd/themes/original/templates/page.html
diff --git a/CTFd/templates/original/profile.html b/CTFd/themes/original/templates/profile.html
similarity index 98%
rename from CTFd/templates/original/profile.html
rename to CTFd/themes/original/templates/profile.html
index 11198963..26f7317e 100644
--- a/CTFd/templates/original/profile.html
+++ b/CTFd/themes/original/templates/profile.html
@@ -136,5 +136,5 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/original/register.html b/CTFd/themes/original/templates/register.html
similarity index 95%
rename from CTFd/templates/original/register.html
rename to CTFd/themes/original/templates/register.html
index 97dc79ac..01b40cff 100644
--- a/CTFd/templates/original/register.html
+++ b/CTFd/themes/original/templates/register.html
@@ -63,7 +63,7 @@
 {% endblock %}
 
 {% block scripts %}
-<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 <script>
 	if (window.location.hash == "#frame"){
 		$('.top-bar').hide()
diff --git a/CTFd/templates/original/reset_password.html b/CTFd/themes/original/templates/reset_password.html
similarity index 95%
rename from CTFd/templates/original/reset_password.html
rename to CTFd/themes/original/templates/reset_password.html
index 281c26a9..1b32d830 100644
--- a/CTFd/templates/original/reset_password.html
+++ b/CTFd/themes/original/templates/reset_password.html
@@ -55,5 +55,5 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/original/scoreboard.html b/CTFd/themes/original/templates/scoreboard.html
similarity index 77%
rename from CTFd/templates/original/scoreboard.html
rename to CTFd/themes/original/templates/scoreboard.html
index a4315560..ec2fa0f1 100644
--- a/CTFd/templates/original/scoreboard.html
+++ b/CTFd/themes/original/templates/scoreboard.html
@@ -50,7 +50,7 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/vendor/plotly.min.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/utils.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/scoreboard.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/vendor/plotly.min.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/utils.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/scoreboard.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/original/setup.html b/CTFd/themes/original/templates/setup.html
similarity index 95%
rename from CTFd/templates/original/setup.html
rename to CTFd/themes/original/templates/setup.html
index 1e1c76ab..1ce8f3bc 100644
--- a/CTFd/templates/original/setup.html
+++ b/CTFd/themes/original/templates/setup.html
@@ -58,5 +58,5 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/style.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/style.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/original/team.html b/CTFd/themes/original/templates/team.html
similarity index 88%
rename from CTFd/templates/original/team.html
rename to CTFd/themes/original/templates/team.html
index 0bb4d4da..0c90dbaf 100644
--- a/CTFd/templates/original/team.html
+++ b/CTFd/themes/original/templates/team.html
@@ -97,7 +97,7 @@
 {% endblock %}
 
 {% block scripts %}
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/vendor/plotly.min.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/utils.js"></script>
-	<script src="{{ request.script_root }}/static/{{ ctf_theme() }}/js/team.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/vendor/plotly.min.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/utils.js"></script>
+	<script src="{{ request.script_root }}/themes/{{ ctf_theme() }}/static/js/team.js"></script>
 {% endblock %}
diff --git a/CTFd/templates/original/teams.html b/CTFd/themes/original/templates/teams.html
similarity index 100%
rename from CTFd/templates/original/teams.html
rename to CTFd/themes/original/templates/teams.html
diff --git a/CTFd/utils.py b/CTFd/utils.py
index ac4f3681..19e97649 100644
--- a/CTFd/utils.py
+++ b/CTFd/utils.py
@@ -328,7 +328,7 @@ def get_kpm(teamid):  # keys per minute
 
 
 def get_themes():
-    dir = os.path.join(app.root_path, app.template_folder)
+    dir = os.path.join(app.root_path, 'themes')
     return [name for name in os.listdir(dir)
             if os.path.isdir(os.path.join(dir, name)) and name != 'admin']
 
diff --git a/CTFd/views.py b/CTFd/views.py
index c30d2b80..16c4055f 100644
--- a/CTFd/views.py
+++ b/CTFd/views.py
@@ -2,6 +2,7 @@ import os
 import re
 
 from flask import current_app as app, render_template, request, redirect, abort, jsonify, url_for, session, Blueprint, Response, send_file
+from flask.helpers import safe_join
 from jinja2.exceptions import TemplateNotFound
 from passlib.hash import bcrypt_sha256
 
@@ -45,7 +46,7 @@ def setup():
 
             # Index page
             page = Pages('index', """<div class="container main-container">
-    <img class="logo" src="static/original/img/logo.png" />
+    <img class="logo" src="themes/original/static/img/logo.png" />
     <h3 class="text-center">
         <p>A cool CTF platform from <a href="https://ctfd.io">ctfd.io</a></p>
         <p>Follow us on social media:</p>
@@ -261,4 +262,13 @@ def file_handler(path):
                 else:
                     abort(403)
     upload_folder = os.path.join(app.root_path, app.config['UPLOAD_FOLDER'])
-    return send_file(os.path.join(upload_folder, f.location))
+    return send_file(safe_join(upload_folder, f.location))
+
+
+@views.route('/themes/<theme>/static/<path:path>')
+def themes_handler(theme, path):
+    filename = safe_join(app.root_path, 'themes', theme, 'static', path)
+    if os.path.isfile(filename):
+        return send_file(filename)
+    else:
+        abort(404)


Test patch:
diff --git a/tests/test_user_facing.py b/tests/test_user_facing.py
index c4c22b80..8ad24c9b 100644
--- a/tests/test_user_facing.py
+++ b/tests/test_user_facing.py
@@ -279,3 +279,22 @@ def test_pages_routing_and_rendering():
             r = client.get('/test')
             output = r.get_data(as_text=True)
             assert "<h2>The quick brown fox jumped over the lazy dog</h2>" in output
+
+
+def test_themes_handler():
+    """Test that the themes handler is working properly"""
+    app = create_ctfd()
+    with app.app_context():
+        with app.test_client() as client:
+            r = client.get('/themes/original/static/css/style.css')
+            assert r.status_code == 200
+            r = client.get('/themes/original/static/css/404_NOT_FOUND')
+            assert r.status_code == 404
+            r = client.get('/themes/original/static/%2e%2e/%2e%2e/%2e%2e/utils.py')
+            assert r.status_code == 404
+            r = client.get('/themes/original/static/%2e%2e%2f%2e%2e%2f%2e%2e%2futils.py')
+            assert r.status_code == 404
+            r = client.get('/themes/original/static/..%2f..%2f..%2futils.py')
+            assert r.status_code == 404
+            r = client.get('/themes/original/static/../../../utils.py')
+            assert r.status_code == 404