From dae2eb440effcf987dfc60d79e68d083e9199bea Mon Sep 17 00:00:00 2001 From: Norm Rasmussen Date: Wed, 15 Mar 2023 17:07:34 -0400 Subject: [PATCH] Code-Input was updated to 1.2.2 and currently works! I have the upload functionality working and have begun working on an undo button. It currently saves all the files to a dir everytime you access /templates but I haven't implemented a full undo yet. --- __pycache__/config.cpython-311.pyc | Bin 556 -> 556 bytes app/__pycache__/__init__.cpython-311.pyc | Bin 653 -> 653 bytes app/__pycache__/forms.cpython-311.pyc | Bin 802 -> 3167 bytes app/__pycache__/routes.cpython-311.pyc | Bin 19324 -> 20994 bytes app/forms.py | 57 +++++- app/routes.py | 143 ++++++++------ .../_cards_course.html.liquid | 49 +++++ .../_cards_featured_course.html.liquid | 44 +++++ .../_course_details.html.liquid | 0 .../_footer.html.liquid | 80 ++++++++ .../_head.html.liquid | 11 ++ .../_header.html.liquid | 183 ++++++++++++++++++ .../_section_faqs.html.liquid | 109 +++++++++++ .../_section_instructors.html.liquid | 91 +++++++++ .../catalog.html.liquid | 39 ++++ .../community.html.liquid | 33 ++++ app/templates/cmtest.html | 13 ++ app/templates/head.html | 4 +- app/templates/index.html | 2 +- app/templates/templates.html | 55 +++--- 20 files changed, 817 insertions(+), 96 deletions(-) create mode 100644 app/static/files/[Sandbox] Norm's Academy/_cards_course.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_cards_featured_course.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_course_details.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_footer.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_head.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_header.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_section_faqs.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/_section_instructors.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/catalog.html.liquid create mode 100644 app/static/files/[Sandbox] Norm's Academy/community.html.liquid create mode 100644 app/templates/cmtest.html diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc index 5fa11ac12b6838298848aafbcb05d8a84c8cfee8..41e977bf1c7f0f285fd164d48ef97fdef34c41c3 100644 GIT binary patch delta 19 ZcmZ3(vWA6gIWI340}#|M+{mTG1OP2@1Tz2t delta 19 ZcmZ3(vWA6gIWI340}%Yu-^iuJ1OP521U>)& diff --git a/app/__pycache__/__init__.cpython-311.pyc b/app/__pycache__/__init__.cpython-311.pyc index be449eda538451b72a35096bf11f0515560470ce..fc92dee82efb5802d62575e279be49abb0c70800 100644 GIT binary patch delta 19 ZcmeBW?PcX!&dbZi00gxQH*z&I0RSoa1Xut7 delta 19 ZcmeBW?PcX!&dbZi00h%bH*z&I0RSj@1O@;A diff --git a/app/__pycache__/forms.cpython-311.pyc b/app/__pycache__/forms.cpython-311.pyc index 020f382b02252e6bf107717bd10cf0c09c5b0a95..34fd422eb6fa804cfbd46afa5420ffb565545534 100644 GIT binary patch literal 3167 zcmcIm&2QUA79UEYsBhU;8po|`YqQ;~)HreD)C~eB_BtQVrb+A|P7h^K2#jW|GA2cJ zDA~2K2OahxU@yMaM`sbFGO9z4`zP#?28;#4Ls4K)zR8GBJ?(o#%Z?-idsys{{Bh=e zXh!pU?+t%SCSwHJ-~Kg7e-|O--#F+r`MC4$7wG&*D4~);Oi7g_><5g18B~L2NDY~? zDw|<7Y$~c^M%0KIRinZtXvEC88aESaLX1O3(oCr-Gp(k@ST+XCL3L2{!^V)AQ8N+= zkOzb+eN%l{f-csl`#|X8piA`W&I?@4;p597;Ku9r*4y65bN>O5zfKTJF^$xw9HqU?#zx#iDUJl-+!0$xRX_Y7V?5=K;s5;YJYEJ!85&>N8d?Ari> zM5X~6Y=zzgKn{=JN`aQ#Em6ZX411?|;rWXGh;3{t@XkW#;2gLdi~#Hgyr8L<0kj`> zB`>z789LRf7Pl9{FH$JrA1D;OSfOBAv}RyGQ7C+0(+pq3F$#GcApzhiT179cvW;Ex z4u<5nxyi3=#_h>6Fvd08tl2gzPu{bNHItRA_T*D;y<|n`++BWBSZ6P^N@WtC6|lFj zRyOz${xm`w9{T}6{p4~}A2rPFhi-1VncPjc(r)f*GyHbyA5%_lb}u)(pPOw5rQDyS zb}*P8J0t){2=xbe@$t?tcd>DjReu5Xe`lj4wE{i6E(1eh8tiB83|j@PA~f_y0w&?{ zn;NAu@D}zG&zV^F#*8z3+5P=z zJGWoWy`FO}UWe^ZOdk?}BZT_Bc9IPcf5LT&? z#y8H$<-O#@esZF|fS11xTtXLN_*byKdkN4@*qIbaJ)7;*1qnq%B}_V{JKcaZxu?uU zj?+rHYp)?QJ`3@A!^m1ZyKI?k^Ftg!QQ>6>{;XckYA`Nwt5&f$vyVG+t88otC4H$C zAsvn_ASspNca~mcHpe7g%tw3qOM;lE0K5>E8IGrf&u1KFDp}O8=+FtzHe*9Yfo;x(U_38Gv?xj2Kr9T5%m%fyK&41DS zcz3)t?&NN^m0)HDvMVzK*_D~8Kf=o=3+L)0>!jAffzw0Q|61#iIvVb$93(PTT9Izr z�CWu#D1Z|1XFTfI53xYt}DQy-3jk$o4@m zcGs$LTjaVYKi8`UJ3v|wC;>}4IRoyBd{1dc!i4Vielb>>k98Z4C z)|inGdXYP8jrV!n`YD8 zwOW>QW!6c|?Iq^+6LaCvfbC@$S@lYZD5IYjBv87dKO{{f1Q3q}9{ literal 802 zcmZuuzi-n}5WeSMN!z3yng}`}8VM-~HAtvPNC*%`VM;*?EM~BryqDDAXQ%Jks@O6x zFm@{=QxGbDOpq9?w=%J%YNt-zv)xJ&oZp?lyL-C(?%lU~eHBpb`x|tZ0Q}a@mDnXX z?;3Y3JviA#vaMrd%;HFIo+7PnoSfB`RoTAzU0jLb}cQ`ACShdO;|SN>?XP1H&^ z^yP&iGW15B<*F5hq^}`|~^bD$=lx@8s zjw>u3b7cMy-{D+yynNbuE3t7WLSn*~Je86~ofq*iPB%%Ps#J8?vz3 zQC_);=(75_c(^BG3thc28KYU4gpdqw&6iIGcjn6{g9r2Fv#>1ETEM^N_|ch;Ui>GO G6Z#9R#na{h diff --git a/app/__pycache__/routes.cpython-311.pyc b/app/__pycache__/routes.cpython-311.pyc index d415f5cdef58e258c129571220c5db00deb4474e..c5ae44804c84f3f163c6a4236e98b61e82395eb8 100644 GIT binary patch delta 6446 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 Bp3eXP diff --git a/app/forms.py b/app/forms.py index cd95e1a..fdc8acd 100644 --- a/app/forms.py +++ b/app/forms.py @@ -1,10 +1,55 @@ from flask_wtf import FlaskForm -from wtforms.fields import SubmitField +from wtforms.fields import (SubmitField, + PasswordField, + StringField, + TextAreaField, + IntegerField, + BooleanField, + RadioField) +from wtforms.validators import InputRequired, Length +from flask_wtf.file import FileField, FileRequired +from werkzeug.utils import secure_filename from flask_codemirror.fields import CodeMirrorField -class TemplateForm(FlaskForm): - template_code = CodeMirrorField( - language='htmlembedded', - config={'lineNumbers': 'true'}) - submit = SubmitField('Submit') + +class ApiKey(FlaskForm): + api_key = PasswordField('Api Key', + validators=[InputRequired(), + Length(min=20, max=25)] + ) + + +class TemplateForm(FlaskForm): + name = StringField("Template File Name", + validators=[InputRequired()]) + + body = TextAreaField("Template Code", + validators=[InputRequired()]) + + submit = SubmitField('Upload Templates') + + # template_code = CodeMirrorField( language='htmlembedded', + # config={'lineNumbers': 'true'}) + +class CsvForm(FlaskForm): + file = FileField(validators=[FileRequired()]) + all_or_some = RadioField("All or Some", + choices=['All learners in all groups', + 'Learners only in adjacent groups'], + validators=[InputRequired()]) + + + +class CourseForm(FlaskForm): + title = StringField('Title', + validators=[InputRequired(), + Length(min=10, max=100)]) + description = TextAreaField('Course Description', + validators=[InputRequired(), + Length(max=200)]) + price = IntegerField('Price', validators=[InputRequired()]) + level = RadioField('Level', + choices=['Beginner', 'Intermediate', 'Advanced'], + validators=[InputRequired()]) + available = BooleanField('Available', default='checked') diff --git a/app/routes.py b/app/routes.py index 0fe81bf..5b5129f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -13,6 +13,7 @@ from flask import ( session, make_response, url_for, + g, ) from werkzeug.utils import secure_filename from app import app, forms @@ -26,6 +27,7 @@ ALLOWED_EXTENSIONS = {"csv"} # Global Variables url = "https://api.northpass.com/" + def download_csv(): if request.method == "GET": download = make_response(session["dfcsv"]) @@ -57,11 +59,13 @@ def allowed_file(filename): def key_required(check): @wraps(check) def decorated_function(*args, **kwargs): - if session.get('key') is None: - return redirect('/',code=302) + if session.get("key") is None: + return redirect("/", code=302) return check(*args, **kwargs) + return decorated_function + @app.route("/", methods=["GET", "POST"]) def ask_key(): """This is the main function that asks for the API Key. @@ -71,8 +75,9 @@ def ask_key(): specials = '"!@#$%^&*()-+?_=,<>/"' if request.method == "POST": session["key"] = request.form.get("apikey") - if (any(char in specials for char in session["key"]) or - re.search(r"[\s]", session["key"])): + if any(char in specials for char in session["key"]) or re.search( + r"[\s]", session["key"] + ): error = "Invalid Key." session.clear() return render_template("index.html", title="Home", error=error) @@ -100,7 +105,7 @@ def render_home(): def clear_session(): if session.get("key"): session.clear() - error="Session Cleared!" + error = "Session Cleared!" return render_template("index.html", error=error, title="Home, New session") return render_template("index.html", title="Home, New session") @@ -109,6 +114,7 @@ def clear_session(): def table(): return render_template("table.html", tables=[session["table"]], titles=["Table"]) + @app.route("/upload_file", methods=["GET", "POST"]) @key_required def upload_file(): @@ -133,11 +139,12 @@ def upload_file(): return divide_values(file) return render_template("home.html", title="Bulk Add") + def divide_values(file): emails = [] groups = [] - selection = request.form.get('learner-groups') - if request.form['submit']: + selection = request.form.get("learner-groups") + if request.form["submit"]: if selection == "all-groups": for item in file[1:]: emails.append(item[0]) @@ -160,13 +167,12 @@ def divide_values(file): return api_csv_parse(emails, groups) return emails - if request.form['preview']: - error="Preview Button Still Under Construction. Try again later." + if request.form["preview"]: + error = "Preview Button Still Under Construction. Try again later." return render_template("bulk_add.html", error=error, title="Preview Not Yet") - return render_template( - "bulk_add.html", title="Uploaded File" - ) + return render_template("bulk_add.html", title="Uploaded File") + def api_csv_parse(emails, groups): if emails and groups: @@ -175,13 +181,15 @@ def api_csv_parse(emails, groups): return api_add_ppl(emails) elif groups: return api_add_groups(groups) - return render_template("bulk_add.html", table=htmlcsv, title="CSV Submission") + return render_template("bulk_add.html", title="CSV Submission") + @app.route("/bulk_add_opts", methods=["GET", "POST"]) @key_required def bulk_add_opts(): return render_template("bulk_add.html", titles="Bulk Add Options") + @app.route("/bulk_add", methods=["GET", "POST"]) @key_required def bulk_add(): @@ -223,8 +231,8 @@ def api_add_ppl(emails): payload2 = [] endpoint = "v2/bulk/people" for email in emails: - payload2.append({"email": email }) - payload = {"data": {"attributes": {"people": payload2 }}} + payload2.append({"email": email}) + payload = {"data": {"attributes": {"people": payload2}}} headers = { "accept": "application/json", "content-type": "application/json", @@ -239,8 +247,8 @@ def api_add_groups(groups): payload2 = [] endpoint = "v2/bulk/people" for group in groups: - payload2.append({"groups" : group }) - payload = {"data": {"attributes": {"people": payload2 }}} + payload2.append({"groups": group}) + payload = {"data": {"attributes": {"people": payload2}}} headers = { "accept": "application/json", "content-type": "application/json", @@ -257,9 +265,7 @@ def api_add_ppl_groups(emails, groups): combinations = list(itertools.product(emails, groups)) for combo in combinations: payload2.append({"email": combo[0], "groups": combo[1]}) - payload = { - "data": {"attributes": {"people": payload2 }} - } + payload = {"data": {"attributes": {"people": payload2}}} headers = { "accept": "application/json", @@ -267,8 +273,8 @@ def api_add_ppl_groups(emails, groups): "X-Api-Key": session["key"], } return payload - #response = requests.post(url + endpoint, json=payload, headers=headers) - #return check_response(response) + # response = requests.post(url + endpoint, json=payload, headers=headers) + # return check_response(response) def check_response(response): @@ -286,11 +292,12 @@ def check_response(response): error = "Something went wrong, but I'm not sure what." return render_template("bulk_add.html", title="Shrug", error=error) + @app.route("/load_templates", methods=["GET", "POST"]) @key_required def load_templates(): count = 0 - templates= [] + templates = [] while True: count += 1 @@ -300,33 +307,44 @@ def load_templates(): "content-type": "application/json", "X-Api-Key": session["key"], } - response = requests.get(url+endpoint, headers=headers) + response = requests.get(url + endpoint, headers=headers) data = response.json() nextlink = data["links"] for response in data["data"]: - name, body = ( - response["attributes"]["name"], response["attributes"]["body"]) - templates.append((name,body)) + last_updated = response["attributes"]["updated_at"].split("T") + last_updated = last_updated[0] + name, body, last_updated = ( + response["attributes"]["name"], + response["attributes"]["body"], + last_updated, + ) + templates.append((name, body, last_updated)) if "next" not in nextlink: break - return render_template("templates.html", - title="Templates", - templates=templates, - ) + save_templates_backup(templates) + return render_template( + "templates.html", + title="Templates", + templates=templates, + ) return render_template("options.html") + @app.route("/templates", methods=["GET", "POST"]) @key_required def templates(): if request.method == "POST": - if request.form['submit-template']: - name = request.form.get('template_name') - body = request.form.get("loaded-content") + if request.form["submit-template"]: + name = request.form.get("template_name") + body = request.form.get("body") + g.last_template = name if body == "": - error = "Ooph. Looks like you didn't load the changes before submitting." + error = ( + "Ooph. Looks like you didn't load the changes before submitting." + ) return render_template("templates.html", error=error) else: endpoint = "v2/custom_templates" @@ -335,22 +353,21 @@ def templates(): "content-type": "application/json", "X-Api-Key": session["key"], } - payload = {"custom_template": { - "name":name, - "body":body - }} - response = requests.post(url+endpoint, json=payload, headers=headers) + payload = {"custom_template": {"name": name, "body": body}} + response = requests.post(url + endpoint, json=payload, headers=headers) return check_templates(response) return load_templates() + def check_templates(response): print(response) response = str(response) if "201" in response: error = "Success! Templates Uploaded." - return render_template("templates.html", - title="Templates Added", - error=error) + button = "Undo" + return render_template( + "templates.html", title="Templates Added", error=error, button=button + ) elif "403" in response: error = "Uh oh. Looks like you don't have appropriate privileges." return render_template("templates.html", error=error) @@ -362,28 +379,44 @@ def check_templates(response): return render_template("templates.html", title="Shrug", error=error) -@app.route("/bulk_courses_to_groups", methods=["GET", "POST"]) +def save_templates_backup(templates): + g.client_path = os.path.join(UPLOAD_FOLDER, session["school"]) + if os.path.exists(g.client_path): + pass + else: + os.mkdir(g.client_path) + + for tupe in templates: + file_name = tupe[0] + ".liquid" + file_body = tupe[1] + complete_path = os.path.join(g.client_path, file_name) + + with open(complete_path, "w+") as temp: + temp.write(file_body) + temp.close + + +@app.route("/undo_template", methods=["POST"]) @key_required -def bulk_courses_to_groups(): - pass +def undo_template(): + print(g.client_path) + template_path = os.path.join(g.client_path, g.last_template) + if request.method == "POST": + if request.form["undo_templates"]: + if os.path.exists(template_path): + print(template_path) -@app.route("/bulk_invite_ppl", methods=["GET", "POST"]) -@key_required -def bulk_invite_ppl(): - pass - -@app.route('/cmtest', methods = ['GET', 'POST']) +@app.route("/cmtest", methods=["GET", "POST"]) def cmtest(): form = TemplateForm() if form.validate_on_submit(): text = form.template_code.data - return render_template('templates.html', form=form) - + return render_template("templates.html", form=form) app.secret_key = "@&I\x1a?\xce\x94\xbb0w\x17\xbf&Y\xa2\xc2(A\xf5\xf2\x97\xba\xeb\xfa" -#if __name__ == "__main__": +# if __name__ == "__main__": # ask_key() diff --git a/app/static/files/[Sandbox] Norm's Academy/_cards_course.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_cards_course.html.liquid new file mode 100644 index 0000000..7d08608 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_cards_course.html.liquid @@ -0,0 +1,49 @@ + +
+ {% if course.ribbon %} +
+ {{ course.ribbon }} +
+ {% endif %} + +
+

+ {{ course.name }} +

+
+ {{ course.full_description }} +
+ +
+ {% t shared.progress, count: course.progress %} +
+ +
+
+
+ diff --git a/app/static/files/[Sandbox] Norm's Academy/_cards_featured_course.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_cards_featured_course.html.liquid new file mode 100644 index 0000000..70cba72 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_cards_featured_course.html.liquid @@ -0,0 +1,44 @@ + diff --git a/app/static/files/[Sandbox] Norm's Academy/_course_details.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_course_details.html.liquid new file mode 100644 index 0000000..e69de29 diff --git a/app/static/files/[Sandbox] Norm's Academy/_footer.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_footer.html.liquid new file mode 100644 index 0000000..79a0481 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_footer.html.liquid @@ -0,0 +1,80 @@ +
+ + + +
diff --git a/app/static/files/[Sandbox] Norm's Academy/_head.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_head.html.liquid new file mode 100644 index 0000000..bde9ff3 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_head.html.liquid @@ -0,0 +1,11 @@ +{% styles default %} +{% styles colors %} +{% styles custom %} + + + + + + + + diff --git a/app/static/files/[Sandbox] Norm's Academy/_header.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_header.html.liquid new file mode 100644 index 0000000..56b76c5 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_header.html.liquid @@ -0,0 +1,183 @@ +
+
+
+ {% if current_person.signed_in? %} + + + {% endif %} +
+ {% if current_school.logo_url %} +

+ + {{ current_school.name }} + +

+ {% else %} + + {{ current_school.name }} + + {% endif %} + +
+ +
+ + {% if current_person.signed_in? %} + +
+ + +
+ {% else %} +
+ +{% include "messages" %} + diff --git a/app/static/files/[Sandbox] Norm's Academy/_section_faqs.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_section_faqs.html.liquid new file mode 100644 index 0000000..7e6d46f --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_section_faqs.html.liquid @@ -0,0 +1,109 @@ + +/ + + + \ No newline at end of file diff --git a/app/static/files/[Sandbox] Norm's Academy/_section_instructors.html.liquid b/app/static/files/[Sandbox] Norm's Academy/_section_instructors.html.liquid new file mode 100644 index 0000000..2433e20 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/_section_instructors.html.liquid @@ -0,0 +1,91 @@ + + + + + \ No newline at end of file diff --git a/app/static/files/[Sandbox] Norm's Academy/catalog.html.liquid b/app/static/files/[Sandbox] Norm's Academy/catalog.html.liquid new file mode 100644 index 0000000..8ce1105 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/catalog.html.liquid @@ -0,0 +1,39 @@ +{% include "header" %} +{% include "course_version_outdated_alert", courses: courses.in_catalog %} +
+
+
+
+
+ Menlo Security Resrouces +
+
+ Resources to help you make the most of your Security Training +
+
+
+{% include "sub_navigation" %} + {% include "courses_catalog" %} + +{% include "footer" %} + + + + + \ No newline at end of file diff --git a/app/static/files/[Sandbox] Norm's Academy/community.html.liquid b/app/static/files/[Sandbox] Norm's Academy/community.html.liquid new file mode 100644 index 0000000..9157fd7 --- /dev/null +++ b/app/static/files/[Sandbox] Norm's Academy/community.html.liquid @@ -0,0 +1,33 @@ + {% include 'header' %} +
+
+

Explore

+
+ {% include 'sub_navigation' %} +
+ +
+
+{% include 'footer' %} + + + \ No newline at end of file diff --git a/app/templates/cmtest.html b/app/templates/cmtest.html new file mode 100644 index 0000000..4131146 --- /dev/null +++ b/app/templates/cmtest.html @@ -0,0 +1,13 @@ + +{% include 'head.html' %} +{% include 'header.html' %} +{% include 'logo.html' %} +

 

+{% if error %} +

{{ error }}

+{% endif %} + +
+ {{ form.name.label }} {{ form.name(size=20) }} + +
diff --git a/app/templates/head.html b/app/templates/head.html index e54e670..f4f9abd 100644 --- a/app/templates/head.html +++ b/app/templates/head.html @@ -17,8 +17,8 @@ - - + + diff --git a/app/templates/index.html b/app/templates/index.html index 53eb833..8ca25c5 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -11,7 +11,7 @@

- +
diff --git a/app/templates/templates.html b/app/templates/templates.html index 9e0d08d..be0e5cd 100644 --- a/app/templates/templates.html +++ b/app/templates/templates.html @@ -6,6 +6,17 @@ {% if error %}

{{ error }}

{% endif %} + +{% if button %} +
+
+ +
+{% endif %} + {% if templates %}

Here are the liquid templates for

{{ session.school }}

@@ -18,10 +29,9 @@ id="templates" action="{{ url_for('templates')}}" method="post"> -

- {{ templates[0] }} -

- {{ templates[0] }} +

Last Updated: {{ templates [2] }}

+ {{ templates[1] }} - @@ -42,12 +48,6 @@ value="{{ templates[0] }}">

 

-
Click here to load changes

 

{% endfor %} - + +{% endif %} - -