We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Challenge Preview Improvements
Challenge Preview should probably preview in the context of a full page. Primarily because it's easier to theme this. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `CTFd/admin/challenges.py`
Content:
```
1 from flask import abort, render_template, request, url_for
2 
3 from CTFd.admin import admin
4 from CTFd.models import Challenges, Flags, Solves
5 from CTFd.plugins.challenges import CHALLENGE_CLASSES, get_chal_class
6 from CTFd.utils.decorators import admins_only
7 
8 
9 @admin.route("/admin/challenges")
10 @admins_only
11 def challenges_listing():
12     q = request.args.get("q")
13     field = request.args.get("field")
14     filters = []
15 
16     if q:
17         # The field exists as an exposed column
18         if Challenges.__mapper__.has_property(field):
19             filters.append(getattr(Challenges, field).like("%{}%".format(q)))
20 
21     query = Challenges.query.filter(*filters).order_by(Challenges.id.asc())
22     challenges = query.all()
23     total = query.count()
24 
25     return render_template(
26         "admin/challenges/challenges.html",
27         challenges=challenges,
28         total=total,
29         q=q,
30         field=field,
31     )
32 
33 
34 @admin.route("/admin/challenges/<int:challenge_id>")
35 @admins_only
36 def challenges_detail(challenge_id):
37     challenges = dict(
38         Challenges.query.with_entities(Challenges.id, Challenges.name).all()
39     )
40     challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
41     solves = (
42         Solves.query.filter_by(challenge_id=challenge.id)
43         .order_by(Solves.date.asc())
44         .all()
45     )
46     flags = Flags.query.filter_by(challenge_id=challenge.id).all()
47 
48     try:
49         challenge_class = get_chal_class(challenge.type)
50     except KeyError:
51         abort(
52             500,
53             f"The underlying challenge type ({challenge.type}) is not installed. This challenge can not be loaded.",
54         )
55 
56     update_j2 = render_template(
57         challenge_class.templates["update"].lstrip("/"), challenge=challenge
58     )
59 
60     update_script = url_for(
61         "views.static_html", route=challenge_class.scripts["update"].lstrip("/")
62     )
63     return render_template(
64         "admin/challenges/challenge.html",
65         update_template=update_j2,
66         update_script=update_script,
67         challenge=challenge,
68         challenges=challenges,
69         solves=solves,
70         flags=flags,
71     )
72 
73 
74 @admin.route("/admin/challenges/new")
75 @admins_only
76 def challenges_new():
77     types = CHALLENGE_CLASSES.keys()
78     return render_template("admin/challenges/new.html", types=types)
79
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/CTFd/admin/challenges.py b/CTFd/admin/challenges.py
--- a/CTFd/admin/challenges.py
+++ b/CTFd/admin/challenges.py
@@ -3,7 +3,10 @@
 from CTFd.admin import admin
 from CTFd.models import Challenges, Flags, Solves
 from CTFd.plugins.challenges import CHALLENGE_CLASSES, get_chal_class
+from CTFd.schemas.tags import TagSchema
 from CTFd.utils.decorators import admins_only
+from CTFd.utils.security.signing import serialize
+from CTFd.utils.user import get_current_team, get_current_user
 
 
 @admin.route("/admin/challenges")
@@ -71,6 +74,43 @@
     )
 
 
+@admin.route("/admin/challenges/preview/<int:challenge_id>")
+@admins_only
+def challenges_preview(challenge_id):
+    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
+    chal_class = get_chal_class(challenge.type)
+    user = get_current_user()
+    team = get_current_team()
+
+    files = []
+    for f in challenge.files:
+        token = {
+            "user_id": user.id,
+            "team_id": team.id if team else None,
+            "file_id": f.id,
+        }
+        files.append(url_for("views.files", path=f.location, token=serialize(token)))
+
+    tags = [
+        tag["value"] for tag in TagSchema("user", many=True).dump(challenge.tags).data
+    ]
+
+    content = render_template(
+        chal_class.templates["view"].lstrip("/"),
+        solves=None,
+        solved_by_me=False,
+        files=files,
+        tags=tags,
+        hints=challenge.hints,
+        max_attempts=challenge.max_attempts,
+        attempts=0,
+        challenge=challenge,
+    )
+    return render_template(
+        "admin/challenges/preview.html", content=content, challenge=challenge
+    )
+
+
 @admin.route("/admin/challenges/new")
 @admins_only
 def challenges_new():

{"golden_diff": "diff --git a/CTFd/admin/challenges.py b/CTFd/admin/challenges.py\n--- a/CTFd/admin/challenges.py\n+++ b/CTFd/admin/challenges.py\n@@ -3,7 +3,10 @@\n from CTFd.admin import admin\n from CTFd.models import Challenges, Flags, Solves\n from CTFd.plugins.challenges import CHALLENGE_CLASSES, get_chal_class\n+from CTFd.schemas.tags import TagSchema\n from CTFd.utils.decorators import admins_only\n+from CTFd.utils.security.signing import serialize\n+from CTFd.utils.user import get_current_team, get_current_user\n \n \n @admin.route(\"/admin/challenges\")\n@@ -71,6 +74,43 @@\n     )\n \n \n+@admin.route(\"/admin/challenges/preview/<int:challenge_id>\")\n+@admins_only\n+def challenges_preview(challenge_id):\n+    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()\n+    chal_class = get_chal_class(challenge.type)\n+    user = get_current_user()\n+    team = get_current_team()\n+\n+    files = []\n+    for f in challenge.files:\n+        token = {\n+            \"user_id\": user.id,\n+            \"team_id\": team.id if team else None,\n+            \"file_id\": f.id,\n+        }\n+        files.append(url_for(\"views.files\", path=f.location, token=serialize(token)))\n+\n+    tags = [\n+        tag[\"value\"] for tag in TagSchema(\"user\", many=True).dump(challenge.tags).data\n+    ]\n+\n+    content = render_template(\n+        chal_class.templates[\"view\"].lstrip(\"/\"),\n+        solves=None,\n+        solved_by_me=False,\n+        files=files,\n+        tags=tags,\n+        hints=challenge.hints,\n+        max_attempts=challenge.max_attempts,\n+        attempts=0,\n+        challenge=challenge,\n+    )\n+    return render_template(\n+        \"admin/challenges/preview.html\", content=content, challenge=challenge\n+    )\n+\n+\n @admin.route(\"/admin/challenges/new\")\n @admins_only\n def challenges_new():\n", "issue": "Challenge Preview Improvements\nChallenge Preview should probably preview in the context of a full page. Primarily because it's easier to theme this. \n", "before_files": [{"content": "from flask import abort, render_template, request, url_for\n\nfrom CTFd.admin import admin\nfrom CTFd.models import Challenges, Flags, Solves\nfrom CTFd.plugins.challenges import CHALLENGE_CLASSES, get_chal_class\nfrom CTFd.utils.decorators import admins_only\n\n\n@admin.route(\"/admin/challenges\")\n@admins_only\ndef challenges_listing():\n    q = request.args.get(\"q\")\n    field = request.args.get(\"field\")\n    filters = []\n\n    if q:\n        # The field exists as an exposed column\n        if Challenges.__mapper__.has_property(field):\n            filters.append(getattr(Challenges, field).like(\"%{}%\".format(q)))\n\n    query = Challenges.query.filter(*filters).order_by(Challenges.id.asc())\n    challenges = query.all()\n    total = query.count()\n\n    return render_template(\n        \"admin/challenges/challenges.html\",\n        challenges=challenges,\n        total=total,\n        q=q,\n        field=field,\n    )\n\n\n@admin.route(\"/admin/challenges/<int:challenge_id>\")\n@admins_only\ndef challenges_detail(challenge_id):\n    challenges = dict(\n        Challenges.query.with_entities(Challenges.id, Challenges.name).all()\n    )\n    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()\n    solves = (\n        Solves.query.filter_by(challenge_id=challenge.id)\n        .order_by(Solves.date.asc())\n        .all()\n    )\n    flags = Flags.query.filter_by(challenge_id=challenge.id).all()\n\n    try:\n        challenge_class = get_chal_class(challenge.type)\n    except KeyError:\n        abort(\n            500,\n            f\"The underlying challenge type ({challenge.type}) is not installed. This challenge can not be loaded.\",\n        )\n\n    update_j2 = render_template(\n        challenge_class.templates[\"update\"].lstrip(\"/\"), challenge=challenge\n    )\n\n    update_script = url_for(\n        \"views.static_html\", route=challenge_class.scripts[\"update\"].lstrip(\"/\")\n    )\n    return render_template(\n        \"admin/challenges/challenge.html\",\n        update_template=update_j2,\n        update_script=update_script,\n        challenge=challenge,\n        challenges=challenges,\n        solves=solves,\n        flags=flags,\n    )\n\n\n@admin.route(\"/admin/challenges/new\")\n@admins_only\ndef challenges_new():\n    types = CHALLENGE_CLASSES.keys()\n    return render_template(\"admin/challenges/new.html\", types=types)\n", "path": "CTFd/admin/challenges.py"}], "after_files": [{"content": "from flask import abort, render_template, request, url_for\n\nfrom CTFd.admin import admin\nfrom CTFd.models import Challenges, Flags, Solves\nfrom CTFd.plugins.challenges import CHALLENGE_CLASSES, get_chal_class\nfrom CTFd.schemas.tags import TagSchema\nfrom CTFd.utils.decorators import admins_only\nfrom CTFd.utils.security.signing import serialize\nfrom CTFd.utils.user import get_current_team, get_current_user\n\n\n@admin.route(\"/admin/challenges\")\n@admins_only\ndef challenges_listing():\n    q = request.args.get(\"q\")\n    field = request.args.get(\"field\")\n    filters = []\n\n    if q:\n        # The field exists as an exposed column\n        if Challenges.__mapper__.has_property(field):\n            filters.append(getattr(Challenges, field).like(\"%{}%\".format(q)))\n\n    query = Challenges.query.filter(*filters).order_by(Challenges.id.asc())\n    challenges = query.all()\n    total = query.count()\n\n    return render_template(\n        \"admin/challenges/challenges.html\",\n        challenges=challenges,\n        total=total,\n        q=q,\n        field=field,\n    )\n\n\n@admin.route(\"/admin/challenges/<int:challenge_id>\")\n@admins_only\ndef challenges_detail(challenge_id):\n    challenges = dict(\n        Challenges.query.with_entities(Challenges.id, Challenges.name).all()\n    )\n    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()\n    solves = (\n        Solves.query.filter_by(challenge_id=challenge.id)\n        .order_by(Solves.date.asc())\n        .all()\n    )\n    flags = Flags.query.filter_by(challenge_id=challenge.id).all()\n\n    try:\n        challenge_class = get_chal_class(challenge.type)\n    except KeyError:\n        abort(\n            500,\n            f\"The underlying challenge type ({challenge.type}) is not installed. This challenge can not be loaded.\",\n        )\n\n    update_j2 = render_template(\n        challenge_class.templates[\"update\"].lstrip(\"/\"), challenge=challenge\n    )\n\n    update_script = url_for(\n        \"views.static_html\", route=challenge_class.scripts[\"update\"].lstrip(\"/\")\n    )\n    return render_template(\n        \"admin/challenges/challenge.html\",\n        update_template=update_j2,\n        update_script=update_script,\n        challenge=challenge,\n        challenges=challenges,\n        solves=solves,\n        flags=flags,\n    )\n\n\n@admin.route(\"/admin/challenges/preview/<int:challenge_id>\")\n@admins_only\ndef challenges_preview(challenge_id):\n    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()\n    chal_class = get_chal_class(challenge.type)\n    user = get_current_user()\n    team = get_current_team()\n\n    files = []\n    for f in challenge.files:\n        token = {\n            \"user_id\": user.id,\n            \"team_id\": team.id if team else None,\n            \"file_id\": f.id,\n        }\n        files.append(url_for(\"views.files\", path=f.location, token=serialize(token)))\n\n    tags = [\n        tag[\"value\"] for tag in TagSchema(\"user\", many=True).dump(challenge.tags).data\n    ]\n\n    content = render_template(\n        chal_class.templates[\"view\"].lstrip(\"/\"),\n        solves=None,\n        solved_by_me=False,\n        files=files,\n        tags=tags,\n        hints=challenge.hints,\n        max_attempts=challenge.max_attempts,\n        attempts=0,\n        challenge=challenge,\n    )\n    return render_template(\n        \"admin/challenges/preview.html\", content=content, challenge=challenge\n    )\n\n\n@admin.route(\"/admin/challenges/new\")\n@admins_only\ndef challenges_new():\n    types = CHALLENGE_CLASSES.keys()\n    return render_template(\"admin/challenges/new.html\", types=types)\n", "path": "CTFd/admin/challenges.py"}]}